Перейти к содержанию

Чек-лист безопасности NGINX

Полный, практический чек-лист для защиты вашего сервера NGINX. Используйте его для аудитов безопасности, проверок соответствия требованиям или усиления защиты новых развёртываний.

Автоматизируйте этот чек-лист

Вместо ручной проверки каждого пункта запустите gixy /etc/nginx/nginx.conf для автоматического обнаружения многих из этих проблем. Подробнее →


Версия и раскрытие информации

  • Скрыть версию NGINX — Установите server_tokens off; в блоке http
  • Пользовательские страницы ошибок — Замените стандартные страницы ошибок, которые могут раскрывать информацию о версии
  • Удалить заголовок Server — Используйте more_clear_headers Server; (требуется модуль headers-more)
  • Скрыть версию PHP — Установите expose_php = Off в php.ini
Конфигурация
http {
    server_tokens off;

    # Пользовательские страницы ошибок
    error_page 404 /custom_404.html;
    error_page 500 502 503 504 /custom_50x.html;
}

✅ Проверка Gixy: version_disclosure


Конфигурация SSL/TLS

  • Отключить устаревшие протоколы — Разрешить только TLSv1.2 и TLSv1.3
  • Использовать надёжные шифры — Следуйте конфигурации Mozilla Intermediate или Modern
  • Отключить слабые шифры — Без RC4, DES, 3DES, EXPORT, NULL
  • Включить OCSP stapling — Уменьшает задержку и улучшает приватность
  • Настроить возобновление сессий — Используйте ssl_session_cache и ssl_session_tickets
  • Использовать DH-параметры 2048+ бит — Сгенерируйте командой openssl dhparam -out dhparam.pem 4096
  • Действительные сертификаты — Проверьте срок действия, полноту цепочки
Конфигурация
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384;
ssl_prefer_server_ciphers off;
ssl_session_timeout 1d;
ssl_session_cache shared:SSL:10m;
ssl_session_tickets off;
ssl_stapling on;
ssl_stapling_verify on;
ssl_dhparam /etc/nginx/dhparam.pem;

✅ Проверка Gixy: weak_ssl_tls


Заголовки безопасности

  • HSTS включёнStrict-Transport-Security с соответствующим max-age
  • X-Frame-Options — Установлен в DENY или SAMEORIGIN
  • X-Content-Type-Options — Установлен в nosniff
  • X-XSS-Protection — Установлен в 1; mode=block
  • Referrer-Policy — Установлена соответствующая политика для вашего случая
  • Content-Security-Policy — Определены разрешённые источники контента
  • Permissions-Policy — Ограничен доступ к функциям браузера
  • Заголовки во всех контекстах — Проверьте, что заголовки не теряются в блоках location
Конфигурация
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-XSS-Protection "1; mode=block" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
add_header Content-Security-Policy "default-src 'self';" always;
add_header Permissions-Policy "geolocation=(), microphone=(), camera=()" always;

✅ Проверки Gixy: hsts_header, add_header_redefinition


Конфигурация хоста и сервера

  • Определён сервер по умолчанию — Отклоняет запросы с неизвестными Host-заголовками
  • Сервер по умолчанию возвращает 444 — Закрывает соединение без ответа
  • Каждый vhost имеет явный server_name — Без catch-all конфигураций
  • Редирект HTTP на HTTPS — Перенаправляет весь HTTP-трафик на HTTPS
  • Без wildcard server_name в продакшене — Используйте явные имена хостов
Конфигурация
# Сервер по умолчанию для отклонения неизвестных хостов
server {
    listen 80 default_server;
    listen 443 ssl default_server;
    server_name _;
    ssl_certificate /etc/nginx/ssl/dummy.crt;
    ssl_certificate_key /etc/nginx/ssl/dummy.key;
    return 444;
}

# Редирект HTTP на HTTPS
server {
    listen 80;
    server_name example.com;
    return 301 https://$server_name$request_uri;
}

