Полная настройка Nginx на Ubuntu и Debian

Установка, настройка и защита веб-сервера Nginx на Ubuntu 22.04/24.04 и Debian 12. SSL, HTTP/2, заголовки безопасности, оптимизация производительности.

Полная настройка 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 автоматически:

  1. Получит сертификат
  2. Обновит конфиг Nginx для HTTPS
  3. Настроит редирект 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/s10 запросов в секунду
burst=20Буфер на 20 «лишних» запросов
nodelayНе задерживать, а сразу обрабатывать burst
zone=general:10m10 МБ памяти (~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
Назад к статьям