From a6155819b6cacb4263b2a00d5f2b90d9ca2c02ba Mon Sep 17 00:00:00 2001 From: Oier Bravo Urtasun Date: Tue, 9 Jun 2026 01:21:17 +0200 Subject: [PATCH] feat(nginx): enforce HTTPS-only with HSTS Add Strict-Transport-Security (max-age 1y, includeSubDomains) to every TLS server block in both vhost templates. Combined with the existing port-80 301 redirect, browsers refuse plain HTTP to these names after first visit. Co-Authored-By: Claude Opus 4.8 (1M context) --- nginx/ulicraft-caddy.conf.tmpl | 5 +++++ nginx/ulicraft.conf.tmpl | 3 +++ 2 files changed, 8 insertions(+) diff --git a/nginx/ulicraft-caddy.conf.tmpl b/nginx/ulicraft-caddy.conf.tmpl index 763af04..8360242 100644 --- a/nginx/ulicraft-caddy.conf.tmpl +++ b/nginx/ulicraft-caddy.conf.tmpl @@ -46,6 +46,7 @@ server { ssl_certificate ${APP_DIR}/certs/${BASE_DOMAIN}/cert.pem; ssl_certificate_key ${APP_DIR}/certs/${BASE_DOMAIN}/key.pem; + add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always; client_max_body_size 4m; # skin uploads (auth) reuse the same proxy block @@ -66,6 +67,7 @@ server { ssl_certificate ${APP_DIR}/certs/www.${BASE_DOMAIN}/cert.pem; ssl_certificate_key ${APP_DIR}/certs/www.${BASE_DOMAIN}/key.pem; + add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always; return 301 https://${BASE_DOMAIN}$request_uri; } @@ -77,6 +79,7 @@ server { ssl_certificate ${APP_DIR}/certs/auth.${BASE_DOMAIN}/cert.pem; ssl_certificate_key ${APP_DIR}/certs/auth.${BASE_DOMAIN}/key.pem; + add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always; client_max_body_size 4m; # skin uploads @@ -96,6 +99,7 @@ server { ssl_certificate ${APP_DIR}/certs/pack.${BASE_DOMAIN}/cert.pem; ssl_certificate_key ${APP_DIR}/certs/pack.${BASE_DOMAIN}/key.pem; + add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always; location / { proxy_pass http://ulicraft_caddy; @@ -113,6 +117,7 @@ server { ssl_certificate ${APP_DIR}/certs/distribution.${BASE_DOMAIN}/cert.pem; ssl_certificate_key ${APP_DIR}/certs/distribution.${BASE_DOMAIN}/key.pem; + add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always; location / { proxy_pass http://ulicraft_caddy; diff --git a/nginx/ulicraft.conf.tmpl b/nginx/ulicraft.conf.tmpl index 1539a36..70d644a 100644 --- a/nginx/ulicraft.conf.tmpl +++ b/nginx/ulicraft.conf.tmpl @@ -34,6 +34,7 @@ server { ssl_certificate ${APP_DIR}/certs/${BASE_DOMAIN}/cert.pem; ssl_certificate_key ${APP_DIR}/certs/${BASE_DOMAIN}/key.pem; + add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always; # Launcher downloads (populated by tooling/fetch-launcher.sh -> ./mirror/launcher). location /launcher/ { @@ -56,6 +57,7 @@ server { ssl_certificate ${APP_DIR}/certs/pack.${BASE_DOMAIN}/cert.pem; ssl_certificate_key ${APP_DIR}/certs/pack.${BASE_DOMAIN}/key.pem; + add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always; # Locally-hosted custom mod jars live outside ./pack; expose them at /custom/. location /custom/ { @@ -77,6 +79,7 @@ server { ssl_certificate ${APP_DIR}/certs/auth.${BASE_DOMAIN}/cert.pem; ssl_certificate_key ${APP_DIR}/certs/auth.${BASE_DOMAIN}/key.pem; + add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always; client_max_body_size 4m; # skin uploads