314fa715fd
Two issues caused TLS to break on photos.carabosse.cloud over IPv6
(GrapheneOS + Immich app via Orange 5G NAT64):
1. Per-service vhosts only listened on IPv4 (listen 443 ssl). On IPv6,
nginx fell back to the first vhost loaded alphabetically and served
its certificate, breaking hostname verification on every other vhost.
2. /etc/letsencrypt/{live,archive} were 0700 root:root after certbot
created them, so the nginx worker (user http on Arch) could not read
the chained intermediates and served the leaf-only chain.
Changes:
- Add catch-all 00-default.conf default_server on :80 and :443 (v4+v6)
with a self-signed cert and 'return 444'. ACME challenges still
answered on :80.
- Add IPv6 listeners ([::]:80 and [::]:443 ssl) to immich, gitea, ntfy,
uptime_kuma vhosts and to the temporary ACME provisioning vhost.
- Apply 0755 on /etc/letsencrypt/live and /etc/letsencrypt/archive on
every run, not only at initial cert provisioning.
36 lines
936 B
Django/Jinja
36 lines
936 B
Django/Jinja
# Catch-all default_server vhosts
|
|
# Managed by Ansible - DO NOT EDIT MANUALLY
|
|
#
|
|
# Purpose: reject any request whose Host/SNI does not match an explicit
|
|
# server_name. Without this, the first vhost loaded alphabetically would
|
|
# leak its certificate to unrelated SNI requests (e.g. clients doing
|
|
# HTTP/2 connection coalescing or hitting the IP directly).
|
|
#
|
|
# `return 444` closes the connection without sending an HTTP response.
|
|
|
|
server {
|
|
listen 80 default_server;
|
|
listen [::]:80 default_server;
|
|
server_name _;
|
|
|
|
# Keep ACME HTTP-01 challenges working for any hostname
|
|
location /.well-known/acme-challenge/ {
|
|
root /var/www/certbot;
|
|
}
|
|
|
|
location / {
|
|
return 444;
|
|
}
|
|
}
|
|
|
|
server {
|
|
listen 443 ssl default_server;
|
|
listen [::]:443 ssl default_server;
|
|
server_name _;
|
|
|
|
ssl_certificate {{ nginx_default_ssl_cert }};
|
|
ssl_certificate_key {{ nginx_default_ssl_key }};
|
|
|
|
return 444;
|
|
}
|