From 719f723ba5e7b21d4a7158086991f2e743b08a38 Mon Sep 17 00:00:00 2001 From: Tyler Hale Date: Sat, 27 Aug 2022 07:42:36 -0600 Subject: [PATCH] General cleanup and adding mapping options --- roles/haproxy/defaults/main.yml | 1 + .../{example.map => example-letsencrypt.map} | 1 + roles/haproxy/maps/example-passthrough.map | 2 + roles/haproxy/maps/example-path.map | 2 + roles/haproxy/maps/example-termination.map | 2 + roles/haproxy/tasks/main.yml | 25 ++++- .../haproxy/templates/example.haproxy.cfg.j2 | 91 ++++++++++++++----- 7 files changed, 98 insertions(+), 26 deletions(-) rename roles/haproxy/maps/{example.map => example-letsencrypt.map} (50%) create mode 100644 roles/haproxy/maps/example-passthrough.map create mode 100644 roles/haproxy/maps/example-path.map create mode 100644 roles/haproxy/maps/example-termination.map diff --git a/roles/haproxy/defaults/main.yml b/roles/haproxy/defaults/main.yml index 0c33294..3eb307b 100644 --- a/roles/haproxy/defaults/main.yml +++ b/roles/haproxy/defaults/main.yml @@ -2,6 +2,7 @@ # file: roles/haproxy/defaults/main.yml haproxy_config_file: "example.haproxy.cfg.j2" +haproxy_local_cert: true # Set for entire group diff --git a/roles/haproxy/maps/example.map b/roles/haproxy/maps/example-letsencrypt.map similarity index 50% rename from roles/haproxy/maps/example.map rename to roles/haproxy/maps/example-letsencrypt.map index b8fd968..c05de96 100644 --- a/roles/haproxy/maps/example.map +++ b/roles/haproxy/maps/example-letsencrypt.map @@ -1 +1,2 @@ #domainname backendname +#ha01.local example-letsencrypt-backend diff --git a/roles/haproxy/maps/example-passthrough.map b/roles/haproxy/maps/example-passthrough.map new file mode 100644 index 0000000..a848a1f --- /dev/null +++ b/roles/haproxy/maps/example-passthrough.map @@ -0,0 +1,2 @@ +#domainname backendname +#ha01.local example-https-passthrough-backend diff --git a/roles/haproxy/maps/example-path.map b/roles/haproxy/maps/example-path.map new file mode 100644 index 0000000..eba04c1 --- /dev/null +++ b/roles/haproxy/maps/example-path.map @@ -0,0 +1,2 @@ +#path backendname +#/ha01 example-http-backend diff --git a/roles/haproxy/maps/example-termination.map b/roles/haproxy/maps/example-termination.map new file mode 100644 index 0000000..e7fe460 --- /dev/null +++ b/roles/haproxy/maps/example-termination.map @@ -0,0 +1,2 @@ +#domainname backendname +#ha01.local example-https-termination-backend diff --git a/roles/haproxy/tasks/main.yml b/roles/haproxy/tasks/main.yml index def0b5f..c795df2 100644 --- a/roles/haproxy/tasks/main.yml +++ b/roles/haproxy/tasks/main.yml @@ -25,7 +25,16 @@ autoconnect: yes type: vlan state: present - when: (haproxy_keepalived_adapter_vlan is defined) and (haproxy_keepalived_ip is defined) + when: (haproxy_keepalived_adapter_vlan != "") and (haproxy_keepalived_ip is defined) + +- name: Add IP + nmcli: + conn_name: "{{ haproxy_keepalived_adapter }}" + ip4: "{{ haproxy_keepalived_ip }}" + autoconnect: yes + type: ethernet + state: present + when: (haproxy_keepalived_adapter_vlan == "") and (haproxy_keepalived_ip is defined) - name: Enable firewall rule for vrrp firewalld: @@ -92,9 +101,21 @@ - "maps/*" notify: reload haproxy +- name: Ensure ssl directory exists + file: + path: "/etc/haproxy/ssl" + state: directory + +- name: Deploy host cert for haproxy use + file: + src: "/etc/ssl/{{ ansible_hostname }}/live/merged.pem" + dest: "/etc/haproxy/ssl/{{ ansible_hostname }}.pem" + state: link + when: haproxy_local_cert == true + - name: Update HAProxy configuration template: - src: haproxy.cfg.j2 + src: "{{ haproxy_config_file }}" dest: /etc/haproxy/haproxy.cfg mode: 0644 validate: haproxy -f %s -c -q diff --git a/roles/haproxy/templates/example.haproxy.cfg.j2 b/roles/haproxy/templates/example.haproxy.cfg.j2 index 961acf7..3ca517c 100644 --- a/roles/haproxy/templates/example.haproxy.cfg.j2 +++ b/roles/haproxy/templates/example.haproxy.cfg.j2 @@ -2,7 +2,6 @@ global log /dev/log local0 log /dev/log local1 notice chroot /var/lib/haproxy - #stats socket /run/haproxy/admin.sock mode 660 level admin expose-fd listeners stats socket /var/lib/haproxy/stats stats timeout 30s user haproxy @@ -23,7 +22,6 @@ global defaults log global mode http - option httplog option dontlognull timeout connect 5000 timeout client 50000 @@ -38,47 +36,92 @@ defaults errorfile 504 /etc/haproxy/errors/504.http {% endif %} +listen stats + bind *:9999 + stats enable + stats refresh 30s + stats show-node + stats uri /stats + +################################## Frontend ################################## + frontend ssh-in mode tcp + option tcplog bind {{ haproxy_shared_ip }}:22 - timeout connect 0ms timeout client 0ms - timeout server 0ms + + tcp-request inspect-delay 5s + acl valid_payload req.payload(0,7) -m str "SSH-2.0" + tcp-request content reject if !valid_payload + tcp-request content accept if { req_ssl_hello_type 1 } + use_backend example-ssh-backend frontend http-in - mode http bind {{ haproxy_shared_ip }}:80 - - use_backend example-http-backend + mode http + option httplog -frontend https-in - mode tcp - tcp-request inspect-delay 1s + # Redirect all urls to not use www + http-request redirect prefix http://%[hdr(host),regsub(^www\.,,i)] code 301 if { hdr_beg(host) -i www. } + + # Redirect if HTTPS is not used and not an acme challenge + redirect scheme https code 301 if !{ ssl_fc } !{ path_beg /.well-known/acme-challenge } + + # Use mapping file to match domain names to req.hdr(host) that are doing a let's encrypt validation + use_backend %[req.hdr(host),lower,map_dom(/etc/haproxy/maps/example-letsencrypt.map)] if { path_beg /.well-known/acme-challenge } + +frontend https-passthrough-in bind {{ haproxy_shared_ip }}:443 + mode tcp + option tcplog + tcp-request inspect-delay 1s tcp-request content accept if { req.ssl_hello_type 1 } - use_backend example-https-backend + # Use mapping file to match domain names to req.ssl_sni + use_backend %[req.ssl_sni,lower,map_dom(/etc/haproxy/maps/example-passthrough.map)] + + # If match is not found, redirect to the tcp_to_http-backend for https-termination + default_backend tcp_to_http-backend + +frontend https-termination-in + bind 127.0.0.1:8443 ssl crt /etc/haproxy/ssl/ alpn h2,http/1.1 accept-proxy + mode http + option httplog + tcp-request inspect-delay 1s + tcp-request content accept if { req.ssl_hello_type 1 } + + # Use mapping file to match path + use_backend %[path,lower,map_beg(/etc/haproxy/maps/example-path.map)] + + # Use mapping file to match domain names to ssl_fc_sni + use_backend %[ssl_fc_sni,lower,map_dom(/etc/haproxy/maps/example-termination.map)] + +################################## Backend ################################## + +backend tcp_to_http-backend + mode tcp + server haproxy 127.0.0.1:8443 send-proxy backend example-ssh-backend mode tcp timeout connect 0ms - timeout client 0ms timeout server 0ms - server example 10.1.1.11:22 check + server example 10.1.25.92:22 check + +backend example-letsencrypt-backend + mode http + server example 10.1.25.92:60080 backend example-http-backend mode http - log global - timeout connect 30000 - timeout server 30000 - retries 3 - server example 10.10.2.11:80 check + server example 10.1.25.92:80 check -backend example-https-backend +backend example-https-passthrough-backend mode tcp - log global - timeout connect 30000 - timeout server 30000 - retries 3 - server example 10.10.2.11:443 check + server example 10.1.25.92:443 check + +backend example-https-termination-backend + mode http + server example 10.1.25.92:80 check