From b97e82bcbbb492aa2769916480147554640a2f06 Mon Sep 17 00:00:00 2001 From: erjemin Date: Wed, 1 Apr 2026 02:12:33 +0300 Subject: [PATCH] =?UTF-8?q?nginx:=20=D0=B4=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB?= =?UTF-8?q?=D0=B5=D0=BD=D1=8B=20=D1=80=D0=B0=D1=81=D1=88=D0=B8=D1=80=D0=B5?= =?UTF-8?q?=D0=BD=D0=BD=D0=BE=D0=B5=20=D0=BB=D0=BE=D0=B3=D0=B8=D1=80=D0=BE?= =?UTF-8?q?=D0=B2=D0=B0=D0=BD=D0=B8=D0=B5=20=D0=B4=D0=BB=D1=8F=20CrowdSec?= =?UTF-8?q?=20=D0=B8=20rate-limiting=20=D0=B4=D0=BB=D1=8F=20DDoS=20=D0=B7?= =?UTF-8?q?=D0=B0=D1=89=D0=B8=D1=82=D1=8B=20-=20=D0=A0=D0=B0=D1=81=D1=88?= =?UTF-8?q?=D0=B8=D1=80=D0=B5=D0=BD=D0=BD=D0=BE=D0=B5=20=D0=BB=D0=BE=D0=B3?= =?UTF-8?q?=D0=B8=D1=80=D0=BE=D0=B2=D0=B0=D0=BD=D0=B8=D0=B5=20=D1=81=20?= =?UTF-8?q?=D1=84=D0=BE=D1=80=D0=BC=D0=B0=D1=82=D0=BE=D0=BC=20'main'=20(IP?= =?UTF-8?q?,=20=D0=B2=D1=80=D0=B5=D0=BC=D1=8F,=20=D0=BC=D0=B5=D1=82=D0=BE?= =?UTF-8?q?=D0=B4,=20URL,=20=D1=81=D1=82=D0=B0=D1=82=D1=83=D1=81)=20-=20?= =?UTF-8?q?=D0=91=D1=83=D1=84=D0=B5=D1=80=D0=B8=D0=B7=D0=B8=D1=80=D0=BE?= =?UTF-8?q?=D0=B2=D0=B0=D0=BD=D0=BD=D1=8B=D0=B5=20=D0=BB=D0=BE=D0=B3=D0=B8?= =?UTF-8?q?=20=D1=81=205-=D1=81=D0=B5=D0=BA=20=D0=BE=D1=87=D0=B8=D1=81?= =?UTF-8?q?=D1=82=D0=BA=D0=BE=D0=B9=20=D0=B4=D0=BB=D1=8F=20=D0=BE=D0=BF?= =?UTF-8?q?=D1=82=D0=B8=D0=BC=D0=B8=D0=B7=D0=B0=D1=86=D0=B8=D0=B8=20=D0=B4?= =?UTF-8?q?=D0=B8=D1=81=D0=BA=D0=BE=D0=B2=D0=BE=D0=B3=D0=BE=20I/O=20-=20Ra?= =?UTF-8?q?te-limiting:=20100=20req/s=20=D0=BD=D0=B0=20IP,=20burst=3D200?= =?UTF-8?q?=20=D0=B4=D0=BB=D1=8F=20=D0=BB=D0=B5=D0=B3=D0=B8=D1=82=D0=B8?= =?UTF-8?q?=D0=BC=D0=BD=D0=BE=D0=B3=D0=BE=20=D1=82=D1=80=D0=B0=D1=84=D0=B8?= =?UTF-8?q?=D0=BA=D0=B0=20-=20=D0=9B=D0=BE=D0=B3=D0=B8=D1=80=D0=BE=D0=B2?= =?UTF-8?q?=D0=B0=D0=BD=D0=B8=D0=B5=20=D1=81=D1=82=D0=B0=D1=82=D0=B8=D0=BA?= =?UTF-8?q?=D0=B8=20=D0=B8=20=D0=BC=D0=B5=D0=B4=D0=B8=D0=B0=20=D0=B2=D0=BA?= =?UTF-8?q?=D0=BB=D1=8E=D1=87=D0=B5=D0=BD=D0=BE=20=D0=B4=D0=BB=D1=8F=20?= =?UTF-8?q?=D0=B0=D0=BD=D0=B0=D0=BB=D0=B8=D0=B7=D0=B0=20=D0=BF=D0=BE=D0=BF?= =?UTF-8?q?=D1=8B=D1=82=D0=BE=D0=BA=20=D1=81=D0=BA=D0=B0=D0=BD=D0=B8=D1=80?= =?UTF-8?q?=D0=BE=D0=B2=D0=B0=D0=BD=D0=B8=D1=8F=20-=20=D0=9E=D1=82=D0=BA?= =?UTF-8?q?=D0=BB=D1=8E=D1=87=D0=B5=D0=BD=20log=5Fnot=5Ffound=20=D0=B4?= =?UTF-8?q?=D0=BB=D1=8F=20=D1=83=D0=BC=D0=B5=D0=BD=D1=8C=D1=88=D0=B5=D0=BD?= =?UTF-8?q?=D0=B8=D1=8F=20=D1=80=D0=B0=D0=B7=D0=BC=D0=B5=D1=80=D0=B0=20?= =?UTF-8?q?=D0=BB=D0=BE=D0=B3=D0=BE=D0=B2=20(404=20=D0=B2=D1=81=D1=91=20?= =?UTF-8?q?=D1=80=D0=B0=D0=B2=D0=BD=D0=BE=20=D0=B2=20error=5Flog)=20-=20?= =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB=D0=B5=D0=BD=D0=BE=20=D1=83?= =?UTF-8?q?=D1=82=D0=BE=D1=87=D0=BD=D0=B5=D0=BD=D0=B8=D0=B5=20=D1=87=D1=82?= =?UTF-8?q?=D0=BE=20WhiteNoise=20=D1=83=D0=B6=D0=B5=20=D1=81=D0=B6=D0=B8?= =?UTF-8?q?=D0=BC=D0=B0=D0=B5=D1=82=20=D1=81=D1=82=D0=B0=D1=82=D0=B8=D0=BA?= =?UTF-8?q?=D1=83=20(gzip=20=D0=B2=20nginx=20=D0=BD=D0=B5=20=D0=BD=D1=83?= =?UTF-8?q?=D0=B6=D0=B5=D0=BD)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- config/nginx/pet-clones--external-nginx.conf | 194 +++++++++++++------ 1 file changed, 131 insertions(+), 63 deletions(-) diff --git a/config/nginx/pet-clones--external-nginx.conf b/config/nginx/pet-clones--external-nginx.conf index 3e6db9e..8845cce 100644 --- a/config/nginx/pet-clones--external-nginx.conf +++ b/config/nginx/pet-clones--external-nginx.conf @@ -1,70 +1,138 @@ # ТЕСТОВОЕ ЗАДАНИЕ РОСМОРПОРТ -# == Конфикурационный файл pet-clones--nginx.conf == +# == Конфикурационный файл config/nginx/pet-clones--external-nginx.conf == -# Описываем апстрим-потоки которые должен подключить Nginx -# Для каждого сайта надо настроить свой поток, со своим уникальным именем. -# Если будете настраивать несколько python (django) сайтов - измените название upstream +# Внешний nginx конфиг для проксирования к контейнеру petclones-site--backend +# Это конфиг для ХОСТА (не внутри контейнера) -upstream pet-clone { - # расположение файла Unix-сокет для взаимодействие с uwsgi - server unix:///home/web/pet-clones.cocorico.ru/socket/clone_pets.sock; +# Upstream (группировка backends) для проксирования запросов в Django контейнер +upstream petclones-backend { + # Контейнер слушает на 127.0.0.1:8040 согласно docker-compose.prod.yml + server 127.0.0.1:8040; + # Сохраняем persistent соединения (требует proxy_http_version 1.1 и proxy_set_header Connection "") + keepalive 32; } -# конфигурируем сервер +# Основной server блок для обработки HTTP запросов server { - server_name pet-clones.cocorico.ru; # доменное имя сайта - listen 443 ssl; # managed by Certbot - - ssl_certificate /etc/letsencrypt/live/pet-clones.cocorico.ru/fullchain.pem; # managed by Certbot - ssl_certificate_key /etc/letsencrypt/live/pet-clones.cocorico.ru/privkey.pem; # managed by Certbot - include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot - ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot - - # ssl_ciphers 'ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA'; - ssl_session_cache builtin:1000 shared:SSL:25m; - keepalive_timeout 75s; - - charset utf-8; # кодировка по умолчанию - - access_log /home/web/pet-clones.cocorico.ru/logs/clone-pets-access.log; # логи с доступом - error_log /home/web/pet-clones.cocorico.ru/logs/clone-pets-error.log; # логи с ошибками - - client_max_body_size 100M; # максимальный объем файла для загрузки на сайт (max upload size) - - error_page 404 /404.html; - error_page 500 /500.html; - - location /media { alias /home/web/pet-clones.cocorico.ru/public/media; } # Расположение media-файлов Django - location /static { alias /home/web/pet-clones.cocorico.ru/public/static; } # Расположение static-файлов Django - - location /robots.txt { root /home/web/pet-clones.cocorico.ru/public; } # Расположение robots.txt - location /favicon.ico { root /home/web/pet-clones.cocorico.ru/public/static/img; } # Расположение favicon.ico - location /favicon.png { root /home/web/pet-clones.cocorico.ru/public/static/img; } # Расположение favicon - location = /404.html { - root /home/web/pet-clones.cocorico.ru/rosmorport_tsts/templates-django/404.html; - internal; - } - location = /500.html { - root /home/web/pet-clones.cocorico.ru/rosmorport_tsts/templates-django/500.html; - internal; - } - location ~ \.(xml|html|htm|txt|svg)$ { - root /home/web/pet-clones.cocorico.ru/public; # Расположение статичных *.xml, *.html и *.txt - } - - location / { - uwsgi_pass pet-clone; # upstream обрабатывающий обращений - include uwsgi_params; # конфигурационный файл uwsgi; - uwsgi_read_timeout 1800; # вдруг некоторые запросы очень долго обрабатываются? - uwsgi_send_timeout 200; # на всякий случай время записи в сокет тоже побольше... - } -} - -server { - if ($host = pet-clones.cocorico.ru) { - return 301 https://$host$request_uri; - } # managed by Certbot - server_name pet-clones.cocorico.ru; + # Слушаем на стандартном HTTP порту (80) для IPv4 и IPv6 listen 80; - return 404; # managed by Certbot -} \ No newline at end of file + listen [::]:80; + server_name pet-clones.cube2.ru; + + # Редирект HTTP → HTTPS (будет активирован после добавления SSL сертификата через certbot) + # Раскомментируй эту строку после получения SSL сертификата: + # return 301 https://$server_name$request_uri; + + # Логирование запросов и ошибок для этого виртуального хоста + access_log /var/log/nginx/petclones.access.log; + error_log /var/log/nginx/petclones.error.log warn; + + # Rate-limiting для защиты от DDoS и автоматизированных запросов + # Разрешаем максимум 100 запросов в секунду с одного IP адреса + limit_req_zone $binary_remote_addr zone=petclones_limit:10m rate=100r/s; + limit_req zone=petclones_limit burst=200 nodelay; + + # ОСНОВНОЙ БЛОК ПРОКСИРОВАНИЯ + # Все запросы, кроме перехвачённых специфичными location'ами, проксируются сюда + location / { + # Проксируем все запросы в upstream контейнер + proxy_pass http://petclones-backend; + + # --- ЗАГОЛОВКИ ДЛЯ КОРРЕКТНОЙ РАБОТЫ ПРИЛОЖЕНИЯ --- + # Передаём оригинальный хост (важно для правильной работы Django и генерации URLs) + proxy_set_header Host $host; + # Передаём оригинальный IP клиента (для логирования и rate-limiting) + proxy_set_header X-Real-IP $remote_addr; + # Добавляем этот прокси в цепь X-Forwarded-For (если было несколько проксей) + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + # Передаём оригинальный протокол (HTTP или HTTPS) - важно для правильной работы redirect'ов + proxy_set_header X-Forwarded-Proto $scheme; + # Передаём оригинальный хост (может отличаться от Host если используется load balancer) + proxy_set_header X-Forwarded-Host $server_name; + # Передаём порт если не стандартный + proxy_set_header X-Forwarded-Port $server_port; + + # --- HTTP KEEP-ALIVE ДЛЯ ПРОИЗВОДИТЕЛЬНОСТИ --- + # Используем HTTP 1.1 для поддержки keep-alive + proxy_http_version 1.1; + # Очищаем Connection header (иначе будет "Connection: close") + proxy_set_header Connection ""; + + # --- ТАЙМАУТЫ ДЛЯ ДЛИТЕЛЬНЫХ ЗАПРОСОВ --- + # Время ожидания подключения к backend + proxy_connect_timeout 60s; + # Время ожидания отправки запроса на backend + proxy_send_timeout 60s; + # Время ожидания ответа от backend (может быть увеличено если есть долгие запросы) + proxy_read_timeout 60s; + + # --- БУФЕРИЗАЦИЯ ОТВЕТОВ --- + # Включаем буферизацию (nginx буферизирует ответ перед отправкой клиенту) + # Это экономит память backend если клиент медленный + proxy_buffering on; + # Размер буфера для первой части ответа (заголовки) + proxy_buffer_size 4k; + # Количество и размер буферов для основного тела ответа + proxy_buffers 8 4k; + } + + # КЭШИРОВАНИЕ СТАТИЧЕСКИХ ФАЙЛОВ + # Кэшируем: HTML, изображения, стили, скрипты, шрифты и иконки + # ВАЖНО: WhiteNoise уже сжимает статику в контейнере (Gzip в nginx не нужен) + location ~* \.(htm|html|gif|png|jpe?g|svg|ico|css|js|woff|woff2|ttf|eot)$ { + # Проксируем запрос к backend (статика часть контейнера) + proxy_pass http://petclones-backend; + # Передаём хост в заголовке + proxy_set_header Host $host; + + # --- КЭШИРОВАНИЕ В БРАУЗЕРЕ КЛИЕНТА --- + # Если файлы имеют хеш в названии (например: app.abc123.js), то cache-control может быть очень долгой + # "immutable" говорит браузеру что файл никогда не изменится (если изменится, то будет другой хеш) + add_header Cache-Control "public, max-age=604800, immutable"; # 7 дней в секундах (604800 = 7*24*60*60) + + # ЛОГИРОВАНИЕ ВКЛЮЧЕНО для CrowdSec анализа подозрительных запросов к статике + # CrowdSec может обнаруживать попытки доступа к несуществующим файлам (признак сканирования) + # Отключаем логирование только найденных файлов (404 всё равно логируются в error_log) + access_log /var/log/nginx/petclones.access.log main buffer=32k flush=5s; + log_not_found off; # Не логируем 404 статики (слишком много шума) + } + + # КЭШИРОВАНИЕ МЕДИА ФАЙЛОВ + # Медиа загруженные пользователями кэшируются меньше чем статика (на случай удаления или обновления) + location ~* ^/media/.*\.(jpg|jpeg|png|gif|webp|svg|pdf|mp4|webm)$ { + proxy_pass http://petclones-backend; + proxy_set_header Host $host; + # Кэшируем на 30 дней (можно менять в зависимости от политики) + add_header Cache-Control "public, max-age=2592000"; # 30 дней в секундах (30*24*60*60) + + # ЛОГИРОВАНИЕ ВКЛЮЧЕНО для CrowdSec анализа + # Подозрительные скачивания медиа файлов (боты, жесткие сканеры и т.п.) должны логироваться + access_log /var/log/nginx/petclones.access.log main buffer=32k flush=5s; + } +} + +# HTTPS SERVER БЛОК (ДОБАВИТЬ ПОСЛЕ ПОЛУЧЕНИЯ SSL СЕРТИФИКАТА) +# После получения SSL сертификата через certbot, раскомментируй и настрой эту секцию: +# +# server { +# listen 443 ssl http2; +# listen [::]:443 ssl http2; +# server_name pet-clones.cube2.ru; +# +# # SSL сертификаты от certbot +# ssl_certificate /etc/letsencrypt/live/pet-clones.cube2.ru/fullchain.pem; +# ssl_certificate_key /etc/letsencrypt/live/pet-clones.cube2.ru/privkey.pem; +# +# # Параметры безопасности SSL +# ssl_protocols TLSv1.2 TLSv1.3; +# ssl_ciphers HIGH:!aNULL:!MD5; +# ssl_prefer_server_ciphers on; +# +# # остальная конфигурация идентична HTTP блоку выше... +# # (копируешь content из server блока выше и вставляешь сюда) +# } +# +# ТАКЖЕ НЕ ЗАБУДЬ: +# 1. Установи certbot: sudo apt-get install certbot python3-certbot-nginx +# 2. Получи сертификат: sudo certbot certonly --standalone -d pet-clones.cube2.ru +# 3. Перезагрузи nginx: sudo systemctl restart nginx