✅ Проверки Gixy: host_spoofing, default_server_flag


Контроль доступа

  • Полные правила allow/deny — Каждый блок allow заканчивается deny all;
  • Защита конфиденциальных файлов — Блокировка доступа к .git, .env, .htaccess и т.д.
  • Защита файлов резервных копий — Блокировка .bak, .old, .swp, .tmp файлов
  • Админ-зона ограничена — Доступ ограничен по IP или аутентификации
  • Ограничения директории загрузок — Отключено выполнение PHP/скриптов в путях загрузки
  • Return не обходит контроль доступа — Учитывайте порядок обработки директив
Конфигурация
# Блокировка конфиденциальных файлов
location ~ /\. {
    deny all;
}

location ~* \.(git|svn|env|htaccess|htpasswd)$ {
    deny all;
}

# Админ-зона
location /admin {
    allow 10.0.0.0/8;
    deny all;
    auth_basic "Admin Area";
    auth_basic_user_file /etc/nginx/.htpasswd;
}

# Загрузки — без выполнения скриптов
location /uploads {
    location ~ \.(php|py|pl|cgi)$ {
        deny all;
    }
}

✅ Проверки Gixy: allow_without_deny, return_bypasses_allow_deny


Обработка путей и файлов

  • Завершающий слэш в alias — Location с alias должен заканчиваться /
  • Без пользовательского контроля путей — Не интерполируйте пользовательский ввод в путях к файлам
  • Проверьте root vs alias — Понимайте разницу
  • Ограничьте область try_files — Будьте осторожны с try_files и пользовательским вводом
Конфигурация
# ПРАВИЛЬНО: завершающий слэш в обоих
location /static/ {
    alias /var/www/static/;
}

# АЛЬТЕРНАТИВА: используйте root вместо alias
location /static/ {
    root /var/www;
}

✅ Проверки Gixy: alias_traversal, try_files_is_evil_too


Конфигурация прокси

  • Без пользовательского контроля proxy_pass — Жёстко задавайте upstream-серверы
  • Внутренние location защищены — Используйте директиву internal;
  • Правильная пересылка заголовков — Установите Host, X-Real-IP, X-Forwarded-For
  • Ограничения таймаутов — Настройте connect, send, read таймауты
  • Resolver настроен для переменных — Требуется при использовании переменных в proxy_pass
Конфигурация
upstream backend {
    server 127.0.0.1:8080;
    keepalive 32;
}

location /api/ {
    proxy_pass http://backend;
    proxy_http_version 1.1;
    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;
}

✅ Проверки Gixy: ssrf, missing_resolver, proxy_pass_normalized


Rate Limiting и защита от DoS

  • Ограничения соединений — Используйте limit_conn_zone и limit_conn
  • Ограничения скорости запросов — Используйте limit_req_zone и limit_req
  • Строгие лимиты для эндпоинтов авторизации — Меньшие лимиты для login, регистрации
  • Ограничение размера тела запроса — Установите соответствующий client_max_body_size
  • Ограничения буфера заголовков — Настройте large_client_header_buffers
  • Значения таймаутов — Установите разумные client_body_timeout, client_header_timeout
Конфигурация
http {
    limit_req_zone $binary_remote_addr zone=general:10m rate=10r/s;
    limit_req_zone $binary_remote_addr zone=login:10m rate=1r/s;
    limit_conn_zone $binary_remote_addr zone=addr:10m;

    client_max_body_size 10m;
    client_body_timeout 12s;
    client_header_timeout 12s;
    large_client_header_buffers 4 16k;

    server {
        limit_req zone=general burst=20 nodelay;
        limit_conn addr 10;

        location /login {
            limit_req zone=login burst=5 nodelay;
        }
    }
}

