diff options
author | Christian Pointner <equinox@spreadspace.org> | 2023-08-22 19:53:49 +0200 |
---|---|---|
committer | Christian Pointner <equinox@spreadspace.org> | 2023-08-22 19:53:49 +0200 |
commit | fc5d0657bfcba53ace230ff2ada64b7fcf9b97a3 (patch) | |
tree | 350a8d401e0113bff7d78aee4d8547cddf06b8f7 /roles/nginx | |
parent | fix docker for debian bookworm+ (diff) | |
parent | some more cleanup for acme specific variables (diff) |
Merge branch 'topic/uacme'
Diffstat (limited to 'roles/nginx')
-rw-r--r-- | roles/nginx/vhost/defaults/main.yml | 33 | ||||
-rw-r--r-- | roles/nginx/vhost/tasks/acme.yml | 44 | ||||
-rw-r--r-- | roles/nginx/vhost/tasks/main.yml | 26 | ||||
-rw-r--r-- | roles/nginx/vhost/templates/generic.conf.j2 | 98 |
4 files changed, 120 insertions, 81 deletions
diff --git a/roles/nginx/vhost/defaults/main.yml b/roles/nginx/vhost/defaults/main.yml index b80a5442..0eb67b42 100644 --- a/roles/nginx/vhost/defaults/main.yml +++ b/roles/nginx/vhost/defaults/main.yml @@ -3,10 +3,14 @@ # default: yes # name: example # template: generic -# acme: yes +# tls: +# certificate_provider: acmetool # hostnames: # - example.com # - www.example.com +# logs: +# access: /var/log/nginx/example_access.log +# error: /var/log/nginx/example_error.log # extra_directives: |- # add_header X-Example-Header "foo"; # locations: @@ -26,7 +30,10 @@ # nginx_vhost: # name: mixed-static-and-proxy # template: generic -# acme: yes +# tls: +# variant: legacy +# hsts: false +# certificate_provider: acmetool # hostnames: # - static.example.com # extra_directives: |- @@ -41,8 +48,30 @@ # add_header X-Example-Header "foo"; # '/subdir/': # alias: /srv/www/foo +# '/private/': +# return: "403" # '/foo/': # proxy_pass: http://127.0.0.1:1234 +# '/custom/': +# custom: |- +# include fastcgi_params; +# fastcgi_param SCRIPT_FILENAME /usr/lib/cgi/foo +# fastcgi_param PATH_INFO $uri; +# fastcgi_pass unix:/run/fcgiwrap/foo.sock; + +# nginx_vhost: +# name: example-custom +# template: generic +# tls: +# variant: legacy +# hsts: false +# certificate_provider: acmetool +# hostnames: +# - static.example.com +# custom: |- +# location / { +# foo "bar"; +# } # nginx_vhost: # name: other-example diff --git a/roles/nginx/vhost/tasks/acme.yml b/roles/nginx/vhost/tasks/acme.yml deleted file mode 100644 index 8a6cddb7..00000000 --- a/roles/nginx/vhost/tasks/acme.yml +++ /dev/null @@ -1,44 +0,0 @@ ---- -- name: check if acme certs already exist - loop: "{{ nginx_vhost.hostnames }}" - loop_control: - loop_var: acme_hostname - stat: - path: "/var/lib/acme/live/{{ acme_hostname }}" - register: acme_cert_stat - -- name: set acmecert_missing_hostnames variable - set_fact: - acmecert_missing_hostnames: "{{ acme_cert_stat.results | acme_cert_nonexistent(nginx_vhost.hostnames) }}" - -- name: link nonexistent hostnames to self-signed interim cert - when: acmecert_missing_hostnames | length > 0 - block: - - name: get id of existing selfsigned interim certificate - command: cat /var/lib/acme/.selfsigned-interim-cert - changed_when: false - check_mode: false - register: selfsigned_interim_cert_id - - - name: set selfsigned_interim_cert_id variable - set_fact: - selfsigned_interim_cert_id: "{{ selfsigned_interim_cert_id.stdout }}" - - - name: link to snakeoil cert for nonexistent hostnames - loop: "{{ acmecert_missing_hostnames }}" - loop_control: - loop_var: acme_missing_hostname - file: - src: "../certs/{{ selfsigned_interim_cert_id }}" - dest: "/var/lib/acme/live/{{ acme_missing_hostname }}" - state: link - -- name: make sure nginx config has been (re)loaded - meta: flush_handlers - -- name: get certificate using acmetool - import_role: - name: x509/acmetool/cert - vars: - acmetool_cert_name: "{{ nginx_vhost.name }}" - acmetool_cert_hostnames: "{{ nginx_vhost.hostnames }}" diff --git a/roles/nginx/vhost/tasks/main.yml b/roles/nginx/vhost/tasks/main.yml index 1b5e3392..2c1f0f29 100644 --- a/roles/nginx/vhost/tasks/main.yml +++ b/roles/nginx/vhost/tasks/main.yml @@ -1,4 +1,15 @@ --- +- name: ensure certificate exists (fake it, until you make it) + when: "'tls' in nginx_vhost" + vars: + x509_certificate_name: "{{ nginx_vhost.name }}" + x509_certificate_hostnames: "{{ nginx_vhost.hostnames }}" + x509_certificate_reload_services: + - nginx + include_role: + name: "x509/{{ nginx_vhost.tls.certificate_provider }}/cert/prepare" + public: true + - name: install nginx configs from template when: "'template' in nginx_vhost" template: @@ -23,5 +34,16 @@ notify: reload nginx - name: generate acme certificate - when: "'acme' in nginx_vhost and nginx_vhost.acme" - include_tasks: acme.yml + when: "'tls' in nginx_vhost" + block: + - name: make sure nginx config has been (re)loaded + meta: flush_handlers + + - name: actually request the certificate + vars: + x509_certificate_name: "{{ nginx_vhost.name }}" + x509_certificate_hostnames: "{{ nginx_vhost.hostnames }}" + x509_certificate_reload_services: + - nginx + include_role: + name: "x509/{{ nginx_vhost.tls.certificate_provider }}/cert/finalize" diff --git a/roles/nginx/vhost/templates/generic.conf.j2 b/roles/nginx/vhost/templates/generic.conf.j2 index 08bf7a60..dae84a2f 100644 --- a/roles/nginx/vhost/templates/generic.conf.j2 +++ b/roles/nginx/vhost/templates/generic.conf.j2 @@ -3,9 +3,20 @@ server { listen [::]:80{% if 'default' in nginx_vhost and nginx_vhost.default %} default_server{% endif %}; server_name {{ nginx_vhost.hostnames | join(' ') }}; -{% if 'acme' in nginx_vhost and nginx_vhost.acme %} - include snippets/acmetool.conf; +{% if 'logs' in nginx_vhost %} +{% if 'access' in nginx_vhost.logs %} + access_log {{ nginx_vhost.logs.access }}; +{% endif %} +{% if 'error' in nginx_vhost.logs %} + error_log {{ nginx_vhost.logs.error }}; +{% endif %} + +{% endif %} +{% if 'tls' in nginx_vhost %} +{% if nginx_vhost.tls.certificate_provider == 'acmetool' or nginx_vhost.tls.certificate_provider == 'uacme' %} + include snippets/{{ nginx_vhost.tls.certificate_provider }}.conf; +{% endif %} location / { return 301 https://$host$request_uri; } @@ -16,20 +27,36 @@ server { listen [::]:443 ssl http2{% if 'default' in nginx_vhost and nginx_vhost.default %} default_server{% endif %}; server_name {{ nginx_vhost.hostnames | join(' ') }}; - include snippets/acmetool.conf; - include snippets/tls{% if 'tls_variant' in nginx_vhost %}-{{ nginx_vhost.tls_variant }}{% endif %}.conf; - ssl_certificate /var/lib/acme/live/{{ nginx_vhost.hostnames[0] }}/fullchain; - ssl_certificate_key /var/lib/acme/live/{{ nginx_vhost.hostnames[0] }}/privkey; +{% if 'logs' in nginx_vhost %} +{% if 'access' in nginx_vhost.logs %} + access_log {{ nginx_vhost.logs.access }}; +{% endif %} +{% if 'error' in nginx_vhost.logs %} + error_log {{ nginx_vhost.logs.error }}; +{% endif %} + +{% endif %} +{% if nginx_vhost.tls.certificate_provider == 'acmetool' or nginx_vhost.tls.certificate_provider == 'uacme' %} + include snippets/{{ nginx_vhost.tls.certificate_provider }}.conf; +{% endif %} + include snippets/tls{% if 'variant' in nginx_vhost.tls %}-{{ nginx_vhost.tls.variant }}{% endif %}.conf; + ssl_certificate {{ x509_certificate_path_fullchain }}; + ssl_certificate_key {{ x509_certificate_path_key }}; +{% if 'hsts' not in nginx_vhost.tls or nginx_vhost.tls.hsts %} include snippets/hsts.conf; +{% endif %} {% endif %} -{% if 'extra_directives' in nginx_vhost %} - {{ nginx_vhost.extra_directives | indent(4) }} +{% if 'custom' in nginx_vhost %} + {{ nginx_vhost.custom | trim | indent(4) }} +{% else %} +{% if 'extra_directives' in nginx_vhost %} + {{ nginx_vhost.extra_directives | trim | indent(4) }} -{% endif %} -{% for path, location in nginx_vhost.locations.items() %} +{% endif %} +{% for path, location in nginx_vhost.locations.items() %} location {{ path }} { -{% if 'proxy_pass' in location %} +{% if 'proxy_pass' in location %} include snippets/proxy-nobuff.conf; proxy_set_header Host $host; include snippets/proxy-forward-headers.conf; @@ -39,36 +66,41 @@ server { proxy_set_header Connection $connection_upgrade; proxy_pass {{ location.proxy_pass }}; -{% if 'proxy_redirect' in location %} -{% for entry in location.proxy_redirect %} +{% if 'proxy_redirect' in location %} +{% for entry in location.proxy_redirect %} proxy_redirect {{ entry.redirect }} {{ entry.replacement }}; -{% endfor %} -{% endif %} -{% if 'proxy_ssl' in location %} -{% for prop in (location.proxy_ssl | list | sort) %} +{% endfor %} +{% endif %} +{% if 'proxy_ssl' in location %} +{% for prop in (location.proxy_ssl | list | sort) %} proxy_ssl_{{ prop }} {{ location.proxy_ssl[prop] }}; -{% endfor %} -{% endif %} -{% else %} -{% if 'root' in location %} +{% endfor %} +{% endif %} +{% elif 'return' in location %} + return {{ location.return }}; +{% elif 'custom' in location %} + {{ location.custom | trim | indent(8) }} +{% else %} +{% if 'root' in location %} root {{ location.root }}; -{% elif 'alias' in location %} +{% elif 'alias' in location %} alias {{ location.alias }}; -{% endif %} -{% if 'index' in location %} +{% endif %} +{% if 'index' in location %} index {{ location.index }}; -{% endif %} -{% if 'autoindex' in location %} +{% endif %} +{% if 'autoindex' in location %} autoindex on; -{% if 'format' in location.autoindex %} +{% if 'format' in location.autoindex %} autoindex_format {{ nginx_vhost.autoindex.format }}; -{% endif %} +{% endif %} +{% endif %} {% endif %} -{% endif %} -{% if 'extra_directives' in location %} +{% if 'extra_directives' in location %} - {{ location.extra_directives | indent(8) }} -{% endif %} + {{ location.extra_directives | trim | indent(8) }} +{% endif %} } -{% endfor %} +{% endfor %} +{% endif %} } |