♻: manage san for certificate/domain/sni routing
All checks were successful
ansible-lint / lint-everything (push) Successful in 1m24s

This commit is contained in:
VC
2025-04-11 17:11:15 +02:00
parent c49025d712
commit 14cc54f4ed
14 changed files with 53 additions and 51 deletions

View File

@@ -42,10 +42,19 @@ frontend http
acl letsencrypt path_beg /.well-known/acme-challenge
redirect scheme https code 301 if !letsencrypt
{% for server in haproxy_backend_servers %}
{% for hostname in hostvars[server]['web_hostname'] | sort(attribute='host') %}
## {{ hostname.host }} configuration
acl host_{{ hostname.host }} hdr(host) -i {{ hostname.host }}
use_backend http_{{ hostvars[server].ansible_host }} if letsencrypt host_{{ hostname.host }}
{% for hostname in (
(hostvars[server].web_hostname
| map(attribute='host'))
+
(hostvars[server].web_hostname
| selectattr('san', 'defined')
| map(attribute='san')
| flatten)
) | sort
%}
## {{ hostname }} configuration
acl host_{{ hostname }} hdr(host) -i {{ hostname }}
use_backend http_{{ hostvars[server].ansible_host }} if letsencrypt host_{{ hostname }}
{% endfor %}
{% endfor %}
@@ -57,14 +66,24 @@ frontend https
tcp-request inspect-delay 3s
tcp-request content accept if { req.ssl_hello_type 1 }
{% for server in haproxy_backend_servers %}
{% for hostname in hostvars[server]['web_hostname'] | sort(attribute='host') %}
## {{ hostname.host }} configuration
acl host_{{ hostname.host }} req.ssl_sni -i {{ hostname.host }}
{% if hostname.allowlistv4 is defined %}
acl network_allowed_{{ hostname.host }} src {% for addrv4 in hostname.allowlistv4 %}{{ addrv4 }}{% endfor %}
{% for hostname in (
(hostvars[server].web_hostname
| map(attribute='host'))
+
(hostvars[server].web_hostname
| selectattr('san', 'defined')
| map(attribute='san')
| flatten)
) | sort
%}
## {{ hostname }} configuration
acl host_{{ hostname }} req.ssl_sni -i {{ hostname }}
{% set host = (hostvars[server].web_hostname | selectattr('host', '==', hostname))[0] %}
{% if host.allowlistv4 is defined %}
acl network_allowed_{{ hostname }} src {% for addrv4 in host.allowlistv4 %}{{ addrv4 }}{% endfor %}
{% endif %}
use_backend https_{{ hostvars[server].ansible_host }} if host_{{ hostname.host }}{% if hostname.allowlistv4 is defined %} network_allowed_{{ hostname.host }}{% endif %}
use_backend https_{{ hostvars[server].ansible_host }} if host_{{ hostname }}{% if host.allowlistv4 is defined %} network_allowed_{{ hostname }}{% endif %}
{% endfor %}

View File

@@ -2,7 +2,7 @@
- name: Issue certificate
ansible.builtin.command:
cmd: "/etc/x509/acme.sh --issue --domain {{ host.host }} --webroot {{ nginx_letsencrypt_dir }} --reloadcmd \"{{ acme_reload_cmd | default('systemctl reload nginx.service') }}\""
cmd: "/etc/x509/acme.sh --issue --domain {{ host.host }} {{ ['--domain'] | product(host.san | default([])) | map('join', ' ') | join(' ') }} --webroot {{ nginx_letsencrypt_dir }} --reloadcmd \"{{ acme_reload_cmd | default('systemctl reload nginx.service') }}\""
creates: "/etc/x509/{{ host.host }}*"
environment:
LE_WORKING_DIR: "/etc/x509"

View File