Логирование и мониторинг

  • Логирование ошибок включено — Никогда не используйте error_log off;
  • Логирование доступа включено — Логируйте все запросы с полезной информацией
  • Формат логов для безопасности — Включайте IP клиента, user agent, время ответа
  • Ротация логов настроена — Используйте logrotate для управления файлами логов
  • Мониторинг логов настроен — Пересылка в SIEM или систему мониторинга
Конфигурация
log_format security '$remote_addr - $remote_user [$time_local] '
                    '"$request" $status $body_bytes_sent '
                    '"$http_referer" "$http_user_agent" '
                    '$request_time $upstream_response_time';

access_log /var/log/nginx/access.log security;
error_log /var/log/nginx/error.log warn;

✅ Проверка Gixy: error_log_off


Гигиена конфигурации

  • Без if в блоках location — Используйте map или try_files вместо этого, когда возможно
  • Валидные regex-паттерны — Тестируйте все regex с помощью nginx -t
  • Якоря в regex — Используйте ^ и $ для предотвращения частичных совпадений
  • Без уязвимостей ReDoS — Избегайте катастрофического возврата
  • Правильные значения по умолчанию в map — Всегда определяйте значения по умолчанию в блоках map
  • Комментарии в конфигурации — Документируйте неочевидные конфигурации

✅ Проверки Gixy: if_is_evil, invalid_regex, unanchored_regex, regex_redos, hash_without_default


Производительность и ограничения ресурсов

  • Worker-процессы — Установите auto или количество ядер CPU
  • Worker-соединения — Установите на основе ожидаемой нагрузки (обычно 1024-4096)
  • Лимиты файловых дескрипторов — Убедитесь, что worker_rlimit_nofile соответствует системным лимитам
  • Настройка keepalive — Установите соответствующие keepalive_timeout и keepalive_requests
  • Gzip включён — Сжимайте текстовые ответы
  • Настройка буферов — Оптимизируйте proxy и fastcgi буферы

✅ Проверки Gixy: worker_rlimit_nofile_vs_connections, low_keepalive_requests


Безопасность файловой системы

  • Права на файлы конфигурацииchmod 640 /etc/nginx/nginx.conf
  • Права на приватные ключиchmod 600 для SSL-ключей
  • Владение — Конфигурация принадлежит root, логи — www-data
  • SELinux/AppArmor — Настройте политики MAC, если включены
  • Без директорий с правами записи для всех — Проверьте права document root
# Проверка и исправление прав
chmod 640 /etc/nginx/nginx.conf
chmod 750 /etc/nginx/conf.d
chmod 600 /etc/nginx/ssl/*.key
chown -R root:root /etc/nginx
chown -R www-data:www-data /var/log/nginx

Валидация и тестирование

  • Тест синтаксиса конфигурации — Запускайте nginx -t после каждого изменения
  • Сканирование безопасности с Gixy — Запускайте gixy /etc/nginx/nginx.conf
  • Тест SSL Labs — Оценка A или A+ на ssllabs.com/ssltest
  • Тест заголовков безопасности — Проверка на securityheaders.com
  • Mozilla Observatory — Проверка на observatory.mozilla.org

Команды для быстрой проверки

# Тест синтаксиса конфигурации
nginx -t

# Сканирование безопасности с Gixy
gixy /etc/nginx/nginx.conf

# Проверка полного дампа конфигурации
nginx -T

# Тест конкретного файла конфигурации
nginx -t -c /path/to/nginx.conf

# Перезагрузка после изменений
nginx -s reload

Скачать этот чек-лист

Распечатайте эту страницу или сохраните как PDF для офлайн-использования. Для автоматической проверки используйте Gixy:

pip install gixy-ng
gixy /etc/nginx/nginx.conf --format json > audit-results.json

См. Руководство по интеграции CI/CD для автоматических проверок безопасности в вашем пайплайне.


Связанные ресурсы

Укрепляйте NGINX с поддерживаемыми RPM

Используйте NGINX Extras от GetPageSpeed для постоянно обновляемого NGINX и модулей на RHEL/CentOS/Alma/Rocky. Подробнее.