commit 3a6f20a0fe241cfcc97111252b261489c6a67f30
parent b0586ed4b23826defdb9e79fd6afd24700a37235
Author: Florian Dold <dold@taler.net>
Date: Mon, 7 Sep 2026 22:07:50 +0200
webserver: scope TLS settings to managed HTTPS servers
Move TLS settings into the shared server snippet to avoid duplicate
directives in Debian nginx.conf. Inherit the packaged TLS protocol
selection and remove the obsolete global drop-in before validation.
Diffstat:
4 files changed, 35 insertions(+), 26 deletions(-)
diff --git a/contrib/tests/test_deployment.py b/contrib/tests/test_deployment.py
@@ -17,6 +17,17 @@ UNITS = ['taler-exchange.target', 'taler-exchange-httpd.service',
'email-challenger-httpd.service', 'postal-challenger-httpd.service']
+def verify_nginx_configuration(container):
+ assert container('test', '-e', '/etc/nginx/conf.d/http2-http3.conf', check=False).returncode == 1
+ result = container('nginx', '-t')
+ assert 'duplicate' not in result.stderr, result.stderr
+ conffiles = container('dpkg-query', '-W', '-f=${Conffiles}', 'nginx-common').stdout
+ packaged_hash = re.search(r'^ /etc/nginx/nginx\.conf ([0-9a-f]+)$', conffiles, re.M)[1]
+ installed_hash = container('md5sum', '/etc/nginx/nginx.conf').stdout.split()[0]
+ assert installed_hash == packaged_hash, 'Deployment modified Debian\'s nginx.conf'
+ print('PASS: nginx accepts the managed sites with an unchanged Debian configuration', flush=True)
+
+
def main():
parser = argparse.ArgumentParser()
parser.add_argument('container')
@@ -29,6 +40,8 @@ def main():
return subprocess.run(['podman', 'exec', '-i', args.container, *cmd],
capture_output=True, text=True, check=check, input=input)
+ verify_nginx_configuration(container)
+
subprocess.run(['podman', 'cp', str(REPO / 'contrib/test-fact-helpers.sh'),
f'{args.container}:/tmp/test-fact-helpers.sh'], check=True)
helper_result = container('env', 'TALER_FACT_HELPERS_DIR=/bin', 'bash', '/tmp/test-fact-helpers.sh')
@@ -72,6 +85,12 @@ print(json.dumps([json.load(open(p)) for p in glob.glob('/etc/ansible/facts.d/*s
def role(name, **variables):
return {'ansible.builtin.include_role': {'name': name}, 'vars': variables}
+ # Repair an old global drop-in that conflicts with Debian's nginx.conf.
+ container('tee', '/etc/nginx/conf.d/http2-http3.conf', input='ssl_prefer_server_ciphers on;\n')
+ assert container('nginx', '-t', check=False).returncode != 0
+ play([role('webserver')])
+ verify_nginx_configuration(container)
+
def states():
return [container('systemctl', 'is-active', unit, check=False).stdout.strip() for unit in UNITS]
diff --git a/roles/webserver/files/etc/nginx/conf.d/http2-http3.conf b/roles/webserver/files/etc/nginx/conf.d/http2-http3.conf
@@ -1,17 +0,0 @@
-# Drop-in placed by Ansible.
-# Sets HTTP/2 and HTTP/3 (QUIC) globally inside the http{} context.
-# All per-server listen/quic directives live in listen.conf.inc.
-
-# FIXME: We still disable http2/http3 for now,
-# due to networking issues with the taler-merchant.
-
-http2 off;
-http3 off;
-quic_retry off;
-
-ssl_early_data off;
-
-## Note: session cache is shared across all services on this server
-ssl_session_cache shared:TLS:10m;
-ssl_dhparam /etc/ssl/private/dhparam.pem;
-ssl_ciphers 'EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH';
diff --git a/roles/webserver/files/etc/nginx/conf.d/listen.conf.inc b/roles/webserver/files/etc/nginx/conf.d/listen.conf.inc
@@ -3,10 +3,20 @@ listen [::]:443 ssl;
#listen 443 quic;
#listen [::]:443 quic;
-http2 off; # redundant with global, but explicit per spec
+# HTTP2/HTTP3 remain disabled due to networking issues with taler-merchant.
+http2 off;
http3 off;
quic_retry off;
+# Inherit ssl_protocols from Debian's nginx.conf (TLSv1.2 and TLSv1.3).
+ssl_early_data off;
+# Override Debian's inherited cipher preference for our HTTPS servers.
+ssl_prefer_server_ciphers on;
+# The named session cache is shared across all managed HTTPS servers.
+ssl_session_cache shared:TLS:10m;
+ssl_dhparam /etc/ssl/private/dhparam.pem;
+ssl_ciphers 'EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH';
+
# Advertise support for HTTP3
#add_header Alt-Svc 'h3=":443"; ma=86400';
diff --git a/roles/webserver/tasks/main.yml b/roles/webserver/tasks/main.yml
@@ -40,16 +40,13 @@
mode: "0644"
notify: Restart nginx
-- name: Setup global HTTP2/HTTP3 configuration
- copy:
- src: etc/nginx/conf.d/http2-http3.conf
- dest: /etc/nginx/conf.d/http2-http3.conf
- owner: root
- group: root
- mode: "0644"
+- name: Remove obsolete global HTTP2/HTTP3 configuration
+ ansible.builtin.file:
+ path: /etc/nginx/conf.d/http2-http3.conf
+ state: absent
notify: Restart nginx
-- name: Setup per-server HTTP2/HTTP3 listen options
+- name: Setup per-server HTTPS configuration
copy:
src: etc/nginx/conf.d/listen.conf.inc
dest: /etc/nginx/conf.d/listen.conf.inc