@@ -46,7 +46,7 @@
- name: Include acme auto cert
ansible.builtin.include_tasks: acme.yml
loop: "{{ web_hostname | rejectattr('acme_unmanaged', 'defined') }}"
loop: "{{ web_hostname }}"
loop_control:
loop_var: "host"

View File

@@ -3,7 +3,7 @@
ssl_certificate /etc/x509/{{ item.host }}/fullchain.cer;
ssl_certificate_key /etc/x509/{{ item.host }}/{{ item.host }}.key;
server_name {{ item.host }};
server_name {{ item.host }}{{ ' ' ~ item.san | join(' ') if item.san is defined }};
access_log /var/log/nginx/{{ item.host }}.access.log combined;
access_log syslog:server=unix:/dev/log combined;
error_log /var/log/nginx/{{ item.host }}.error.log;

View File

@@ -1,15 +1,5 @@
server {
listen *:443 ssl http2;
listen [::]:443 ssl http2;
server_name r.mateu.be perso.nintendojo.fr perso.libertus.eu;
access_log /var/log/nginx/r.mateu.be.access.log combined;
access_log syslog:server=unix:/dev/log combined;
error_log /var/log/nginx/r.mateu.be.error.log;
error_log syslog:server=unix:/dev/log;
ssl_certificate /etc/x509/r.mateu.be/fullchain.cer;
ssl_certificate_key /etc/x509/r.mateu.be/r.mateu.be.key;
{% include './templates/header.conf.j2' %}
root /srv/www-data/r.mateu.be/;
location / {

View File

@@ -7,15 +7,7 @@ fastcgi_cache_path
max_size=250m;
server {
listen *:443 ssl http2;
listen [::]:443 ssl http2;
server_name nintendojo.fr www.nintendojo.fr;
access_log /var/log/nginx/nintendojo.fr.access.log combined;
access_log syslog:server=unix:/dev/log combined;
error_log /var/log/nginx/nintendojo.fr.error.log;
error_log syslog:server=unix:/dev/log;
ssl_certificate /etc/x509/www.nintendojo.fr/fullchain.cer;
ssl_certificate_key /etc/x509/www.nintendojo.fr/www.nintendojo.fr.key;
{% include './templates/header.conf.j2' %}
root /var/www/www.nintendojo.fr/;
index index.html index.htm index.php;

View File

@@ -1,13 +1,5 @@
server {
listen *:443 ssl http2;
listen [::]:443 ssl http2;
server_name www.nintendojofr.com nintendojofr.com;
access_log /var/log/nginx/nintendojofr.com.access.log combined;
access_log syslog:server=unix:/dev/log combined;
error_log /var/log/nginx/nintendojofr.com.error.log;
error_log syslog:server=unix:/dev/log;
ssl_certificate /etc/x509/www.nintendojofr.com/fullchain.cer;
ssl_certificate_key /etc/x509/www.nintendojofr.com/www.nintendojofr.com.key;
{% include './templates/header.conf.j2' %}
root /var/www/www.nintendojofr.com/;
index index.html index.htm index.php;

View File

@@ -11,7 +11,17 @@
dns_serial: "{{ ansible_date_time.epoch }}"
web_hostname_block: |-
{% for webserver in groups['webservers'] | sort -%}
{% for web_hostname in (hostvars[webserver]['web_hostname'] | selectattr('host', 'match', '.*' ~ item.name) | map(attribute='host') | sort) -%}
{% for web_hostname in (
(hostvars[webserver]['web_hostname']
| selectattr('host', 'match', '.*' ~ item.name)
| map(attribute='host')
+
(hostvars[webserver]['web_hostname']
| selectattr('san', 'defined')
| map(attribute='san')
| flatten
| select('match', '.*' ~ item.name)))
| sort) -%}
{% if web_hostname is match("(\S+\.){2}") %}
{{ web_hostname | regex_replace('\.' ~ item.name ~ '$', '') }} IN CNAME {{ hostvars[webserver].ansible_host }}.
{% else %}