-
Notifications
You must be signed in to change notification settings - Fork 1
/
haproxy-external.jinja.cfg
150 lines (139 loc) · 6.96 KB
/
haproxy-external.jinja.cfg
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
global
log /dev/log local0
#log /dev/log local1 notice
chroot /var/lib/haproxy
stats socket /run/haproxy/admin-external.sock mode 660 level admin
stats timeout 30s
user haproxy
group haproxy
daemon
# Default SSL material locations
ca-base /etc/ssl/certs
crt-base /etc/ssl/private
# Default ciphers to use on SSL-enabled listening sockets.
# For more information, see ciphers(1SSL). This list is from:
# https://mozilla.github.io/server-side-tls/ssl-config-generator/?server=haproxy-1.5.14&openssl=1.0.1k&hsts=yes&profile=modern
# set default parameters to the modern configuration
tune.ssl.default-dh-param 2048
ssl-default-bind-ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!3DES:!MD5:!PSK
ssl-default-bind-options no-sslv3
defaults
log global
mode http
option httplog
option dontlognull
timeout connect 5000
timeout client 50000
timeout server 50000
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
{%- if "http" in services.group_by_tagvalue("smartstack:protocol:") -%}
{%- set http_services = services.group_by_tagvalue("smartstack:protocol:")["http"] -%}
{%- endif -%}
{%- if "sni" in services.group_by_tagvalue("smartstack:protocol:") -%}
{%- set sni_services = services.group_by_tagvalue("smartstack:protocol:")["sni"] -%}
{%- endif -%}
{%- if "https" in services.group_by_tagvalue("smartstack:protocol:") -%}
{%- set https_services = services.group_by_tagvalue("smartstack:protocol:")["https"] -%}
{%- endif -%}
{%- set use_sni_dispatch = sni_services is defined and sni_services and https_services is defined and https_services -%}
{#- first let's handle all port 80 http services. We also redirect SSL services to HTTPS, if
they have the right tags -#}
{% if http_services is defined or "https-redirect" in https_services.tagvalue_set("smartstack:") %}
frontend http-routing
bind {{localip}}:80
reqadd X-Forwarded-Proto:\ http
{% if http_services is defined %}
{% for svcname, svclist in http_services.group_by("name").items() -%}
{% for hostname in svclist.tagvalue_set("smartstack:hostname:") -%}
acl host_{{svcname}} hdr(Host) -i {{hostname}}
{% endfor %}
{% for option in svclist.tagvalue_set("haproxy:frontend:option:") -%}
option {{option}}
{% endfor %}
{% for timeout in group.tagvalue_set("haproxy:frontend:timeout:") %}
timeout {{timeout.split(':', 1)[0]}} {{timeout.split(':', 1)[1]}}
{% endfor %}
use_backend backend-http-{{svcname}} if host_{{svcname}}
{% endfor -%}
{% endif %}
{% for svcname, svclist in https_services.group_by("name").items() -%}
{% for hostname in svclist.tagvalue_set("smartstack:hostname:") -%}
{% if "https-redirect" in svclist.tagvalue_set("smartstack:") -%}
acl host_{{hostname}}_httpsredir hdr(Host) -i {{hostname}}
redirect prefix https://{{hostname}} code 301 if host_{{hostname}}_httpsredir
{%- endif -%}
{% endfor %}
{% endfor -%}
{% endif -%}
{#- If we have SNI based services, the routing will go like this:
ingress -> SNI routing -> local port https routing
| |
+-> servers +-> servers
This routing might become a performance problem at some point since SSL termination passes
through two frontends in this configuration. When that happens, split the loadbalancer in two,
where one routes SNI and one routes SSL terminated connections. -#}
{% if sni_services is defined and sni_services %}
frontend sni-routing
bind {{localip}}:443
tcp-request inspect-delay 5s
tcp-request content accept if { req_ssl_hello_type 1 }
mode tcp
{% for name, svc in sni_services.group_by("name").items() -%}
{% for hostname in svc.tagvalue_set("smartstack:hostname:") -%}
acl host_{{name}} req.ssl_sni {{hostname}}
{% endfor %}
use_backend backend-sni-{{name}} if host_{{name}}
{% endfor %}
{%- if https_services is defined and https_services -%}
# dispatch to https SSL termination
{% for name, svc in https_services.group_by("name").items() -%}
{% for hostname in svc.tagvalue_set("smartstack:hostname:") -%}
acl sslterminate_dispatch req.ssl_sni {{hostname}}
{% endfor %}
{% endfor %}
use_backend ssl-termination-dispatch if sslterminate_dispatch
{%- endif %}
{% endif -%}
{% if use_sni_dispatch -%}
backend ssl-termination-dispatch
mode tcp
server dispatch localhost:10443
{%- endif %}
{% if https_services is defined and https_services %}
frontend https-routing
bind {% if use_sni_dispatch %}localhost:10443{% else %}{{localip}}:443{% endif %} ssl {% if maincert is defined %}crt {{maincert}}{% endif %}{% for cert in https_services.tagvalue_set("crt") %} crt {{cert}}{% endfor %}
reqadd X-Forwarded-Proto:\ https
{% for name, svc in https_services.group_by("name").items() %}
{% for hostname in svc.tagvalue_set("smartstack:hostname:") %}
acl host_{{name}} hdr(host) -i {{hostname}}
{% endfor %}
{% for option in svc.tagvalue_set("haproxy:frontend:option:") %}
option {{option}}
{% endfor %}
use_backend backend-https-{{name}} if host_{{name}}
{% endfor %}
{% endif %}
{% for prot, servicegroup in services.group_by_tagvalue("smartstack:protocol:").items() %}
{% for name, svc in servicegroup.group_by("name").items() %}
backend backend-{{prot}}-{{name}}
{% for backend in svc %}
server {{name}}-{{prot}}-srv{{loop.index}} {{backend.ip}}:{{backend.port}} check
{% endfor %}
mode {% if prot == "sni" %}tcp{% else %}http{% endif %}
{% for option in svc.tagvalue_set("haproxy:backend:option:") %}
option {{option}}
{% endfor %}
{% if svc[0].tagvalue("haproxy:backend:timeout:") %}
timeout {{timeout.split(':', 1)[0]}} {{timeout.split(':', 1)[1]}}
{% endif %}
{% if prot.startswith("http") and not svc[0].tagvalue("haproxy:no-forward-for") %}
option forwardfor
{% endif %}
{% endfor %}
{% endfor %}