chef/cookbooks/haproxy/templates/default/haproxy.cfg.erb
global
log 127.0.0.1 local0
log 127.0.0.1 local1 notice
maxconn <%= node[:haproxy][:global][:maxconn] %>
tune.bufsize <%= node[:haproxy][:global][:bufsize] %>
tune.maxrewrite <%= node[:haproxy][:global][:maxrewrite] %>
tune.chksize <%= node[:haproxy][:global][:chksize] %>
chroot /var/lib/haproxy
user <%= node[:haproxy][:platform][:user] %>
group <%= node[:haproxy][:platform][:group] %>
daemon
stats socket /var/lib/haproxy/stats.sock user haproxy group haproxy mode 0640 level operator
tune.ssl.default-dh-param 2048
ssl-default-bind-options no-sslv3 no-tlsv10
ssl-default-server-options no-sslv3 no-tlsv10
ssl-default-bind-ciphers DEFAULT_SUSE
ssl-default-server-ciphers DEFAULT_SUSE
defaults
log global
mode tcp
option tcplog
option dontlognull
option redispatch
retries 3
timeout http-request 10s
timeout http-keep-alive 10s
timeout queue 1m
timeout connect 5s
timeout client 3h
timeout server 3h
timeout check 5s
balance <%= node[:haproxy][:defaults][:balance] %>
<% # if stats are not enabled, but there's no configured section, we setup stats on 127.0.0.1 to generate a valid config file (it needs at least one section) -%>
<% if node[:haproxy][:stats][:enabled] || node[:haproxy][:sections].empty? -%>
listen admin-stats <%= node[:haproxy][:stats][:enabled] ? node[:haproxy][:stats][:address] : "127.0.0.1" %>:<%= node[:haproxy][:stats][:port] %>
mode http
option httplog
stats uri /
<% end -%>
<% node[:haproxy][:sections].keys.sort.each do |type| -%>
<% node[:haproxy][:sections][type].keys.sort.each do |name| -%>
<% content = node[:haproxy][:sections][type][name] -%>
<%= type %> <%= name %>
<% if content[:terminate_ssl] -%>
bind <%= content[:address] %>:<%= content[:port] %> ssl crt <%= content[:pemfile] %>
<% else -%>
bind <%= content[:address] %>:<%= content[:port] %>
<% end -%>
mode <%= content[:mode] %>
<% unless content[:balance].nil? -%>
balance <%= content[:balance] %>
<% end -%>
<% if content[:use_ssl] && !content[:terminate_ssl] # http://www.haproxy.com/blog/maintain-affinity-based-on-ssl-session-id/ -%>
# maximum SSL session ID length is 32 bytes.
stick-table type binary len 32 size 100k expire <%= content[:stick] ? content[:stick][:expire] : "32m" %>
acl clienthello req.ssl_hello_type 1
acl serverhello res.ssl_hello_type 2
# use tcp content accepts to detects ssl client and server hello.
tcp-request inspect-delay 5s
tcp-request content accept if clienthello
# no timeout on response inspect delay by default.
tcp-response content accept if serverhello
# SSL session ID (SSLID) may be present on a client or server hello.
# Its length is coded on 1 byte at offset 43 and its value starts
# at offset 44.
# Match and learn on request if client hello.
stick on payload_lv(43,1) if clienthello
# Learn on response if server hello.
stick store-response payload_lv(43,1) if serverhello
<% elsif content[:mode] == "http" && content[:stick] &&
content[:stick][:cookies] && !content[:stick][:cookies].empty?
# There are various options here, described in:
# http://stackoverflow.com/questions/27094501/haproxy-1-5-8-how-do-i-configure-cookie-based-stickiness
# We go with the stick-table to avoid no-cache and exposing backends
# through cookies.
# Note that appsession is easier, but deprecated:
# http://serverfault.com/questions/550910/haproxy-appsession-vs-cookie-precedence
-%>
stick-table type string len 64 size 100k expire <%= content[:stick][:expire] %>
<% content[:stick][:cookies].each do |cookie| -%>
stick store-response res.cook(<%= cookie %>)
stick match req.cook(<%= cookie %>)
<% end -%>
<% end -%>
<% if content[:stick] && content[:stick][:on] && !content[:stick][:on].empty? -%>
stick-table type ip size 1000
stick on <%= content[:stick][:on] %>
<% end -%>
<% unless content[:rate_limit].nil? || content[:rate_limit].to_i.zero? -%>
# Rate limiting config options
tcp-request inspect-delay 5s
acl too_many_reqs_by_user sc0_gpc0_rate() gt <%= content[:rate_limit] %>
acl mark_seen sc0_inc_gpc0 gt 0
stick-table type string size 100k expire 60s store gpc0_rate(60s)
tcp-request content track-sc0 src
use_backend be_429_slow_down if mark_seen too_many_reqs_by_user
# End Rate limiting config options
<% end -%>
<% content[:options].each do |option| -%>
option <%= option %>
<% end -%>
<% unless content[:max_connections].nil? -%>
maxconn <%= content[:max_connections] %>
<% end -%>
<% unless content[:default_server].nil? -%>
default-server <%= content[:default_server] %>
<% end -%>
<% content[:servers].each do |server| -%>
<%
ssl = content[:use_ssl] ? " check-ssl verify none" : ""
inter = " inter #{server[:inter] || 2000}"
fastinter = server[:fastinter] ? " fastinter #{server[:fastinter]}" : ""
downinter = server[:downinter] ? " downinter #{server[:downinter]}" : ""
rise = " rise #{server[:rise] || 5}"
fall = " fall #{server[:fall] || 2}"
backup = server[:backup] ? " backup" : ""
on_marked_down_shutdown = server[:on_marked_down_shutdown] ? " on-marked-down shutdown-sessions" : ""
terminate_ssl = content[:terminate_ssl] ? " ssl" : ""
%>
server <%= server[:name] %> <%= server[:address] %>:<%= server[:port] %> check<%= ssl %><%= inter %><%= fastinter %><%= downinter %><%= rise %><%= fall %><%= backup %><%= on_marked_down_shutdown %><%= terminate_ssl %>
<% end -%>
<% end -%>
<% end -%>
<% if @rate_limit_enabled -%>
backend be_429_slow_down
mode http
timeout tarpit 2s
errorfile 500 <%= node[:haproxy][:platform][:error_dir] %>/429.http
http-request tarpit
<% end -%>