Files
nginx-analize/docs/Минимизация_поверхности_атаки_nginx_—_проверка.md
Redsandyg fcc9139361 init
2026-06-15 06:31:35 +03:00

409 lines
30 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Минимизация поверхности атаки nginx — результаты проверки
**Дата проверки:** 10.06.2026
**Объект проверки:** upstream nginx + меры минимизации поверхности атаки
**Метод:** ревью мер минимизации, подтверждение по документации nginx, примеры реализации и команды аудита (без практической настройки на стенде)
## Сводная таблица
| № | Объект минимизации | Статус | Уровень |
|---|-------------------|--------|---------|
| 1 | Состав обязательных модулей | Организационная мера | сборка / поставка |
| 2 | Состав необязательных модулей | Организационная мера | сборка / поставка |
| 3 | Динамические модули | Комбинированная мера | конфигурация + FIM |
| 4 | Auth Request | Условно (если используется) | конфигурация |
| 5 | WebDAV | Условно (если используется) | конфигурация |
| 6 | njs | Условно (если используется) | сборка / конфигурация |
| 7 | Perl module | Условно (если используется) | сборка / конфигурация |
| 8 | XSLT | Условно (если используется) | конфигурация |
| 9 | SSI | Условно (если используется) | конфигурация |
| 10 | Autoindex | Реализуемо | конфигурация |
| 11 | Лишние HTTP-методы | Реализуемо | конфигурация |
| 12 | Reverse proxy / upstream | Реализуемо | конфигурация |
| 13 | FastCGI/uWSGI/SCGI/gRPC | Реализуемо | конфигурация |
| 14 | Права файловой системы | Комбинированная мера | ОС |
| 15 | Пользователь и группа nginx | Реализуемо | конфигурация / процесс |
---
1. **Состав обязательных модулей**
- Что необходимо определить: Какие модули нужны для базовой работы nginx как веб-сервера.
- Возможное решение: Оставить обязательные модули в базовой поставке.
- Риск / комментарий: Нужно не нарушить штатные сценарии эксплуатации.
- Проверка:
- **Статус:** Организационная мера
- **Ревью меры минимизации:** Задача и решение корректны. nginx не предоставляет runtime-API для отключения встроенных модулей — минимизация выполняется на этапе сборки (`./configure`) или выбора пакета поставки. Базовый набор: `http`, `core`, `events`, `ngx_http_core_module`, `ngx_http_static_module`, `ngx_http_log_module`, `ngx_http_access_module`. Риск «нарушить штатные сценарии» учтён: перечень обязательных модулей фиксируется в ТУ/эксплуатационной документации.
- **Источник:** https://nginx.org/en/docs/configure.html , https://nginx.org/en/docs/
- **Пример реализации:**
```
# Сборка с минимальным набором HTTP-модулей
./configure \
--with-http_ssl_module \
--with-http_realip_module \
--with-http_gzip_static_module \
--with-http_stub_status_module
# В ТУ/ЭД: перечень обязательных модулей из вывода nginx -V
```
- **Проверка эффективности:**
```bash
nginx -V 2>&1
# Сверить --with-* / --add-module с утверждённым перечнем в ТУ
rpm -qi nginx 2>/dev/null || dpkg -s nginx 2>/dev/null
```
- **Примечание:** См. п. 24 в `Требования безопасности для включения в ТУ — проверка.md`.
2. **Состав необязательных модулей**
- Что необходимо определить: Какие модули не нужны для базовой роли веб-сервера.
- Возможное решение: Вынести в отдельные пакеты или не загружать по умолчанию.
- Риск / комментарий: Возможны риски совместимости с существующими конфигурациями.
- Проверка:
- **Статус:** Организационная мера
- **Ревью меры минимизации:** Решение адекватно. Необязательные модули (Perl, njs, XSLT, WebDAV, auth_request, stream и др.) исключаются при сборке (`--without-http_perl_module`, `--without-http_dav_module`) или поставляются отдельными пакетами (`nginx-module-perl`, `nginx-module-njs`). Риск совместимости снимается документированием: при обновлении поставки проверять `nginx -t` и наличие директив в конфигурации.
- **Источник:** https://nginx.org/en/docs/configure.html
- **Пример реализации:**
```
# Исключение при сборке
./configure \
--without-http_perl_module \
--without-http_dav_module \
--without-http_xslt_module \
--without-http_auth_request_module
# Или: базовый пакет nginx без модулей-расширений;
# опциональные модули — отдельные RPM/DEB, не устанавливаются по умолчанию
```
- **Проверка эффективности:**
```bash
nginx -V 2>&1 | grep -E 'perl|dav|xslt|auth_request|njs'
# Ожидание: отсутствие неутверждённых модулей в выводе
dpkg -l 'nginx-module-*' 2>/dev/null || rpm -qa 'nginx-module-*' 2>/dev/null
```
- **Примечание:** См. п. 24 в `Требования безопасности для включения в ТУ — проверка.md`.
3. **Динамические модули**
- Что необходимо определить: Какие .so-модули разрешены к загрузке.
- Возможное решение: Разрешить только утверждённый перечень модулей.
- Риск / комментарий: Неразрешённый модуль может выполнять код в процессе nginx.
- Проверка:
- **Статус:** Комбинированная мера
- **Ревью меры минимизации:** Решение полностью адекватно риску. Белый список `load_module` в конфигурации + FIM на каталог `.so` + организационный запрет сторонних модулей без процедуры утверждения.
- **Источник:** https://nginx.org/en/docs/ngx_core_module.html#load_module
- **Пример реализации:**
```nginx
# /etc/nginx/nginx.conf — только утверждённые модули
load_module modules/ngx_http_geoip_module.so;
# load_module /path/to/unapproved.so; # запрещено
```
```
# /etc/afick.conf (фрагмент)
/usr/lib/nginx/modules/ R
```
- **Проверка эффективности:**
```bash
nginx -T 2>/dev/null | grep load_module
ls -la /usr/lib/nginx/modules/
# Сверить с утверждённым перечнем в эксплуатационной документации
afick -c /etc/afick.conf --check
```
- **Примечание:** См. п. 5 в `Контроль целостности хранимого кода и конфигурации — проверка.md`; п. 1011 в `Контроль выполнения кода — проверка.md`.
4. **Auth Request**
- Что необходимо определить: Требуется ли авторизация через внешний сервис в базовой поставке.
- Возможное решение: Оставить только при наличии обоснованных сценариев.
- Риск / комментарий: Модуль не является обязательным для простого веб-сервера.
- Проверка:
- **Статус:** Условно (если используется)
- **Ревью меры минимизации:** Решение корректно. `ngx_http_auth_request_module` не нужен для статического веб-сервера с `auth_basic`. Включается только при сценарии делегированной авторизации (OAuth-шлюз, внешний IdP). Риск минимален при отсутствии модуля в сборке и директив в конфигурации.
- **Источник:** https://nginx.org/en/docs/http/ngx_http_auth_request_module.html
- **Пример реализации:**
```nginx
# Базовая конфигурация — auth_request не используется
# При необходимости (после утверждения сценария):
# location /protected/ {
# auth_request /auth;
# proxy_pass http://backend;
# }
```
- **Проверка эффективности:**
```bash
nginx -V 2>&1 | grep auth_request
nginx -T 2>/dev/null | grep -E 'auth_request|auth_request_set'
# Ожидание для минимальной поставки: отсутствие директив
```
- **Примечание:** См. п. 4 в `Требования безопасности для включения в ТУ — проверка.md`.
5. **WebDAV**
- Что необходимо определить: Требуется ли возможность записи/изменения файлов через HTTP.
- Возможное решение: Отключить или не включать в базовую конфигурацию, если не требуется.
- Риск / комментарий: Может позволить загрузку файлов, которые затем попадут в обработку.
- Проверка:
- **Статус:** Условно (если используется)
- **Ревью меры минимизации:** Решение адекватно. WebDAV не включается в базовую конфигурацию. При необходимости — изолированный `location` без пересечения с FastCGI/uWSGI и без исполняемых расширений в upload-каталоге.
- **Источник:** https://nginx.org/en/docs/http/ngx_http_dav_module.html
- **Пример реализации:**
```nginx
# WebDAV не включён в базовой конфигурации
# При необходимости — изолированный location:
# location /uploads/ {
# root /var/www/static-only;
# dav_methods PUT;
# # Нет fastcgi_pass / uwsgi_pass
# }
```
- **Проверка эффективности:**
```bash
nginx -T 2>/dev/null | grep -E 'dav_methods|dav_access|create_full_put_path'
# Ожидание: dav_methods отсутствует вне утверждённых location
```
- **Примечание:** См. п. 10 в `Контроль целостности хранимого кода и конфигурации — проверка.md`; п. 12 в `Контроль выполнения кода — проверка.md`.
6. **njs**
- Что необходимо определить: Требуется ли серверная JavaScript-логика внутри nginx.
- Возможное решение: Не включать или не загружать без обоснованной необходимости.
- Риск / комментарий: Выполняет логику внутри процесса nginx.
- Проверка:
- **Статус:** Условно (если используется)
- **Ревью меры минимизации:** Решение корректно. njs выполняет JavaScript в процессе worker — для базового веб-сервера не требуется. Не загружать `ngx_http_js_module.so`, не использовать `js_import`/`js_content` без утверждённого сценария.
- **Источник:** https://nginx.org/en/docs/njs/
- **Пример реализации:**
```nginx
# Базовая конфигурация — njs не используется
# load_module modules/ngx_http_js_module.so; # только после утверждения
```
- **Проверка эффективности:**
```bash
nginx -V 2>&1 | grep -i njs
nginx -T 2>/dev/null | grep -E 'js_import|js_content|js_set|load_module.*js'
# Ожидание: отсутствие njs в минимальной поставке
```
- **Примечание:** См. п. 6 в `Контроль целостности хранимого кода и конфигурации — проверка.md`; п. 6 в `Контроль выполнения кода — проверка.md`.
7. **Perl module**
- Что необходимо определить: Требуется ли Perl-логика внутри nginx.
- Возможное решение: Не включать или не загружать без обоснованной необходимости.
- Риск / комментарий: Выполняет логику внутри процесса nginx.
- Проверка:
- **Статус:** Условно (если используется)
- **Ревью меры минимизации:** Решение полностью адекватно. Perl-модуль — наиболее рискованный встроенный интерпретатор. Рекомендация: не собирать (`--without-http_perl_module`), не устанавливать пакет `nginx-module-perl`.
- **Источник:** https://nginx.org/en/docs/http/ngx_http_perl_module.html
- **Пример реализации:**
```
# Сборка без Perl
./configure --without-http_perl_module
# Конфигурация — директивы perl/perl_require отсутствуют
```
- **Проверка эффективности:**
```bash
nginx -V 2>&1 | grep -i perl
nginx -T 2>/dev/null | grep -E 'perl|perl_require|perl_modules'
# Ожидание: Perl отсутствует
```
- **Примечание:** См. п. 7 в `Контроль целостности хранимого кода и конфигурации — проверка.md`; п. 7 в `Контроль выполнения кода — проверка.md`.
8. **XSLT**
- Что необходимо определить: Требуется ли преобразование XML через XSLT.
- Возможное решение: Оставить только при наличии сценариев эксплуатации.
- Риск / комментарий: Добавляет дополнительную поверхность обработки данных.
- Проверка:
- **Статус:** Условно (если используется)
- **Ревью меры минимизации:** Решение корректно. XSLT-модуль не нужен для типового веб-сервера. При использовании — только утверждённые `.xslt` в FIM-области.
- **Источник:** https://nginx.org/en/docs/http/ngx_http_xslt_module.html
- **Пример реализации:**
```nginx
# Базовая конфигурация — XSLT не используется
# xslt_stylesheet отсутствует
```
- **Проверка эффективности:**
```bash
nginx -V 2>&1 | grep xslt
nginx -T 2>/dev/null | grep xslt_stylesheet
# Ожидание: xslt_stylesheet отсутствует
```
- **Примечание:** См. п. 8 в `Контроль целостности хранимого кода и конфигурации — проверка.md`.
9. **SSI**
- Что необходимо определить: Требуется ли обработка SSI-команд.
- Возможное решение: Отключить в конфигурации, если не требуется.
- Риск / комментарий: Может влиять на формирование ответа.
- Проверка:
- **Статус:** Условно (если используется)
- **Ревью меры минимизации:** Решение адекватно. По умолчанию `ssi off`. При включении — запрет `<!--#exec-->`, контроль SSI-файлов через FIM (web-root).
- **Источник:** https://nginx.org/en/docs/http/ngx_http_ssi_module.html
- **Пример реализации:**
```nginx
http {
ssi off; # явно в базовой конфигурации
}
```
- **Проверка эффективности:**
```bash
nginx -T 2>/dev/null | grep -i 'ssi on'
# Ожидание: ssi on отсутствует вне утверждённых location
grep -r '#exec' /var/www/ 2>/dev/null
```
- **Примечание:** См. п. 9 в `Контроль целостности хранимого кода и конфигурации — проверка.md`; п. 8 в `Контроль выполнения кода — проверка.md`.
10. **Autoindex**
- Что необходимо определить: Требуется ли листинг директорий.
- Возможное решение: Отключить по умолчанию.
- Риск / комментарий: Раскрывает структуру директорий и файлов.
- Проверка:
- **Статус:** Реализуемо
- **Ревью меры минимизации:** Решение полностью адекватно. `autoindex off` — значение по умолчанию; явное указание в `http {}` обеспечивает однозначность аудита. При отсутствии `index` — 403, не листинг.
- **Источник:** https://nginx.org/en/docs/http/ngx_http_autoindex_module.html
- **Пример реализации:**
```nginx
http {
autoindex off;
}
```
- **Проверка эффективности:**
```bash
nginx -T 2>/dev/null | grep autoindex
# Ожидание: autoindex off или директива отсутствует (default off)
curl -s -o /dev/null -w '%{http_code}' http://localhost/no-index-dir/
# Ожидание: 403
```
- **Примечание:** См. п. 21 в `Проверочные мероприятия для ПМИ — проверка.md`; п. 21 в `Требования безопасности для включения в ТУ — проверка.md`.
11. **Лишние HTTP-методы**
- Что необходимо определить: Какие методы реально нужны приложениям.
- Возможное решение: Ограничить PUT, DELETE и другие методы, если они не требуются.
- Риск / комментарий: Ненужные методы расширяют поверхность атаки.
- Проверка:
- **Статус:** Реализуемо
- **Ревью меры минимизации:** Решение корректно. Для статического веб-сервера достаточно GET, HEAD, POST (если есть формы). PUT, DELETE, PATCH, OPTIONS — блокировать, если не требуются API/WebDAV.
- **Источник:** https://nginx.org/en/docs/http/ngx_http_limit_except_module.html
- **Пример реализации:**
```nginx
location / {
limit_except GET HEAD POST {
deny all;
}
root /var/www/html;
}
# Альтернатива для глобального ограничения:
# if ($request_method !~ ^(GET|HEAD|POST)$) {
# return 405;
# }
```
- **Проверка эффективности:**
```bash
nginx -T 2>/dev/null | grep -E 'limit_except|request_method'
curl -s -o /dev/null -w '%{http_code}' -X DELETE http://localhost/
# Ожидание: 403 или 405
```
- **Примечание:** См. п. 7 в `Требования безопасности для включения в ТУ — проверка.md`.
12. **Reverse proxy / upstream**
- Что необходимо определить: Какие backend-направления разрешены.
- Возможное решение: Разрешить только утверждённые backend-сервисы.
- Риск / комментарий: Неверная настройка может открыть доступ к внутренним сервисам.
- Проверка:
- **Статус:** Реализуемо
- **Ревью меры минимизации:** Решение адекватно риску SSRF и доступа к внутренним сервисам. Белый список `upstream` с фиксированными адресами; запрет произвольных `proxy_pass http://$variable` без валидации.
- **Источник:** https://nginx.org/en/docs/http/ngx_http_proxy_module.html , https://nginx.org/en/docs/http/ngx_http_upstream_module.html
- **Пример реализации:**
```nginx
upstream approved_backend {
server 127.0.0.1:8080;
server 10.0.0.5:8080;
}
location /api/ {
proxy_pass http://approved_backend;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
```
- **Проверка эффективности:**
```bash
nginx -T 2>/dev/null | grep -E 'proxy_pass|upstream'
# Сверить все proxy_pass с утверждённым перечнем backend
# Нет proxy_pass на 127.0.0.1:22, 169.254.169.254 и т.п.
```
- **Примечание:** См. п. 4 в `Контроль выполнения кода — проверка.md`.
13. **FastCGI/uWSGI/SCGI/gRPC**
- Что необходимо определить: Какие внешние обработчики допустимы.
- Возможное решение: Разрешить только утверждённые обработчики и маршруты.
- Риск / комментарий: Ошибка маршрутизации может привести к обработке неразрешённого кода.
- Проверка:
- **Статус:** Реализуемо
- **Ревью меры минимизации:** Решение полностью адекватно. Включать только необходимые протоколы; фиксированные `*_pass` на утверждённые сокеты/адреса; `try_files $uri =404` перед FastCGI; безопасный `SCRIPT_FILENAME`.
- **Источник:** https://nginx.org/en/docs/http/ngx_http_fastcgi_module.html , https://nginx.org/en/docs/http/ngx_http_uwsgi_module.html , https://nginx.org/en/docs/http/ngx_http_scgi_module.html , https://nginx.org/en/docs/http/ngx_http_grpc_module.html
- **Пример реализации:**
```nginx
# Только FastCGI — утверждённый PHP-FPM
location ~ \.php$ {
try_files $uri =404;
fastcgi_pass unix:/run/php/php-fpm.sock;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}
# uwsgi_pass, scgi_pass, grpc_pass — только при утверждённом сценарии
```
- **Проверка эффективности:**
```bash
nginx -T 2>/dev/null | grep -E 'fastcgi_pass|uwsgi_pass|scgi_pass|grpc_pass'
nginx -T 2>/dev/null | grep SCRIPT_FILENAME
# Все *_pass — из утверждённого перечня
# SCRIPT_FILENAME = $document_root$fastcgi_script_name
```
- **Примечание:** См. п. 15 в `Контроль выполнения кода — проверка.md`.
14. **Права файловой системы**
- Что необходимо определить: Какие права нужны nginx для чтения/записи.
- Возможное решение: Выдать минимально необходимые права.
- Риск / комментарий: Избыточные права повышают риск компрометации.
- Проверка:
- **Статус:** Комбинированная мера
- **Ревью меры минимизации:** Решение корректно. Worker-процесс должен иметь доступ только на чтение к web-root и конфигурации; запись — только в журналы, кэш, upload (если WebDAV). Ключи TLS — `600`, конфигурация — `644 root:root`, web-root — `755`/`644`, без world-writable.
- **Источник:** https://nginx.org/en/docs/ngx_core_module.html#user
- **Пример реализации:**
```
# Минимальные права
chown -R root:root /etc/nginx/
chmod 644 /etc/nginx/nginx.conf
chown -R root:www-data /var/www/html/
chmod -R 755 /var/www/html/
find /var/www/html -type f -exec chmod 644 {} \;
chmod 600 /etc/nginx/ssl/*.key
chown root:adm /var/log/nginx/
chmod 750 /var/log/nginx/
```
- **Проверка эффективности:**
```bash
namei -l /var/www/html/index.html
ls -la /etc/nginx/ /var/www/ /var/log/nginx/
stat -c '%a %U:%G %n' /etc/nginx/ssl/*
# Нет каталогов с mode 777; ключи — 600
```
- **Примечание:** Детальный FIM — в `Контроль целостности хранимого кода и конфигурации — проверка.md` п. 34, 11. Здесь акцент на минимальных правах для worker.
15. **Пользователь и группа nginx**
- Что необходимо определить: От чьего имени выполняются worker-процессы.
- Возможное решение: Запускать worker-процессы от непривилегированного пользователя.
- Риск / комментарий: Избыточные полномочия процесса повышают ущерб при компрометации.
- Проверка:
- **Статус:** Реализуемо
- **Ревью меры минимизации:** Решение полностью адекватно. Master — root (для привязки к портам <1024), worker — непривилегированный пользователь (`nginx`, `www-data`). Директива `user` в конфигурации обязательна для однозначности.
- **Источник:** https://nginx.org/en/docs/ngx_core_module.html#user
- **Пример реализации:**
```nginx
# /etc/nginx/nginx.conf
user nginx nginx;
# или: user www-data www-data;
```
- **Проверка эффективности:**
```bash
nginx -T 2>/dev/null | grep '^user '
ps aux | grep 'nginx: worker'
# Worker-процессы — не root (UID != 0)
id nginx 2>/dev/null || id www-data
```
- **Примечание:** Master-процесс остаётся root — это штатное поведение nginx для bind к 80/443.