Add nginx config and rewrite README with usage and deployment guide
nginx: path allowlist, GET/HEAD only, CSP and security headers, gzip. README: what the app is, how to use it, CSV format, step-by-step deploy. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 5.5
parent
401833104b
commit
743389b133
@@ -0,0 +1,81 @@
|
||||
# Thumbnail Tinder: static site.
|
||||
#
|
||||
# Куда положить: /etc/nginx/sites-available/thumbnail-tinder
|
||||
# (затем ссылка в sites-enabled; на RHEL-подобных системах просто /etc/nginx/conf.d/thumbnail-tinder.conf).
|
||||
# Перед запуском замените thumbnails.example.com на свой домен.
|
||||
# HTTPS добавляется одной командой после запуска: sudo certbot --nginx -d <домен>
|
||||
# (подробности в README.md, раздел «Развёртывание»).
|
||||
|
||||
server {
|
||||
listen 80;
|
||||
listen [::]:80;
|
||||
server_name thumbnails.example.com;
|
||||
|
||||
root /var/www/thumbnail-tinder;
|
||||
index index.html;
|
||||
charset utf-8;
|
||||
|
||||
access_log /var/log/nginx/thumbnail-tinder.access.log;
|
||||
error_log /var/log/nginx/thumbnail-tinder.error.log;
|
||||
|
||||
# Приложение только отдаёт статику.
|
||||
if ($request_method !~ ^(GET|HEAD)$) {
|
||||
return 405;
|
||||
}
|
||||
|
||||
# ---------- Сжатие ----------
|
||||
gzip on;
|
||||
gzip_comp_level 5;
|
||||
gzip_min_length 512;
|
||||
gzip_vary on;
|
||||
gzip_types text/css text/plain application/javascript application/json image/svg+xml;
|
||||
# text/html сжимается по умолчанию
|
||||
|
||||
# ---------- Заголовки безопасности ----------
|
||||
# Страницам нужны: шрифты с Google Fonts и превью с i.ytimg.com.
|
||||
# Скрипты и стили встроены в HTML, поэтому разрешён 'unsafe-inline'.
|
||||
# connect-src 'none': приложение не делает сетевых запросов, файл CSV читается локально в браузере.
|
||||
# Важно: add_header в location сбрасывает унаследованные заголовки,
|
||||
# поэтому ниже в location используется только expires.
|
||||
add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline' https://fonts.googleapis.com; font-src https://fonts.gstatic.com; img-src 'self' data: https://i.ytimg.com; connect-src 'none'; object-src 'none'; base-uri 'none'; form-action 'none'; frame-ancestors 'none'" always;
|
||||
add_header X-Content-Type-Options "nosniff" always;
|
||||
add_header X-Frame-Options "DENY" always;
|
||||
add_header Referrer-Policy "no-referrer" always;
|
||||
add_header Permissions-Policy "camera=(), microphone=(), geolocation=()" always;
|
||||
|
||||
# ---------- Маршруты: белый список ----------
|
||||
# Отдаются только три файла приложения. Всё остальное (в том числе случайно
|
||||
# скопированные CSV, .git, README) отвечает 404.
|
||||
|
||||
location = / {
|
||||
try_files /index.html =404;
|
||||
expires epoch; # Cache-Control: no-cache, страница всегда свежая
|
||||
}
|
||||
|
||||
location = /index.html {
|
||||
expires epoch;
|
||||
}
|
||||
|
||||
location = /liked.html {
|
||||
expires epoch;
|
||||
}
|
||||
|
||||
location = /style.css {
|
||||
expires 1h; # файл без хеша в имени, поэтому кэш короткий
|
||||
}
|
||||
|
||||
location = /favicon.ico {
|
||||
access_log off;
|
||||
return 204;
|
||||
}
|
||||
|
||||
# Для certbot (если используется метод webroot, а не --nginx)
|
||||
location ^~ /.well-known/acme-challenge/ {
|
||||
root /var/www/certbot;
|
||||
default_type text/plain;
|
||||
}
|
||||
|
||||
location / {
|
||||
return 404;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user