diff options
| author | Leitwolf11 | 2026-10-15 18:28:17 +0300 |
|---|---|---|
| committer | Leitwolf11 | 2026-10-15 18:28:17 +0300 |
| commit | a460c4c7e922f37705b2be3f1fa7c789f514cd51 (patch) | |
| tree | bf5eeb2c283222c96890c37078537e1251f32f8e | |
| parent | 18951f0c5c6e3f54ccd8757cec040a40bd2b5068 (diff) | |
| download | website-a460c4c7e922f37705b2be3f1fa7c789f514cd51.tar.gz | |
Treat tala.run as an HSTS-preloaded domain
.run has no HSTS requirement of its own, but tala.run is served as if it
had one: every HTTPS response of tala.run, www, talac, tazel and forum
sends max-age=63072000; includeSubDomains; preload, and plain HTTP only
answers the ACME challenge and otherwise redirects to HTTPS. A test
checks both for every tala.run block of the three Nginx files. The
redirects of the former .xyz domain keep their header.
| -rw-r--r-- | frontend/tests/site-integrity.test.mjs | 21 | ||||
| -rw-r--r-- | ops/nginx/forum.conf | 2 | ||||
| -rw-r--r-- | ops/nginx/tala-maintenance.conf | 2 | ||||
| -rw-r--r-- | ops/nginx/tala.conf | 8 |
4 files changed, 27 insertions, 6 deletions
diff --git a/frontend/tests/site-integrity.test.mjs b/frontend/tests/site-integrity.test.mjs index 588755c..922c03d 100644 --- a/frontend/tests/site-integrity.test.mjs +++ b/frontend/tests/site-integrity.test.mjs @@ -309,3 +309,24 @@ test("the former domain is left to the server: the page carries no notice about assert.doesNotMatch(app, /domainNotice|domain-notice|onDepartingDomain/); assert.doesNotMatch(read("src/styles/site.css"), /\.domain-notice/); }); + +test("every tala.run host behaves as if HSTS were preloaded for its top-level domain", () => { + for (const file of ["tala.conf", "forum.conf", "tala-maintenance.conf"]) { + const config = readFileSync(join(websiteRoot, "ops/nginx", file), "utf8"); + const blocks = config.split(/\nserver \{/).slice(1); + for (const block of blocks) { + const names = block.match(/server_name ([^;]+);/)?.[1] ?? ""; + if (!/\btala\.run\b/.test(names)) continue; + if (/listen 443/.test(block)) { + assert.match( + block, + /add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload" always;/, + `${file}: ${names} must send the preload header`, + ); + } else { + // Plain HTTP answers only the ACME challenge and otherwise sends the visitor to HTTPS. + assert.match(block, /return 308 https:\/\//, `${file}: ${names} must redirect to HTTPS`); + } + } + } +}); diff --git a/ops/nginx/forum.conf b/ops/nginx/forum.conf index e77be65..5ae383c 100644 --- a/ops/nginx/forum.conf +++ b/ops/nginx/forum.conf @@ -29,7 +29,7 @@ server { ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; add_header X-Robots-Tag "noindex, nofollow" always; - add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always; + add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload" always; add_header X-Content-Type-Options "nosniff" always; add_header Referrer-Policy "strict-origin-when-cross-origin" always; add_header Content-Security-Policy "default-src 'none'; script-src 'self'; style-src 'self'; img-src 'self'; base-uri 'none'; frame-ancestors 'none'; form-action 'none'" always; diff --git a/ops/nginx/tala-maintenance.conf b/ops/nginx/tala-maintenance.conf index d712808..35e78d9 100644 --- a/ops/nginx/tala-maintenance.conf +++ b/ops/nginx/tala-maintenance.conf @@ -29,7 +29,7 @@ server { add_header Retry-After "3600" always; add_header Cache-Control "no-store" always; - add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always; + add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload" always; add_header X-Content-Type-Options "nosniff" always; add_header X-Frame-Options "DENY" always; add_header Content-Security-Policy "default-src 'none'; style-src 'unsafe-inline'; base-uri 'none'; frame-ancestors 'none'" always; diff --git a/ops/nginx/tala.conf b/ops/nginx/tala.conf index 6bb7f83..7f67bce 100644 --- a/ops/nginx/tala.conf +++ b/ops/nginx/tala.conf @@ -57,7 +57,7 @@ server { add_header Content-Security-Policy "default-src 'self'; img-src 'self' data:; base-uri 'self'; form-action 'self'; frame-ancestors 'none'; object-src 'none'" always; add_header Referrer-Policy "strict-origin-when-cross-origin" always; - add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always; + add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload" always; add_header X-Content-Type-Options "nosniff" always; add_header X-Frame-Options "DENY" always; @@ -120,7 +120,7 @@ server { add_header Content-Security-Policy "default-src 'self'; img-src 'self' data:; base-uri 'self'; form-action 'self'; frame-ancestors 'none'; object-src 'none'" always; add_header Referrer-Policy "strict-origin-when-cross-origin" always; - add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always; + add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload" always; add_header X-Content-Type-Options "nosniff" always; add_header X-Frame-Options "DENY" always; @@ -166,7 +166,7 @@ server { add_header Content-Security-Policy "default-src 'self'; img-src 'self' data:; base-uri 'self'; form-action 'self'; frame-ancestors 'none'; object-src 'none'" always; add_header Referrer-Policy "strict-origin-when-cross-origin" always; - add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always; + add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload" always; add_header X-Content-Type-Options "nosniff" always; add_header X-Frame-Options "DENY" always; @@ -207,7 +207,7 @@ server { include /etc/letsencrypt/options-ssl-nginx.conf; ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; - add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always; + add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload" always; return 308 https://tala.run$request_uri; } |