This commit is contained in:
Redsandyg
2026-06-15 06:31:35 +03:00
commit fcc9139361
50 changed files with 5400 additions and 0 deletions

View File

@@ -0,0 +1,408 @@
# Минимизация поверхности атаки 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.