deploy: fix nginx security headers dropped by add_header inheritance

Found while verifying the first real provision: none of the four
security headers reached the browser on any HTML page.

nginx's add_header inheritance is all-or-nothing — a location that sets
any add_header of its own discards every header inherited from the
server block. "/" resolves through try_files to `location = /index.html`,
which sets Cache-Control, so HSTS, X-Content-Type-Options,
X-Frame-Options and Referrer-Policy were silently dropped exactly where
they matter. /assets/ lost them the same way.

Move the four into snippets/security-headers.conf and include it in the
server block and in both locations that add a header of their own.

Also from the same provision run:
- ssl_stapling is dead config now that Let's Encrypt certificates carry
  no OCSP responder URL; it only logs a warning per cert on each reload;
- README step 3 chmod'ed /etc/exo to 750 but never set its group, so the
  exo user could not traverse it and exo-deploy died on "cannot read
  /etc/exo/<app>.env";
- README step 7 dropped http-extras.conf into conf.d without disabling
  the same directives in Debian's stock nginx.conf, and nginx refuses to
  start on a duplicate gzip / server_tokens.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Yuriy Panov
2026-09-06 23:56:16 +06:00
co-authored by Claude Opus 5
parent 51f39c9b88
commit 9736024e60
4 changed files with 32 additions and 7 deletions
+8
View File
@@ -77,6 +77,7 @@ mkdir -p /srv/exo/{fitnes,hotel,medcenterphysio,medcenterstart}/releases
mkdir -p /etc/exo /var/www/certbot
chown -R exo:exo /srv/exo
chmod 755 /srv/exo # www-data must traverse to reach dist/client
chown root:exo /etc/exo # without the group, exo cannot traverse it at 750
chmod 750 /etc/exo
for app in fitnes hotel medcenterphysio medcenterstart; do
@@ -149,6 +150,13 @@ MaxRetentionSec=14day
install -m 644 nginx/snippets/*.conf /etc/nginx/snippets/
install -m 644 nginx/http-extras.conf /etc/nginx/conf.d/00-exo-http.conf
# Debian's stock nginx.conf sets some of the same http{} directives (gzip,
# server_tokens), and nginx refuses to start on a duplicate. Comment out every
# stock directive that 00-exo-http.conf now owns.
for d in $(grep -oE '^[a-z_]+' /etc/nginx/conf.d/00-exo-http.conf | sort -u); do
sed -i -E "s@^([[:space:]]*)($d[[:space:]]+[^;]*;)@\\1# \\2@" /etc/nginx/nginx.conf
done
bin/exo-render-nginx /etc/nginx/sites-available # after filling in apps.conf
ln -s /etc/nginx/sites-available/exo-*.conf /etc/nginx/sites-enabled/
rm -f /etc/nginx/sites-enabled/default