diff --git a/docs/maintenance.md b/docs/maintenance.md index 2b410eb2e33a613d0e99a1221aebdff9e23f2fef..c7fbd82088a4bcb7fd23cadbbb65075b837319c9 100644 --- a/docs/maintenance.md +++ b/docs/maintenance.md @@ -27,6 +27,7 @@ The basic configuration looks like this: service_name: "<service name>" service_domain: "{{ service_domain }}" service_alternate_domains: [] + service_legacy_domains: [] service_nginx_conf: "{{ service_nginx_conf }}" when: maintenance is defined ``` diff --git a/roles/archweb/defaults/main.yml b/roles/archweb/defaults/main.yml index 7530dda6a8e7d484c446a0c18cde69b59ed88fd8..d2ee0c9b471f501aacd84766cfbafec794de0785 100644 --- a/roles/archweb/defaults/main.yml +++ b/roles/archweb/defaults/main.yml @@ -1,6 +1,7 @@ archweb_dir: '/srv/http/archweb' archweb_domain: 'archlinux.org' -archweb_alternate_domains: ['www.archlinux.org', 'master-key.archlinux.org', 'dev.archlinux.org', 'packages.archlinux.org', 'ipxe.archlinux.org', 'planet.archlinux.org'] +archweb_alternate_domains: ['www.archlinux.org', 'master-key.archlinux.org', 'dev.archlinux.org', 'packages.archlinux.org', 'planet.archlinux.org'] +archweb_legacy_domains: ['ipxe.archlinux.org'] archweb_domains_redirects: 'www.archlinux.org': '$request_uri' 'master-key.archlinux.org': '/master-keys/' diff --git a/roles/archweb/tasks/main.yml b/roles/archweb/tasks/main.yml index aeb233fc281309b3a69ec09f6ae2013c77544fbe..487dc715a150d92900643c1c61ae4aa35b054789 100644 --- a/roles/archweb/tasks/main.yml +++ b/roles/archweb/tasks/main.yml @@ -5,6 +5,7 @@ service_name: "site" service_domain: "{{ archweb_domain }}" service_alternate_domains: "{{ archweb_alternate_domains }}" + service_legacy_domains: "{{ archweb_legacy_domains }}" service_nginx_conf: "{{ archweb_nginx_conf }}" service_nginx_template: "maintenance-nginx.d.conf.j2" when: maintenance is defined and archweb_site @@ -29,6 +30,15 @@ domains: "{{ [archweb_domain] + archweb_alternate_domains }}" when: archweb_site | bool and maintenance is not defined +- name: Create legacy ssl cert + include_role: + name: certificate + vars: + cert_name: "{{ archweb_domain }}_legacy" + domains: "{{ archweb_legacy_domains }}" + legacy: true + when: archweb_site | bool and maintenance is not defined + - name: Set up nginx template: src=nginx.d.conf.j2 dest="{{ archweb_nginx_conf }}" owner=root group=root mode=644 notify: Reload nginx diff --git a/roles/archweb/templates/ipxe.archlinux.org.j2 b/roles/archweb/templates/ipxe.archlinux.org.j2 index 721b8e3c393b7f8afbf57891cb52806078bdb68e..2df4e1d6007c854437a4340c8ee5e6e6e6aeaf96 100644 --- a/roles/archweb/templates/ipxe.archlinux.org.j2 +++ b/roles/archweb/templates/ipxe.archlinux.org.j2 @@ -27,9 +27,9 @@ server { ssl_ciphers AES128-SHA:AES256-SHA:AES128-SHA256:AES256-SHA256; - ssl_certificate /etc/letsencrypt/live/{{ archweb_domain }}/fullchain.pem; - ssl_certificate_key /etc/letsencrypt/live/{{ archweb_domain }}/privkey.pem; - ssl_trusted_certificate /etc/letsencrypt/live/{{ archweb_domain }}/chain.pem; + ssl_certificate /etc/letsencrypt/live/{{ archweb_domain }}_legacy/fullchain.pem; + ssl_certificate_key /etc/letsencrypt/live/{{ archweb_domain }}_legacy/privkey.pem; + ssl_trusted_certificate /etc/letsencrypt/live/{{ archweb_domain }}_legacy/chain.pem; location /releng/netboot/ { access_log /var/log/nginx/{{ archweb_domain }}/access.log main; diff --git a/roles/archweb/templates/maintenance-nginx.d.conf.j2 b/roles/archweb/templates/maintenance-nginx.d.conf.j2 index 4ce5ca758378321dc9484e5e8591d33426eaa108..6eddee94891bc5189a37bcfc1578d3fdde6dd19f 100644 --- a/roles/archweb/templates/maintenance-nginx.d.conf.j2 +++ b/roles/archweb/templates/maintenance-nginx.d.conf.j2 @@ -2,9 +2,7 @@ upstream archweb { server unix:///run/uwsgi/archweb.sock; } -{% if service_alternate_domains %} -{% for domain in service_alternate_domains %} - +{% for domain in service_alternate_domains | default([]) %} server { listen 80; listen [::]:80; @@ -18,7 +16,7 @@ server { location / { access_log off; - return 301 https://$server_name$request_uri; + return 302 https://$server_name$request_uri; } } @@ -38,16 +36,51 @@ server { location / { access_log off; - return 301 https://{{ service_domain }}; + return 302 https://{{ service_domain }}; } } + {% endfor %} +{% for domain in service_legacy_domains | default([]) %} +server { + listen 80; + listen [::]:80; + server_name {{ domain }}; + + access_log {{ maintenance_logs_dir }}/{{ service_domain }}-access.log reduced; + access_log {{ maintenance_logs_dir }}/{{ service_domain }}-access.log.json json_reduced; + error_log {{ maintenance_logs_dir }}/{{ service_domain }}-error.log; + + include snippets/letsencrypt.conf; + + location / { + access_log off; + return 302 https://$server_name$request_uri; + } +} server { -{% else %} + listen 443 ssl; + listen [::]:443 ssl; + http2 on; + server_name {{ domain }}; + + access_log {{ maintenance_logs_dir }}/{{ service_domain }}-access.log reduced; + access_log {{ maintenance_logs_dir }}/{{ service_domain }}-access.log.json json_reduced; + error_log {{ maintenance_logs_dir }}/{{ service_domain }}-error.log; + + ssl_certificate /etc/letsencrypt/live/{{ service_domain }}_legacy/fullchain.pem; + ssl_certificate_key /etc/letsencrypt/live/{{ service_domain }}_legacy/privkey.pem; + ssl_trusted_certificate /etc/letsencrypt/live/{{ service_domain }}_legacy/chain.pem; + + location / { + access_log off; + return 302 https://{{ service_domain }}; + } +} +{% endfor %} server { -{% endif %} listen 80; listen [::]:80; server_name {{ service_domain }}; @@ -60,7 +93,7 @@ server { location / { access_log off; - return 301 https://$server_name$request_uri; + return 302 https://$server_name$request_uri; } } diff --git a/roles/archwiki/tasks/main.yml b/roles/archwiki/tasks/main.yml index 7ab910b99a2e0063a5e99d2cc2414c6e3621d9a2..9140317c71e77a078cf0c94e0184de3d2ae2c486 100644 --- a/roles/archwiki/tasks/main.yml +++ b/roles/archwiki/tasks/main.yml @@ -4,7 +4,6 @@ vars: service_name: "wiki" service_domain: "{{ archwiki_domain }}" - service_alternate_domains: [] service_nginx_conf: "{{ archwiki_nginx_conf }}" when: maintenance is defined diff --git a/roles/certbot/files/certbot-renewal.service b/roles/certbot/files/certbot-renewal.service index b9d5844830c3717652b7f2f232695ebb94632eff..846b94a5fa88a1953a04f56baccb113fc3101dee 100644 --- a/roles/certbot/files/certbot-renewal.service +++ b/roles/certbot/files/certbot-renewal.service @@ -3,7 +3,7 @@ Description=Let's Encrypt renewal [Service] Type=oneshot -ExecStart=/usr/bin/certbot renew --key-type ecdsa \ +ExecStart=/usr/bin/certbot renew \ --no-random-sleep-on-renew \ --pre-hook "/etc/letsencrypt/hook.sh pre" \ --post-hook "/etc/letsencrypt/hook.sh post" \ diff --git a/roles/certificate/tasks/main.yml b/roles/certificate/tasks/main.yml index 4d76a141803f0359f4ff1c38d3318c222bf5b6bf..c1d3f98f1fe6d1c73164fef60c2fde60d22320bc 100644 --- a/roles/certificate/tasks/main.yml +++ b/roles/certificate/tasks/main.yml @@ -1,17 +1,17 @@ -- name: Create ssl cert (HTTP-01) +- name: Create ssl cert (HTTP-01) named {{ cert_name | default(domains | first) }} shell: | set -o pipefail # We can't start nginx without the certificate and we can't issue a certificate without nginx running. # So use Python built-in http.server for the initial certificate issuance python -m http.server --directory {{ letsencrypt_validation_dir }} 80 & trap "jobs -p | xargs --no-run-if-empty kill" EXIT - certbot certonly --email {{ certificate_contact_email }} --agree-tos --key-type ecdsa --renew-by-default --webroot -w {{ letsencrypt_validation_dir }} -d {{ domains | join(' -d ') }} + certbot certonly --email {{ certificate_contact_email }} --agree-tos --key-type {{ 'ecdsa' if not (legacy | default(false)) else 'rsa --rsa-key-size 4096' }} --renew-by-default --webroot -w {{ letsencrypt_validation_dir }} -d {{ domains | join(' -d ') }} --cert-name {{ cert_name | default(domains | first) }} args: - creates: '/etc/letsencrypt/live/{{ domains | first }}/fullchain.pem' + creates: '/etc/letsencrypt/live/{{ cert_name | default(domains | first) }}/fullchain.pem' when: challenge | default(certificate_challenge) == "HTTP-01" -- name: Create ssl cert (DNS-01) - command: certbot certonly --email {{ certificate_contact_email }} --agree-tos --key-type ecdsa --renew-by-default --dns-rfc2136 --dns-rfc2136-credentials /etc/letsencrypt/rfc2136.ini -d {{ domains | join(' -d ') }} +- name: Create ssl cert (DNS-01) named {{ cert_name | default(domains | first) }} + command: certbot certonly --email {{ certificate_contact_email }} --agree-tos --key-type {{ 'ecdsa' if not (legacy | default(false)) else 'rsa --rsa-key-size 4096' }} --renew-by-default --dns-rfc2136 --dns-rfc2136-credentials /etc/letsencrypt/rfc2136.ini -d {{ domains | join(' -d ') }} --cert-name {{ cert_name | default(domains | first) }} args: - creates: '/etc/letsencrypt/live/{{ domains | first }}/fullchain.pem' + creates: '/etc/letsencrypt/live/{{ cert_name | default(domains | first) }}/fullchain.pem' when: challenge | default(certificate_challenge) == "DNS-01" diff --git a/roles/gitlab/tasks/main.yml b/roles/gitlab/tasks/main.yml index 52d8a6f96147743d60282c3ff8921eb967f45439..8a3b3457835c3ffcccd5461c70b250a9637c3c0c 100644 --- a/roles/gitlab/tasks/main.yml +++ b/roles/gitlab/tasks/main.yml @@ -34,7 +34,7 @@ registry_external_url 'https://registry.archlinux.org' nginx['client_max_body_size'] = '10g' nginx['listen_addresses'] = {{ gitlab_primary_addresses }} - nginx['custom_gitlab_server_config'] = "set $bypass 0;\nif ($remote_addr = \"{{ hostvars['gemini.archlinux.org']['ipv4_address'] }}\") {\nset $bypass 1;\n}\nif ($remote_addr = \"{{hostvars['gemini.archlinux.org']['ipv6_address']}}\") {\nset $bypass 1;\n}\nproxy_set_header Gitlab-Bypass-Rate-Limiting $bypass;\n" + nginx['custom_gitlab_server_config'] = "set $bypass 0;\nif ($remote_addr = \"{{ hostvars['gemini.archlinux.org']['ipv4_address'] }}\") {\nset $bypass 1;\n}\nif ($remote_addr = \"{{ hostvars['gemini.archlinux.org']['ipv6_address'] }}\") {\nset $bypass 1;\n}\nproxy_set_header Gitlab-Bypass-Rate-Limiting $bypass;\n" registry_nginx['listen_addresses'] = {{ gitlab_primary_addresses }} gitlab_pages['inplace_chroot'] = true pages_external_url "http://{{ gitlab_domain }}" diff --git a/roles/maintenance/templates/nginx-maintenance.conf.j2 b/roles/maintenance/templates/nginx-maintenance.conf.j2 index 640c9504b0ae235a16e96ded304fb11b14d6c63d..2493c1b78c2c3b9d177d36e23d6137ae6b2da86d 100644 --- a/roles/maintenance/templates/nginx-maintenance.conf.j2 +++ b/roles/maintenance/templates/nginx-maintenance.conf.j2 @@ -1,6 +1,4 @@ -{% if service_alternate_domains %} -{% for domain in service_alternate_domains %} - +{% for domain in service_alternate_domains | default([]) %} server { listen 80; listen [::]:80; @@ -14,7 +12,7 @@ server { location / { access_log off; - return 301 https://$server_name$request_uri; + return 302 https://$server_name$request_uri; } } @@ -34,16 +32,51 @@ server { location / { access_log off; - return 301 https://{{ service_domain }}; + return 302 https://{{ service_domain }}; } } + {% endfor %} +{% for domain in service_legacy_domains | default([]) %} +server { + listen 80; + listen [::]:80; + server_name {{ domain }}; + + access_log {{ maintenance_logs_dir }}/{{ service_domain }}-access.log reduced; + access_log {{ maintenance_logs_dir }}/{{ service_domain }}-access.log.json json_reduced; + error_log {{ maintenance_logs_dir }}/{{ service_domain }}-error.log; + + include snippets/letsencrypt.conf; + + location / { + access_log off; + return 302 https://$server_name$request_uri; + } +} server { -{% else %} + listen 443 ssl; + listen [::]:443 ssl; + http2 on; + server_name {{ domain }}; + + access_log {{ maintenance_logs_dir }}/{{ service_domain }}-access.log reduced; + access_log {{ maintenance_logs_dir }}/{{ service_domain }}-access.log.json json_reduced; + error_log {{ maintenance_logs_dir }}/{{ service_domain }}-error.log; + + ssl_certificate /etc/letsencrypt/live/{{ service_domain }}_legacy/fullchain.pem; + ssl_certificate_key /etc/letsencrypt/live/{{ service_domain }}_legacy/privkey.pem; + ssl_trusted_certificate /etc/letsencrypt/live/{{ service_domain }}_legacy/chain.pem; + + location / { + access_log off; + return 302 https://{{ service_domain }}; + } +} +{% endfor %} server { -{% endif %} listen 80; listen [::]:80; server_name {{ service_domain }}; @@ -56,7 +89,7 @@ server { location / { access_log off; - return 301 https://$server_name$request_uri; + return 302 https://$server_name$request_uri; } } diff --git a/roles/security_tracker/tasks/main.yml b/roles/security_tracker/tasks/main.yml index 4037e58a041b53af28052437222e0821ddbe6ec5..f689f48d07227cbf8292bfcc3ff3ea0928d54e63 100644 --- a/roles/security_tracker/tasks/main.yml +++ b/roles/security_tracker/tasks/main.yml @@ -4,7 +4,6 @@ vars: service_name: "security tracker" service_domain: "{{ security_tracker_domain }}" - service_alternate_domains: [] service_nginx_conf: "{{ security_tracker_nginx_conf }}" when: maintenance is defined