Skip to content

Instantly share code, notes, and snippets.

@Niemi
Forked from dannysheehan/gist:9d67adb67eeef6ad1413
Last active September 16, 2015 10:05
Show Gist options
  • Save Niemi/d434f2b94566796a4502 to your computer and use it in GitHub Desktop.
Save Niemi/d434f2b94566796a4502 to your computer and use it in GitHub Desktop.
haproxy.cfg configuration for 1Gb KVM with 1 CPU with backend NGINX and percona /mariadb cluster.
#---------------------------------------------------------------------------
# @(#)$Id$
#title :/etc/haproxy/haproxy.cfg
#description :ftmon cluster haproxy config. NGINX and XtraDB Cluster backend
#author :Danny W Sheehan
#date :July 2014
#website :ftmon.org
#
# This is a work in progress. A lot of trial and error and man hours have
# gone into this configuration. I have referenced sources that have been
# helpful.
#
# ftmon cluster is tuned for KVM with 1G of memory and 1 cpu.
#
# Final configuration will be available at https://github.com/ftmon as
# opensource.
#---------------------------------------------------------------------------
global
# just turn this on when you need to do debugging
log /dev/log local7
user haproxy
group haproxy
daemon
#debug
#quiet
ulimit-n 65536
# Distribute the health checks with a bit of randomness
spread-checks 5
# access for monitoring by nagios or by other tools
stats socket /var/run/haproxy.stat mode 777
defaults
# apply log settings from the global section above to services
log global
# http://haproxy.1wt.eu/download/1.3/examples/antidos.cfg
maxconn 2000
# Don't queue requests too long if we get saturaed with a DOs
timeout queue 5s
timeout tarpit 1m
# https://www.twilio.com/engineering/2013/10/16/haproxy
# If sending request to one server fails, then try another before failing.
retries 1
# Don't enforce sessions affinity. Requests can be served by any backend
# not just the one that started it.
option redispatch
# Must match the longest time we must wait for a response from the server.
# since our backends may be on different servers it is set quite large.
timeout connect 63s
# wordpress and other software installs can take time.
timeout server 500s
# time you let a client to send it's request
# some people set pretty low
timeout client 30s
# Good notes below on errorfile
# http://www.kloppmagic.ca/load-balancing-with-haproxy/
errorfile 400 /etc/haproxy/errors/400.http
# Show "Not Found" 404 errors in place of "Forbidden" 403 errors, because
# forbidden errors allow attackers potential insight into your server's
# configuration and contents.
errorfile 403 /etc/haproxy/errors/404.http
# chrome bug from May 2014. It may be since fixed.
# http://blog.haproxy.com/2014/05/26/haproxy-and-http-errors-408-in-chrome/
errorfile 408 /dev/null
errorfile 500 /etc/haproxy/errors/500.http
errorfile 502 /etc/haproxy/errors/502.http
errorfile 503 /etc/haproxy/errors/503.http
errorfile 504 /etc/haproxy/errors/504.http
frontend www
bind ${LB1}:80
# option accept-invalid-http-request
# https://community.qualys.com/blogs/securitylabs/2011/10/17/mitigating-the-beast-attack-on-tls
bind ${LB1}:443 ssl crt /etc/haproxy/default.pem crt /etc/haproxy/certs.d ciphers ECDHE-RSA-AES256-SHA:RC4-SHA:RC4:HIGH:!MD5:!aNULL:!EDH:!AESGCM
# no-sslv3 ?
# no-tls-tickets ?
mode http
option httplog
# do not log requests with no data
option dontlognull
monitor-uri /haproxy-test
maxconn 2000
# http://blog.killtheradio.net/technology/haproxys-keep-alive-functionality-and-how-it-can-speed-up-your-site/
option http-server-close
timeout http-keep-alive 5s
# Thwart Slowloris like attacks
# http://blog.exceliance.fr/2012/02/27/use-a-load-balancer-as-a-first-row-of-defense-against-ddos/
#timeout http-request 5s
timeout http-request 7s
# http://serverfault.com/questions/291467/haproxy-badreq-errors
# timeout http-request 20s
# support for 'X-Forwarded-For: IP'
option forwardfor except 127.0.0.1
# useful for tracking requests in logs.
capture request header Host len 30
capture request header User-Agent len 30
capture request header Content-Length len 10
capture request header Referer len 20
# http-request deny any unwanted source IP addresses or networks
# acl forbidden_src src 0.0.0.0/7 224.0.0.0/3
# acl forbidden_src src_port 0:1023
# http-request deny if forbidden_src
# ... some HTTP content smugling and other various things
acl forbidden_hdrs hdr_cnt(host) gt 1
acl forbidden_hdrs hdr_cnt(content-length) gt 1
acl forbidden_hdrs hdr_val(content-length) lt 0
acl forbidden_hdrs hdr_cnt(proxy-authorization) gt 0
http-request deny if forbidden_hdrs
#
# http-request deny requests to "*" URL with methods other than "OPTIONS" in
# addition to POST requests without content-length
acl missing_cl hdr_cnt(Content-length) eq 0
http-request deny if HTTP_URL_STAR !METH_OPTIONS || METH_POST missing_cl
# http-request deny if GET with content.
http-request deny if METH_GET HTTP_CONTENT
# http-request deny unless GET/HEAD/POST/OPTIONS request
# http-request deny unless METH_GET or METH_POST or METH_OPTIONS
# http-request deny requests to domains we don't host.
acl valid_domains hdr_end(host) -i -f /etc/haproxy/valid_domains.lst
# where you login from.
acl mgmt_src src -f /etc/haproxy/whitelist.lst
# stuff you don't want others to access.
acl adminurls url_sub -i -f /etc/haproxy/adminurls.lst
# domains you don't want others to access.
acl admin_domains hdr_end(host) -i -f /etc/haproxy/admin_domains.lst
# IP's you don't trust.
acl badguys src -f /etc/haproxy/badguys.lst
# domains you want to allow login access to. e.g. forums.
acl forum_domains hdr_end(host) -i -f /etc/haproxy/forum_domains.lst
# urls that allow login.
acl loginurls url_beg -f /etc/haproxy/loginurls.lst
# only allow admin access from admin desktop to admin websites
http-request deny if !mgmt_src admin_domains
# if we don't host the domain we deny it.
http-request deny if !valid_domains !admin_domains
# allow legitimate access
# - management urls accessible only from management workstations
http-request deny if adminurls !mgmt_src
# - login urls accessible only to forum domains and management workstations
http-request deny if loginurls !forum_domains !mgmt_src
#
# http-request deny ip address ranges you deem as bad guys
#
http-request deny if badguys
#
# stop bad bots and spiders
#
acl badbots hdr_reg(User-Agent) -i -f /etc/haproxy/badbots.lst
http-request deny if !mgmt_src badbots
#
# stop bad referers
#
acl badreferer hdr_sub(referer) -i -f /etc/haproxy/badreferer.lst
http-request deny if !mgmt_src badreferer
# insert certificate information ?
# This example config sends all available certificate details to your backend application as HTTP Headers:
# https://raymii.org/s/tutorials/haproxy_client_side_ssl_certificates.html
# The {+Q} means that the data is quoted as a string. Otherwise it would be binary or boolean.
# log-format %ci:%cp\ [%t]\ %ft\ %b/%s\ %Tq/%Tw/%Tc/%Tr/%Tt\ %ST\ %B\ %CC\ %CS\ %tsc\ %ac/%fc/%bc/%sc/%rc\ %sq/%bq\ %hr\ %hs\ {%[ssl_c_verify],%{+Q}[ssl_c_s_dn],%{+Q}[ssl_c_i_dn]}\ %{+Q}r
http-request set-header X-SSL %[ssl_fc]
http-request set-header X-SSL-Client-Verify %[ssl_c_verify]
http-request set-header X-SSL-Client-DN %{+Q}[ssl_c_s_dn]
http-request set-header X-SSL-Client-CN %{+Q}[ssl_c_s_dn(cn)]
http-request set-header X-SSL-Issuer %{+Q}[ssl_c_i_dn]
http-request set-header X-SSL-Client-NotBefore %{+Q}[ssl_c_notbefore]
http-request set-header X-SSL-Client-NotAfter %{+Q}[ssl_c_notafter]
# https://gist.github.com/rnewson/8384304
# https://raymii.org/s/snippets/haproxy_add_strict_transport_security_or_any_other_http_header.html
# http://www.debian-administration.org/article/662/Enabling_HTTP_Strict_Transport_Security_on_debian_servers
# https://www.owasp.org/index.php/HTTP_Strict_Transport_Security
# rspadd Strict-Transport-Security:\ max-age=31536000;\ includeSubDomains if { ssl_fc }
# https://raymii.org/s/tutorials/haproxy_intercept_all_cookies_and_set_secure_attribute.html
#rspirep ^(set-cookie:.*) \1;\ Secure if { ssl_fc }
reqadd X-Forwarded-Proto:\ https if { ssl_fc }
reqadd X-Proto:\ SSL if { ssl_fc }
# hide what type of server and software we run.
rspidel ^Server:\
rspadd Server:\ ftmon.org\ cluster
# Only allow hastats to be visible from admin hosts not from website domains.
acl hastatsurl url_sub -i /haproxy
use_backend hastats if hastatsurl admin_domains
use_backend adminsrv if { ssl_fc }
acl cron url_beg /wp-cron.php /wp-admin/admin-ajax.php?action=wp_multisite_cron_call
use_backend adminsrv if cron
acl static_domains hdr_end(host) -i -f /etc/haproxy/staticsite_domains.lst
use_backend static if static_domains
default_backend www
backend adminsrv
mode http
# option accept-invalid-http-response
option abortonclose
option httplog
balance roundrobin
server admin 127.0.0.1:8080
backend hastats
mode http
stats enable
stats scope http
stats scope www
stats scope static
stats scope mysql
stats scope https
stats scope adminsrv
stats hide-version
stats uri /haproxy
backend static
mode http
option abortonclose
option httpchk
option httplog
balance roundrobin
server static1 127.0.0.1:8080
backend www
option accept-invalid-http-response
mode http
option abortonclose
option httplog
balance roundrobin
server php1 127.0.0.1:8080
#option httpchk GET /checkserver.php HTTP/1.1\r\nHost:\ localhost
#server php2 127.0.2.2:8080 check port 80 inter 7000 fastinter 2000 rise 3 fall 3
#server php3 127.0.2.3:8080 check port 80 inter 12000 fastinter 2000 rise 3 fall 3 backup
#backend spdy_srv
# server speed1 127.0.0.1:80
#backend discourse
# mode http
# option abortonclose
# option httplog
listen mysql 127.0.0.1:3306
mode tcp
balance roundrobin
option httpchk
server lb1 ${LB1}:3306 check addr ${LB1} port 9200 inter 6000 fastinter 2000 rise 2 fall 2
server lb2 ${LB2}:3306 check addr ${LB2} port 9200 inter 11000 fastinter 2000 rise 2 fall 2 backup
server lb3 ${LB3}:3306 check addr ${LB3} port 9200 inter 11000 fastinter 2000 rise 2 fall 2 backup
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment