Skip to content
Snippets Groups Projects
haproxy_cfg 14.8 KiB
Newer Older
  • Learn to ignore specific revisions
  • jurgenhaas's avatar
    jurgenhaas committed
    global
    
      log 127.0.0.1:20514 local1
    
    jurgenhaas's avatar
    jurgenhaas committed
      chroot /var/lib/haproxy
      stats socket /run/haproxy/admin.sock mode 660 level admin
      stats timeout 30s
      user haproxy
      group haproxy
      daemon
      ca-base /etc/haproxy/certs
      crt-base /etc/haproxy/private
    
    jurgenhaas's avatar
    jurgenhaas committed
      ssl-default-bind-ciphers kEECDH+aRSA+AES:kRSA+AES:+AES256:!RC4-SHA:!kEDH:!LOW:!EXP:!MD5:!aNULL:!eNULL
    
    jurgenhaas's avatar
    jurgenhaas committed
      pidfile /run/haproxy.pid
    
    defaults
      log global
    
    jurgenhaas's avatar
    jurgenhaas committed
      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\ %{+Q}r
    
    jurgenhaas's avatar
    jurgenhaas committed
      mode http
      option dontlognull
    
    jurgenhaas's avatar
    jurgenhaas committed
      timeout connect {{ proxy_timeout_connect }}
      timeout client {{ proxy_timeout_client }}
      timeout server {{ proxy_timeout_server }}
    
    jurgenhaas's avatar
    jurgenhaas committed
      timeout http-keep-alive 3s
    
      timeout http-request 10s  # slowloris protection
      default-server inter 3s fall 2 rise 2 slowstart 60s
    
    jurgenhaas's avatar
    jurgenhaas committed
      errorfile 400 /etc/haproxy/errors/400.http
      errorfile 403 /etc/haproxy/errors/403.http
      errorfile 408 /etc/haproxy/errors/408.http
      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
      option forwardfor
      option http-server-close
      retries 3
    
      default_backend backend_{{proxy_default_backend}}
    
    jurgenhaas's avatar
    jurgenhaas committed
    
    
    jurgenhaas's avatar
    jurgenhaas committed
    listen stats
      bind 127.0.0.1:7000
    
    jurgenhaas's avatar
    jurgenhaas committed
      mode http
      stats enable
      stats admin if TRUE
      stats uri /haproxy_stats
    
      stats realm LoadBalancerStats
    
    {% if kibana_users is defined %}
    
    userlist kibana
    {% for user in kibana_users %}
      user {{ user.username }} insecure-password '{{ user.password }}'
    {% endfor %}
    {% endif %}
    
    jurgenhaas's avatar
    jurgenhaas committed
    
    
    jurgenhaas's avatar
    jurgenhaas committed
      bind *:80
    
      http-request del-header Proxy
    
      acl blockedip src -f /etc/haproxy/blacklist.ip
    
      http-request deny if blockedip
    
      acl blockedreferer hdr_sub(referer) -i -f /etc/haproxy/blacklist.referer
      http-request deny if blockedreferer
      acl blockedagent hdr_sub(user-agent) -i -f /etc/haproxy/blacklist.agent
      http-request deny if blockedagent
    
    {% for rule in proxy_blacklist.other|default([]) %}
      http-request deny if { {{ rule }} }
    {% endfor %}
    
      http-request set-header x-routing-host undefined
    
    {% for host in groups['all'] %}
    {% for redirect in hostvars[host].proxy_redirect|default([]) %}
    
    {% for from in redirect.from %}
    {% for path in redirect.paths|default([]) %}
    
    {% if path.deny|default(false) %}
    
      http-request deny if { hdr(host) -i -n {{from}}{% if path.from is defined %} } { {{path.exact|default(false)|ternary('path','path_beg')}} /{{path.from}}{% endif %} }
    
    {% else %}
    {% if path.regex is defined and path.from is defined %}
      http-request redirect code 301 location %[capture.req.uri,regsub({{path.regex}},)] if { hdr(host) -i -n {{from}} } { path_beg /{{path.from}} }
    {% endif %}
    
    {% endif %}
    {% endfor %}
    {% endfor %}
    {% endfor %}
    {% endfor %}
    {% for host in groups['all'] %}
    {% for redirect in hostvars[host].proxy_redirect|default([]) %}
    {% for from in redirect.from %}
    {% for path in redirect.paths|default([]) %}
    {% if not path.deny|default(false) %}
    
    {% if path.regex is not defined or path.from is not defined %}
    
      redirect location {{ redirect.protocol|default('https') }}://{{redirect.to}}/{{path.to|default('')}} code 301 if { hdr(host) -i -n {{from}}{% if path.from is defined %} } { {{path.exact|default(false)|ternary('path','path_beg')}} /{{path.from}}{% endif %} }
    
    {% endfor %}
    
    {% if from != redirect.to or redirect.protocol|default('https') == 'https' %}
    
      redirect prefix {{ redirect.protocol|default('https') }}://{{redirect.to}} code 301 if { hdr(host) -i -n {{from}} }
    
    {% endfor %}
    
    {% endfor %}
    {% if proxy_redirect_aliase %}
    {% for drupal in hostvars[host].drupal_settings|default([]) %}
    {% for domain in drupal.domains|default([]) %}
    
    jurgenhaas's avatar
    jurgenhaas committed
    {% if not domain.multidomain|default(false) %}
    
    {% for alias in domain.aliases|default([]) %}
    
      redirect prefix {{ domain.protocol|default('https') }}://{{domain.domain}} code 301 if { hdr(host) -i -n {{alias}} }
    
    jurgenhaas's avatar
    jurgenhaas committed
    {% endif %}
    
    {% endfor %}
    {% endfor %}
    {% endif %}
    {% endfor %}
    
    {% for host in groups['webserver'] %}
    {% if hostvars[host].routing is defined %}
      http-request set-header x-routing-host {{ host }} if { hdr(x-routing-host) undefined } { hdr(host) -i -n {{ hostvars[host].routing.domain }} } { path -i -n -f /etc/haproxy/{{ host }}.path.list }
    {% endif %}
    {% endfor %}
    {% for host in groups['webserver'] %}
    {% if hostvars[host].routing is defined %}
    {% for path in hostvars[host].routing.paths|default([]) %}
      http-request set-header x-routing-host {{ host }} if { hdr(x-routing-host) undefined } { hdr(host) -i -n {{ hostvars[host].routing.domain }} } { path_beg {{ path }} }
    {% endfor %}
    {% endif %}
    {% endfor %}
    {% if routing is defined and routing.default is defined %}
      http-request set-header x-routing-host {{ routing.default }} if { hdr(x-routing-host) undefined } { hdr(host) -i -n {{ routing.domain }} }
    {% endif %}
    
      acl letsencrypt_challenge path_beg /.well-known/acme-challenge/
      use_backend backend_letsencrypt if letsencrypt_challenge
    
    {% if kibana_users is defined %}
    
      acl kibana_present hdr(host) -i -n '{{ kibana_domain|default(inventory_hostname) }}'
    
    jurgenhaas's avatar
    jurgenhaas committed
      use_backend backend_redirect_ssl if kibana_present
    
      acl redirect_ssl_{{host}} hdr(host) -i -n -f /etc/haproxy/{{host}}.ssl.list
      use_backend backend_redirect_ssl if redirect_ssl_{{host}}
    {% endfor %}
    
      acl domain_uses_bigpipe hdr(host) -i -n -f /etc/haproxy/use_bigpipe.list
    
    {% if varnish_host|default(false) %}
    
      acl is_purge method PURGE
      use_backend backend_varnish if is_purge
    
      acl is_ban method BAN
      use_backend backend_varnish if is_ban
    
      acl domain_ignores_varnish hdr(host) -i -n -f /etc/haproxy/ignore_varnish.list
    
      use_backend backend_varnish_bigpipe if domain_uses_bigpipe !domain_ignores_varnish
    
      acl static_content path_end .jpg .jpeg .gif .png .ico .swf .css .js .htm .html
    
      use_backend backend_varnish if static_content !domain_ignores_varnish
    
    {% endif %}
    
    {% for host in groups['webserver'] %}
      use_backend backend_{{ host }}_bigpipe if domain_uses_bigpipe { hdr(x-routing-host) {{ host }} }
      use_backend backend_{{ host }} if { hdr(x-routing-host) {{ host }} }
    {% endfor %}
    
      acl domain_in_{{host}} hdr(host) -i -n -f /etc/haproxy/{{host}}.list
    
      use_backend backend_{{host}}_bigpipe if domain_uses_bigpipe domain_in_{{host}}
    
    jurgenhaas's avatar
    jurgenhaas committed
      use_backend backend_{{host}} if domain_in_{{host}}
    
    {% for rule in hostvars[host].proxy_special_rules|default([]) %}
      acl proxy_special_rules_{{host}}_{{rule}} {{ hostvars[host].proxy_special_rules[rule] }}
      use_backend backend_{{host}} if proxy_special_rules_{{host}}_{{rule}}
    {% endfor %}
    
    {% if hostvars[host].proxy_crm_domains is defined %}
    
      acl crm_domain_in_{{host}} hdr_dom(host) -i -n -f /etc/haproxy/{{host}}.crm.list
    
    jurgenhaas's avatar
    jurgenhaas committed
      use_backend backend_{{host}} if crm_domain_in_{{host}}
    {% endif %}
    {% endfor %}
    
    {% for cert in proxy_certificates %}
    
    frontend https_in_{{ cert.ip }}
    
      bind {{ cert.ip }}:443 ssl crt /etc/haproxy/certs/{{ cert.file }} no-sslv3
    
      http-request del-header Proxy
    
      acl blockedip src -f /etc/haproxy/blacklist.ip
    
      http-request deny if blockedip
    
      acl blockedreferer hdr_sub(referer) -i -f /etc/haproxy/blacklist.referer
      http-request deny if blockedreferer
      acl blockedagent hdr_sub(user-agent) -i -f /etc/haproxy/blacklist.agent
      http-request deny if blockedagent
    
    {% for rule in proxy_blacklist.other|default([]) %}
      http-request deny if { {{ rule }} }
    {% endfor %}
    
      http-request set-header x-routing-host undefined
    
    {% for host in groups['all'] %}
    {% for redirect in hostvars[host].proxy_redirect|default([]) %}
    
    {% for from in redirect.from %}
    {% for path in redirect.paths|default([]) %}
    
      http-request deny if { hdr(host) -i -n {{from}}{% if path.from is defined %} } { {{path.exact|default(false)|ternary('path','path_beg')}} /{{path.from}}{% endif %} }
    
    {% else %}
    {% if path.regex is defined and path.from is defined %}
      http-request redirect code 301 location %[capture.req.uri,regsub({{path.regex}},)] if { hdr(host) -i -n {{from}} } { path_beg /{{path.from}} }
    {% endif %}
    
    {% endif %}
    {% endfor %}
    {% endfor %}
    {% endfor %}
    {% endfor %}
    {% for host in groups['all'] %}
    {% for redirect in hostvars[host].proxy_redirect|default([]) %}
    {% for from in redirect.from %}
    {% for path in redirect.paths|default([]) %}
    {% if not path.deny|default(false) %}
    
    {% if path.regex is not defined or path.from is not defined %}
    
      redirect location {{ redirect.protocol|default('https') }}://{{redirect.to}}/{{path.to|default('')}} code 301 if { hdr(host) -i -n {{from}}{% if path.from is defined %} } { {{path.exact|default(false)|ternary('path','path_beg')}} /{{path.from}}{% endif %} }
    
    {% endfor %}
    
    {% if from != redirect.to or redirect.protocol|default('https') != 'https' %}
    
      redirect prefix {{ redirect.protocol|default('https') }}://{{redirect.to}} code 301 if { hdr(host) -i -n {{from}} }
    
    {% endfor %}
    
    {% endfor %}
    {% if proxy_redirect_aliase %}
    {% for drupal in hostvars[host].drupal_settings|default([]) %}
    {% for domain in drupal.domains|default([]) %}
    
    jurgenhaas's avatar
    jurgenhaas committed
    {% if not domain.multidomain|default(false) %}
    
    {% for alias in domain.aliases|default([]) %}
    
      redirect prefix {{ domain.protocol|default('https') }}://{{domain.domain}} code 301 if { hdr(host) -i -n {{alias}} }
    
    jurgenhaas's avatar
    jurgenhaas committed
    {% endif %}
    
    {% endfor %}
    {% endfor %}
    {% endif %}
    {% endfor %}
    
    {% for host in groups['webserver'] %}
    {% if hostvars[host].routing is defined %}
      http-request set-header x-routing-host {{ host }} if { hdr(x-routing-host) undefined } { hdr(host) -i -n {{ hostvars[host].routing.domain }} } { path -i -n -f /etc/haproxy/{{ host }}.path.list }
    {% endif %}
    {% endfor %}
    {% for host in groups['webserver'] %}
    {% if hostvars[host].routing is defined %}
    {% for path in hostvars[host].routing.paths|default([]) %}
      http-request set-header x-routing-host {{ host }} if { hdr(x-routing-host) undefined } { hdr(host) -i -n {{ hostvars[host].routing.domain }} } { path_beg {{ path }} }
    {% endfor %}
    {% endif %}
    {% endfor %}
    {% if routing is defined and routing.default is defined %}
      http-request set-header x-routing-host {{ routing.default }} if { hdr(x-routing-host) undefined } { hdr(host) -i -n {{ routing.domain }} }
    {% endif %}
    
    {% if kibana_users is defined %}
    
      acl kibana_present hdr(host) -i -n '{{ kibana_domain|default(inventory_hostname) }}'
    
      use_backend backend_kibana if kibana_present
    {% endif %}
    
    {% for external in cert.external|default([]) %}
      acl is_{{ external.key }} {{ external.acl }}
      use_backend backend_{{ external.key }} if is_{{ external.key }}
    
      acl crm_redirect_{{host}} hdr(host) -i -n -f /etc/haproxy/{{host}}.list
      use_backend backend_redirect if crm_redirect_{{host}}
    
      acl domain_uses_bigpipe hdr(host) -i -n -f /etc/haproxy/use_bigpipe.list
    
    {% if varnish_host|default(false) %}
    
      acl domain_ignores_varnish hdr(host) -i -n -f /etc/haproxy/ignore_varnish.list
    
      use_backend backend_varnish_bigpipe if domain_uses_bigpipe !domain_ignores_varnish
    
      acl static_content path_end .jpg .jpeg .gif .png .ico .swf .css .js .htm .html
    
      use_backend backend_varnish if static_content !domain_ignores_varnish
    
    {% endif %}
    
    {% for host in groups['webserver'] %}
      use_backend backend_{{ host }}_https_bigpipe if domain_uses_bigpipe { hdr(x-routing-host) {{ host }} }
      use_backend backend_{{ host }}_https if { hdr(x-routing-host) {{ host }} }
    {% endfor %}
    
      acl ssl_domain_in_{{host}} hdr(host) -i -n -f /etc/haproxy/{{host}}.ssl.list
    
      use_backend backend_{{host}}_https_bigpipe if domain_uses_bigpipe ssl_domain_in_{{host}}
    
      use_backend backend_{{host}}_https if ssl_domain_in_{{host}}
    
      acl redirect_{{host}} hdr(host) -i -n -f /etc/haproxy/{{host}}.list
    
    jurgenhaas's avatar
    jurgenhaas committed
      use_backend backend_redirect if redirect_{{host}}
    
    {% for rule in hostvars[host].proxy_special_rules|default([]) %}
      acl proxy_special_rules_{{host}}_{{rule}} {{ hostvars[host].proxy_special_rules[rule] }}
      use_backend backend_{{host}}_https if proxy_special_rules_{{host}}_{{rule}}
    {% endfor %}
    
    {% if hostvars[host].proxy_crm_domains is defined %}
    
    jurgenhaas's avatar
    jurgenhaas committed
    {% endif %}
    {% endfor %}
    
    {% for external in cert.external|default([]) %}
    
    backend backend_{{ external.key }}
    
      server server_{{ external.key }} {{ external.server }} check {{ external.options }}
    
    {% endfor %}
    
    {% if proxy_default_backend not in groups['webserver'] %}
    
    backend backend_{{ proxy_default_backend }}
      http-response deny
    {% endif %}
    {% for host in groups['webserver'] %}
    
    jurgenhaas's avatar
    jurgenhaas committed
    backend backend_{{host}}
    
    jurgenhaas's avatar
    jurgenhaas committed
    {% if host == inventory_hostname or host == 'localhost' %}
    
      server server_{{host}} {{hostvars[host]['static_ipv4']}}:80 check maxconn {{hostvars[host]['proxy_maxconn']|default(proxy_maxconn)}}
    
    backend backend_{{host}}_bigpipe
    {% if host == inventory_hostname or host == 'localhost' %}
      http-response deny
    {% else %}
      no option http-buffer-request
    
      server server_{{host}} {{hostvars[host]['static_ipv4']}}:80 check maxconn {{hostvars[host]['proxy_maxconn']|default(proxy_maxconn)}}
    
    jurgenhaas's avatar
    jurgenhaas committed
    {% if host == inventory_hostname or host == 'localhost' %}
    
      http-response deny
    {% else %}
      http-response set-header Strict-Transport-Security "max-age=16000000; includeSubDomains; preload;"
    
      server server_{{host}} {{hostvars[host]['static_ipv4']}}:80 check maxconn {{hostvars[host]['proxy_maxconn']|default(proxy_maxconn)}}
    
    
    backend backend_{{host}}_https_bigpipe
    {% if host == inventory_hostname or host == 'localhost' %}
      http-response deny
    {% else %}
      no option http-buffer-request
      http-response set-header Strict-Transport-Security "max-age=16000000; includeSubDomains; preload;"
    
      server server_{{host}} {{hostvars[host]['static_ipv4']}}:80 check maxconn {{hostvars[host]['proxy_maxconn']|default(proxy_maxconn)}}
    
    jurgenhaas's avatar
    jurgenhaas committed
    {% endfor %}
    
    {% if varnish_host|default(false) %}
    
    backend backend_varnish
    
      option httpchk HEAD /varnishcheck
    
      http-request set-header x-real-ip %[src]
    
      http-check expect status 200
      option forwardfor
      hash-type consistent
    
    jurgenhaas's avatar
    jurgenhaas committed
    {% if varnish_host == inventory_hostname %}
    
      server varnish 127.0.0.1:6081 maxconn {{proxy_varnish_maxconn}}
    
      server varnish {{ varnish_host_ip|default('') }}:6081 maxconn {{proxy_varnish_maxconn}}
    
    
    backend backend_varnish_bigpipe
      no option http-buffer-request
      option httpchk HEAD /varnishcheck
      http-check expect status 200
      option forwardfor
      hash-type consistent
    {% if varnish_host == inventory_hostname %}
    
      server varnish 127.0.0.1:6081 maxconn {{proxy_varnish_maxconn}}
    
      server varnish {{ varnish_host_ip|default('') }}:6081 maxconn {{proxy_varnish_maxconn}}
    
    {% endif %}
    
    jurgenhaas's avatar
    jurgenhaas committed
    
    backend backend_redirect_ssl
      redirect scheme https if TRUE
    
    backend backend_redirect
      redirect scheme http if TRUE
    
    
    backend backend_letsencrypt
      server letsencrypt 127.0.0.1:54321
    
    {% if kibana_users is defined %}
    
    backend backend_kibana
    
      acl kibana_auth http_auth(kibana) if kibana_present
      http-request auth realm Kibana if !kibana_auth
    {% endif %}