Server hardening: nginx origin locked to ArvanCloud + CSP, demo logins removed, docs

- ops/nginx/: the two nginx sites as they now run on 249. Only ArvanCloud
  edges reach the app (direct hits on the IP get 403, so Arvan's DDoS/WAF
  can't be skipped); the frontend gets CSP (own sources only, the one inline
  script by hash), X-Frame-Options, nosniff, Referrer-Policy,
  Permissions-Policy, HSTS; API body limit 100M -> 20M plus HSTS. Checked from
  outside and in Chrome (all tabs and an island quiz, logged in): no CSP errors.
- Demo accounts (users 11-15, 25) and TEST_LOGIN_PHONES removed from the server;
  the health warning for fixed-code logins now has a test and says how to
  test instead (an OTPCode made in the admin).
- SMS daily cap on the server is 2000 (launch of ~600 users).
- CLAUDE.md: never run tests with --parallel on macOS, always --noinput
  (both hang forever without an error).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-13 19:17:11 +03:30
parent 2a03dc81b5
commit ba4ecff29e
9 changed files with 196 additions and 117 deletions

23
ops/nginx/mathapp Normal file
View File

@@ -0,0 +1,23 @@
# روی ۲۴۹: /etc/nginx/sites-enabled/mathapp (فایلِ معمولی، نه symlink) — API، mathapi.tadrisino2.ir.
server {
listen 80;
listen 443 ssl;
server_name mathapi.tadrisino2.ir;
ssl_certificate /etc/ssl/certs/mathapp.crt;
ssl_certificate_key /etc/ssl/private/mathapp.key;
include /etc/nginx/snippets/zareian-arvan-only.conf;
# بزرگ‌ترین آپلودِ واقعی فایلِ سوال/برنامه‌ی درسی در پنلِ ادمین است (~۹ مگابایت). nginx بدنه را پیش از
# رد شدن روی دیسکِ مشترک می‌نویسد، پس سقفِ ۱۰۰ مگابایتیِ قبلی جای پر کردنِ دیسک می‌داد.
client_max_body_size 20M;
# بقیه‌ی هدرهای امنیتی (nosniff، X-Frame-Options، Referrer-Policy) را خودِ جنگو می‌گذارد.
add_header Strict-Transport-Security "max-age=31536000" always;
location / {
include proxy_params;
proxy_pass http://unix:/run/gunicorn/mathapp.sock;
}
}