Harden the edge: catch-all server, modern TLS and HSTS

- Unknown hostnames and direct IP access no longer land on the first
  vhost (Gitea): port 80 closes the connection, except for ACME
  challenges, and port 443 refuses the handshake.
- Mozilla intermediate ciphers (forward secrecy only, no CBC), session
  cache, no session tickets, and HSTS with a short max-age for now.
- Set X-Forwarded-For to the client address instead of appending to
  whatever the client sent.
This commit is contained in:
2026-09-24 15:05:44 +02:00
parent 3e1ee28125
commit 22213a5592
4 changed files with 47 additions and 2 deletions
+25
View File
@@ -0,0 +1,25 @@
# Catch-all for Host headers no vhost claims (scanners, direct IP access,
# stale DNS). Without it nginx hands them to the first vhost it loaded,
# i.e. Gitea. ACME stays reachable here so a certificate for a new hostname
# can be issued before its vhost exists.
server {
listen 80 default_server;
listen [::]:80 default_server;
server_name _;
location /.well-known/acme-challenge/ {
root /var/www/certbot;
}
location / {
return 444;
}
}
# No certificate to present for an unknown name, so refuse the handshake.
server {
listen 443 ssl default_server;
listen [::]:443 ssl default_server;
server_name _;
ssl_reject_handshake on;
}
+3 -1
View File
@@ -1,7 +1,9 @@
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# The edge is the first hop, so whatever X-Forwarded-For the client sent is
# made up: replace it instead of appending to it.
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
+12 -1
View File
@@ -1,2 +1,13 @@
# Mozilla "intermediate" profile, without the DHE suites (they'd need a
# dhparam file): forward secrecy on every connection, no CBC.
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305;
ssl_prefer_server_ciphers off;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 1d;
ssl_session_tickets off;
# Short max-age for now: raise it (e.g. 63072000) once every hostname is
# confirmed working over https. A location that sets its own add_header
# stops inheriting this one.
add_header Strict-Transport-Security "max-age=86400" always;