Полная настройка Nginx
Подробное руководство по установке, настройке и защите Nginx на Ubuntu и Debian. Покрываем всё: от базовой установки до продвинутой конфигурации с SSL, HTTP/2, rate limiting и заголовками безопасности.
Требования
- ОС: Ubuntu 22.04 / 24.04 LTS или Debian 12 (Bookworm)
- Доступ: root или пользователь с
sudo - Домен: направленный на IP-адрес сервера (для SSL)
- Порты: открытые
80и443
Установка Nginx
Ubuntu
sudo apt update && sudo apt upgrade -y
sudo apt install -y nginx
Debian
sudo apt update && sudo apt upgrade -y
sudo apt install -y nginx
Проверка установки
nginx -v
sudo systemctl status nginx
Если Nginx запущен, откройте в браузере http://ваш_ip — вы увидите страницу «Welcome to nginx!».
Автозапуск
sudo systemctl enable nginx
sudo systemctl start nginx
Структура каталогов
/etc/nginx/
├── nginx.conf # Главный конфиг
├── sites-available/ # Доступные конфигурации сайтов
├── sites-enabled/ # Активные конфигурации (симлинки)
├── snippets/ # Переиспользуемые фрагменты
├── conf.d/ # Дополнительные конфиги
└── mime.types # MIME-типы
- sites-available/ — здесь лежат конфиги всех сайтов
- sites-enabled/ — симлинки на активные конфиги из
sites-available/ - snippets/ — сюда удобно выносить повторяющиеся блоки (SSL, заголовки)
Настройка главного конфига
Отредактируйте /etc/nginx/nginx.conf:
sudo nano /etc/nginx/nginx.conf
user www-data;
worker_processes auto;
pid /run/nginx.pid;
error_log /var/log/nginx/error.log warn;
events {
worker_connections 1024;
multi_accept on;
use epoll;
}
http {
# Базовые настройки
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 2048;
server_tokens off;
client_max_body_size 64m;
# MIME
include /etc/nginx/mime.types;
default_type application/octet-stream;
# Логи
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
# Gzip-сжатие
gzip on;
gzip_vary on;
gzip_proxied any;
gzip_comp_level 5;
gzip_min_length 256;
gzip_types
text/plain
text/css
text/javascript
application/javascript
application/json
application/xml
application/xml+rss
image/svg+xml
font/woff2;
# Подключение конфигов
include /etc/nginx/conf.d/*.conf;
include /etc/nginx/sites-enabled/*;
}
Что здесь важно
| Параметр | Зачем |
|---|---|
worker_processes auto | Использует все ядра CPU |
server_tokens off | Скрывает версию Nginx в заголовках |
client_max_body_size 64m | Максимальный размер загружаемого файла |
gzip_comp_level 5 | Баланс между сжатием и нагрузкой на CPU |
multi_accept on | Принимать несколько соединений за раз |
Создание конфига сайта
Удалите дефолтный конфиг
sudo rm /etc/nginx/sites-enabled/default
Создайте конфиг для вашего домена
sudo nano /etc/nginx/sites-available/example.com
Начнём с простого HTTP-конфига (SSL добавим позже):
server {
listen 80;
listen [::]:80;
server_name example.com www.example.com;
root /var/www/example.com/html;
index index.html;
# Логи
access_log /var/log/nginx/example.com.access.log;
error_log /var/log/nginx/example.com.error.log;
location / {
try_files $uri $uri/ =404;
}
# Блокируем скрытые файлы
location ~ /\. {
deny all;
access_log off;
log_not_found off;
}
}
Активируйте конфиг
sudo ln -s /etc/nginx/sites-available/example.com /etc/nginx/sites-enabled/
Создайте директорию сайта
sudo mkdir -p /var/www/example.com/html
sudo chown -R www-data:www-data /var/www/example.com
echo '<h1>It works!</h1>' | sudo tee /var/www/example.com/html/index.html
Проверка и перезагрузка
sudo nginx -t
sudo systemctl reload nginx
Всегда проверяйте конфиг через nginx -t перед перезагрузкой. Если есть ошибки — Nginx покажет строку и файл.
SSL-сертификат с Let's Encrypt
Установка Certbot
Ubuntu:
sudo apt install -y certbot python3-certbot-nginx
Debian:
sudo apt install -y certbot python3-certbot-nginx
Получение сертификата
sudo certbot --nginx -d example.com -d www.example.com
Certbot автоматически:
- Получит сертификат
- Обновит конфиг Nginx для HTTPS
- Настроит редирект HTTP → HTTPS
Автоматическое продление
Certbot ставит таймер автопродления. Проверьте:
sudo systemctl status certbot.timer
Тестовый прогон продления:
sudo certbot renew --dry-run
Продвинутая HTTPS-конфигурация
После получения сертификата улучшим SSL-настройки. Создадим сниппет:
sudo nano /etc/nginx/snippets/ssl-params.conf
# Протоколы и шифры
ssl_protocols TLSv1.2 TLSv1.3;
ssl_prefer_server_ciphers off;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384;
# OCSP Stapling
ssl_stapling on;
ssl_stapling_verify on;
resolver 1.1.1.1 8.8.8.8 valid=300s;
resolver_timeout 5s;
# Кэш SSL-сессий
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 1d;
ssl_session_tickets off;
# Diffie-Hellman (опционально, для TLS 1.2)
# Сгенерировать: sudo openssl dhparam -out /etc/nginx/dhparam.pem 2048
# ssl_dhparam /etc/nginx/dhparam.pem;
Заголовки безопасности
Создайте сниппет с заголовками:
sudo nano /etc/nginx/snippets/security-headers.conf
# Защита от кликджекинга
add_header X-Frame-Options "SAMEORIGIN" always;
# Защита от MIME-снифинга
add_header X-Content-Type-Options "nosniff" always;
# XSS-фильтр
add_header X-XSS-Protection "1; mode=block" always;
# Referrer
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
# Permissions Policy
add_header Permissions-Policy "camera=(), microphone=(), geolocation=()" always;
# HSTS (включать только когда SSL точно работает!)
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;
# Content Security Policy (настройте под свой сайт)
# add_header Content-Security-Policy "default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline';" always;
Что делает каждый заголовок
| Заголовок | Защита от |
|---|---|
X-Frame-Options | Встраивание сайта через iframe (кликджекинг) |
X-Content-Type-Options | Подмена MIME-типа браузером |
X-XSS-Protection | Отражённые XSS-атаки |
Referrer-Policy | Утечка URL при переходах на другие сайты |
Permissions-Policy | Доступ к камере, микрофону, геолокации |
HSTS | Даунгрейд с HTTPS на HTTP |
Итоговый конфиг сайта с SSL
sudo nano /etc/nginx/sites-available/example.com
# Редирект HTTP → HTTPS
server {
listen 80;
listen [::]:80;
server_name example.com www.example.com;
return 301 https://$server_name$request_uri;
}
# Редирект www → без www
server {
listen 443 ssl;
listen [::]:443 ssl;
http2 on;
server_name www.example.com;
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
return 301 https://example.com$request_uri;
}
# Основной сайт
server {
listen 443 ssl;
listen [::]:443 ssl;
http2 on;
server_name example.com;
# SSL
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
include snippets/ssl-params.conf;
# Заголовки безопасности
include snippets/security-headers.conf;
# Корень сайта
root /var/www/example.com/html;
index index.html;
# Логи
access_log /var/log/nginx/example.com.access.log;
error_log /var/log/nginx/example.com.error.log;
# Основная маршрутизация
location / {
try_files $uri $uri/ =404;
}
# Кэш статики
location ~* \.(css|js|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot|webp|avif)$ {
expires 30d;
add_header Cache-Control "public, immutable";
access_log off;
}
# Запрет доступа к скрытым файлам
location ~ /\. {
deny all;
access_log off;
log_not_found off;
}
# Страницы ошибок
error_page 404 /404.html;
error_page 500 502 503 504 /50x.html;
}
Проверка и применение:
sudo nginx -t && sudo systemctl reload nginx
Reverse Proxy (проксирование приложений)
Если на сервере работает Node.js, Python или другое приложение, Nginx может проксировать трафик к нему.
Пример: проксирование на Node.js (порт 3000)
server {
listen 443 ssl;
listen [::]:443 ssl;
http2 on;
server_name app.example.com;
ssl_certificate /etc/letsencrypt/live/app.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/app.example.com/privkey.pem;
include snippets/ssl-params.conf;
include snippets/security-headers.conf;
location / {
proxy_pass http://127.0.0.1:3000;
proxy_http_version 1.1;
# WebSocket поддержка
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
# Передача реального IP
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
# Таймауты
proxy_connect_timeout 60s;
proxy_send_timeout 60s;
proxy_read_timeout 60s;
}
}
Rate Limiting (защита от DDoS/брутфорса)
Добавьте в http {} блок /etc/nginx/nginx.conf:
http {
# Лимит запросов: 10 запросов в секунду с одного IP
limit_req_zone $binary_remote_addr zone=general:10m rate=10r/s;
# Лимит для логин-страниц: 5 в минуту
limit_req_zone $binary_remote_addr zone=login:10m rate=5r/m;
# Лимит соединений
limit_conn_zone $binary_remote_addr zone=addr:10m;
# ...остальной конфиг
}
Применение в конфиге сайта:
server {
# Общий лимит
limit_req zone=general burst=20 nodelay;
limit_conn addr 100;
# Строгий лимит для авторизации
location /login {
limit_req zone=login burst=3 nodelay;
proxy_pass http://127.0.0.1:3000;
}
}
| Параметр | Значение |
|---|---|
rate=10r/s | 10 запросов в секунду |
burst=20 | Буфер на 20 «лишних» запросов |
nodelay | Не задерживать, а сразу обрабатывать burst |
zone=general:10m | 10 МБ памяти (~160 000 IP-адресов) |
Блокировка ботов и сканеров
Добавьте в конфиг сайта:
# Блокировка типичных сканеров
location ~* (\.php|\.asp|\.aspx|\.jsp|\.cgi|\.env|\.git) {
deny all;
access_log off;
log_not_found off;
return 444;
}
# Блокировка по User-Agent
if ($http_user_agent ~* (SemrushBot|AhrefsBot|MJ12bot|DotBot|BLEXBot)) {
return 444;
}
Код 444 — специальный код Nginx, который мгновенно закрывает соединение без отправки ответа.
Мониторинг и логи
Полезные команды
# Статус Nginx
sudo systemctl status nginx
# Последние ошибки
sudo tail -f /var/log/nginx/error.log
# Последние запросы
sudo tail -f /var/log/nginx/example.com.access.log
# Количество активных соединений
sudo ss -tlnp | grep nginx
# Тест конфигурации
sudo nginx -t
# Перезагрузка без даунтайма
sudo systemctl reload nginx
Ротация логов
Ubuntu и Debian автоматически ротируют логи через logrotate. Проверьте конфиг:
cat /etc/logrotate.d/nginx
Файрвол (UFW)
# Разрешить HTTP и HTTPS
sudo ufw allow 'Nginx Full'
# Или по отдельности
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
# Включить файрвол
sudo ufw enable
sudo ufw status
Проверка безопасности
После настройки проверьте свой сайт:
| Сервис | Что проверяет | Ссылка |
|---|---|---|
| SSL Labs | Качество SSL-конфигурации | ssllabs.com/ssltest |
| Security Headers | Заголовки безопасности | securityheaders.com |
| Mozilla Observatory | Комплексная проверка | observatory.mozilla.org |
При правильной настройке по этому руководству вы должны получить A+ на SSL Labs и A на Security Headers.
Частые ошибки
«nginx: emerg bind() to 0.0.0.0:80 failed»
Порт 80 уже занят. Найдите процесс:
sudo ss -tlnp | grep :80
«502 Bad Gateway»
Приложение за reverse proxy не отвечает. Проверьте:
# Работает ли приложение?
curl http://127.0.0.1:3000
# Логи Nginx
sudo tail -20 /var/log/nginx/error.log
«413 Request Entity Too Large»
Увеличьте client_max_body_size в конфиге:
client_max_body_size 128m;
Изменения не применяются
# Проверить конфиг
sudo nginx -t
# Именно reload, не restart
sudo systemctl reload nginx