init
This commit is contained in:
451
docs/Контроль_выполнения_кода_—_проверка.md
Normal file
451
docs/Контроль_выполнения_кода_—_проверка.md
Normal file
@@ -0,0 +1,451 @@
|
|||||||
|
# Контроль выполнения кода nginx — результаты проверки
|
||||||
|
|
||||||
|
**Дата проверки:** 10.06.2026
|
||||||
|
**Объект проверки:** upstream nginx + меры контроля выполнения кода
|
||||||
|
**Метод:** ревью мер контроля, подтверждение по документации nginx, примеры реализации и способы аудита (без практического аудита на стенде)
|
||||||
|
|
||||||
|
## Сводная таблица
|
||||||
|
|
||||||
|
| № | Механизм | Статус | Тип контроля |
|
||||||
|
|---|----------|--------|--------------|
|
||||||
|
| 1 | FastCGI / PHP-FPM | Реализуемо | Конфигурация nginx |
|
||||||
|
| 2 | uWSGI | Реализуемо | Конфигурация nginx |
|
||||||
|
| 3 | SCGI | Реализуемо | Конфигурация nginx |
|
||||||
|
| 4 | HTTP reverse proxy | Реализуемо | Конфигурация nginx |
|
||||||
|
| 5 | gRPC backend | Реализуемо с оговорками | Конфигурация nginx |
|
||||||
|
| 6 | njs | Реализуемо с оговорками | Конфигурация + FIM |
|
||||||
|
| 7 | Perl module | Реализуемо с оговорками | Организационный запрет / FIM |
|
||||||
|
| 8 | SSI | Реализуемо | Конфигурация nginx |
|
||||||
|
| 9 | XSLT | Реализуемо с оговорками | Конфигурация + FIM |
|
||||||
|
| 10 | Динамические модули nginx | Реализуемо | Конфигурация + FIM |
|
||||||
|
| 11 | Сторонние динамические модули | Реализуемо с оговорками | Организационный белый список + FIM |
|
||||||
|
| 12 | WebDAV | Реализуемо | Конфигурация nginx |
|
||||||
|
| 13 | Внутренние перенаправления | Реализуемо | Конфигурация nginx |
|
||||||
|
| 14 | root / alias | Реализуемо | Конфигурация + права ФС |
|
||||||
|
| 15 | Конфигурация nginx | Требует внешних/организационных мер | FIM + права доступа |
|
||||||
|
| 16 | Файлы веб-приложений | Требует внешних/организационных мер | FIM |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
1. **Механизм:** FastCGI / PHP-FPM
|
||||||
|
- **Риск:** Передача в обработку файла из неразрешённого каталога ОС.
|
||||||
|
- **Требование / решение:** Разрешить передачу файлов во внешний обработчик только из утверждённых директорий веб-приложений.
|
||||||
|
- **Что контролировать:** location; root; alias; try_files; fastcgi_param SCRIPT_FILENAME.
|
||||||
|
- Проверка:
|
||||||
|
- **Статус:** Реализуемо
|
||||||
|
- **Ревью меры контроля:** Требование адекватно риску path traversal и произвольного `SCRIPT_FILENAME`. Перечень «Что контролировать» полный. Ключевой контроль — привязка `location ~ \.php$` к фиксированному `root` и безопасное значение `SCRIPT_FILENAME`.
|
||||||
|
- **Источник:** https://nginx.org/en/docs/http/ngx_http_fastcgi_module.html
|
||||||
|
- **Пример реализации контроля:**
|
||||||
|
```nginx
|
||||||
|
server {
|
||||||
|
root /var/www/app/public;
|
||||||
|
|
||||||
|
location / {
|
||||||
|
try_files $uri =404;
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
- **Проверка эффективности контроля:**
|
||||||
|
```bash
|
||||||
|
nginx -T 2>/dev/null | grep -E 'SCRIPT_FILENAME|fastcgi_pass|root|alias'
|
||||||
|
# Убедиться: SCRIPT_FILENAME = $document_root$fastcgi_script_name
|
||||||
|
# Нет fastcgi_param SCRIPT_FILENAME с пользовательскими переменными
|
||||||
|
# root указывает только на утверждённый каталог
|
||||||
|
```
|
||||||
|
- **Примечание:** Зафиксировать перечень разрешённых директорий в эксплуатационной документации. См. классификацию п. 2 в `Выполнение кода — проверка.md`.
|
||||||
|
|
||||||
|
2. **Механизм:** uWSGI
|
||||||
|
- **Риск:** Передача запроса в приложение, выполняющее код вне контроля nginx.
|
||||||
|
- **Требование:** Разрешить маршрутизацию только к утверждённым uWSGI-приложениям.
|
||||||
|
- **Что контролировать:** uwsgi_pass; upstream; конфигурация backend.
|
||||||
|
- Проверка:
|
||||||
|
- **Статус:** Реализуемо
|
||||||
|
- **Ревью меры контроля:** Требование корректно: nginx не исполняет код, но направляет запросы. Контроль — фиксированный `upstream` с явным списком сокетов/адресов, без произвольных `uwsgi_pass` на внешние хосты.
|
||||||
|
- **Источник:** https://nginx.org/en/docs/http/ngx_http_uwsgi_module.html
|
||||||
|
- **Пример реализации контроля:**
|
||||||
|
```nginx
|
||||||
|
upstream approved_uwsgi {
|
||||||
|
server unix:/run/uwsgi/app.sock;
|
||||||
|
}
|
||||||
|
|
||||||
|
location / {
|
||||||
|
uwsgi_pass approved_uwsgi;
|
||||||
|
include uwsgi_params;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
- **Проверка эффективности контроля:**
|
||||||
|
```bash
|
||||||
|
nginx -T 2>/dev/null | grep -E 'uwsgi_pass|upstream'
|
||||||
|
# Все uwsgi_pass ссылаются на утверждённый upstream
|
||||||
|
# Нет uwsgi_pass на произвольные IP/порты вне списка
|
||||||
|
```
|
||||||
|
- **Примечание:** См. классификацию п. 3 в `Выполнение кода — проверка.md`.
|
||||||
|
|
||||||
|
3. **Механизм:** SCGI
|
||||||
|
- **Риск:** Передача запроса во внешний обработчик, выполняющий код приложения.
|
||||||
|
- **Требование:** Разрешить маршрутизацию только к утверждённым SCGI-приложениям.
|
||||||
|
- **Что контролировать:** scgi_pass; upstream; конфигурация backend.
|
||||||
|
- Проверка:
|
||||||
|
- **Статус:** Реализуемо
|
||||||
|
- **Ревью меры контроля:** Аналогично uWSGI. Мера достаточна при фиксированном upstream и документированном перечне SCGI-приложений.
|
||||||
|
- **Источник:** https://nginx.org/en/docs/http/ngx_http_scgi_module.html
|
||||||
|
- **Пример реализации контроля:**
|
||||||
|
```nginx
|
||||||
|
upstream approved_scgi {
|
||||||
|
server 127.0.0.1:4000;
|
||||||
|
}
|
||||||
|
|
||||||
|
location / {
|
||||||
|
scgi_pass approved_scgi;
|
||||||
|
include scgi_params;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
- **Проверка эффективности контроля:**
|
||||||
|
```bash
|
||||||
|
nginx -T 2>/dev/null | grep -E 'scgi_pass|upstream'
|
||||||
|
```
|
||||||
|
- **Примечание:** См. классификацию п. 4 в `Выполнение кода — проверка.md`.
|
||||||
|
|
||||||
|
4. **Механизм:** HTTP reverse proxy
|
||||||
|
- **Риск:** Передача запроса во внешний backend, где выполняется код приложения.
|
||||||
|
- **Требование:** Разрешить proxy_pass только к утверждённым backend-сервисам.
|
||||||
|
- **Что контролировать:** proxy_pass; upstream; proxy_set_header.
|
||||||
|
- Проверка:
|
||||||
|
- **Статус:** Реализуемо
|
||||||
|
- **Ревью меры контроля:** Требование адекватно. Контроль через именованный `upstream` с фиксированными backend; запрет `proxy_pass http://$variable` (динамический backend). Сетевая изоляция backend — дополнительная мера на уровне firewall.
|
||||||
|
- **Источник:** https://nginx.org/en/docs/http/ngx_http_proxy_module.html
|
||||||
|
- **Пример реализации контроля:**
|
||||||
|
```nginx
|
||||||
|
upstream approved_backend {
|
||||||
|
server 127.0.0.1:8080;
|
||||||
|
keepalive 32;
|
||||||
|
}
|
||||||
|
|
||||||
|
location /api/ {
|
||||||
|
proxy_pass http://approved_backend;
|
||||||
|
proxy_set_header Host $host;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
- **Проверка эффективности контроля:**
|
||||||
|
```bash
|
||||||
|
nginx -T 2>/dev/null | grep -E 'proxy_pass|upstream'
|
||||||
|
# Нет proxy_pass с переменными или на неутверждённые адреса
|
||||||
|
```
|
||||||
|
- **Примечание:** См. классификацию п. 5 в `Выполнение кода — проверка.md`.
|
||||||
|
|
||||||
|
5. **Механизм:** gRPC backend
|
||||||
|
- **Риск:** Передача запроса во внешний gRPC-сервис, где выполняется код.
|
||||||
|
- **Требование:** Разрешить grpc_pass только к утверждённым gRPC-сервисам.
|
||||||
|
- **Что контролировать:** grpc_pass; upstream; TLS-настройки при необходимости.
|
||||||
|
- Проверка:
|
||||||
|
- **Статус:** Реализуемо с оговорками
|
||||||
|
- **Ревью меры контроля:** Требование корректно. Дополнительно контролировать TLS для gRPC (HTTP/2). Перечень «Что контролировать» полный.
|
||||||
|
- **Источник:** https://nginx.org/en/docs/http/ngx_http_grpc_module.html
|
||||||
|
- **Пример реализации контроля:**
|
||||||
|
```nginx
|
||||||
|
upstream approved_grpc {
|
||||||
|
server 127.0.0.1:50051;
|
||||||
|
}
|
||||||
|
|
||||||
|
location /grpc.service/ {
|
||||||
|
grpc_pass grpc://approved_grpc;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
- **Проверка эффективности контроля:**
|
||||||
|
```bash
|
||||||
|
nginx -T 2>/dev/null | grep -E 'grpc_pass|upstream'
|
||||||
|
```
|
||||||
|
- **Примечание:** См. классификацию п. 6 в `Выполнение кода — проверка.md`.
|
||||||
|
|
||||||
|
6. **Механизм:** njs
|
||||||
|
- **Риск:** Выполнение JavaScript-логики внутри процесса nginx.
|
||||||
|
- **Требование:** Разрешить использование njs только из утверждённых файлов/модулей, если njs применяется.
|
||||||
|
- **Что контролировать:** js_import; js_content; js_set; файлы JavaScript.
|
||||||
|
- Проверка:
|
||||||
|
- **Статус:** Реализуемо с оговорками
|
||||||
|
- **Ревью меры контроля:** Требование адекватно. Рекомендуется по умолчанию не использовать njs; при необходимости — белый список JS-файлов и FIM на `/etc/nginx/njs/`. Перечень контролируемых объектов полный.
|
||||||
|
- **Источник:** https://nginx.org/en/docs/njs/
|
||||||
|
- **Пример реализации контроля:**
|
||||||
|
```nginx
|
||||||
|
# Только утверждённые модули и файлы
|
||||||
|
load_module modules/ngx_http_js_module.so;
|
||||||
|
|
||||||
|
http {
|
||||||
|
js_import main from /etc/nginx/njs/main.js;
|
||||||
|
|
||||||
|
location /njs-handler {
|
||||||
|
js_content main.handler;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
- **Проверка эффективности контроля:**
|
||||||
|
```bash
|
||||||
|
nginx -T 2>/dev/null | grep -E 'js_import|js_content|js_set|load_module.*js'
|
||||||
|
ls -la /etc/nginx/njs/
|
||||||
|
# Сверить перечень JS-файлов с утверждённым списком
|
||||||
|
```
|
||||||
|
- **Примечание:** JS-файлы включить в контроль целостности (afick). См. условное отключение в `Минимизация поверхности атаки nginx — проверка.md` п. 6 (njs). См. классификацию п. 7 в `Выполнение кода — проверка.md`.
|
||||||
|
|
||||||
|
7. **Механизм:** Perl module
|
||||||
|
- **Риск:** Выполнение Perl-логики внутри процесса nginx.
|
||||||
|
- **Требование:** Разрешить использование Perl-модуля только при наличии обоснованной необходимости.
|
||||||
|
- **Что контролировать:** perl; perl_set; perl_require; Perl-файлы.
|
||||||
|
- Проверка:
|
||||||
|
- **Статус:** Реализуемо с оговорками
|
||||||
|
- **Ревью меры контроля:** Требование корректно — предпочтительно не включать Perl-модуль. Если включён — обоснование в документации, FIM на Perl-файлы, аудит директив `perl`/`perl_require`.
|
||||||
|
- **Источник:** https://nginx.org/en/docs/http/ngx_http_perl_module.html
|
||||||
|
- **Пример реализации контроля:**
|
||||||
|
```nginx
|
||||||
|
# Рекомендация: не включать Perl-модуль в сборку/конфигурацию
|
||||||
|
# Если необходим — только утверждённые файлы:
|
||||||
|
# perl_modules /etc/nginx/perl;
|
||||||
|
# perl_require approved.pm;
|
||||||
|
```
|
||||||
|
- **Проверка эффективности контроля:**
|
||||||
|
```bash
|
||||||
|
nginx -V 2>&1 | grep -i perl
|
||||||
|
nginx -T 2>/dev/null | grep -E 'perl|perl_require|perl_set'
|
||||||
|
# Ожидание для безопасной конфигурации: отсутствие директив perl
|
||||||
|
```
|
||||||
|
- **Примечание:** См. условное отключение в `Минимизация поверхности атаки nginx — проверка.md` п. 7 (Perl). См. классификацию п. 8 в `Выполнение кода — проверка.md`.
|
||||||
|
|
||||||
|
8. **Механизм:** SSI
|
||||||
|
- **Риск:** Обработка SSI-команд в ответах может изменить формируемый контент.
|
||||||
|
- **Требование:** Разрешить SSI только для утверждённых ресурсов или отключить, если не требуется.
|
||||||
|
- **Что контролировать:** ssi; SSI-файлы; location, где включён SSI.
|
||||||
|
- Проверка:
|
||||||
|
- **Статус:** Реализуемо
|
||||||
|
- **Ревью меры контроля:** Требование адекватно. Дополнительно: запретить `<!--#exec cmd="..."-->` в SSI-файлах (выполнение shell-команд). По умолчанию `ssi off`.
|
||||||
|
- **Источник:** https://nginx.org/en/docs/http/ngx_http_ssi_module.html
|
||||||
|
- **Пример реализации контроля:**
|
||||||
|
```nginx
|
||||||
|
http {
|
||||||
|
ssi off; # по умолчанию отключено
|
||||||
|
}
|
||||||
|
|
||||||
|
location /ssi-approved/ {
|
||||||
|
ssi on;
|
||||||
|
root /var/www/html;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
- **Проверка эффективности контроля:**
|
||||||
|
```bash
|
||||||
|
nginx -T 2>/dev/null | grep -i ssi
|
||||||
|
grep -r '#exec' /var/www/html/ 2>/dev/null
|
||||||
|
# ssi on только в утверждённых location; нет exec в SSI-файлах
|
||||||
|
```
|
||||||
|
- **Примечание:** См. условное отключение в `Минимизация поверхности атаки nginx — проверка.md` п. 9 (SSI). См. классификацию п. 9 в `Выполнение кода — проверка.md`.
|
||||||
|
|
||||||
|
9. **Механизм:** XSLT
|
||||||
|
- **Риск:** Выполнение логики преобразования XML с использованием XSLT-стилей.
|
||||||
|
- **Требование:** Разрешить XSLT-преобразования только с утверждёнными XSLT-файлами, если функция используется.
|
||||||
|
- **Что контролировать:** xslt_stylesheet; XSLT-файлы.
|
||||||
|
- Проверка:
|
||||||
|
- **Статус:** Реализуемо с оговорками
|
||||||
|
- **Ревью меры контроля:** Требование корректно. XSLT-файлы — объекты FIM. Рекомендуется не использовать модуль, если не требуется.
|
||||||
|
- **Источник:** https://nginx.org/en/docs/http/ngx_http_xslt_module.html
|
||||||
|
- **Пример реализации контроля:**
|
||||||
|
```nginx
|
||||||
|
location /api/xml {
|
||||||
|
proxy_pass http://backend;
|
||||||
|
xslt_stylesheet /etc/nginx/xslt/approved-transform.xslt;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
- **Проверка эффективности контроля:**
|
||||||
|
```bash
|
||||||
|
nginx -T 2>/dev/null | grep xslt_stylesheet
|
||||||
|
ls -la /etc/nginx/xslt/
|
||||||
|
# Все XSLT-файлы в утверждённом перечне
|
||||||
|
```
|
||||||
|
- **Примечание:** См. условное отключение в `Минимизация поверхности атаки nginx — проверка.md` п. 8 (XSLT). См. классификацию п. 10 в `Выполнение кода — проверка.md`.
|
||||||
|
|
||||||
|
10. **Механизм:** Динамические модули nginx
|
||||||
|
- **Риск:** Загрузка неразрешённого .so-модуля, выполняемого в процессе nginx.
|
||||||
|
- **Требование:** Разрешить загрузку только модулей из утверждённого перечня.
|
||||||
|
- **Что контролировать:** load_module; директории модулей; .so-файлы.
|
||||||
|
- Проверка:
|
||||||
|
- **Статус:** Реализуемо
|
||||||
|
- **Ревью меры контроля:** Требование полностью адекватно риску. Организационный белый список `load_module` + FIM на каталог модулей.
|
||||||
|
- **Источник:** https://nginx.org/en/docs/ngx_core_module.html#load_module
|
||||||
|
- **Пример реализации контроля:**
|
||||||
|
```nginx
|
||||||
|
# В nginx.conf — только утверждённые модули
|
||||||
|
load_module modules/ngx_http_geoip_module.so;
|
||||||
|
# load_module /path/to/unapproved.so; # запрещено
|
||||||
|
```
|
||||||
|
- **Проверка эффективности контроля:**
|
||||||
|
```bash
|
||||||
|
nginx -T 2>/dev/null | grep load_module
|
||||||
|
ls -la /usr/lib/nginx/modules/
|
||||||
|
# Сверить с утверждённым перечнем в эксплуатационной документации
|
||||||
|
afick -c /etc/afick.conf --check
|
||||||
|
```
|
||||||
|
- **Примечание:** См. условное отключение в `Минимизация поверхности атаки nginx — проверка.md` п. 3 (динамические модули). См. классификацию п. 11 в `Выполнение кода — проверка.md`.
|
||||||
|
|
||||||
|
11. **Механизм:** Сторонние динамические модули
|
||||||
|
- **Риск:** Подключение стороннего кода без контроля поставки и целостности.
|
||||||
|
- **Требование:** Запретить сторонние модули либо допускать только после включения в утверждённый список.
|
||||||
|
- **Что контролировать:** load_module; пакет модуля; путь к .so.
|
||||||
|
- Проверка:
|
||||||
|
- **Статус:** Реализуемо с оговорками
|
||||||
|
- **Ревью меры контроля:** Требование корректно. Сочетание организационного запрета, процедуры включения в белый список, контроля пакета (подпись, репозиторий) и FIM на `.so`.
|
||||||
|
- **Источник:** https://nginx.org/en/docs/ngx_core_module.html#load_module
|
||||||
|
- **Пример реализации контроля:**
|
||||||
|
```nginx
|
||||||
|
# Политика: только модули из дистрибутивного пакета nginx
|
||||||
|
# load_module modules/ngx_http_js_module.so; # только после утверждения
|
||||||
|
```
|
||||||
|
- **Проверка эффективности контроля:**
|
||||||
|
```bash
|
||||||
|
nginx -T 2>/dev/null | grep load_module
|
||||||
|
rpm -V nginx 2>/dev/null || dpkg -V nginx 2>/dev/null
|
||||||
|
# Проверка целостности пакета и отсутствия посторонних .so
|
||||||
|
find /usr/lib/nginx/modules/ -name '*.so' -newer /etc/nginx/nginx.conf
|
||||||
|
```
|
||||||
|
- **Примечание:** Процедура утверждения сторонних модулей — организационная мера. См. условное отключение в `Минимизация поверхности атаки nginx — проверка.md` п. 7 (Perl). См. условное отключение в `Минимизация поверхности атаки nginx — проверка.md` п. 9 (SSI). См. условное отключение в `Минимизация поверхности атаки nginx — проверка.md` п. 8 (XSLT). См. условное отключение в `Минимизация поверхности атаки nginx — проверка.md` п. 3 (динамические модули). См. условное отключение в `Минимизация поверхности атаки nginx — проверка.md` п. 3 (сторонние модули). См. классификацию п. 8 в `Выполнение кода — проверка.md`. См. классификацию п. 9 в `Выполнение кода — проверка.md`. См. классификацию п. 10 в `Выполнение кода — проверка.md`. См. классификацию п. 11 в `Выполнение кода — проверка.md`. См. классификацию п. 12 в `Выполнение кода — проверка.md`.
|
||||||
|
- **Примечание:** Процедура утверждения сторонних модулей — организационная мера. См. условное отключение в `Минимизация поверхности атаки nginx — проверка.md` п. 3 (сторонние модули). См. классификацию п. 12 в `Выполнение кода — проверка.md`.
|
||||||
|
|
||||||
|
12. **Механизм:** WebDAV
|
||||||
|
- **Риск:** Загрузка файла, который затем может быть обработан как код внешним обработчиком.
|
||||||
|
- **Требование:** Запретить WebDAV в базовой конфигурации либо ограничить загрузку в директории, не передаваемые обработчикам кода.
|
||||||
|
- **Что контролировать:** dav_methods; права на директории; location WebDAV.
|
||||||
|
- Проверка:
|
||||||
|
- **Статус:** Реализуемо
|
||||||
|
- **Ревью меры контроля:** Требование адекватно косвенному риску. WebDAV не должен пересекаться с каталогами, обрабатываемыми FastCGI/uWSGI. Upload-директория — только статика, без `.php`/скриптов.
|
||||||
|
- **Источник:** 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 в этом location
|
||||||
|
}
|
||||||
|
```
|
||||||
|
- **Проверка эффективности контроля:**
|
||||||
|
```bash
|
||||||
|
nginx -T 2>/dev/null | grep -E 'dav_methods|dav_access'
|
||||||
|
# dav_methods отсутствует вне утверждённых location
|
||||||
|
# upload-директория не содержит исполняемых расширений
|
||||||
|
```
|
||||||
|
- **Примечание:** См. условное отключение в `Минимизация поверхности атаки nginx — проверка.md` п. 5 (WebDAV). См. классификацию п. 13 в `Выполнение кода — проверка.md`.
|
||||||
|
|
||||||
|
13. **Механизм:** Внутренние перенаправления
|
||||||
|
- **Риск:** Перенаправление запроса к обработчику кода в обход ожидаемой логики доступа.
|
||||||
|
- **Требование:** Контролировать внутренние маршруты и исключить передачу в обработку файлов из неразрешённых директорий.
|
||||||
|
- **Что контролировать:** try_files; error_page; internal; named location.
|
||||||
|
- Проверка:
|
||||||
|
- **Статус:** Реализуемо
|
||||||
|
- **Ревью меры контроля:** Требование корректно. Аудит цепочек `try_files` → FastCGI, `error_page` → internal location, `rewrite` на обход `root`.
|
||||||
|
- **Источник:** https://nginx.org/en/docs/http/ngx_http_core_module.html#try_files , https://nginx.org/en/docs/http/ngx_http_core_module.html#internal
|
||||||
|
- **Пример реализации контроля:**
|
||||||
|
```nginx
|
||||||
|
location / {
|
||||||
|
root /var/www/app/public;
|
||||||
|
try_files $uri $uri/ =404;
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
- **Проверка эффективности контроля:**
|
||||||
|
```bash
|
||||||
|
nginx -T 2>/dev/null | grep -E 'try_files|error_page|rewrite|internal'
|
||||||
|
# Все try_files перед FastCGI содержат =404
|
||||||
|
# internal location не ведут за пределы root
|
||||||
|
```
|
||||||
|
- **Примечание:** См. классификацию п. 14 в `Выполнение кода — проверка.md`.
|
||||||
|
|
||||||
|
14. **Механизм:** root / alias
|
||||||
|
- **Риск:** Ошибка настройки может открыть произвольный каталог ОС или передать файл во внешний обработчик.
|
||||||
|
- **Требование:** Разрешить обслуживание и обработку файлов только из утверждённых директорий.
|
||||||
|
- **Что контролировать:** root; alias; location; права ФС.
|
||||||
|
- Проверка:
|
||||||
|
- **Статус:** Реализуемо
|
||||||
|
- **Ревью меры контроля:** Требование полностью адекватно. Контроль конфигурации + права ФС (nginx не должен читать `/etc`, `/root` и т.д.). Осторожность с `alias` и regex location.
|
||||||
|
- **Источник:** https://nginx.org/en/docs/http/ngx_http_core_module.html#root , https://nginx.org/en/docs/http/ngx_http_core_module.html#alias
|
||||||
|
- **Пример реализации контроля:**
|
||||||
|
```nginx
|
||||||
|
server {
|
||||||
|
root /var/www/app/public;
|
||||||
|
|
||||||
|
location / {
|
||||||
|
try_files $uri =404;
|
||||||
|
}
|
||||||
|
|
||||||
|
location ~ /\. {
|
||||||
|
deny all;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
- **Проверка эффективности контроля:**
|
||||||
|
```bash
|
||||||
|
nginx -T 2>/dev/null | grep -E '^\s*(root|alias)\s'
|
||||||
|
namei -l /var/www/app/public
|
||||||
|
# root/alias только на утверждённые пути
|
||||||
|
# права: каталоги 755, файлы 644, владелец не root для web-контента
|
||||||
|
```
|
||||||
|
- **Примечание:** См. классификацию п. 15 в `Выполнение кода — проверка.md`.
|
||||||
|
|
||||||
|
15. **Механизм:** Конфигурация nginx
|
||||||
|
- **Риск:** Изменение конфигурации может разрешить выполнение/передачу неразрешённого кода.
|
||||||
|
- **Требование:** Поставить конфигурацию nginx на контроль целостности и ограничить права изменения.
|
||||||
|
- **Что контролировать:** /etc/nginx/nginx.conf; подключаемые конфигурации.
|
||||||
|
- Проверка:
|
||||||
|
- **Статус:** Требует внешних/организационных мер
|
||||||
|
- **Ревью меры контроля:** Требование корректно. nginx не обеспечивает FIM самостоятельно. Необходимы: afick/AIDE, ограничение прав записи (`chmod 644`, владелец root), разделение ролей (изменение конфигурации — только администратор).
|
||||||
|
- **Источник:** Внешняя мера (FIM); https://nginx.org/en/docs/
|
||||||
|
- **Пример реализации контроля:**
|
||||||
|
```
|
||||||
|
# /etc/afick.conf (фрагмент)
|
||||||
|
/etc/nginx/ R
|
||||||
|
|
||||||
|
# Права доступа
|
||||||
|
# chmod 644 /etc/nginx/nginx.conf
|
||||||
|
# chmod 644 /etc/nginx/conf.d/*.conf
|
||||||
|
# chown root:root /etc/nginx/
|
||||||
|
```
|
||||||
|
- **Проверка эффективности контроля:**
|
||||||
|
```bash
|
||||||
|
afick -c /etc/afick.conf --check
|
||||||
|
ls -la /etc/nginx/nginx.conf /etc/nginx/conf.d/
|
||||||
|
# Только root может изменять конфигурацию
|
||||||
|
stat -c '%a %U' /etc/nginx/nginx.conf
|
||||||
|
```
|
||||||
|
- **Примечание:** Изменение конфигурации — через процедуру Change Management с повторным `nginx -t`. Статус отражает внешнюю меру. См. `Контроль целостности хранимого кода и конфигурации — проверка.md` п. 1–2; функции 9.3 в `функции безопасности — проверка.md`. См. условное отключение в `Минимизация поверхности атаки nginx — проверка.md` п. 5 (WebDAV). См. классификацию п. 13 в `Выполнение кода — проверка.md`. См. классификацию п. 14 в `Выполнение кода — проверка.md`. См. классификацию п. 15 в `Выполнение кода — проверка.md`.
|
||||||
|
- **Примечание:** Статус отражает внешнюю меру. См. `Контроль целостности хранимого кода и конфигурации — проверка.md` п. 1–2; функции 9.3 в `функции безопасности — проверка.md`.
|
||||||
|
|
||||||
|
16. **Механизм:** Файлы веб-приложений
|
||||||
|
- **Риск:** Изменение файлов приложения может привести к выполнению неразрешённого кода.
|
||||||
|
- **Требование:** Поставить разрешённые директории веб-приложений на контроль целостности.
|
||||||
|
- **Что контролировать:** web-root; директории приложений; исполняемые скрипты.
|
||||||
|
- Проверка:
|
||||||
|
- **Статус:** Требует внешних/организационных мер
|
||||||
|
- **Ревью меры контроля:** Требование адекватно. Контроль целостности web-root и скриптов (.php, .py и др.) — внешнее средство (afick). nginx не отслеживает изменения файлов приложения.
|
||||||
|
- **Источник:** Внешняя мера (FIM)
|
||||||
|
- **Пример реализации контроля:**
|
||||||
|
```
|
||||||
|
# /etc/afick.conf (фрагмент)
|
||||||
|
/var/www/ R
|
||||||
|
```
|
||||||
|
- **Проверка эффективности контроля:**
|
||||||
|
```bash
|
||||||
|
afick -c /etc/afick.conf --check
|
||||||
|
find /var/www -name '*.php' -o -name '*.py' | head -20
|
||||||
|
# Сверить перечень скриптов с утверждённым
|
||||||
|
# После тестового изменения файла — afick должен зафиксировать нарушение
|
||||||
|
```
|
||||||
|
- **Примечание:** Дополняет конфигурационный контроль (п. 1, 14); не заменяет его. Статус отражает внешнюю меру. См. `Контроль целостности хранимого кода и конфигурации — проверка.md` п. 3–4; функции 9.3 в `функции безопасности — проверка.md`.
|
||||||
|
- **Примечание:** Статус отражает внешнюю меру. См. `Контроль целостности хранимого кода и конфигурации — проверка.md` п. 3–4; функции 9.3 в `функции безопасности — проверка.md`.
|
||||||
@@ -0,0 +1,356 @@
|
|||||||
|
# Контроль целостности хранимого кода и конфигурации — результаты проверки
|
||||||
|
|
||||||
|
**Дата проверки:** 10.06.2026
|
||||||
|
**Объект проверки:** внешний FIM (afick или аналог) + пути, связанные с nginx
|
||||||
|
**Метод:** ревью мер контроля, примеры конфигурации FIM и прав доступа, команды верификации (без настройки afick на стенде)
|
||||||
|
|
||||||
|
## Сводная таблица
|
||||||
|
|
||||||
|
| № | Объект контроля | Статус | Механизм |
|
||||||
|
|---|-----------------|--------|----------|
|
||||||
|
| 1 | Основной конфигурационный файл nginx | Обязательно | afick |
|
||||||
|
| 2 | Подключаемые конфигурационные файлы nginx | Обязательно | afick |
|
||||||
|
| 3 | Разрешённые директории веб-приложений | Обязательно | afick |
|
||||||
|
| 4 | Директории статического веб-контента | Обязательно | afick |
|
||||||
|
| 5 | Динамические .so-модули nginx | Обязательно | afick |
|
||||||
|
| 6 | Файлы njs | Условно (если используется njs) | afick |
|
||||||
|
| 7 | Perl-файлы | Условно (если используется Perl) | afick |
|
||||||
|
| 8 | XSLT-файлы | Условно (если используется XSLT) | afick |
|
||||||
|
| 9 | SSI-файлы | Условно (если включён SSI) | afick |
|
||||||
|
| 10 | Файлы WebDAV upload | Условно (если включён WebDAV) | afick |
|
||||||
|
| 11 | Сертификаты и ключи TLS | Обязательно | afick + права ФС |
|
||||||
|
| 12 | Файлы паролей Basic Authentication | Условно (если используется auth_basic) | afick + права ФС |
|
||||||
|
| 13 | Файлы журналов nginx | Комбинированная мера | права ФС + syslog |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
1. **Основной конфигурационный файл nginx**
|
||||||
|
- *Причина контроля*: Конфигурация определяет правила доступа, маршрутизацию, передачу запросов обработчикам и загрузку модулей.
|
||||||
|
- *Механизм контроля*: afick или иной утверждённый механизм контроля целостности.
|
||||||
|
- *Ожидаемый результат*: Несанкционированное изменение конфигурации выявляется.
|
||||||
|
- Проверка:
|
||||||
|
- **Статус:** Обязательно
|
||||||
|
- **Ревью меры контроля:** Причина и механизм полностью адекватны. Изменение `nginx.conf` может включить `load_module`, `proxy_pass` на произвольный backend или ослабить `allow`/`deny`. FIM — единственный корректный способ контроля; nginx сам целостность не проверяет.
|
||||||
|
- **Источник:** Внешнее средство FIM; https://nginx.org/en/docs/ (встроенный FIM не описан)
|
||||||
|
- **Связь с nginx:** главный файл конфигурации, директива `include` подключает остальные файлы
|
||||||
|
- **Контролируемые пути (пример):** `/etc/nginx/nginx.conf`
|
||||||
|
- **Пример реализации:**
|
||||||
|
```
|
||||||
|
# /etc/afick.conf (фрагмент)
|
||||||
|
/etc/nginx/nginx.conf R
|
||||||
|
|
||||||
|
# Права доступа
|
||||||
|
# chown root:root /etc/nginx/nginx.conf
|
||||||
|
# chmod 644 /etc/nginx/nginx.conf
|
||||||
|
```
|
||||||
|
- **Проверка эффективности контроля:**
|
||||||
|
```bash
|
||||||
|
afick -c /etc/afick.conf --check
|
||||||
|
ls -la /etc/nginx/nginx.conf
|
||||||
|
# Тест: echo "# test" >> /etc/nginx/nginx.conf
|
||||||
|
afick -c /etc/afick.conf --check
|
||||||
|
# Ожидание: отчёт о нарушении; затем восстановить файл
|
||||||
|
```
|
||||||
|
- **Примечание:** См. также функции 9.3 в `функции безопасности — проверка.md`; `Контроль выполнения кода — проверка.md` п. 15; `Минимально необходимые полномочия nginx — проверка.md` п. 2.
|
||||||
|
|
||||||
|
2. **Подключаемые конфигурационные файлы nginx**
|
||||||
|
- *Причина*: Через подключаемые файлы могут быть добавлены новые location, proxy_pass, fastcgi_pass или load_module.
|
||||||
|
- *Механизм*: afick или иной утверждённый механизм контроля целостности.
|
||||||
|
- *Результат*: Изменение подключаемой конфигурации выявляется.
|
||||||
|
- Проверка:
|
||||||
|
- **Статус:** Обязательно
|
||||||
|
- **Ревью меры контроля:** Причина корректна: атака часто идёт через новый файл в `conf.d/` или `sites-enabled/`, а не через правку основного `nginx.conf`. Механизм достаточен.
|
||||||
|
- **Источник:** Внешнее средство FIM
|
||||||
|
- **Связь с nginx:** `include /etc/nginx/conf.d/*.conf;`, `include /etc/nginx/sites-enabled/*;`
|
||||||
|
- **Контролируемые пути (пример):** `/etc/nginx/conf.d/`, `/etc/nginx/sites-enabled/`
|
||||||
|
- **Пример реализации:**
|
||||||
|
```
|
||||||
|
# /etc/afick.conf (фрагмент)
|
||||||
|
/etc/nginx/conf.d/ R
|
||||||
|
/etc/nginx/sites-enabled/ R
|
||||||
|
```
|
||||||
|
- **Проверка эффективности контроля:**
|
||||||
|
```bash
|
||||||
|
afick -c /etc/afick.conf --check
|
||||||
|
ls -la /etc/nginx/conf.d/
|
||||||
|
# Тест: создать /etc/nginx/conf.d/evil.conf с proxy_pass
|
||||||
|
afick -c /etc/afick.conf --check
|
||||||
|
```
|
||||||
|
- **Примечание:** См. права и полномочия в `Минимально необходимые полномочия nginx — проверка.md` п. 2.
|
||||||
|
|
||||||
|
3. **Разрешённые директории веб-приложений**
|
||||||
|
- *Причина*: В этих директориях хранится код или контент, который может быть передан внешнему обработчику.
|
||||||
|
- *Механизм*: afick или иной утверждённый механизм контроля целостности.
|
||||||
|
- *Результат*: Изменение файлов веб-приложений выявляется.
|
||||||
|
- Проверка:
|
||||||
|
- **Статус:** Обязательно
|
||||||
|
- **Ревью меры контроля:** Причина и механизм адекватны. Изменение `.php`, `.py` и других скриптов — прямой риск выполнения кода через FastCGI/uWSGI. Пути должны соответствовать `root`/`alias` в конфигурации nginx.
|
||||||
|
- **Источник:** Внешнее средство FIM
|
||||||
|
- **Связь с nginx:** директивы `root`, `alias`, `fastcgi_param SCRIPT_FILENAME`
|
||||||
|
- **Контролируемые пути (пример):** `/var/www/app/`, `/var/www/app/public/`
|
||||||
|
- **Пример реализации:**
|
||||||
|
```
|
||||||
|
# /etc/afick.conf (фрагмент)
|
||||||
|
/var/www/app/ R
|
||||||
|
```
|
||||||
|
- **Проверка эффективности контроля:**
|
||||||
|
```bash
|
||||||
|
nginx -T 2>/dev/null | grep -E '^\s*root\s|^\s*alias\s'
|
||||||
|
afick -c /etc/afick.conf --check
|
||||||
|
find /var/www/app -name '*.php' -o -name '*.py' | head -10
|
||||||
|
# Сверить пути с утверждённым перечнем в эксплуатационной документации
|
||||||
|
```
|
||||||
|
- **Примечание:** См. права и полномочия в `Минимально необходимые полномочия nginx — проверка.md` п. 3.
|
||||||
|
|
||||||
|
4. **Директории статического веб-контента**
|
||||||
|
- *Причина*: Статические файлы могут быть изменены для подмены содержимого сайта.
|
||||||
|
- *Механизм*: afick или иной утверждённый механизм контроля целостности.
|
||||||
|
- *Результат*: Изменение статического контента выявляется, если он включён в область контроля.
|
||||||
|
- Проверка:
|
||||||
|
- **Статус:** Обязательно
|
||||||
|
- **Ревью меры контроля:** Причина корректна (подмена HTML, JS, вредоносные вложения). Может быть объединена с п. 3 одной записью `/var/www/ R`, если статика и приложение в одном дереве каталогов.
|
||||||
|
- **Источник:** Внешнее средство FIM
|
||||||
|
- **Связь с nginx:** `root` для статических `location`
|
||||||
|
- **Контролируемые пути (пример):** `/var/www/html/`
|
||||||
|
- **Пример реализации:**
|
||||||
|
```
|
||||||
|
# Вариант 1: отдельная запись
|
||||||
|
/var/www/html/ R
|
||||||
|
|
||||||
|
# Вариант 2: объединение с п. 3
|
||||||
|
/var/www/ R
|
||||||
|
```
|
||||||
|
- **Проверка эффективности контроля:**
|
||||||
|
```bash
|
||||||
|
afick -c /etc/afick.conf --check
|
||||||
|
# Тест: изменить index.html в web-root
|
||||||
|
afick -c /etc/afick.conf --check
|
||||||
|
```
|
||||||
|
- **Примечание:** См. права и полномочия в `Минимально необходимые полномочия nginx — проверка.md` п. 3. См. `Минимизация поверхности атаки nginx — проверка.md` п. 3–4.
|
||||||
|
|
||||||
|
5. **Динамические .so-модули nginx**
|
||||||
|
- *Причина*: Динамические модули выполняются в процессе nginx и расширяют функциональность сервера.
|
||||||
|
- *Механизм*: afick или иной утверждённый механизм контроля целостности.
|
||||||
|
- *Результат*: Подмена или изменение модуля выявляется.
|
||||||
|
- Проверка:
|
||||||
|
- **Статус:** Обязательно
|
||||||
|
- **Ревью меры контроля:** Причина и механизм полностью адекватны. Подмена `.so` — выполнение произвольного нативного кода в процессе nginx. FIM обязателен в сочетании с белым списком в `load_module`.
|
||||||
|
- **Источник:** Внешнее средство FIM; https://nginx.org/en/docs/ngx_core_module.html#load_module
|
||||||
|
- **Связь с nginx:** `load_module modules/...so;`
|
||||||
|
- **Контролируемые пути (пример):** `/usr/lib/nginx/modules/`
|
||||||
|
- **Пример реализации:**
|
||||||
|
```
|
||||||
|
# /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
|
||||||
|
rpm -V nginx 2>/dev/null || dpkg -V nginx 2>/dev/null
|
||||||
|
```
|
||||||
|
- **Примечание:** См. права и полномочия в `Минимально необходимые полномочия nginx — проверка.md` п. 10.
|
||||||
|
|
||||||
|
6. **Файлы njs**
|
||||||
|
- *Причина*: При использовании njs JavaScript-файлы могут выполняться внутри nginx.
|
||||||
|
- *Механизм*: afick или иной утверждённый механизм контроля целостности.
|
||||||
|
- *Результат*: Изменение njs-кода выявляется.
|
||||||
|
- Проверка:
|
||||||
|
- **Статус:** Условно (если используется njs)
|
||||||
|
- **Ревью меры контроля:** Причина корректна при наличии njs. Если `js_import` не используется — объект не включается в область контроля. Механизм достаточен.
|
||||||
|
- **Источник:** Внешнее средство FIM; https://nginx.org/en/docs/njs/
|
||||||
|
- **Связь с nginx:** `js_import`, `js_content`, `js_set`
|
||||||
|
- **Контролируемые пути (пример):** `/etc/nginx/njs/`
|
||||||
|
- **Пример реализации:**
|
||||||
|
```
|
||||||
|
# /etc/afick.conf (фрагмент) — только при использовании njs
|
||||||
|
/etc/nginx/njs/ R
|
||||||
|
```
|
||||||
|
- **Проверка эффективности контроля:**
|
||||||
|
```bash
|
||||||
|
nginx -T 2>/dev/null | grep -E 'js_import|load_module.*js'
|
||||||
|
# Если njs не используется — записи в afick и директивы js_* отсутствуют
|
||||||
|
afick -c /etc/afick.conf --check
|
||||||
|
```
|
||||||
|
- **Примечание:** См. права и полномочия в `Минимально необходимые полномочия nginx — проверка.md` п. 6.
|
||||||
|
|
||||||
|
7. **Perl-файлы**
|
||||||
|
- *Причина*: При использовании Perl-модуля Perl-код может выполняться внутри nginx.
|
||||||
|
- *Механизм*: afick или иной утверждённый механизм контроля целостности.
|
||||||
|
- *Результат*: Изменение Perl-кода выявляется.
|
||||||
|
- Проверка:
|
||||||
|
- **Статус:** Условно (если используется Perl)
|
||||||
|
- **Ревью меры контроля:** Причина корректна. Рекомендация: не использовать Perl-модуль; при наличии — обязательный FIM на Perl-файлы.
|
||||||
|
- **Источник:** Внешнее средство FIM; https://nginx.org/en/docs/http/ngx_http_perl_module.html
|
||||||
|
- **Связь с nginx:** `perl_modules`, `perl_require`, `perl`
|
||||||
|
- **Контролируемые пути (пример):** `/etc/nginx/perl/`
|
||||||
|
- **Пример реализации:**
|
||||||
|
```
|
||||||
|
# /etc/afick.conf (фрагмент) — только при использовании Perl
|
||||||
|
/etc/nginx/perl/ R
|
||||||
|
```
|
||||||
|
- **Проверка эффективности контроля:**
|
||||||
|
```bash
|
||||||
|
nginx -V 2>&1 | grep -i perl
|
||||||
|
nginx -T 2>/dev/null | grep -E 'perl|perl_require'
|
||||||
|
# Ожидание для безопасной конфигурации: отсутствие Perl
|
||||||
|
```
|
||||||
|
- **Примечание:** См. права и полномочия в `Минимально необходимые полномочия nginx — проверка.md` п. 7.
|
||||||
|
|
||||||
|
8. **XSLT-файлы**
|
||||||
|
- *Причина*: XSLT-файлы управляют логикой преобразования XML-ответов.
|
||||||
|
- *Механизм*: afick или иной утверждённый механизм контроля целостности.
|
||||||
|
- *Результат*: Изменение XSLT-файлов выявляется.
|
||||||
|
- Проверка:
|
||||||
|
- **Статус:** Условно (если используется XSLT)
|
||||||
|
- **Ревью меры контроля:** Причина и механизм адекватны при использовании `xslt_stylesheet`. Иначе объект исключается из области контроля.
|
||||||
|
- **Источник:** Внешнее средство FIM; https://nginx.org/en/docs/http/ngx_http_xslt_module.html
|
||||||
|
- **Связь с nginx:** `xslt_stylesheet`
|
||||||
|
- **Контролируемые пути (пример):** `/etc/nginx/xslt/`
|
||||||
|
- **Пример реализации:**
|
||||||
|
```
|
||||||
|
# /etc/afick.conf (фрагмент) — только при использовании XSLT
|
||||||
|
/etc/nginx/xslt/ R
|
||||||
|
```
|
||||||
|
- **Проверка эффективности контроля:**
|
||||||
|
```bash
|
||||||
|
nginx -T 2>/dev/null | grep xslt_stylesheet
|
||||||
|
afick -c /etc/afick.conf --check
|
||||||
|
```
|
||||||
|
- **Примечание:** См. права и полномочия в `Минимально необходимые полномочия nginx — проверка.md` п. 8.
|
||||||
|
|
||||||
|
9. **SSI-файлы**
|
||||||
|
- *Причина*: SSI-команды могут влиять на формирование ответа.
|
||||||
|
- *Механизм*: afick или иной утверждённый механизм контроля целостности.
|
||||||
|
- *Результат*: Изменение SSI-файлов выявляется.
|
||||||
|
- Проверка:
|
||||||
|
- **Статус:** Условно (если включён SSI)
|
||||||
|
- **Ревью меры контроля:** Причина корректна. SSI-файлы обычно находятся в web-root (п. 3–4); отдельная запись нужна, если SSI включён в выделенном location. Дополнительно контролировать отсутствие `<!--#exec-->` в файлах.
|
||||||
|
- **Источник:** Внешнее средство FIM; https://nginx.org/en/docs/http/ngx_http_ssi_module.html
|
||||||
|
- **Связь с nginx:** `ssi on` в `location`
|
||||||
|
- **Контролируемые пути (пример):** каталоги с `ssi on` внутри web-root, например `/var/www/html/ssi/`
|
||||||
|
- **Пример реализации:**
|
||||||
|
```
|
||||||
|
# Покрывается записью web-root (п. 3–4), либо явно:
|
||||||
|
/var/www/html/ssi/ R
|
||||||
|
```
|
||||||
|
- **Проверка эффективности контроля:**
|
||||||
|
```bash
|
||||||
|
nginx -T 2>/dev/null | grep -i 'ssi on'
|
||||||
|
grep -r '#exec' /var/www/html/ 2>/dev/null
|
||||||
|
# exec в SSI не должен присутствовать
|
||||||
|
```
|
||||||
|
- **Примечание:** См. права и полномочия в `Минимально необходимые полномочия nginx — проверка.md` п. 3.
|
||||||
|
|
||||||
|
10. **Файлы, доступные для загрузки через WebDAV**
|
||||||
|
- *Причина*: Загруженные файлы могут стать источником риска при попадании в обработку внешним интерпретатором.
|
||||||
|
- *Механизм*: afick или иной утверждённый механизм контроля целостности.
|
||||||
|
- *Результат*: Несанкционированные изменения или появление файлов выявляются, если директория включена в контроль.
|
||||||
|
- Проверка:
|
||||||
|
- **Статус:** Условно (если включён WebDAV)
|
||||||
|
- **Ревью меры контроля:** Причина корректна. FIM на upload-директорию выявляет появление новых файлов (в т.ч. `.php`). Рекомендация: upload-директория не должна пересекаться с FastCGI `root`.
|
||||||
|
- **Источник:** Внешнее средство FIM; https://nginx.org/en/docs/http/ngx_http_dav_module.html
|
||||||
|
- **Связь с nginx:** `dav_methods`, `location` с WebDAV
|
||||||
|
- **Контролируемые пути (пример):** `/var/www/uploads/`
|
||||||
|
- **Пример реализации:**
|
||||||
|
```
|
||||||
|
# /etc/afick.conf (фрагмент) — только при использовании WebDAV
|
||||||
|
/var/www/uploads/ R
|
||||||
|
```
|
||||||
|
- **Проверка эффективности контроля:**
|
||||||
|
```bash
|
||||||
|
nginx -T 2>/dev/null | grep dav_methods
|
||||||
|
# Тест: загрузить файл через WebDAV, затем afick --check
|
||||||
|
afick -c /etc/afick.conf --check
|
||||||
|
```
|
||||||
|
- **Примечание:** См. права и полномочия в `Минимально необходимые полномочия nginx — проверка.md` п. 4.
|
||||||
|
|
||||||
|
11. **Сертификаты и ключи TLS**
|
||||||
|
- *Причина*: Подмена сертификатов или ключей может нарушить доверие к защищённому соединению.
|
||||||
|
- *Механизм*: afick или иной утверждённый механизм контроля целостности + ограничение прав доступа.
|
||||||
|
- *Результат*: Изменение сертификатов/ключей выявляется.
|
||||||
|
- Проверка:
|
||||||
|
- **Статус:** Обязательно
|
||||||
|
- **Ревью меры контроля:** Причина и комбинированный механизм (FIM + права) полностью адекватны. Приватные ключи — `chmod 600`, владелец root; сертификаты — `644`.
|
||||||
|
- **Источник:** Внешнее средство FIM; https://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_certificate
|
||||||
|
- **Связь с nginx:** `ssl_certificate`, `ssl_certificate_key`, `ssl_client_certificate`
|
||||||
|
- **Контролируемые пути (пример):** `/etc/nginx/ssl/`, `/etc/ssl/nginx/`
|
||||||
|
- **Пример реализации:**
|
||||||
|
```
|
||||||
|
# /etc/afick.conf (фрагмент)
|
||||||
|
/etc/nginx/ssl/ R
|
||||||
|
|
||||||
|
# Права доступа
|
||||||
|
# chmod 600 /etc/nginx/ssl/*.key
|
||||||
|
# chmod 644 /etc/nginx/ssl/*.crt
|
||||||
|
# chown root:root /etc/nginx/ssl/
|
||||||
|
```
|
||||||
|
- **Проверка эффективности контроля:**
|
||||||
|
```bash
|
||||||
|
afick -c /etc/afick.conf --check
|
||||||
|
ls -la /etc/nginx/ssl/
|
||||||
|
stat -c '%a %U %n' /etc/nginx/ssl/*
|
||||||
|
# Ключи: 600, сертификаты: 644, владелец root
|
||||||
|
```
|
||||||
|
- **Примечание:** См. права и полномочия в `Минимально необходимые полномочия nginx — проверка.md` п. 6–7.
|
||||||
|
|
||||||
|
12. **Файлы паролей Basic Authentication**
|
||||||
|
- *Причина*: Изменение файла пользователей может привести к несанкционированному доступу.
|
||||||
|
- *Механизм*: afick или иной утверждённый механизм контроля целостности + ограничение прав доступа.
|
||||||
|
- *Результат*: Изменение файла пользователей выявляется.
|
||||||
|
- Проверка:
|
||||||
|
- **Статус:** Условно (если используется auth_basic)
|
||||||
|
- **Ревью меры контроля:** Причина и механизм корректны. FIM + `chmod 640`, владелец root, группа nginx (или без доступа для others).
|
||||||
|
- **Источник:** Внешнее средство FIM; https://nginx.org/en/docs/http/ngx_http_auth_basic_module.html#auth_basic_user_file
|
||||||
|
- **Связь с nginx:** `auth_basic_user_file`
|
||||||
|
- **Контролируемые пути (пример):** `/etc/nginx/htpasswd`, `/etc/nginx/htpasswd.d/`
|
||||||
|
- **Пример реализации:**
|
||||||
|
```
|
||||||
|
# /etc/afick.conf (фрагмент) — при использовании auth_basic
|
||||||
|
/etc/nginx/htpasswd R
|
||||||
|
|
||||||
|
# chmod 640 /etc/nginx/htpasswd
|
||||||
|
# chown root:root /etc/nginx/htpasswd
|
||||||
|
```
|
||||||
|
- **Проверка эффективности контроля:**
|
||||||
|
```bash
|
||||||
|
nginx -T 2>/dev/null | grep auth_basic_user_file
|
||||||
|
ls -la /etc/nginx/htpasswd
|
||||||
|
afick -c /etc/afick.conf --check
|
||||||
|
```
|
||||||
|
- **Примечание:** См. права и полномочия в `Минимально необходимые полномочия nginx — проверка.md` п. 8.
|
||||||
|
|
||||||
|
13. **Файлы журналов nginx**
|
||||||
|
- *Причина*: Журналы содержат события доступа и ошибок, важные для анализа безопасности.
|
||||||
|
- *Механизм*: Контроль прав доступа; защита от несанкционированного изменения; централизованное журналирование.
|
||||||
|
- *Результат*: Несанкционированное изменение или удаление журналов затруднено/выявляется.
|
||||||
|
- Проверка:
|
||||||
|
- **Статус:** Комбинированная мера
|
||||||
|
- **Ревью меры контроля:** Причина корректна. Классический FIM на активно пишущиеся log-файлы неприменим (ложные срабатывания при каждой записи). Корректный подход: строгие права (`adm`/`root`), передача в syslog (см. ПМИ п. 14), ротация logrotate, опционально `chattr +a` (append-only). Механизм в исходнике описан верно.
|
||||||
|
- **Источник:** Внешняя мера; https://nginx.org/en/docs/ngx_core_module.html#error_log , https://nginx.org/en/docs/syslog.html
|
||||||
|
- **Связь с nginx:** `access_log`, `error_log`
|
||||||
|
- **Контролируемые пути (пример):** `/var/log/nginx/access.log`, `/var/log/nginx/error.log`
|
||||||
|
- **Пример реализации:**
|
||||||
|
```
|
||||||
|
# Права доступа (не afick на сами log-файлы)
|
||||||
|
# chown root:adm /var/log/nginx/
|
||||||
|
# chmod 750 /var/log/nginx/
|
||||||
|
# chmod 640 /var/log/nginx/*.log
|
||||||
|
|
||||||
|
# Централизованное журналирование в nginx.conf:
|
||||||
|
# access_log syslog:server=192.168.1.1:514,... combined;
|
||||||
|
# error_log syslog:server=192.168.1.1:514,...;
|
||||||
|
|
||||||
|
# Опционально append-only (осторожно с ротацией):
|
||||||
|
# chattr +a /var/log/nginx/access.log
|
||||||
|
```
|
||||||
|
- **Проверка эффективности контроля:**
|
||||||
|
```bash
|
||||||
|
ls -la /var/log/nginx/
|
||||||
|
stat -c '%a %U:%G' /var/log/nginx/access.log
|
||||||
|
# Попытка удаления от непривилегированного пользователя должна завершиться отказом
|
||||||
|
nginx -T 2>/dev/null | grep -E 'access_log|error_log'
|
||||||
|
# При syslog — проверить наличие записей на приёмнике (journalctl -t nginx)
|
||||||
|
```
|
||||||
|
- **Примечание:** Статус — комбинированная мера. См. `Минимально необходимые полномочия nginx — проверка.md` п. 5; ПМИ п. 14 в `Проверочные мероприятия для ПМИ — проверка.md`; функции 4.4 и 9.3 в `функции безопасности — проверка.md`.
|
||||||
339
docs/Минимально_необходимые_полномочия_nginx_—_проверка.md
Normal file
339
docs/Минимально_необходимые_полномочия_nginx_—_проверка.md
Normal file
@@ -0,0 +1,339 @@
|
|||||||
|
# Минимально необходимые полномочия nginx — результаты проверки
|
||||||
|
|
||||||
|
**Дата проверки:** 10.06.2026
|
||||||
|
**Объект проверки:** полномочия процесса nginx и доступ к ресурсам ОС
|
||||||
|
**Метод:** ревью модели полномочий, подтверждение по документации nginx и практикам ОС, примеры прав доступа и команды аудита (без практической настройки на стенде)
|
||||||
|
|
||||||
|
## Сводная таблица
|
||||||
|
|
||||||
|
| № | Объект полномочий | Статус | Уровень |
|
||||||
|
|---|-------------------|--------|---------|
|
||||||
|
| 1 | Worker-процессы nginx | Реализуемо | процесс |
|
||||||
|
| 2 | Конфигурация nginx | Реализуемо | ФС |
|
||||||
|
| 3 | Директории веб-контента | Реализуемо | ФС |
|
||||||
|
| 4 | Директории загрузки файлов | Условно (если используется) | ФС |
|
||||||
|
| 5 | Журналы nginx | Комбинированная мера | ФС / syslog |
|
||||||
|
| 6 | TLS-сертификаты | Реализуемо | ФС |
|
||||||
|
| 7 | TLS-ключи | Реализуемо | ФС |
|
||||||
|
| 8 | Файл пользователей Basic Auth | Условно (если используется) | ФС |
|
||||||
|
| 9 | Unix-сокеты backend | Реализуемо | ФС / процесс |
|
||||||
|
| 10 | Динамические модули nginx | Комбинированная мера | ФС + FIM |
|
||||||
|
| 11 | Временные директории nginx | Реализуемо | ФС |
|
||||||
|
| 12 | Сетевые соединения к backend | Комбинированная мера | сеть / конфигурация |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
1. **Worker-процессы nginx**
|
||||||
|
- Необходимые полномочия: выполнение от непривилегированного пользователя, заданного в конфигурации; повышенные права master-процесса допускаются только для запуска службы и системных операций.
|
||||||
|
- Запрещено: работа worker-процессов с избыточными правами root.
|
||||||
|
- Комментарий: master-процесс может стартовать с повышенными правами для привязки к портам, worker-процессы должны работать с минимальными правами.
|
||||||
|
- Проверка:
|
||||||
|
- **Статус:** Реализуемо
|
||||||
|
- **Ревью полномочий:** Модель полномочий корректна и соответствует архитектуре nginx. Master (root) выполняет bind к портам <1024, чтение TLS-ключей при reload, fork worker-процессов. Worker работает от пользователя из директивы `user` с минимальными правами. Запрет worker от root — обязательное требование; `worker_processes` на привилегии не влияет.
|
||||||
|
- **Источник:** https://nginx.org/en/docs/ngx_core_module.html#user
|
||||||
|
- **Пример реализации:**
|
||||||
|
```nginx
|
||||||
|
# /etc/nginx/nginx.conf
|
||||||
|
user nginx nginx;
|
||||||
|
# или: user www-data www-data;
|
||||||
|
worker_processes auto;
|
||||||
|
```
|
||||||
|
- **Проверка эффективности:**
|
||||||
|
```bash
|
||||||
|
nginx -T 2>/dev/null | grep '^user '
|
||||||
|
ps aux | grep 'nginx:'
|
||||||
|
# Master — root; worker — UID пользователя из user (не 0)
|
||||||
|
id nginx 2>/dev/null || id www-data
|
||||||
|
```
|
||||||
|
- **Примечание:** См. п. 15 в `Минимизация поверхности атаки nginx — проверка.md`.
|
||||||
|
|
||||||
|
2. **Конфигурация nginx**
|
||||||
|
- Необходимые полномочия: чтение конфигурации nginx.
|
||||||
|
- Запрещено: запись в конфигурацию от имени пользователя nginx.
|
||||||
|
- Комментарий: изменение конфигурации должно быть доступно только администратору.
|
||||||
|
- Проверка:
|
||||||
|
- **Статус:** Реализуемо
|
||||||
|
- **Ревью полномочий:** Требования адекватны. Master читает конфигурацию при старте/reload (от root); worker не должен иметь прав на запись в `/etc/nginx/`. Владелец — root, права на файлы — `644`, на каталоги — `755`. Изменения — только администратором; контроль целостности — FIM.
|
||||||
|
- **Источник:** https://nginx.org/en/docs/ngx_core_module.html#include
|
||||||
|
- **Пример реализации:**
|
||||||
|
```
|
||||||
|
chown -R root:root /etc/nginx/
|
||||||
|
find /etc/nginx -type f -exec chmod 644 {} \;
|
||||||
|
find /etc/nginx -type d -exec chmod 755 {} \;
|
||||||
|
```
|
||||||
|
- **Проверка эффективности:**
|
||||||
|
```bash
|
||||||
|
ls -la /etc/nginx/
|
||||||
|
namei -l /etc/nginx/nginx.conf
|
||||||
|
# Пользователь nginx не имеет write на /etc/nginx/
|
||||||
|
sudo -u nginx test -w /etc/nginx/nginx.conf && echo FAIL || echo OK
|
||||||
|
```
|
||||||
|
- **Примечание:** См. п. 1–2 в `Контроль целостности хранимого кода и конфигурации — проверка.md`.
|
||||||
|
|
||||||
|
3. **Директории веб-контента**
|
||||||
|
- Необходимые полномочия: чтение файлов, которые должны обслуживаться пользователям.
|
||||||
|
- Запрещено: запись в web-root, если nginx не должен изменять контент.
|
||||||
|
- Комментарий: для статического сайта nginx обычно нужны только права чтения.
|
||||||
|
- Проверка:
|
||||||
|
- **Статус:** Реализуемо
|
||||||
|
- **Ревью полномочий:** Требования корректны. Worker нужен только `read`/`execute` (traverse) на каталоги и `read` на файлы. Запись в web-root для статического сайта запрещена — снижает риск подмены контента при компрометации worker. Каталоги — `755`, файлы — `644`; без world-writable (`777`, `666`).
|
||||||
|
- **Источник:** https://nginx.org/en/docs/http/ngx_http_core_module.html#root
|
||||||
|
- **Пример реализации:**
|
||||||
|
```
|
||||||
|
chown -R root:www-data /var/www/html/
|
||||||
|
find /var/www/html -type d -exec chmod 755 {} \;
|
||||||
|
find /var/www/html -type f -exec chmod 644 {} \;
|
||||||
|
# nginx (www-data) — только чтение, без write
|
||||||
|
```
|
||||||
|
- **Проверка эффективности:**
|
||||||
|
```bash
|
||||||
|
nginx -T 2>/dev/null | grep -E '^\s*root\s|^\s*alias\s'
|
||||||
|
namei -l /var/www/html/index.html
|
||||||
|
ls -la /var/www/html/
|
||||||
|
sudo -u nginx test -w /var/www/html/index.html && echo FAIL || echo OK
|
||||||
|
find /var/www -perm -0002 -type f 2>/dev/null
|
||||||
|
# Не должно быть world-writable файлов
|
||||||
|
```
|
||||||
|
- **Примечание:** См. п. 3–4 в `Контроль целостности хранимого кода и конфигурации — проверка.md`; п. 14 в `Минимизация поверхности атаки nginx — проверка.md`.
|
||||||
|
|
||||||
|
4. **Директории загрузки файлов**
|
||||||
|
- Необходимые полномочия: запись только в специально выделенные директории (если функция загрузки нужна).
|
||||||
|
- Запрещено: запись в директории, передаваемые обработчикам кода, если это не предусмотрено.
|
||||||
|
- Комментарий: нужно исключить загрузку исполняемого кода в директории обработки.
|
||||||
|
- Проверка:
|
||||||
|
- **Статус:** Условно (если используется)
|
||||||
|
- **Ревью полномочий:** Требования адекватны при использовании WebDAV или иной загрузки. Write — только в выделенный каталог (`/var/www/uploads/`), изолированный от FastCGI `root`. Запрет исполняемых расширений (`.php`, `.py`) в upload-директории. Без WebDAV — запись worker в web-root не нужна.
|
||||||
|
- **Источник:** https://nginx.org/en/docs/http/ngx_http_dav_module.html
|
||||||
|
- **Пример реализации:**
|
||||||
|
```
|
||||||
|
mkdir -p /var/www/uploads
|
||||||
|
chown nginx:nginx /var/www/uploads
|
||||||
|
chmod 750 /var/www/uploads
|
||||||
|
# Нет fastcgi_pass в location /uploads/
|
||||||
|
```
|
||||||
|
```nginx
|
||||||
|
location /uploads/ {
|
||||||
|
root /var/www/static-only;
|
||||||
|
dav_methods PUT;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
- **Проверка эффективности:**
|
||||||
|
```bash
|
||||||
|
nginx -T 2>/dev/null | grep dav_methods
|
||||||
|
ls -la /var/www/uploads/ 2>/dev/null
|
||||||
|
# Upload-каталог не пересекается с root для .php
|
||||||
|
find /var/www/uploads -name '*.php' -o -name '*.py' 2>/dev/null
|
||||||
|
```
|
||||||
|
- **Примечание:** См. п. 10 в `Контроль целостности хранимого кода и конфигурации — проверка.md`; п. 5 в `Минимизация поверхности атаки nginx — проверка.md`.
|
||||||
|
|
||||||
|
5. **Журналы nginx**
|
||||||
|
- Необходимые полномочия: права на запись текущих журналов или передачу событий в syslog.
|
||||||
|
- Запрещено: изменение, удаление и подмена архивных журналов (ограничить правами ОС и/или централизованным журналированием).
|
||||||
|
- Комментарий: для аудита важна защита журналов от подмены и удаления.
|
||||||
|
- Проверка:
|
||||||
|
- **Статус:** Комбинированная мера
|
||||||
|
- **Ревью полномочий:** Модель корректна. Активные журналы — write для пользователя nginx (или группа `adm`); архивы после logrotate — read-only для nginx (`chmod 440`, владелец root:adm). Централизованное журналирование через syslog снимает зависимость от локальных файлов. Worker не должен удалять/перезаписывать архивы.
|
||||||
|
- **Источник:** https://nginx.org/en/docs/ngx_core_module.html#error_log , https://nginx.org/en/docs/syslog.html
|
||||||
|
- **Пример реализации:**
|
||||||
|
```
|
||||||
|
chown root:adm /var/log/nginx/
|
||||||
|
chmod 750 /var/log/nginx/
|
||||||
|
chmod 640 /var/log/nginx/access.log /var/log/nginx/error.log
|
||||||
|
```
|
||||||
|
```nginx
|
||||||
|
# Альтернатива: централизованное журналирование
|
||||||
|
# access_log syslog:server=192.168.1.1:514,facility=local7,tag=nginx,severity=info combined;
|
||||||
|
# error_log syslog:server=192.168.1.1:514,facility=local7,tag=nginx;
|
||||||
|
```
|
||||||
|
- **Проверка эффективности:**
|
||||||
|
```bash
|
||||||
|
ls -la /var/log/nginx/
|
||||||
|
stat -c '%a %U:%G' /var/log/nginx/*.log
|
||||||
|
sudo -u nginx rm /var/log/nginx/access.log.1 2>&1
|
||||||
|
# Ожидание: отказ в удалении архива
|
||||||
|
nginx -T 2>/dev/null | grep -E 'access_log|error_log'
|
||||||
|
```
|
||||||
|
- **Примечание:** См. п. 13 в `Контроль целостности хранимого кода и конфигурации — проверка.md`; п. 14 в `Проверочные мероприятия для ПМИ — проверка.md`.
|
||||||
|
|
||||||
|
6. **TLS-сертификаты**
|
||||||
|
- Необходимые полномочия: минимальные права для чтения сертификатов на этапе запуска/перезагрузки конфигурации.
|
||||||
|
- Запрещено: запись/изменение сертификатов от имени nginx.
|
||||||
|
- Комментарий: сертификаты должны изменяться только администратором.
|
||||||
|
- Проверка:
|
||||||
|
- **Статус:** Реализуемо
|
||||||
|
- **Ревью полномочий:** Требования корректны. Сертификаты (публичная часть) — `644`, владелец root. Master читает при старте/reload; worker не нуждается в write. Обновление сертификатов — администратором, с последующим `nginx -s reload`.
|
||||||
|
- **Источник:** https://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_certificate
|
||||||
|
- **Пример реализации:**
|
||||||
|
```
|
||||||
|
chown root:root /etc/nginx/ssl/
|
||||||
|
chmod 644 /etc/nginx/ssl/*.crt
|
||||||
|
chmod 755 /etc/nginx/ssl/
|
||||||
|
```
|
||||||
|
- **Проверка эффективности:**
|
||||||
|
```bash
|
||||||
|
ls -la /etc/nginx/ssl/
|
||||||
|
stat -c '%a %U:%G %n' /etc/nginx/ssl/*.crt
|
||||||
|
sudo -u nginx test -w /etc/nginx/ssl/server.crt && echo FAIL || echo OK
|
||||||
|
```
|
||||||
|
- **Примечание:** См. п. 11 в `Контроль целостности хранимого кода и конфигурации — проверка.md`.
|
||||||
|
|
||||||
|
7. **TLS-ключи**
|
||||||
|
- Необходимые полномочия: минимальные права для чтения закрытых ключей на этапе запуска/перезагрузки конфигурации.
|
||||||
|
- Запрещено: доступ к закрытым ключам для неуполномоченных пользователей/процессов.
|
||||||
|
- Комментарий: доступ к закрытым ключам должен быть ограничен только необходимыми системными пользователями/процессами.
|
||||||
|
- Проверка:
|
||||||
|
- **Статус:** Реализуемо
|
||||||
|
- **Ревью полномочий:** Требования полностью адекватны. Закрытые ключи читает **master-процесс** (root) при старте и `nginx -s reload`; worker обычно не обращается к ключам напрямую. Права — `600`, владелец root:root. Пользователь nginx и прочие — без read. Запись nginx на ключи запрещена.
|
||||||
|
- **Источник:** https://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_certificate_key
|
||||||
|
- **Пример реализации:**
|
||||||
|
```
|
||||||
|
chmod 600 /etc/nginx/ssl/*.key
|
||||||
|
chown root:root /etc/nginx/ssl/*.key
|
||||||
|
```
|
||||||
|
- **Проверка эффективности:**
|
||||||
|
```bash
|
||||||
|
stat -c '%a %U:%G %n' /etc/nginx/ssl/*.key
|
||||||
|
# Ожидание: 600 root root
|
||||||
|
sudo -u nginx cat /etc/nginx/ssl/server.key 2>&1
|
||||||
|
# Ожидание: Permission denied
|
||||||
|
getfacl /etc/nginx/ssl/server.key 2>/dev/null
|
||||||
|
```
|
||||||
|
- **Примечание:** См. п. 11 в `Контроль целостности хранимого кода и конфигурации — проверка.md`.
|
||||||
|
|
||||||
|
8. **Файл пользователей Basic Auth**
|
||||||
|
- Необходимые полномочия: чтение файла для проверки паролей.
|
||||||
|
- Запрещено: запись в файл пользователей от имени nginx.
|
||||||
|
- Комментарий: изменение учётных данных должно выполняться администратором.
|
||||||
|
- Проверка:
|
||||||
|
- **Статус:** Условно (если используется)
|
||||||
|
- **Ревью полномочий:** Требования корректны при использовании `auth_basic`. Worker нужен read; write — только root (администратор). Рекомендуемые права — `640`, владелец root:root (или root:nginx при необходимости read для worker через группу).
|
||||||
|
- **Источник:** https://nginx.org/en/docs/http/ngx_http_auth_basic_module.html#auth_basic_user_file
|
||||||
|
- **Пример реализации:**
|
||||||
|
```
|
||||||
|
chown root:root /etc/nginx/htpasswd
|
||||||
|
chmod 640 /etc/nginx/htpasswd
|
||||||
|
# Обновление: htpasswd от root, затем nginx -s reload
|
||||||
|
```
|
||||||
|
- **Проверка эффективности:**
|
||||||
|
```bash
|
||||||
|
nginx -T 2>/dev/null | grep auth_basic_user_file
|
||||||
|
ls -la /etc/nginx/htpasswd
|
||||||
|
sudo -u nginx test -w /etc/nginx/htpasswd && echo FAIL || echo OK
|
||||||
|
```
|
||||||
|
- **Примечание:** См. п. 12 в `Контроль целостности хранимого кода и конфигурации — проверка.md`.
|
||||||
|
|
||||||
|
9. **Unix-сокеты backend**
|
||||||
|
- Необходимые полномочия: доступ только к сокетам тех backend, которые используются конфигурацией.
|
||||||
|
- Запрещено: доступ к произвольным сокетам и сервисам ОС.
|
||||||
|
- Комментарий: например, socket PHP-FPM/uWSGI должен быть доступен только при необходимости.
|
||||||
|
- Проверка:
|
||||||
|
- **Статус:** Реализуемо
|
||||||
|
- **Ревью полномочий:** Требования адекватны. Доступ к Unix-сокету — через группу: пользователь nginx в группе `www-data`/`php-fpm`, сокет с правами `660` и группой `www-data`. Не использовать world-readable сокеты (`777`). Доступ только к сокетам из `fastcgi_pass`/`uwsgi_pass` в конфигурации.
|
||||||
|
- **Источник:** https://nginx.org/en/docs/http/ngx_http_fastcgi_module.html#fastcgi_pass , https://nginx.org/en/docs/http/ngx_http_uwsgi_module.html#uwsgi_pass
|
||||||
|
- **Пример реализации:**
|
||||||
|
```
|
||||||
|
# PHP-FPM pool: listen.owner = www-data, listen.group = www-data, listen.mode = 0660
|
||||||
|
usermod -aG www-data nginx
|
||||||
|
```
|
||||||
|
```nginx
|
||||||
|
location ~ \.php$ {
|
||||||
|
fastcgi_pass unix:/run/php/php-fpm.sock;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
- **Проверка эффективности:**
|
||||||
|
```bash
|
||||||
|
nginx -T 2>/dev/null | grep -E 'fastcgi_pass|uwsgi_pass|scgi_pass'
|
||||||
|
namei -l /run/php/php-fpm.sock
|
||||||
|
ls -la /run/php/
|
||||||
|
groups nginx 2>/dev/null || groups www-data
|
||||||
|
# Сокет не world-writable; nginx в нужной группе
|
||||||
|
```
|
||||||
|
- **Примечание:** См. п. 1–3 в `Контроль выполнения кода — проверка.md`.
|
||||||
|
|
||||||
|
10. **Динамические модули nginx**
|
||||||
|
- Необходимые полномочия: чтение разрешённых .so-модулей.
|
||||||
|
- Запрещено: запись/подмена .so-модулей от имени nginx.
|
||||||
|
- Комментарий: модули выполняются в процессе nginx, поэтому требуют контроля целостности.
|
||||||
|
- Проверка:
|
||||||
|
- **Статус:** Комбинированная мера
|
||||||
|
- **Ревью полномочий:** Требования корректны. Master загружает `.so` при старте (read); каталог `/usr/lib/nginx/modules/` — root:root, `755`, файлы `644`. Пользователь nginx не имеет write. Подмена модулей предотвращается FIM и организационным белым списком `load_module`.
|
||||||
|
- **Источник:** https://nginx.org/en/docs/ngx_core_module.html#load_module
|
||||||
|
- **Пример реализации:**
|
||||||
|
```
|
||||||
|
chown -R root:root /usr/lib/nginx/modules/
|
||||||
|
chmod 755 /usr/lib/nginx/modules/
|
||||||
|
chmod 644 /usr/lib/nginx/modules/*.so
|
||||||
|
```
|
||||||
|
```nginx
|
||||||
|
load_module modules/ngx_http_geoip_module.so;
|
||||||
|
```
|
||||||
|
- **Проверка эффективности:**
|
||||||
|
```bash
|
||||||
|
ls -la /usr/lib/nginx/modules/
|
||||||
|
nginx -T 2>/dev/null | grep load_module
|
||||||
|
sudo -u nginx test -w /usr/lib/nginx/modules/ngx_http_geoip_module.so && echo FAIL || echo OK
|
||||||
|
afick -c /etc/afick.conf --check
|
||||||
|
```
|
||||||
|
- **Примечание:** См. п. 5 в `Контроль целостности хранимого кода и конфигурации — проверка.md`; п. 3 в `Минимизация поверхности атаки nginx — проверка.md`.
|
||||||
|
|
||||||
|
11. **Временные директории nginx**
|
||||||
|
- Необходимые полномочия: запись во временные директории, необходимые для buffering/client body.
|
||||||
|
- Запрещено: запись в произвольные системные директории.
|
||||||
|
- Комментарий: временные директории должны быть ограничены и контролируемы правами.
|
||||||
|
- Проверка:
|
||||||
|
- **Статус:** Реализуемо
|
||||||
|
- **Ревью полномочий:** Требования адекватны. По умолчанию nginx использует `client_body_temp_path`, `proxy_temp_path`, `fastcgi_temp_path` под `/var/cache/nginx` или compile-time пути. Явно задать пути в конфигурации; каталог — владелец nginx:nginx, `700` или `750`. Не использовать world-writable `/tmp`.
|
||||||
|
- **Источник:** https://nginx.org/en/docs/http/ngx_http_core_module.html#client_body_temp_path , https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_temp_path
|
||||||
|
- **Пример реализации:**
|
||||||
|
```nginx
|
||||||
|
http {
|
||||||
|
client_body_temp_path /var/cache/nginx/client_temp;
|
||||||
|
proxy_temp_path /var/cache/nginx/proxy_temp;
|
||||||
|
fastcgi_temp_path /var/cache/nginx/fastcgi_temp;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
```
|
||||||
|
mkdir -p /var/cache/nginx/{client_temp,proxy_temp,fastcgi_temp}
|
||||||
|
chown -R nginx:nginx /var/cache/nginx/
|
||||||
|
chmod 750 /var/cache/nginx/
|
||||||
|
```
|
||||||
|
- **Проверка эффективности:**
|
||||||
|
```bash
|
||||||
|
nginx -T 2>/dev/null | grep -E 'client_body_temp_path|proxy_temp_path|fastcgi_temp_path'
|
||||||
|
ls -la /var/cache/nginx/
|
||||||
|
find /var/cache/nginx -perm -0002 2>/dev/null
|
||||||
|
# Нет world-writable каталогов
|
||||||
|
```
|
||||||
|
- **Примечание:** При `proxy_buffering off` часть temp-файлов не создаётся; пути всё равно зафиксировать в ЭД.
|
||||||
|
|
||||||
|
12. **Сетевые соединения к backend**
|
||||||
|
- Необходимые полномочия: исходящие соединения только к утверждённым backend-сервисам (при проксировании).
|
||||||
|
- Запрещено: произвольные исходящие соединения, если они не нужны.
|
||||||
|
- Комментарий: ограничивается архитектурой, межсетевыми правилами и конфигурацией.
|
||||||
|
- Проверка:
|
||||||
|
- **Статус:** Комбинированная мера
|
||||||
|
- **Ревью полномочий:** Требования корректны, но nginx **не имеет встроенного egress-filter**. Ограничение исходящих соединений — комбинация: (1) конфигурация с белым списком `upstream`/`proxy_pass`; (2) файрвол/nftables на хосте; (3) сегментация сети. Без проксирования исходящие соединения nginx минимальны (DNS при resolver, syslog при централизованном журналировании).
|
||||||
|
- **Источник:** https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_pass , 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;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
```
|
||||||
|
# nftables (фрагмент): исходящие от nginx только к утверждённым адресам
|
||||||
|
# ip saddr @nginx_workers ip daddr { 10.0.0.5, 127.0.0.1 } tcp dport 8080 accept
|
||||||
|
```
|
||||||
|
- **Проверка эффективности:**
|
||||||
|
```bash
|
||||||
|
nginx -T 2>/dev/null | grep -E 'proxy_pass|fastcgi_pass|uwsgi_pass|grpc_pass|resolver'
|
||||||
|
ss -tnp | grep nginx
|
||||||
|
# Сверить активные соединения с утверждённым перечнем backend
|
||||||
|
nft list ruleset 2>/dev/null | grep -i nginx
|
||||||
|
```
|
||||||
|
- **Примечание:** См. п. 12–13 в `Минимизация поверхности атаки nginx — проверка.md`; п. 4 в `Контроль выполнения кода — проверка.md`.
|
||||||
408
docs/Минимизация_поверхности_атаки_nginx_—_проверка.md
Normal file
408
docs/Минимизация_поверхности_атаки_nginx_—_проверка.md
Normal 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`; п. 10–11 в `Контроль выполнения кода — проверка.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
|
||||||
|
```
|
||||||
|
- **Примечание:** См. п. 1–5 в `Контроль выполнения кода — проверка.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` п. 3–4, 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.
|
||||||
664
docs/Проверочные_мероприятия_для_ПМИ_—_проверка.md
Normal file
664
docs/Проверочные_мероприятия_для_ПМИ_—_проверка.md
Normal file
@@ -0,0 +1,664 @@
|
|||||||
|
# Проверочные мероприятия для ПМИ — результаты проверки
|
||||||
|
|
||||||
|
**Дата проверки:** 10.06.2026
|
||||||
|
**Объект проверки:** upstream nginx + методика ПМИ
|
||||||
|
**Метод:** ревью пригодности мероприятий, подтверждение по документации nginx, примеры конфигурации и команд испытания (без проведения испытаний на стенде)
|
||||||
|
|
||||||
|
## Сводная таблица
|
||||||
|
|
||||||
|
| № | Проверяемое требование | Статус | Механизм |
|
||||||
|
|---|------------------------|--------|----------|
|
||||||
|
| 1 | Ограничение доступа по IP-адресу | Пригодно с оговорками | allow; deny |
|
||||||
|
| 2 | Аутентификация по имени пользователя и паролю | Пригодно для ПМИ | auth_basic; auth_basic_user_file |
|
||||||
|
| 3 | Проверка клиентского TLS-сертификата | Пригодно с оговорками | ssl_verify_client; ssl_client_certificate |
|
||||||
|
| 4 | Авторизация через внешний сервис | Пригодно с оговорками | auth_request |
|
||||||
|
| 5 | Комбинирование проверок доступа | Пригодно для ПМИ | satisfy |
|
||||||
|
| 6 | Разграничение доступа по URL | Пригодно для ПМИ | server; location |
|
||||||
|
| 7 | Ограничение HTTP-методов | Пригодно для ПМИ | limit_except |
|
||||||
|
| 8 | Запрет прямого доступа к внутренним ресурсам | Пригодно для ПМИ | internal |
|
||||||
|
| 9 | Защита соединения TLS | Пригодно с оговорками | listen 443 ssl; ssl_certificate |
|
||||||
|
| 10 | Ограничение версий TLS и шифров | Пригодно для ПМИ | ssl_protocols; ssl_ciphers |
|
||||||
|
| 11 | Принудительное использование HTTPS | Пригодно для ПМИ | return 301/308; HSTS |
|
||||||
|
| 12 | Журналирование HTTP-запросов | Пригодно для ПМИ | access_log; log_format |
|
||||||
|
| 13 | Журналирование ошибок | Пригодно для ПМИ | error_log |
|
||||||
|
| 14 | Передача журналов в syslog | Требует внешних средств | syslog |
|
||||||
|
| 15 | Ограничение частоты запросов | Пригодно для ПМИ | limit_req_zone; limit_req |
|
||||||
|
| 16 | Ограничение количества соединений | Пригодно для ПМИ | limit_conn_zone; limit_conn |
|
||||||
|
| 17 | Ограничение размера запроса | Пригодно для ПМИ | client_max_body_size |
|
||||||
|
| 18 | Настройка таймаутов | Пригодно с оговорками | client_*_timeout; send_timeout |
|
||||||
|
| 19 | Сокрытие версии nginx | Пригодно для ПМИ | server_tokens off |
|
||||||
|
| 20 | Управление страницами ошибок | Пригодно для ПМИ | error_page |
|
||||||
|
| 21 | Отключение листинга директорий | Пригодно для ПМИ | autoindex off |
|
||||||
|
| 22 | Обратное проксирование backend | Пригодно с оговорками | proxy_pass |
|
||||||
|
| 23 | Ограничение директорий веб-контента | Пригодно для ПМИ | root; alias; location |
|
||||||
|
| 24 | Контроль целостности | Требует внешних средств | afick или иной механизм |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
1. **Проверяемое требование:** Ограничение доступа по IP-адресу
|
||||||
|
- **Настройка / механизм:** allow; deny
|
||||||
|
- **Действия испытателя:** Настроить доступ к ресурсу только с разрешённого IP. Выполнить запрос с разрешённого и запрещённого адреса.
|
||||||
|
- **Ожидаемый результат:** С разрешённого адреса доступ предоставлен, с запрещённого адреса доступ запрещён.
|
||||||
|
- **Признак выполнения:** Разные HTTP-ответы для разрешённого и запрещённого IP.
|
||||||
|
- Проверка:
|
||||||
|
- **Статус:** Пригодно с оговорками
|
||||||
|
- **Ревью мероприятия:** Действия, ожидаемый результат и признак выполнения корректны. Для проверки «запрещённого IP» необходим второй хост в другой подсети или изменение IP испытательной машины; подмена IP через заголовок `X-Forwarded-For` не влияет на `$remote_addr` без модуля `realip`.
|
||||||
|
- **Источник:** https://nginx.org/en/docs/http/ngx_http_access_module.html
|
||||||
|
- **Пример конфигурации:**
|
||||||
|
```nginx
|
||||||
|
location /admin/ {
|
||||||
|
allow 192.168.1.100;
|
||||||
|
deny all;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
- **Примеры команд испытания:**
|
||||||
|
```bash
|
||||||
|
# С разрешённого хоста (192.168.1.100)
|
||||||
|
curl -s -o /dev/null -w "%{http_code}" http://nginx-test/admin/
|
||||||
|
|
||||||
|
# С запрещённого хоста (другой IP)
|
||||||
|
curl -s -o /dev/null -w "%{http_code}" http://nginx-test/admin/
|
||||||
|
```
|
||||||
|
- **Проверка признака выполнения:** С разрешённого IP — код 200 (или иной успешный); с запрещённого — 403 Forbidden.
|
||||||
|
- **Примечание:** Зафиксировать в протоколе IP-адреса испытательных хостов.
|
||||||
|
|
||||||
|
2. **Проверяемое требование:** Аутентификация по имени пользователя и паролю
|
||||||
|
- **Настройка / механизм:** auth_basic; auth_basic_user_file
|
||||||
|
- **Действия испытателя:** Настроить защищённый location. Выполнить запрос без учётных данных, с неверными и с корректными учётными данными.
|
||||||
|
- **Ожидаемый результат:** Без учётных данных и с неверными данными доступ запрещён, с корректными данными доступ разрешён.
|
||||||
|
- **Признак выполнения:** HTTP 401 для отказа и успешный ответ при корректной аутентификации.
|
||||||
|
- Проверка:
|
||||||
|
- **Статус:** Пригодно для ПМИ
|
||||||
|
- **Ревью мероприятия:** Мероприятие полностью воспроизводимо. Три сценария (без credentials, неверные, верные) покрывают требование. Признак выполнения однозначен.
|
||||||
|
- **Источник:** https://nginx.org/en/docs/http/ngx_http_auth_basic_module.html
|
||||||
|
- **Пример конфигурации:**
|
||||||
|
```nginx
|
||||||
|
location /secure/ {
|
||||||
|
auth_basic "Restricted";
|
||||||
|
auth_basic_user_file /etc/nginx/htpasswd;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
- **Примеры команд испытания:**
|
||||||
|
```bash
|
||||||
|
curl -s -o /dev/null -w "%{http_code}" http://nginx-test/secure/
|
||||||
|
curl -s -o /dev/null -w "%{http_code}" -u wrong:wrong http://nginx-test/secure/
|
||||||
|
curl -s -o /dev/null -w "%{http_code}" -u user:password http://nginx-test/secure/
|
||||||
|
```
|
||||||
|
- **Проверка признака выполнения:** Первые два запроса — 401; третий — 200 (или иной успешный код).
|
||||||
|
|
||||||
|
3. **Проверяемое требование:** Проверка клиентского TLS-сертификата
|
||||||
|
- **Настройка / механизм:** ssl_verify_client; ssl_client_certificate
|
||||||
|
- **Действия испытателя:** Настроить проверку клиентского сертификата. Выполнить подключение без сертификата, с недоверенным и с доверенным сертификатом.
|
||||||
|
- **Ожидаемый результат:** Доступ разрешён только при предъявлении доверенного клиентского сертификата.
|
||||||
|
- **Признак выполнения:** Успешное TLS-подключение только с доверенным сертификатом.
|
||||||
|
- Проверка:
|
||||||
|
- **Статус:** Пригодно с оговорками
|
||||||
|
- **Ревью мероприятия:** Действия и ожидаемый результат корректны. Требуется подготовка тестовых сертификатов (CA, доверенный клиентский, недоверенный). При `ssl_verify_client on` подключение без сертификата завершается ошибкой на этапе handshake.
|
||||||
|
- **Источник:** https://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_verify_client
|
||||||
|
- **Пример конфигурации:**
|
||||||
|
```nginx
|
||||||
|
server {
|
||||||
|
listen 443 ssl;
|
||||||
|
ssl_certificate /etc/nginx/ssl/server.crt;
|
||||||
|
ssl_certificate_key /etc/nginx/ssl/server.key;
|
||||||
|
ssl_client_certificate /etc/nginx/ssl/ca.crt;
|
||||||
|
ssl_verify_client on;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
- **Примеры команд испытания:**
|
||||||
|
```bash
|
||||||
|
# Без клиентского сертификата — ошибка handshake
|
||||||
|
openssl s_client -connect nginx-test:443 -servername nginx-test </dev/null
|
||||||
|
|
||||||
|
# С доверенным сертификатом
|
||||||
|
openssl s_client -connect nginx-test:443 -cert client.crt -key client.key </dev/null
|
||||||
|
|
||||||
|
# С недоверенным (самоподписанным) сертификатом
|
||||||
|
openssl s_client -connect nginx-test:443 -cert untrusted.crt -key untrusted.key </dev/null
|
||||||
|
```
|
||||||
|
- **Проверка признака выполнения:** Успешный handshake и HTTP-ответ только при доверенном сертификате; без сертификата или с недоверенным — ошибка TLS (verify return code != 0).
|
||||||
|
|
||||||
|
4. **Проверяемое требование:** Авторизация через внешний сервис
|
||||||
|
- **Настройка / механизм:** auth_request
|
||||||
|
- **Действия испытателя:** Настроить внешний сервис авторизации. Проверить доступ при ответах 2xx, 401 и 403 от сервиса авторизации.
|
||||||
|
- **Ожидаемый результат:** При 2xx доступ разрешён, при 401/403 доступ запрещён.
|
||||||
|
- **Признак выполнения:** Поведение nginx соответствует ответу сервиса авторизации.
|
||||||
|
- Проверка:
|
||||||
|
- **Статус:** Пригодно с оговорками
|
||||||
|
- **Ревью мероприятия:** Мероприятие корректно. Требуется mock-сервер авторизации с переключаемыми ответами. Необходимо подтвердить наличие модуля `auth_request` в поставке nginx (`nginx -V`).
|
||||||
|
- **Источник:** https://nginx.org/en/docs/http/ngx_http_auth_request_module.html
|
||||||
|
- **Пример конфигурации:**
|
||||||
|
```nginx
|
||||||
|
location = /auth {
|
||||||
|
internal;
|
||||||
|
proxy_pass http://127.0.0.1:9999/validate;
|
||||||
|
proxy_pass_request_body off;
|
||||||
|
proxy_set_header Content-Length "";
|
||||||
|
}
|
||||||
|
|
||||||
|
location / {
|
||||||
|
auth_request /auth;
|
||||||
|
proxy_pass http://backend;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
- **Примеры команд испытания:**
|
||||||
|
```bash
|
||||||
|
# Mock возвращает 200 — доступ разрешён
|
||||||
|
curl -s -o /dev/null -w "%{http_code}" http://nginx-test/
|
||||||
|
|
||||||
|
# Переключить mock на 401/403 — повторить запрос
|
||||||
|
curl -s -o /dev/null -w "%{http_code}" http://nginx-test/
|
||||||
|
```
|
||||||
|
- **Проверка признака выполнения:** При ответе auth-сервиса 2xx — успешный код от nginx; при 401 — 401; при 403 — 403.
|
||||||
|
|
||||||
|
5. **Проверяемое требование:** Комбинирование проверок доступа
|
||||||
|
- **Настройка / механизм:** satisfy
|
||||||
|
- **Действия испытателя:** Настроить совместное применение IP-ограничения и Basic Authentication. Проверить сценарии прохождения одной или нескольких проверок.
|
||||||
|
- **Ожидаемый результат:** Доступ предоставляется в соответствии с выбранным режимом satisfy all/any.
|
||||||
|
- **Признак выполнения:** Фактический доступ соответствует заданной политике.
|
||||||
|
- Проверка:
|
||||||
|
- **Статус:** Пригодно для ПМИ
|
||||||
|
- **Ревью мероприятия:** Мероприятие корректно. Рекомендуется в протоколе явно фиксировать значение `satisfy` (all/any) и матрицу сценариев: IP+пароль, только IP, только пароль, ни то ни другое.
|
||||||
|
- **Источник:** https://nginx.org/en/docs/http/ngx_http_core_module.html#satisfy
|
||||||
|
- **Пример конфигурации:**
|
||||||
|
```nginx
|
||||||
|
location /admin/ {
|
||||||
|
satisfy all;
|
||||||
|
allow 10.0.0.0/8;
|
||||||
|
deny all;
|
||||||
|
auth_basic "Admin";
|
||||||
|
auth_basic_user_file /etc/nginx/htpasswd;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
- **Примеры команд испытания:**
|
||||||
|
```bash
|
||||||
|
# IP из allow + верный пароль
|
||||||
|
curl -u user:password http://nginx-test/admin/
|
||||||
|
|
||||||
|
# IP из allow + без пароля
|
||||||
|
curl http://nginx-test/admin/
|
||||||
|
|
||||||
|
# IP вне allow + верный пароль (при satisfy all — отказ)
|
||||||
|
curl -u user:password http://nginx-test/admin/
|
||||||
|
```
|
||||||
|
- **Проверка признака выполнения:** Сверить фактические коды ответов с матрицей для выбранного `satisfy all` или `satisfy any`.
|
||||||
|
|
||||||
|
6. **Проверяемое требование:** Разграничение доступа по URL
|
||||||
|
- **Настройка / механизм:** server; location
|
||||||
|
- **Действия испытателя:** Настроить разные правила доступа для публичного и защищённого location. Выполнить запросы к обоим разделам.
|
||||||
|
- **Ожидаемый результат:** Публичный раздел доступен, защищённый раздел доступен только при выполнении условий доступа.
|
||||||
|
- **Признак выполнения:** Разные правила доступа применяются к разным URL.
|
||||||
|
- Проверка:
|
||||||
|
- **Статус:** Пригодно для ПМИ
|
||||||
|
- **Ревью мероприятия:** Мероприятие корректно и воспроизводимо. Достаточно двух location с разными правилами.
|
||||||
|
- **Источник:** https://nginx.org/en/docs/http/ngx_http_core_module.html#location
|
||||||
|
- **Пример конфигурации:**
|
||||||
|
```nginx
|
||||||
|
location /public/ {
|
||||||
|
root /var/www/html;
|
||||||
|
}
|
||||||
|
|
||||||
|
location /admin/ {
|
||||||
|
allow 10.0.0.0/8;
|
||||||
|
deny all;
|
||||||
|
root /var/www/html;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
- **Примеры команд испытания:**
|
||||||
|
```bash
|
||||||
|
curl -s -o /dev/null -w "%{http_code}" http://nginx-test/public/index.html
|
||||||
|
curl -s -o /dev/null -w "%{http_code}" http://nginx-test/admin/
|
||||||
|
```
|
||||||
|
- **Проверка признака выполнения:** `/public/` — 200; `/admin/` — 403 с неразрешённого IP или 200 с разрешённого.
|
||||||
|
|
||||||
|
7. **Проверяемое требование:** Ограничение HTTP-методов
|
||||||
|
- **Настройка / механизм:** limit_except
|
||||||
|
- **Действия испытателя:** Настроить ограничение методов. Выполнить запросы методами GET, POST, PUT, DELETE.
|
||||||
|
- **Ожидаемый результат:** Разрешённые методы обрабатываются, запрещённые методы блокируются.
|
||||||
|
- **Признак выполнения:** Запрещённые методы возвращают отказ.
|
||||||
|
- Проверка:
|
||||||
|
- **Статус:** Пригодно для ПМИ
|
||||||
|
- **Ревью мероприятия:** Мероприятие корректно. В протоколе указать, какие методы разрешены в `limit_except`.
|
||||||
|
- **Источник:** https://nginx.org/en/docs/http/ngx_http_core_module.html#limit_except
|
||||||
|
- **Пример конфигурации:**
|
||||||
|
```nginx
|
||||||
|
location /api/ {
|
||||||
|
limit_except GET POST {
|
||||||
|
deny all;
|
||||||
|
}
|
||||||
|
proxy_pass http://backend;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
- **Примеры команд испытания:**
|
||||||
|
```bash
|
||||||
|
curl -s -o /dev/null -w "%{http_code}" -X GET http://nginx-test/api/
|
||||||
|
curl -s -o /dev/null -w "%{http_code}" -X POST http://nginx-test/api/
|
||||||
|
curl -s -o /dev/null -w "%{http_code}" -X PUT http://nginx-test/api/
|
||||||
|
curl -s -o /dev/null -w "%{http_code}" -X DELETE http://nginx-test/api/
|
||||||
|
```
|
||||||
|
- **Проверка признака выполнения:** GET и POST — успешные коды; PUT и DELETE — 403.
|
||||||
|
|
||||||
|
8. **Проверяемое требование:** Запрет прямого доступа к внутренним ресурсам
|
||||||
|
- **Настройка / механизм:** internal
|
||||||
|
- **Действия испытателя:** Настроить internal location. Выполнить прямой запрос к нему и внутреннее перенаправление.
|
||||||
|
- **Ожидаемый результат:** Прямой запрос запрещён, внутреннее перенаправление работает.
|
||||||
|
- **Признак выполнения:** Прямой доступ получает отказ, внутренний сценарий успешен.
|
||||||
|
- Проверка:
|
||||||
|
- **Статус:** Пригодно для ПМИ
|
||||||
|
- **Ревью мероприятия:** Мероприятие корректно. Прямой запрос к internal location возвращает 404 (не 403) — это штатное поведение nginx; признак выполнения следует трактовать как «отказ в доступе» (404).
|
||||||
|
- **Источник:** https://nginx.org/en/docs/http/ngx_http_core_module.html#internal
|
||||||
|
- **Пример конфигурации:**
|
||||||
|
```nginx
|
||||||
|
location /protected/ {
|
||||||
|
internal;
|
||||||
|
alias /var/data/files/;
|
||||||
|
}
|
||||||
|
|
||||||
|
location /download {
|
||||||
|
rewrite ^ /protected/document.pdf last;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
- **Примеры команд испытания:**
|
||||||
|
```bash
|
||||||
|
# Прямой запрос — отказ
|
||||||
|
curl -s -o /dev/null -w "%{http_code}" http://nginx-test/protected/document.pdf
|
||||||
|
|
||||||
|
# Внутреннее перенаправление — успех
|
||||||
|
curl -s -o /dev/null -w "%{http_code}" http://nginx-test/download
|
||||||
|
```
|
||||||
|
- **Проверка признака выполнения:** Прямой запрос — 404; через `/download` — 200 и содержимое файла.
|
||||||
|
|
||||||
|
9. **Проверяемое требование:** Защита соединения TLS
|
||||||
|
- **Настройка / механизм:** listen 443 ssl; ssl_certificate; ssl_certificate_key
|
||||||
|
- **Действия испытателя:** Настроить HTTPS-сервер. Выполнить подключение по HTTPS.
|
||||||
|
- **Ожидаемый результат:** Соединение устанавливается по TLS.
|
||||||
|
- **Признак выполнения:** Клиент видит действующее TLS-соединение.
|
||||||
|
- Проверка:
|
||||||
|
- **Статус:** Пригодно с оговорками
|
||||||
|
- **Ревью мероприятия:** Мероприятие корректно. Требуются тестовые сертификаты. Для самоподписанных сертификатов в командах нужен флаг `-k`/`--insecure`.
|
||||||
|
- **Источник:** https://nginx.org/en/docs/http/ngx_http_ssl_module.html
|
||||||
|
- **Пример конфигурации:**
|
||||||
|
```nginx
|
||||||
|
server {
|
||||||
|
listen 443 ssl;
|
||||||
|
server_name nginx-test;
|
||||||
|
ssl_certificate /etc/nginx/ssl/server.crt;
|
||||||
|
ssl_certificate_key /etc/nginx/ssl/server.key;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
- **Примеры команд испытания:**
|
||||||
|
```bash
|
||||||
|
curl -vk https://nginx-test/
|
||||||
|
openssl s_client -connect nginx-test:443 -servername nginx-test </dev/null
|
||||||
|
```
|
||||||
|
- **Проверка признака выполнения:** В выводе `openssl s_client` — строка `Verify return code: 0` (или успешный handshake); `curl` завершается без ошибки SSL.
|
||||||
|
|
||||||
|
10. **Проверяемое требование:** Ограничение версий TLS и шифров
|
||||||
|
- **Настройка / механизм:** ssl_protocols; ssl_ciphers
|
||||||
|
- **Действия испытателя:** Настроить допустимые версии TLS и шифры. Выполнить подключение с разрешёнными и запрещёнными версиями/шифрами.
|
||||||
|
- **Ожидаемый результат:** Разрешённые параметры работают, запрещённые отклоняются.
|
||||||
|
- **Признак выполнения:** Результат подключения соответствует политике TLS.
|
||||||
|
- Проверка:
|
||||||
|
- **Статус:** Пригодно для ПМИ
|
||||||
|
- **Ревью мероприятия:** Мероприятие корректно. Рекомендуется зафиксировать в ТУ/ПМИ конкретную политику (например, только TLSv1.2 и TLSv1.3).
|
||||||
|
- **Источник:** https://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_protocols
|
||||||
|
- **Пример конфигурации:**
|
||||||
|
```nginx
|
||||||
|
ssl_protocols TLSv1.2 TLSv1.3;
|
||||||
|
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256;
|
||||||
|
```
|
||||||
|
- **Примеры команд испытания:**
|
||||||
|
```bash
|
||||||
|
# Разрешённая версия
|
||||||
|
openssl s_client -connect nginx-test:443 -tls1_2 </dev/null
|
||||||
|
|
||||||
|
# Запрещённая версия (если в политике только TLSv1.2+)
|
||||||
|
openssl s_client -connect nginx-test:443 -tls1_1 </dev/null
|
||||||
|
```
|
||||||
|
- **Проверка признака выполнения:** TLSv1.2 — успешный handshake; TLSv1.1 — ошибка handshake (alert protocol version).
|
||||||
|
|
||||||
|
11. **Проверяемое требование:** Принудительное использование HTTPS
|
||||||
|
- **Настройка / механизм:** return 301/308; Strict-Transport-Security
|
||||||
|
- **Действия испытателя:** Выполнить HTTP-запрос к ресурсу. Проверить перенаправление и наличие HSTS-заголовка, если он настроен.
|
||||||
|
- **Ожидаемый результат:** HTTP-запрос перенаправляется на HTTPS.
|
||||||
|
- **Признак выполнения:** В ответе присутствует redirect на HTTPS и/или HSTS.
|
||||||
|
- Проверка:
|
||||||
|
- **Статус:** Пригодно для ПМИ
|
||||||
|
- **Ревью мероприятия:** Мероприятие корректно. HSTS проверяется только на HTTPS-ответе, не на HTTP-редиректе.
|
||||||
|
- **Источник:** https://nginx.org/en/docs/http/ngx_http_rewrite_module.html#return
|
||||||
|
- **Пример конфигурации:**
|
||||||
|
```nginx
|
||||||
|
server {
|
||||||
|
listen 80;
|
||||||
|
return 301 https://$host$request_uri;
|
||||||
|
}
|
||||||
|
|
||||||
|
server {
|
||||||
|
listen 443 ssl;
|
||||||
|
add_header Strict-Transport-Security "max-age=31536000" always;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
- **Примеры команд испытания:**
|
||||||
|
```bash
|
||||||
|
curl -I http://nginx-test/
|
||||||
|
curl -I https://nginx-test/
|
||||||
|
```
|
||||||
|
- **Проверка признака выполнения:** HTTP — `301` и заголовок `Location: https://...`; HTTPS — заголовок `Strict-Transport-Security`.
|
||||||
|
|
||||||
|
12. **Проверяемое требование:** Журналирование HTTP-запросов
|
||||||
|
- **Настройка / механизм:** access_log; log_format
|
||||||
|
- **Действия испытателя:** Выполнить несколько HTTP-запросов. Проверить появление записей в access log.
|
||||||
|
- **Ожидаемый результат:** Запросы зарегистрированы в журнале.
|
||||||
|
- **Признак выполнения:** В журнале присутствуют записи с требуемыми полями.
|
||||||
|
- Проверка:
|
||||||
|
- **Статус:** Пригодно для ПМИ
|
||||||
|
- **Ревью мероприятия:** Мероприятие корректно. В ПМИ зафиксировать перечень обязательных полей журнала (IP, время, метод, URI, статус).
|
||||||
|
- **Источник:** https://nginx.org/en/docs/http/ngx_http_log_module.html
|
||||||
|
- **Пример конфигурации:**
|
||||||
|
```nginx
|
||||||
|
log_format pmi '$remote_addr - [$time_local] "$request" $status';
|
||||||
|
access_log /var/log/nginx/access.log pmi;
|
||||||
|
```
|
||||||
|
- **Примеры команд испытания:**
|
||||||
|
```bash
|
||||||
|
curl http://nginx-test/test-page
|
||||||
|
curl http://nginx-test/another-page
|
||||||
|
tail -n 5 /var/log/nginx/access.log
|
||||||
|
```
|
||||||
|
- **Проверка признака выполнения:** В журнале две новые записи с IP клиента, URI `/test-page` и `/another-page`, кодами ответа.
|
||||||
|
|
||||||
|
13. **Проверяемое требование:** Журналирование ошибок
|
||||||
|
- **Настройка / механизм:** error_log
|
||||||
|
- **Действия испытателя:** Сформировать ошибочную ситуацию, которая гарантированно фиксируется в error log: ошибка доступа к файлу, ошибка взаимодействия с backend, некорректный upstream или иная ошибка обработки. Проверить наличие записи в error log.
|
||||||
|
- **Ожидаемый результат:** Ошибка зарегистрирована в журнале ошибок.
|
||||||
|
- **Признак выполнения:** В error log появилась запись о событии.
|
||||||
|
- Проверка:
|
||||||
|
- **Статус:** Пригодно для ПМИ
|
||||||
|
- **Ревью мероприятия:** Мероприятие корректно. Простейший воспроизводимый сценарий — `proxy_pass` на недоступный upstream (connection refused).
|
||||||
|
- **Источник:** https://nginx.org/en/docs/ngx_core_module.html#error_log
|
||||||
|
- **Пример конфигурации:**
|
||||||
|
```nginx
|
||||||
|
error_log /var/log/nginx/error.log warn;
|
||||||
|
|
||||||
|
location /broken/ {
|
||||||
|
proxy_pass http://127.0.0.1:59999;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
- **Примеры команд испытания:**
|
||||||
|
```bash
|
||||||
|
curl http://nginx-test/broken/
|
||||||
|
tail -n 10 /var/log/nginx/error.log
|
||||||
|
```
|
||||||
|
- **Проверка признака выполнения:** В error log — запись об ошибке подключения к upstream (`connect() failed`).
|
||||||
|
|
||||||
|
14. **Проверяемое требование:** Передача журналов в syslog
|
||||||
|
- **Настройка / механизм:** access_log syslog:...; error_log syslog:...
|
||||||
|
- **Действия испытателя:** Настроить вывод журналов в syslog. Выполнить запросы и проверить внешнюю систему журналирования.
|
||||||
|
- **Ожидаемый результат:** События передаются во внешнюю систему журналирования.
|
||||||
|
- **Признак выполнения:** Записи обнаружены в syslog/централизованном журнале.
|
||||||
|
- Проверка:
|
||||||
|
- **Статус:** Требует внешних средств
|
||||||
|
- **Ревью мероприятия:** Мероприятие корректно, но зависит от rsyslog/journald или централизованного SIEM. nginx только отправляет в syslog; приёмник — внешний компонент стенда.
|
||||||
|
- **Источник:** https://nginx.org/en/docs/syslog.html
|
||||||
|
- **Пример конфигурации:**
|
||||||
|
```nginx
|
||||||
|
error_log syslog:server=127.0.0.1:514,facility=local7,tag=nginx,severity=error;
|
||||||
|
access_log syslog:server=127.0.0.1:514,facility=local7,tag=nginx,severity=info combined;
|
||||||
|
```
|
||||||
|
- **Примеры команд испытания:**
|
||||||
|
```bash
|
||||||
|
curl http://nginx-test/
|
||||||
|
# На приёмнике syslog (Linux)
|
||||||
|
journalctl -t nginx --since "1 min ago"
|
||||||
|
# или
|
||||||
|
tail -f /var/log/syslog | grep nginx
|
||||||
|
```
|
||||||
|
- **Проверка признака выполнения:** Запись с тегом `nginx` и данными HTTP-запроса в syslog/journal.
|
||||||
|
- **Примечание:** Статус отражает внешнюю меру. См. `Контроль целостности хранимого кода и конфигурации — проверка.md` п. 13; `Минимально необходимые полномочия nginx — проверка.md` п. 5; функции 4.4 в `функции безопасности — проверка.md`.
|
||||||
|
|
||||||
|
15. **Проверяемое требование:** Ограничение частоты запросов
|
||||||
|
- **Настройка / механизм:** limit_req_zone; limit_req
|
||||||
|
- **Действия испытателя:** Настроить лимит запросов. Выполнить серию запросов с превышением лимита.
|
||||||
|
- **Ожидаемый результат:** Избыточные запросы ограничиваются или отклоняются.
|
||||||
|
- **Признак выполнения:** При превышении лимита сервер возвращает отказ/задержку согласно настройке.
|
||||||
|
- Проверка:
|
||||||
|
- **Статус:** Пригодно для ПМИ
|
||||||
|
- **Ревью мероприятия:** Мероприятие корректно. По умолчанию nginx возвращает 503 при превышении `limit_req` (без `limit_req_status`).
|
||||||
|
- **Источник:** https://nginx.org/en/docs/http/ngx_http_limit_req_module.html
|
||||||
|
- **Пример конфигурации:**
|
||||||
|
```nginx
|
||||||
|
limit_req_zone $binary_remote_addr zone=one:10m rate=2r/s;
|
||||||
|
|
||||||
|
location / {
|
||||||
|
limit_req zone=one burst=5 nodelay;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
- **Примеры команд испытания:**
|
||||||
|
```bash
|
||||||
|
for i in $(seq 1 20); do
|
||||||
|
curl -s -o /dev/null -w "%{http_code}\n" http://nginx-test/
|
||||||
|
done
|
||||||
|
```
|
||||||
|
- **Проверка признака выполнения:** Первые запросы — 200; при превышении лимита — 503 (или задержка при отсутствии `nodelay`).
|
||||||
|
|
||||||
|
16. **Проверяемое требование:** Ограничение количества соединений
|
||||||
|
- **Настройка / механизм:** limit_conn_zone; limit_conn
|
||||||
|
- **Действия испытателя:** Настроить лимит соединений. Открыть число соединений выше допустимого.
|
||||||
|
- **Ожидаемый результат:** Лишние соединения отклоняются.
|
||||||
|
- **Признак выполнения:** При превышении лимита сервер возвращает отказ.
|
||||||
|
- Проверка:
|
||||||
|
- **Статус:** Пригодно для ПМИ
|
||||||
|
- **Ревью мероприятия:** Мероприятие корректно. Для воспроизведения удобен `ab` или параллельные `curl` с длительным запросом (sleep на backend).
|
||||||
|
- **Источник:** https://nginx.org/en/docs/http/ngx_http_limit_conn_module.html
|
||||||
|
- **Пример конфигурации:**
|
||||||
|
```nginx
|
||||||
|
limit_conn_zone $binary_remote_addr zone=addr:10m;
|
||||||
|
|
||||||
|
location / {
|
||||||
|
limit_conn addr 2;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
- **Примеры команд испытания:**
|
||||||
|
```bash
|
||||||
|
for i in $(seq 1 5); do
|
||||||
|
curl -s http://nginx-test/slow &
|
||||||
|
done
|
||||||
|
wait
|
||||||
|
```
|
||||||
|
- **Проверка признака выполнения:** Часть запросов получает 503 (`limit_conn_status` по умолчанию).
|
||||||
|
|
||||||
|
17. **Проверяемое требование:** Ограничение размера запроса
|
||||||
|
- **Настройка / механизм:** client_max_body_size
|
||||||
|
- **Действия испытателя:** Настроить максимальный размер тела запроса. Отправить запрос меньше и больше лимита.
|
||||||
|
- **Ожидаемый результат:** Запрос меньше лимита принимается, больше лимита отклоняется.
|
||||||
|
- **Признак выполнения:** Большой запрос получает ошибку ограничения размера.
|
||||||
|
- Проверка:
|
||||||
|
- **Статус:** Пригодно для ПМИ
|
||||||
|
- **Ревью мероприятия:** Мероприятие корректно и полностью воспроизводимо.
|
||||||
|
- **Источник:** https://nginx.org/en/docs/http/ngx_http_core_module.html#client_max_body_size
|
||||||
|
- **Пример конфигурации:**
|
||||||
|
```nginx
|
||||||
|
client_max_body_size 1m;
|
||||||
|
```
|
||||||
|
- **Примеры команд испытания:**
|
||||||
|
```bash
|
||||||
|
# Меньше лимита
|
||||||
|
dd if=/dev/zero bs=1024 count=100 2>/dev/null | curl -s -o /dev/null -w "%{http_code}" -X POST -d @- http://nginx-test/upload
|
||||||
|
|
||||||
|
# Больше лимита
|
||||||
|
dd if=/dev/zero bs=1M count=2 2>/dev/null | curl -s -o /dev/null -w "%{http_code}" -X POST -d @- http://nginx-test/upload
|
||||||
|
```
|
||||||
|
- **Проверка признака выполнения:** Малый запрос — 200/204; большой — 413 Request Entity Too Large.
|
||||||
|
|
||||||
|
18. **Проверяемое требование:** Настройка таймаутов
|
||||||
|
- **Настройка / механизм:** client_header_timeout; client_body_timeout; send_timeout; keepalive_timeout
|
||||||
|
- **Действия испытателя:** Настроить таймауты. Смоделировать медленную отправку заголовков/тела запроса.
|
||||||
|
- **Ожидаемый результат:** Медленные соединения закрываются по таймауту.
|
||||||
|
- **Признак выполнения:** Соединение разрывается после заданного времени.
|
||||||
|
- Проверка:
|
||||||
|
- **Статус:** Пригодно с оговорками
|
||||||
|
- **Ревью мероприятия:** Мероприятие корректно по смыслу, но воспроизведение медленной отправки заголовков требует специальных инструментов (`nc`, скрипт на Python) или модулей; `curl --limit-rate` подходит для тела запроса (`client_body_timeout`).
|
||||||
|
- **Источник:** https://nginx.org/en/docs/http/ngx_http_core_module.html#client_body_timeout
|
||||||
|
- **Пример конфигурации:**
|
||||||
|
```nginx
|
||||||
|
client_header_timeout 5s;
|
||||||
|
client_body_timeout 5s;
|
||||||
|
```
|
||||||
|
- **Примеры команд испытания:**
|
||||||
|
```bash
|
||||||
|
# Медленная отправка тела (превышение client_body_timeout)
|
||||||
|
dd if=/dev/zero bs=1K count=1000 2>/dev/null | curl --limit-rate 1K -m 30 -X POST -d @- http://nginx-test/upload
|
||||||
|
```
|
||||||
|
- **Проверка признака выполнения:** curl завершается с ошибкой (timeout/connection reset) примерно через заданный `client_body_timeout`.
|
||||||
|
|
||||||
|
19. **Проверяемое требование:** Сокрытие версии nginx
|
||||||
|
- **Настройка / механизм:** server_tokens off
|
||||||
|
- **Действия испытателя:** Выполнить запрос и проверить заголовки/страницы ошибок.
|
||||||
|
- **Ожидаемый результат:** Версия nginx не раскрывается в ответах.
|
||||||
|
- **Признак выполнения:** В ответе отсутствует номер версии nginx.
|
||||||
|
- Проверка:
|
||||||
|
- **Статус:** Пригодно для ПМИ
|
||||||
|
- **Ревью мероприятия:** Мероприятие корректно. `server_tokens off` убирает версию, но заголовок `Server: nginx` остаётся — это соответствует документации.
|
||||||
|
- **Источник:** https://nginx.org/en/docs/http/ngx_http_core_module.html#server_tokens
|
||||||
|
- **Пример конфигурации:**
|
||||||
|
```nginx
|
||||||
|
http {
|
||||||
|
server_tokens off;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
- **Примеры команд испытания:**
|
||||||
|
```bash
|
||||||
|
curl -I http://nginx-test/
|
||||||
|
curl http://nginx-test/nonexistent-page
|
||||||
|
```
|
||||||
|
- **Проверка признака выполнения:** Заголовок `Server: nginx` без номера версии (не `nginx/1.24.0`); в теле ошибки 404 нет номера версии.
|
||||||
|
|
||||||
|
20. **Проверяемое требование:** Управление страницами ошибок
|
||||||
|
- **Настройка / механизм:** error_page
|
||||||
|
- **Действия испытателя:** Настроить пользовательскую страницу ошибки. Вызвать ошибку 404/403/500.
|
||||||
|
- **Ожидаемый результат:** Отображается настроенная страница ошибки без раскрытия лишних деталей.
|
||||||
|
- **Признак выполнения:** Пользователь видит заданную страницу ошибки.
|
||||||
|
- Проверка:
|
||||||
|
- **Статус:** Пригодно для ПМИ
|
||||||
|
- **Ревью мероприятия:** Мероприятие корректно и воспроизводимо.
|
||||||
|
- **Источник:** https://nginx.org/en/docs/http/ngx_http_core_module.html#error_page
|
||||||
|
- **Пример конфигурации:**
|
||||||
|
```nginx
|
||||||
|
error_page 404 /custom_404.html;
|
||||||
|
|
||||||
|
location = /custom_404.html {
|
||||||
|
root /var/www/errors;
|
||||||
|
internal;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
- **Примеры команд испытания:**
|
||||||
|
```bash
|
||||||
|
curl http://nginx-test/nonexistent-page
|
||||||
|
```
|
||||||
|
- **Проверка признака выполнения:** Тело ответа содержит текст/разметку из `/var/www/errors/custom_404.html`, а не стандартную страницу nginx.
|
||||||
|
|
||||||
|
21. **Проверяемое требование:** Отключение листинга директорий
|
||||||
|
- **Настройка / механизм:** autoindex off
|
||||||
|
- **Действия испытателя:** Обратиться к директории без индексного файла.
|
||||||
|
- **Ожидаемый результат:** Листинг директории не отображается.
|
||||||
|
- **Признак выполнения:** Сервер возвращает отказ или штатную ошибку, но не список файлов.
|
||||||
|
- Проверка:
|
||||||
|
- **Статус:** Пригодно для ПМИ
|
||||||
|
- **Ревью мероприятия:** Мероприятие корректно. `autoindex off` — значение по умолчанию; при отсутствии index.html ожидается 403.
|
||||||
|
- **Источник:** https://nginx.org/en/docs/http/ngx_http_autoindex_module.html
|
||||||
|
- **Пример конфигурации:**
|
||||||
|
```nginx
|
||||||
|
location /files/ {
|
||||||
|
autoindex off;
|
||||||
|
root /var/www/html;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
- **Примеры команд испытания:**
|
||||||
|
```bash
|
||||||
|
curl http://nginx-test/files/
|
||||||
|
```
|
||||||
|
- **Проверка признака выполнения:** Ответ 403 Forbidden (или 404), в теле нет HTML-листинга с перечнем файлов.
|
||||||
|
|
||||||
|
22. **Проверяемое требование:** Обратное проксирование backend
|
||||||
|
- **Настройка / механизм:** proxy_pass
|
||||||
|
- **Действия испытателя:** Настроить proxy_pass на backend. Если архитектурой предусмотрена изоляция backend-сервиса, проверить, что пользовательский доступ к backend выполняется через nginx, а прямой доступ к backend ограничен сетевыми правилами/настройками инфраструктуры.
|
||||||
|
- **Ожидаемый результат:** Запрос проходит через nginx; прямой доступ к backend ограничен, если это предусмотрено архитектурой.
|
||||||
|
- **Признак выполнения:** Backend обслуживается через nginx согласно настройке.
|
||||||
|
- Проверка:
|
||||||
|
- **Статус:** Пригодно с оговорками
|
||||||
|
- **Ревью мероприятия:** Проверка proxy_pass через nginx — корректна. Проверка сетевой изоляции backend — отдельное инфраструктурное мероприятие (firewall, bind только на 127.0.0.1); в протоколе разделить результаты.
|
||||||
|
- **Источник:** https://nginx.org/en/docs/http/ngx_http_proxy_module.html
|
||||||
|
- **Пример конфигурации:**
|
||||||
|
```nginx
|
||||||
|
location /api/ {
|
||||||
|
proxy_pass http://127.0.0.1:8080/;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
- **Примеры команд испытания:**
|
||||||
|
```bash
|
||||||
|
# Через nginx — успех
|
||||||
|
curl http://nginx-test/api/status
|
||||||
|
|
||||||
|
# Прямой доступ к backend (с испытательной машины, если backend на 127.0.0.1 — недоступен)
|
||||||
|
curl http://127.0.0.1:8080/status
|
||||||
|
```
|
||||||
|
- **Проверка признака выполнения:** Запрос через nginx возвращает ответ backend; прямой доступ с внешней сети к порту 8080 — отказ (если изоляция настроена).
|
||||||
|
|
||||||
|
23. **Проверяемое требование:** Ограничение директорий веб-контента
|
||||||
|
- **Настройка / механизм:** root; alias; location; try_files
|
||||||
|
- **Действия испытателя:** Настроить разрешённую директорию веб-контента. Выполнить запрос к файлу внутри и вне разрешённой директории.
|
||||||
|
- **Ожидаемый результат:** Файлы внутри разрешённой директории доступны, вне директории не обслуживаются.
|
||||||
|
- **Признак выполнения:** Доступ к произвольным каталогам ОС отсутствует.
|
||||||
|
- Проверка:
|
||||||
|
- **Статус:** Пригодно для ПМИ
|
||||||
|
- **Ревью мероприятия:** Мероприятие корректно. Для «вне директории» использовать path traversal (`/../etc/passwd`) или запрос к URI вне `root`.
|
||||||
|
- **Источник:** https://nginx.org/en/docs/http/ngx_http_core_module.html#root
|
||||||
|
- **Пример конфигурации:**
|
||||||
|
```nginx
|
||||||
|
server {
|
||||||
|
root /var/www/app/public;
|
||||||
|
|
||||||
|
location / {
|
||||||
|
try_files $uri =404;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
- **Примеры команд испытания:**
|
||||||
|
```bash
|
||||||
|
# Файл внутри root
|
||||||
|
curl -s -o /dev/null -w "%{http_code}" http://nginx-test/index.html
|
||||||
|
|
||||||
|
# Попытка path traversal
|
||||||
|
curl -s -o /dev/null -w "%{http_code}" http://nginx-test/../../../etc/passwd
|
||||||
|
```
|
||||||
|
- **Проверка признака выполнения:** Легитимный файл — 200; traversal — 404 (содержимое `/etc/passwd` не отдаётся).
|
||||||
|
|
||||||
|
24. **Проверяемое требование:** Контроль целостности
|
||||||
|
- **Настройка / механизм:** afick или иной механизм
|
||||||
|
- **Действия испытателя:** Настроить контроль целостности для конфигурации, web-root и модулей. Изменить контролируемый файл.
|
||||||
|
- **Ожидаемый результат:** Изменение обнаруживается механизмом контроля целостности.
|
||||||
|
- **Признак выполнения:** Средство контроля фиксирует нарушение целостности.
|
||||||
|
- Проверка:
|
||||||
|
- **Статус:** Требует внешних средств
|
||||||
|
- **Ревью мероприятия:** Мероприятие корректно. nginx не выполняет FIM; испытание относится к внешнему средству (afick, AIDE). В протоколе указать версию и конфигурацию FIM.
|
||||||
|
- **Источник:** https://nginx.org/en/docs/ (функция FIM в nginx не описана)
|
||||||
|
- **Пример конфигурации внешнего средства (afick):**
|
||||||
|
```
|
||||||
|
# /etc/afick.conf (фрагмент)
|
||||||
|
/etc/nginx/ R
|
||||||
|
/var/www/ R
|
||||||
|
/usr/lib/nginx/modules/ R
|
||||||
|
```
|
||||||
|
- **Примеры команд испытания:**
|
||||||
|
```bash
|
||||||
|
# Базовая проверка (без изменений)
|
||||||
|
afick -c /etc/afick.conf --check
|
||||||
|
|
||||||
|
# Изменить контролируемый файл
|
||||||
|
echo "# test change" >> /etc/nginx/nginx.conf
|
||||||
|
|
||||||
|
# Повторная проверка
|
||||||
|
afick -c /etc/afick.conf --check
|
||||||
|
```
|
||||||
|
- **Проверка признака выполнения:** Отчёт afick содержит запись об изменении `/etc/nginx/nginx.conf`. После испытания восстановить файл из эталона.
|
||||||
|
- **Примечание:** Не относится к функциям nginx; включается в ПМИ как проектное/инфраструктурное мероприятие. Статус отражает внешнюю меру. См. `Контроль целостности хранимого кода и конфигурации — проверка.md` (весь документ); функции 9.3 в `функции безопасности — проверка.md`; `Контроль выполнения кода — проверка.md` п. 15–16.
|
||||||
547
docs/Требования_безопасности_для_включения_в_ТУ_—_проверка.md
Normal file
547
docs/Требования_безопасности_для_включения_в_ТУ_—_проверка.md
Normal file
@@ -0,0 +1,547 @@
|
|||||||
|
# Требования безопасности для включения в ТУ — результаты проверки
|
||||||
|
|
||||||
|
**Дата проверки:** 10.06.2026
|
||||||
|
**Объект проверки:** upstream nginx (официальная документация nginx.org)
|
||||||
|
**Метод:** анализ официальной документации, примеры конфигурации и вывод о пригодности требований для включения в ТУ (без практических тестов на работающем экземпляре)
|
||||||
|
|
||||||
|
## Сводная таблица
|
||||||
|
|
||||||
|
| № | Требование | Статус | Механизм nginx |
|
||||||
|
|---|------------|--------|----------------|
|
||||||
|
| 1 | Ограничение доступа по IP-адресу | Подтверждено | ngx_http_access_module; allow; deny |
|
||||||
|
| 2 | Аутентификация по имени пользователя и паролю | Подтверждено | ngx_http_auth_basic_module |
|
||||||
|
| 3 | Аутентификация по клиентскому TLS-сертификату | Подтверждено с оговорками | ngx_http_ssl_module |
|
||||||
|
| 4 | Авторизация через внешний сервис | Подтверждено с оговорками | ngx_http_auth_request_module |
|
||||||
|
| 5 | Комбинирование механизмов доступа | Подтверждено | satisfy |
|
||||||
|
| 6 | Разграничение доступа по URL и виртуальным серверам | Подтверждено | server; location |
|
||||||
|
| 7 | Ограничение HTTP-методов | Подтверждено | limit_except |
|
||||||
|
| 8 | Запрет прямого доступа к внутренним ресурсам | Подтверждено | internal |
|
||||||
|
| 9 | Защита соединения с использованием TLS | Подтверждено с оговорками | ngx_http_ssl_module |
|
||||||
|
| 10 | Ограничение версий TLS и наборов шифров | Подтверждено | ssl_protocols; ssl_ciphers |
|
||||||
|
| 11 | Принудительное использование HTTPS | Подтверждено | return; add_header (HSTS) |
|
||||||
|
| 12 | Журналирование HTTP-запросов | Подтверждено | access_log; log_format |
|
||||||
|
| 13 | Журналирование ошибок | Подтверждено | error_log |
|
||||||
|
| 14 | Передача журналов во внешнюю систему | Подтверждено | syslog |
|
||||||
|
| 15 | Ограничение частоты запросов | Подтверждено | ngx_http_limit_req_module |
|
||||||
|
| 16 | Ограничение количества соединений | Подтверждено | ngx_http_limit_conn_module |
|
||||||
|
| 17 | Ограничение размера клиентского запроса | Подтверждено | client_max_body_size |
|
||||||
|
| 18 | Настройка таймаутов соединений | Подтверждено | client_*_timeout; send_timeout; keepalive_timeout |
|
||||||
|
| 19 | Сокрытие версии веб-сервера | Подтверждено | server_tokens off |
|
||||||
|
| 20 | Управление страницами ошибок | Подтверждено | error_page |
|
||||||
|
| 21 | Управление листингом директорий | Подтверждено | autoindex off |
|
||||||
|
| 22 | Обратное проксирование backend-сервисов | Подтверждено | proxy_pass; proxy_set_header |
|
||||||
|
| 23 | Управление директориями веб-контента | Подтверждено | root; alias; location; try_files |
|
||||||
|
| 24 | Минимизация поверхности атаки | Подтверждено с оговорками | configure; load_module; конфигурация |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
1. **Ограничение доступа по IP-адресу**
|
||||||
|
- Требование для ТУ: Веб-сервер должен обеспечивать возможность ограничения доступа к защищаемым ресурсам по IP-адресу клиента.
|
||||||
|
- Механизм nginx: ngx_http_access_module; allow; deny
|
||||||
|
- Комментарий: Проверяется через настройку разрешённых и запрещённых IP-адресов.
|
||||||
|
- Проверка:
|
||||||
|
- **Статус:** Подтверждено
|
||||||
|
- **Ревью требования:** Формулировка требования согласуется с возможностями nginx.
|
||||||
|
- **Вывод для ТУ:** Требование может быть включено в ТУ — nginx обеспечивает ограничение доступа по IP-адресу клиента.
|
||||||
|
- **Источник:** https://nginx.org/en/docs/http/ngx_http_access_module.html
|
||||||
|
- **Результат:** Модуль `ngx_http_access_module` входит в стандартную сборку nginx. Директивы `allow` и `deny` позволяют задавать правила доступа по IP-адресу, сети CIDR или `all`, что полностью соответствует формулировке требования.
|
||||||
|
- **Пример конфигурации:**
|
||||||
|
```nginx
|
||||||
|
location /admin/ {
|
||||||
|
allow 192.168.1.0/24;
|
||||||
|
allow 10.0.0.1;
|
||||||
|
deny all;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
2. **Аутентификация по имени пользователя и паролю**
|
||||||
|
- Требование для ТУ: Веб-сервер должен обеспечивать возможность аутентификации пользователей по имени пользователя и паролю при доступе к защищаемым ресурсам.
|
||||||
|
- Механизм nginx: ngx_http_auth_basic_module; auth_basic; auth_basic_user_file
|
||||||
|
- Комментарий: Реализуется через HTTP Basic Authentication.
|
||||||
|
- Проверка:
|
||||||
|
- **Статус:** Подтверждено
|
||||||
|
- **Ревью требования:** Формулировка требования согласуется с возможностями nginx.
|
||||||
|
- **Вывод для ТУ:** Требование может быть включено в ТУ — nginx поддерживает аутентификацию по имени пользователя и паролю.
|
||||||
|
- **Источник:** https://nginx.org/en/docs/http/ngx_http_auth_basic_module.html
|
||||||
|
- **Результат:** Модуль `ngx_http_auth_basic_module` реализует HTTP Basic Authentication. Директивы `auth_basic` и `auth_basic_user_file` обеспечивают проверку учётных данных пользователя при доступе к защищаемым ресурсам.
|
||||||
|
- **Пример конфигурации:**
|
||||||
|
```nginx
|
||||||
|
location /secure/ {
|
||||||
|
auth_basic "Restricted Area";
|
||||||
|
auth_basic_user_file /etc/nginx/htpasswd;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
3. **Аутентификация по клиентскому TLS-сертификату**
|
||||||
|
- Требование для ТУ: Веб-сервер должен обеспечивать возможность проверки клиентского TLS-сертификата при доступе к защищаемым ресурсам.
|
||||||
|
- Механизм nginx: ngx_http_ssl_module; ssl_client_certificate; ssl_verify_client
|
||||||
|
- Комментарий: Применяется при использовании HTTPS и доверенного центра сертификации.
|
||||||
|
- Проверка:
|
||||||
|
- **Статус:** Подтверждено с оговорками
|
||||||
|
- **Ревью требования:** Описание и механизм в целом адекватны; учтены оговорки сборки, конфигурации или эксплуатации.
|
||||||
|
- **Вывод для ТУ:** Требование может быть включено в ТУ — nginx обеспечивает проверку клиентского TLS-сертификата при использовании HTTPS.
|
||||||
|
- **Источник:** https://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_verify_client
|
||||||
|
- **Результат:** Модуль `ngx_http_ssl_module` поддерживает проверку клиентских сертификатов через `ssl_verify_client` и `ssl_client_certificate`. Требуется сборка с SSL-модулем и настроенный HTTPS.
|
||||||
|
- **Пример конфигурации:**
|
||||||
|
```nginx
|
||||||
|
server {
|
||||||
|
listen 443 ssl;
|
||||||
|
ssl_certificate /etc/nginx/ssl/server.crt;
|
||||||
|
ssl_certificate_key /etc/nginx/ssl/server.key;
|
||||||
|
ssl_client_certificate /etc/nginx/ssl/ca.crt;
|
||||||
|
ssl_verify_client on;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
- **Примечание:** В ТУ следует указать требование наличия SSL-модуля и доверенного CA.
|
||||||
|
|
||||||
|
4. **Авторизация через внешний сервис**
|
||||||
|
- Требование для ТУ: Веб-сервер должен обеспечивать возможность принятия решения о доступе на основании ответа внешнего сервиса авторизации.
|
||||||
|
- Механизм nginx: ngx_http_auth_request_module; auth_request
|
||||||
|
- Комментарий: Наличие модуля зависит от состава сборки nginx.
|
||||||
|
- Проверка:
|
||||||
|
- **Статус:** Подтверждено с оговорками
|
||||||
|
- **Ревью требования:** Описание и механизм в целом адекватны; учтены оговорки сборки, конфигурации или эксплуатации.
|
||||||
|
- **Вывод для ТУ:** Требование может быть включено в ТУ при условии наличия модуля `auth_request` в поставке nginx.
|
||||||
|
- **Источник:** https://nginx.org/en/docs/http/ngx_http_auth_request_module.html
|
||||||
|
- **Результат:** Модуль `ngx_http_auth_request_module` выполняет подзапрос к внешнему сервису авторизации и разрешает или запрещает доступ по коду ответа (2xx — разрешено, 401/403 — запрещено). Состав сборки nginx должен быть зафиксирован в ТУ.
|
||||||
|
- **Пример конфигурации:**
|
||||||
|
```nginx
|
||||||
|
location = /auth {
|
||||||
|
internal;
|
||||||
|
proxy_pass http://auth-service:8080/validate;
|
||||||
|
proxy_pass_request_body off;
|
||||||
|
proxy_set_header Content-Length "";
|
||||||
|
}
|
||||||
|
|
||||||
|
location / {
|
||||||
|
auth_request /auth;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
- **Примечание:** В ТУ указать требование включения `--with-http_auth_request_module` или подтверждение наличия модуля в дистрибутивном пакете.
|
||||||
|
|
||||||
|
5. **Комбинирование механизмов доступа**
|
||||||
|
- Требование для ТУ: Веб-сервер должен обеспечивать возможность совместного применения нескольких механизмов контроля доступа.
|
||||||
|
- Механизм nginx: satisfy; allow; deny; auth_basic; auth_request
|
||||||
|
- Комментарий: Например, доступ по IP или по паролю.
|
||||||
|
- Проверка:
|
||||||
|
- **Статус:** Подтверждено
|
||||||
|
- **Ревью требования:** Формулировка требования согласуется с возможностями nginx.
|
||||||
|
- **Вывод для ТУ:** Требование может быть включено в ТУ — nginx позволяет комбинировать механизмы контроля доступа.
|
||||||
|
- **Источник:** https://nginx.org/en/docs/http/ngx_http_core_module.html#satisfy
|
||||||
|
- **Результат:** Директива `satisfy` управляет логикой совместного применения `allow`/`deny`, `auth_basic` и `auth_request`. Значение `any` позволяет доступ при успехе любой проверки; `all` — при успехе всех.
|
||||||
|
- **Пример конфигурации:**
|
||||||
|
```nginx
|
||||||
|
location /admin/ {
|
||||||
|
satisfy any;
|
||||||
|
allow 10.0.0.0/8;
|
||||||
|
deny all;
|
||||||
|
auth_basic "Admin";
|
||||||
|
auth_basic_user_file /etc/nginx/htpasswd;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
6. **Разграничение доступа по URL и виртуальным серверам**
|
||||||
|
- Требование для ТУ: Веб-сервер должен обеспечивать возможность задания разных правил доступа для разных виртуальных серверов и разделов сайта.
|
||||||
|
- Механизм nginx: server; location
|
||||||
|
- Комментарий: Используется для разделения публичных, служебных и закрытых ресурсов.
|
||||||
|
- Проверка:
|
||||||
|
- **Статус:** Подтверждено
|
||||||
|
- **Ревью требования:** Формулировка требования согласуется с возможностями nginx.
|
||||||
|
- **Вывод для ТУ:** Требование может быть включено в ТУ — nginx поддерживает разграничение по виртуальным серверам и URL.
|
||||||
|
- **Источник:** https://nginx.org/en/docs/http/ngx_http_core_module.html#server , https://nginx.org/en/docs/http/ngx_http_core_module.html#location
|
||||||
|
- **Результат:** Блоки `server` определяют виртуальные хосты, блоки `location` — правила для URI-путей. Это базовый механизм nginx для задания разных правил доступа на разных серверах и разделах сайта.
|
||||||
|
- **Пример конфигурации:**
|
||||||
|
```nginx
|
||||||
|
server {
|
||||||
|
listen 80;
|
||||||
|
server_name public.example.com;
|
||||||
|
location / { root /var/www/public; }
|
||||||
|
}
|
||||||
|
|
||||||
|
server {
|
||||||
|
listen 80;
|
||||||
|
server_name admin.example.com;
|
||||||
|
location / {
|
||||||
|
allow 10.0.0.0/8;
|
||||||
|
deny all;
|
||||||
|
root /var/www/admin;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
7. **Ограничение HTTP-методов**
|
||||||
|
- Требование для ТУ: Веб-сервер должен обеспечивать возможность ограничения использования HTTP-методов для защищаемых ресурсов.
|
||||||
|
- Механизм nginx: limit_except
|
||||||
|
- Комментарий: Позволяет ограничивать методы PUT, DELETE и другие методы, если они не требуются.
|
||||||
|
- Проверка:
|
||||||
|
- **Статус:** Подтверждено
|
||||||
|
- **Ревью требования:** Формулировка требования согласуется с возможностями nginx.
|
||||||
|
- **Вывод для ТУ:** Требование может быть включено в ТУ — nginx позволяет ограничивать HTTP-методы.
|
||||||
|
- **Источник:** https://nginx.org/en/docs/http/ngx_http_core_module.html#limit_except
|
||||||
|
- **Результат:** Директива `limit_except` задаёт методы, для которых применяются вложенные правила доступа. Методы, не перечисленные в блоке, обрабатываются без дополнительных ограничений.
|
||||||
|
- **Пример конфигурации:**
|
||||||
|
```nginx
|
||||||
|
location /uploads/ {
|
||||||
|
limit_except GET HEAD {
|
||||||
|
deny all;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
- **Минимальный аудит конфигурации:**
|
||||||
|
```bash
|
||||||
|
nginx -T 2>/dev/null | grep -E 'limit_except|request_method'
|
||||||
|
```
|
||||||
|
- **Примечание:** См. `Минимизация поверхности атаки nginx — проверка.md` п. 11; `Проверочные мероприятия для ПМИ — проверка.md` п. 7.
|
||||||
|
|
||||||
|
8. **Запрет прямого доступа к внутренним ресурсам**
|
||||||
|
- Требование для ТУ: Веб-сервер должен обеспечивать возможность запрета прямого доступа пользователя к внутренним ресурсам.
|
||||||
|
- Механизм nginx: internal
|
||||||
|
- Комментарий: Внутренние location-блоки доступны только для внутренних перенаправлений.
|
||||||
|
- Проверка:
|
||||||
|
- **Статус:** Подтверждено
|
||||||
|
- **Ревью требования:** Формулировка требования согласуется с возможностями nginx.
|
||||||
|
- **Вывод для ТУ:** Требование может быть включено в ТУ — nginx обеспечивает запрет прямого доступа к внутренним ресурсам.
|
||||||
|
- **Источник:** https://nginx.org/en/docs/http/ngx_http_core_module.html#internal
|
||||||
|
- **Результат:** Директива `internal` ограничивает доступ к location только для внутренних запросов (error_page, rewrite, X-Accel-Redirect и др.). Прямые клиентские запросы возвращают 404.
|
||||||
|
- **Пример конфигурации:**
|
||||||
|
```nginx
|
||||||
|
location /protected/ {
|
||||||
|
internal;
|
||||||
|
alias /var/data/files/;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
9. **Защита соединения с использованием TLS**
|
||||||
|
- Требование для ТУ: Веб-сервер должен обеспечивать возможность защиты сетевого соединения с использованием TLS.
|
||||||
|
- Механизм nginx: ngx_http_ssl_module; ssl_certificate; ssl_certificate_key
|
||||||
|
- Комментарий: Используется для HTTPS-соединений.
|
||||||
|
- Проверка:
|
||||||
|
- **Статус:** Подтверждено с оговорками
|
||||||
|
- **Ревью требования:** Описание и механизм в целом адекватны; учтены оговорки сборки, конфигурации или эксплуатации. Модуль `ngx_http_ssl_module` обеспечивает HTTPS через `ssl_certificate` и `ssl_certificate_key`.
|
||||||
|
- **Вывод для ТУ:** Требование может быть включено в ТУ — nginx обеспечивает защиту соединения с использованием TLS.
|
||||||
|
- **Источник:** https://nginx.org/en/docs/http/ngx_http_ssl_module.html
|
||||||
|
- **Результат:** Модуль `ngx_http_ssl_module` обеспечивает HTTPS через `ssl_certificate` и `ssl_certificate_key`. Требуется сборка с `--with-http_ssl_module` и библиотека OpenSSL.
|
||||||
|
- **Пример конфигурации:**
|
||||||
|
```nginx
|
||||||
|
server {
|
||||||
|
listen 443 ssl;
|
||||||
|
server_name example.com;
|
||||||
|
ssl_certificate /etc/nginx/ssl/example.com.crt;
|
||||||
|
ssl_certificate_key /etc/nginx/ssl/example.com.key;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
10. **Ограничение версий TLS и наборов шифров**
|
||||||
|
- Требование для ТУ: Веб-сервер должен обеспечивать возможность задания допустимых версий TLS и наборов шифров.
|
||||||
|
- Механизм nginx: ssl_protocols; ssl_ciphers
|
||||||
|
- Комментарий: Конкретные допустимые значения должны определяться политикой безопасности.
|
||||||
|
- Проверка:
|
||||||
|
- **Статус:** Подтверждено
|
||||||
|
- **Ревью требования:** Формулировка требования согласуется с возможностями nginx. Директивы `ssl_protocols` и `ssl_ciphers` позволяют ограничить версии протокола и наборы шифров.
|
||||||
|
- **Вывод для ТУ:** Требование может быть включено в ТУ — nginx позволяет задавать допустимые версии TLS и шифры; конкретные значения фиксируются в политике безопасности ТУ.
|
||||||
|
- **Источник:** https://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_protocols , https://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_ciphers
|
||||||
|
- **Результат:** Директивы `ssl_protocols` и `ssl_ciphers` позволяют ограничить версии протокола и наборы шифров. Формулировка требования ТУ корректна: nginx обеспечивает возможность задания, а конкретные значения определяются политикой.
|
||||||
|
- **Минимальный аудит конфигурации:**
|
||||||
|
```bash
|
||||||
|
nginx -T 2>/dev/null | grep -E 'limit_except|request_method'
|
||||||
|
```
|
||||||
|
- **Пример конфигурации:**
|
||||||
|
```nginx
|
||||||
|
ssl_protocols TLSv1.2 TLSv1.3;
|
||||||
|
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256;
|
||||||
|
ssl_prefer_server_ciphers on;
|
||||||
|
```
|
||||||
|
- **Примечание:** В ТУ отдельно зафиксировать допустимую криптографическую политику (версии TLS, список шифров). См. `Минимизация поверхности атаки nginx — проверка.md` п. 11; `Проверочные мероприятия для ПМИ — проверка.md` п. 7.
|
||||||
|
|
||||||
|
11. **Принудительное использование HTTPS**
|
||||||
|
- Требование для ТУ: Веб-сервер должен обеспечивать возможность перенаправления HTTP-запросов на HTTPS.
|
||||||
|
- Механизм nginx: return 301/308; Strict-Transport-Security
|
||||||
|
- Комментарий: HSTS реализуется через HTTP-заголовок.
|
||||||
|
- Проверка:
|
||||||
|
- **Статус:** Подтверждено
|
||||||
|
- **Ревью требования:** Формулировка требования согласуется с возможностями nginx. Редирект HTTP→HTTPS реализуется директивой `return 301` или `308`.
|
||||||
|
- **Вывод для ТУ:** Требование может быть включено в ТУ — nginx обеспечивает перенаправление HTTP на HTTPS и заголовок HSTS.
|
||||||
|
- **Источник:** https://nginx.org/en/docs/http/ngx_http_rewrite_module.html#return , https://nginx.org/en/docs/http/ngx_http_headers_module.html#add_header
|
||||||
|
- **Результат:** Редирект HTTP→HTTPS реализуется директивой `return 301` или `308`. Заголовок `Strict-Transport-Security` добавляется через `add_header` в HTTPS-блоке.
|
||||||
|
- **Пример конфигурации:**
|
||||||
|
```nginx
|
||||||
|
server {
|
||||||
|
listen 80;
|
||||||
|
server_name example.com;
|
||||||
|
return 301 https://$host$request_uri;
|
||||||
|
}
|
||||||
|
|
||||||
|
server {
|
||||||
|
listen 443 ssl;
|
||||||
|
server_name example.com;
|
||||||
|
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
12. **Журналирование HTTP-запросов**
|
||||||
|
- Требование для ТУ: Веб-сервер должен обеспечивать регистрацию HTTP-запросов пользователей.
|
||||||
|
- Механизм nginx: access_log; log_format
|
||||||
|
- Комментарий: В журнале должны фиксироваться параметры, необходимые для анализа событий.
|
||||||
|
- Проверка:
|
||||||
|
- **Статус:** Подтверждено
|
||||||
|
- **Ревью требования:** Формулировка требования согласуется с возможностями nginx. Модуль `ngx_http_log_module` записывает access log.
|
||||||
|
- **Вывод для ТУ:** Требование может быть включено в ТУ — nginx обеспечивает регистрацию HTTP-запросов в настраиваемом формате.
|
||||||
|
- **Источник:** https://nginx.org/en/docs/http/ngx_http_log_module.html
|
||||||
|
- **Результат:** Модуль `ngx_http_log_module` записывает access log. Директива `log_format` позволяет задать поля, необходимые для анализа событий безопасности (IP, время, запрос, статус, user-agent и др.).
|
||||||
|
- **Пример конфигурации:**
|
||||||
|
```nginx
|
||||||
|
log_format security '$remote_addr - $remote_user [$time_local] '
|
||||||
|
'"$request" $status $body_bytes_sent '
|
||||||
|
'"$http_referer" "$http_user_agent"';
|
||||||
|
|
||||||
|
access_log /var/log/nginx/access.log security;
|
||||||
|
```
|
||||||
|
|
||||||
|
13. **Журналирование ошибок**
|
||||||
|
- Требование для ТУ: Веб-сервер должен обеспечивать регистрацию ошибок обработки запросов и ошибок конфигурации.
|
||||||
|
- Механизм nginx: error_log
|
||||||
|
- Комментарий: Используется для диагностики и анализа событий безопасности.
|
||||||
|
- Проверка:
|
||||||
|
- **Статус:** Подтверждено
|
||||||
|
- **Ревью требования:** Формулировка требования согласуется с возможностями nginx. Директива `error_log` задаёт файл журнала и уровень детализации (`warn`, `error`, `crit` и др.
|
||||||
|
- **Вывод для ТУ:** Требование может быть включено в ТУ — nginx обеспечивает регистрацию ошибок.
|
||||||
|
- **Источник:** https://nginx.org/en/docs/ngx_core_module.html#error_log
|
||||||
|
- **Результат:** Директива `error_log` задаёт файл журнала и уровень детализации (`warn`, `error`, `crit` и др.). Ошибки обработки запросов, конфигурации и взаимодействия с backend фиксируются в error log.
|
||||||
|
- **Пример конфигурации:**
|
||||||
|
```nginx
|
||||||
|
error_log /var/log/nginx/error.log warn;
|
||||||
|
```
|
||||||
|
|
||||||
|
14. **Передача журналов во внешнюю систему**
|
||||||
|
- Требование для ТУ: Веб-сервер должен обеспечивать возможность передачи журналов во внешнюю систему журналирования.
|
||||||
|
- Механизм nginx: syslog в access_log/error_log
|
||||||
|
- Комментарий: Используется для централизованного сбора событий.
|
||||||
|
- Проверка:
|
||||||
|
- **Статус:** Подтверждено
|
||||||
|
- **Ревью требования:** Формулировка требования согласуется с возможностями nginx. nginx поддерживает запись `access_log` и `error_log` в syslog с параметрами `server`, `facility`, `tag`, `severity`, что обеспечивает централизованный сбор событий во внешней системе журналирования.
|
||||||
|
- **Вывод для ТУ:** Требование может быть включено в ТУ — nginx поддерживает передачу журналов в syslog.
|
||||||
|
- **Источник:** https://nginx.org/en/docs/syslog.html
|
||||||
|
- **Результат:** nginx поддерживает запись `access_log` и `error_log` в syslog с параметрами `server`, `facility`, `tag`, `severity`, что обеспечивает централизованный сбор событий во внешней системе журналирования.
|
||||||
|
- **Пример конфигурации:**
|
||||||
|
```nginx
|
||||||
|
error_log syslog:server=192.168.1.1:514,facility=local7,tag=nginx,severity=error;
|
||||||
|
access_log syslog:server=192.168.1.1:514,facility=local7,tag=nginx,severity=info security;
|
||||||
|
```
|
||||||
|
|
||||||
|
15. **Ограничение частоты запросов**
|
||||||
|
- Требование для ТУ: Веб-сервер должен обеспечивать возможность ограничения частоты запросов от клиента.
|
||||||
|
- Механизм nginx: limit_req_zone; limit_req
|
||||||
|
- Комментарий: Снижает риск избыточной нагрузки и злоупотреблений.
|
||||||
|
- Проверка:
|
||||||
|
- **Статус:** Подтверждено
|
||||||
|
- **Ревью требования:** Формулировка требования согласуется с возможностями nginx. Модуль `ngx_http_limit_req_module` реализует ограничение частоты запросов по ключу (например, IP-адрес клиента) с использованием алгоритма leaky bucket.
|
||||||
|
- **Вывод для ТУ:** Требование может быть включено в ТУ — nginx обеспечивает ограничение частоты запросов.
|
||||||
|
- **Источник:** https://nginx.org/en/docs/http/ngx_http_limit_req_module.html
|
||||||
|
- **Результат:** Модуль `ngx_http_limit_req_module` реализует ограничение частоты запросов по ключу (например, IP-адрес клиента) с использованием алгоритма leaky bucket.
|
||||||
|
- **Пример конфигурации:**
|
||||||
|
```nginx
|
||||||
|
http {
|
||||||
|
limit_req_zone $binary_remote_addr zone=one:10m rate=10r/s;
|
||||||
|
|
||||||
|
server {
|
||||||
|
location / {
|
||||||
|
limit_req zone=one burst=20 nodelay;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
16. **Ограничение количества соединений**
|
||||||
|
- Требование для ТУ: Веб-сервер должен обеспечивать возможность ограничения количества одновременных соединений.
|
||||||
|
- Механизм nginx: limit_conn_zone; limit_conn
|
||||||
|
- Комментарий: Снижает риск исчерпания ресурсов.
|
||||||
|
- Проверка:
|
||||||
|
- **Статус:** Подтверждено
|
||||||
|
- **Ревью требования:** Формулировка требования согласуется с возможностями nginx. Модуль `ngx_http_limit_conn_module` ограничивает число одновременных соединений по заданному ключу, что соответствует требованию ТУ.
|
||||||
|
- **Вывод для ТУ:** Требование может быть включено в ТУ — nginx обеспечивает ограничение количества соединений.
|
||||||
|
- **Источник:** https://nginx.org/en/docs/http/ngx_http_limit_conn_module.html
|
||||||
|
- **Результат:** Модуль `ngx_http_limit_conn_module` ограничивает число одновременных соединений по заданному ключу, что соответствует требованию ТУ.
|
||||||
|
- **Пример конфигурации:**
|
||||||
|
```nginx
|
||||||
|
http {
|
||||||
|
limit_conn_zone $binary_remote_addr zone=addr:10m;
|
||||||
|
|
||||||
|
server {
|
||||||
|
location / {
|
||||||
|
limit_conn addr 10;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
17. **Ограничение размера клиентского запроса**
|
||||||
|
- Требование для ТУ: Веб-сервер должен обеспечивать возможность ограничения размера тела клиентского запроса.
|
||||||
|
- Механизм nginx: client_max_body_size
|
||||||
|
- Комментарий: Используется для защиты от чрезмерно больших запросов и нежелательных загрузок.
|
||||||
|
- Проверка:
|
||||||
|
- **Статус:** Подтверждено
|
||||||
|
- **Ревью требования:** Формулировка требования согласуется с возможностями nginx. Директива `client_max_body_size` задаёт максимальный размер тела запроса.
|
||||||
|
- **Вывод для ТУ:** Требование может быть включено в ТУ — nginx обеспечивает ограничение размера тела запроса.
|
||||||
|
- **Источник:** https://nginx.org/en/docs/http/ngx_http_core_module.html#client_max_body_size
|
||||||
|
- **Результат:** Директива `client_max_body_size` задаёт максимальный размер тела запроса. При превышении nginx возвращает 413 (Request Entity Too Large).
|
||||||
|
- **Пример конфигурации:**
|
||||||
|
```nginx
|
||||||
|
server {
|
||||||
|
client_max_body_size 10m;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
18. **Настройка таймаутов соединений**
|
||||||
|
- Требование для ТУ: Веб-сервер должен обеспечивать возможность настройки таймаутов обработки клиентских соединений.
|
||||||
|
- Механизм nginx: client_header_timeout; client_body_timeout; send_timeout; keepalive_timeout
|
||||||
|
- Комментарий: Снижает риск удержания ресурсов медленными соединениями.
|
||||||
|
- Проверка:
|
||||||
|
- **Статус:** Подтверждено
|
||||||
|
- **Ревью требования:** Формулировка требования согласуется с возможностями nginx. Директивы `client_header_timeout`, `client_body_timeout`, `send_timeout` и `keepalive_timeout` позволяют задавать таймауты на разных этапах обработки клиентского соединения.
|
||||||
|
- **Вывод для ТУ:** Требование может быть включено в ТУ — nginx обеспечивает настройку таймаутов соединений.
|
||||||
|
- **Источник:** https://nginx.org/en/docs/http/ngx_http_core_module.html
|
||||||
|
- **Результат:** Директивы `client_header_timeout`, `client_body_timeout`, `send_timeout` и `keepalive_timeout` позволяют задавать таймауты на разных этапах обработки клиентского соединения.
|
||||||
|
- **Пример конфигурации:**
|
||||||
|
```nginx
|
||||||
|
http {
|
||||||
|
client_header_timeout 10s;
|
||||||
|
client_body_timeout 10s;
|
||||||
|
send_timeout 10s;
|
||||||
|
keepalive_timeout 30s;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
19. **Сокрытие версии веб-сервера**
|
||||||
|
- Требование для ТУ: Веб-сервер должен обеспечивать возможность отключения раскрытия версии nginx в ответах сервера.
|
||||||
|
- Механизм nginx: server_tokens off
|
||||||
|
- Комментарий: Снижает объём информации, доступной внешнему пользователю.
|
||||||
|
- Проверка:
|
||||||
|
- **Статус:** Подтверждено
|
||||||
|
- **Ревью требования:** Формулировка требования согласуется с возможностями nginx. Директива `server_tokens off` убирает номер версии из заголовка `Server` и со страниц ошибок nginx.
|
||||||
|
- **Вывод для ТУ:** Требование может быть включено в ТУ — nginx позволяет отключить раскрытие версии.
|
||||||
|
- **Источник:** https://nginx.org/en/docs/http/ngx_http_core_module.html#server_tokens
|
||||||
|
- **Результат:** Директива `server_tokens off` убирает номер версии из заголовка `Server` и со страниц ошибок nginx.
|
||||||
|
- **Минимальный аудит конфигурации:**
|
||||||
|
```bash
|
||||||
|
nginx -T 2>/dev/null | grep server_tokens
|
||||||
|
```
|
||||||
|
- **Пример конфигурации:**
|
||||||
|
```nginx
|
||||||
|
http {
|
||||||
|
server_tokens off;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
20. **Управление страницами ошибок**
|
||||||
|
- Требование для ТУ: Веб-сервер должен обеспечивать возможность настройки пользовательских страниц ошибок.
|
||||||
|
- Механизм nginx: error_page
|
||||||
|
- Комментарий: Позволяет не раскрывать технические детали пользователю.
|
||||||
|
- Проверка:
|
||||||
|
- **Статус:** Подтверждено
|
||||||
|
- **Ревью требования:** Формулировка требования согласуется с возможностями nginx. Директива `error_page` перенаправляет обработку указанных кодов ошибок на пользовательские страницы, скрывая технические детали nginx.
|
||||||
|
- **Вывод для ТУ:** Требование может быть включено в ТУ — nginx обеспечивает настройку пользовательских страниц ошибок.
|
||||||
|
- **Источник:** https://nginx.org/en/docs/http/ngx_http_core_module.html#error_page
|
||||||
|
- **Результат:** Директива `error_page` перенаправляет обработку указанных кодов ошибок на пользовательские страницы, скрывая технические детали nginx.
|
||||||
|
- **Пример конфигурации:**
|
||||||
|
```nginx
|
||||||
|
error_page 404 /custom_404.html;
|
||||||
|
error_page 500 502 503 504 /custom_50x.html;
|
||||||
|
|
||||||
|
location = /custom_404.html {
|
||||||
|
root /var/www/errors;
|
||||||
|
internal;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
21. **Управление листингом директорий**
|
||||||
|
- Требование для ТУ: Веб-сервер должен обеспечивать возможность отключения листинга директорий.
|
||||||
|
- Механизм nginx: autoindex off
|
||||||
|
- Комментарий: В безопасной конфигурации листинг директорий должен быть отключён, если не требуется.
|
||||||
|
- Проверка:
|
||||||
|
- **Статус:** Подтверждено
|
||||||
|
- **Ревью требования:** Формулировка требования согласуется с возможностями nginx. По умолчанию `autoindex off`. Директива `autoindex off` явно отключает формирование листинга каталога, что соответствует требованию безопасной конфигурации.
|
||||||
|
- **Вывод для ТУ:** Требование может быть включено в ТУ — nginx позволяет отключить листинг директорий.
|
||||||
|
- **Источник:** https://nginx.org/en/docs/http/ngx_http_autoindex_module.html
|
||||||
|
- **Результат:** По умолчанию `autoindex off`. Директива `autoindex off` явно отключает формирование листинга каталога, что соответствует требованию безопасной конфигурации.
|
||||||
|
- **Минимальный аудит конфигурации:**
|
||||||
|
```bash
|
||||||
|
nginx -T 2>/dev/null | grep autoindex
|
||||||
|
```
|
||||||
|
- **Пример конфигурации:**
|
||||||
|
```nginx
|
||||||
|
server {
|
||||||
|
autoindex off;
|
||||||
|
root /var/www/html;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
- **Примечание:** См. `Минимизация поверхности атаки nginx — проверка.md` п. 10; `Проверочные мероприятия для ПМИ — проверка.md` п. 21.
|
||||||
|
|
||||||
|
22. **Обратное проксирование backend-сервисов**
|
||||||
|
- Требование для ТУ: Веб-сервер должен обеспечивать возможность изоляции backend-сервисов через обратное проксирование.
|
||||||
|
- Механизм nginx: proxy_pass; proxy_set_header
|
||||||
|
- Комментарий: Backend-сервисы не должны быть доступны напрямую, если это предусмотрено архитектурой.
|
||||||
|
- Проверка:
|
||||||
|
- **Статус:** Подтверждено
|
||||||
|
- **Ревью требования:** Формулировка требования согласуется с возможностями nginx. Модуль `ngx_http_proxy_module` передаёт запросы на внутренние backend-сервисы.
|
||||||
|
- **Вывод для ТУ:** Требование может быть включено в ТУ — nginx обеспечивает изоляцию backend через обратное проксирование.
|
||||||
|
- **Источник:** https://nginx.org/en/docs/http/ngx_http_proxy_module.html
|
||||||
|
- **Результат:** Модуль `ngx_http_proxy_module` передаёт запросы на внутренние backend-сервисы. `proxy_set_header` позволяет корректно передавать адрес клиента. Backend может быть недоступен напрямую извне при правильной сетевой архитектуре.
|
||||||
|
- **Пример конфигурации:**
|
||||||
|
```nginx
|
||||||
|
location /api/ {
|
||||||
|
proxy_pass http://127.0.0.1:8080;
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
23. **Управление директориями веб-контента**
|
||||||
|
- Требование для ТУ: Веб-сервер должен обеспечивать возможность задания разрешённых директорий веб-контента.
|
||||||
|
- Механизм nginx: root; alias; location; try_files
|
||||||
|
- Комментарий: Требует безопасной настройки, чтобы исключить доступ к произвольным каталогам ОС.
|
||||||
|
- Проверка:
|
||||||
|
- **Статус:** Подтверждено
|
||||||
|
- **Ревью требования:** Формулировка требования согласуется с возможностями nginx. Директивы `root`, `alias`, `location` и `try_files` позволяют ограничить область обслуживаемого контента.
|
||||||
|
- **Вывод для ТУ:** Требование может быть включено в ТУ — nginx позволяет задавать разрешённые директории веб-контента через конфигурацию.
|
||||||
|
- **Источник:** https://nginx.org/en/docs/http/ngx_http_core_module.html#root , https://nginx.org/en/docs/http/ngx_http_core_module.html#alias
|
||||||
|
- **Результат:** Директивы `root`, `alias`, `location` и `try_files` позволяют ограничить область обслуживаемого контента. Встроенного allowlist нет — перечень разрешённых директорий фиксируется в ТУ и реализуется конфигурацией.
|
||||||
|
- **Пример конфигурации:**
|
||||||
|
```nginx
|
||||||
|
server {
|
||||||
|
root /var/www/app/public;
|
||||||
|
|
||||||
|
location / {
|
||||||
|
try_files $uri =404;
|
||||||
|
}
|
||||||
|
|
||||||
|
location ~ /\. {
|
||||||
|
deny all;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
- **Примечание:** В ТУ зафиксировать перечень разрешённых директорий веб-контента. См. `Минимизация поверхности атаки nginx — проверка.md` п. 10; `Проверочные мероприятия для ПМИ — проверка.md` п. 21.
|
||||||
|
|
||||||
|
24. **Минимизация поверхности атаки**
|
||||||
|
- Требование для ТУ: Поставка и конфигурация веб-сервера должны обеспечивать возможность минимизации поверхности атаки за счёт исключения, отделения или незагрузки неиспользуемых модулей и функциональных возможностей.
|
||||||
|
- Механизм nginx: параметры сборки; dynamic modules; load_module; конфигурация nginx
|
||||||
|
- Комментарий: Конкретные меры определяются по составу поставки и целевой конфигурации.
|
||||||
|
- Проверка:
|
||||||
|
- **Статус:** Подтверждено с оговорками
|
||||||
|
- **Ревью требования:** Описание и механизм в целом адекватны; учтены оговорки сборки, конфигурации или эксплуатации. nginx позволяет исключать модули при сборке (`.
|
||||||
|
- **Вывод для ТУ:** Требование может быть включено в ТУ как проектно-эксплуатационное — nginx предоставляет механизмы минимизации поверхности атаки; конкретные меры фиксируются в ТУ по составу поставки.
|
||||||
|
- **Источник:** https://nginx.org/en/docs/configure.html , https://nginx.org/en/docs/ngx_core_module.html#load_module
|
||||||
|
- **Результат:** nginx позволяет исключать модули при сборке (`./configure --without-...`), не загружать неиспользуемые динамические модули (`load_module`) и отключать возможности конфигурацией (`autoindex off`, удаление лишних `location`). Конкретный перечень мер определяется целевой конфигурацией и должен быть зафиксирован в ТУ.
|
||||||
|
- **Пример конфигурации:**
|
||||||
|
```nginx
|
||||||
|
# Загрузка только утверждённых динамических модулей
|
||||||
|
# load_module modules/ngx_http_geoip_module.so;
|
||||||
|
|
||||||
|
http {
|
||||||
|
autoindex off;
|
||||||
|
server_tokens off;
|
||||||
|
# Неиспользуемые proxy/fastcgi-направления не включаются
|
||||||
|
}
|
||||||
|
```
|
||||||
|
- **Примечание:** В ТУ указать: состав модулей поставки, запрет загрузки неутверждённых `.so`, перечень отключённых возможностей конфигурации. См. `Минимизация поверхности атаки nginx — проверка.md` п. 1–15.
|
||||||
743
docs/функции безопасности — проверка.md
Normal file
743
docs/функции безопасности — проверка.md
Normal file
@@ -0,0 +1,743 @@
|
|||||||
|
# Функции безопасности nginx — результаты проверки
|
||||||
|
|
||||||
|
**Дата проверки:** 10.06.2026
|
||||||
|
**Объект проверки:** upstream nginx (официальная документация nginx.org)
|
||||||
|
**Метод:** анализ официальной документации и составление примеров конфигурации (без практических тестов на работающем экземпляре)
|
||||||
|
|
||||||
|
## Сводная таблица
|
||||||
|
|
||||||
|
| № | Функция безопасности | Статус | Модуль / механизм |
|
||||||
|
|---|---------------------|--------|-------------------|
|
||||||
|
| 1.1 | Ограничение доступа по IP-адресу | Подтверждено | ngx_http_access_module; allow; deny |
|
||||||
|
| 1.2 | Аутентификация по имени пользователя и паролю | Подтверждено | ngx_http_auth_basic_module; auth_basic; auth_basic_user_file |
|
||||||
|
| 1.3 | Аутентификация по клиентскому TLS-сертификату | Подтверждено с оговорками | ngx_http_ssl_module; ssl_verify_client |
|
||||||
|
| 1.4 | Авторизация через внешний сервис | Подтверждено с оговорками | ngx_http_auth_request_module; auth_request |
|
||||||
|
| 1.5 | Комбинирование нескольких проверок доступа | Подтверждено | satisfy; access; auth_basic; auth_request |
|
||||||
|
| 2.1 | Разделение правил по виртуальным серверам и путям | Подтверждено | ngx_http_core_module; server; location |
|
||||||
|
| 2.2 | Ограничение HTTP-методов | Подтверждено | ngx_http_core_module; limit_except |
|
||||||
|
| 2.3 | Запрет доступа к служебным и скрытым файлам | Подтверждено | location; deny all |
|
||||||
|
| 2.4 | Запрет прямого доступа к внутренним ресурсам | Подтверждено | ngx_http_core_module; internal |
|
||||||
|
| 3.1 | Поддержка HTTPS/TLS | Подтверждено с оговорками | ngx_http_ssl_module; ssl_certificate |
|
||||||
|
| 3.2 | Ограничение версий TLS и шифров | Подтверждено | ngx_http_ssl_module; ssl_protocols; ssl_ciphers |
|
||||||
|
| 3.3 | Проверка клиентского сертификата | Подтверждено | ssl_client_certificate; ssl_verify_client |
|
||||||
|
| 3.4 | Принудительное использование HTTPS | Подтверждено | return 301/308; Strict-Transport-Security |
|
||||||
|
| 4.1 | Журналирование HTTP-запросов | Подтверждено | ngx_http_log_module; access_log |
|
||||||
|
| 4.2 | Журналирование ошибок | Подтверждено | error_log |
|
||||||
|
| 4.3 | Настройка формата журналов | Подтверждено | log_format |
|
||||||
|
| 4.4 | Передача журналов в syslog | Подтверждено | access_log syslog; error_log syslog |
|
||||||
|
| 5.1 | Ограничение частоты запросов | Подтверждено | ngx_http_limit_req_module; limit_req |
|
||||||
|
| 5.2 | Ограничение количества соединений | Подтверждено | ngx_http_limit_conn_module; limit_conn |
|
||||||
|
| 5.3 | Ограничение размера клиентского запроса | Подтверждено | ngx_http_core_module; client_max_body_size |
|
||||||
|
| 5.4 | Ограничение скорости отдачи данных | Подтверждено | ngx_http_core_module; limit_rate |
|
||||||
|
| 5.5 | Настройка таймаутов соединений | Подтверждено | client_*_timeout; send_timeout; keepalive_timeout |
|
||||||
|
| 6.1 | Сокрытие версии nginx | Подтверждено | server_tokens off |
|
||||||
|
| 6.2 | Управление страницами ошибок | Подтверждено | error_page |
|
||||||
|
| 6.3 | Управление листингом директорий | Подтверждено | ngx_http_autoindex_module; autoindex |
|
||||||
|
| 7.1 | Обратное проксирование HTTP/HTTPS | Подтверждено | ngx_http_proxy_module; proxy_pass |
|
||||||
|
| 7.2 | Балансировка и группы upstream | Подтверждено | ngx_http_upstream_module; upstream |
|
||||||
|
| 7.3 | Управление заголовками при проксировании | Подтверждено | proxy_set_header |
|
||||||
|
| 8.1 | Задание корневой директории сайта | Подтверждено | ngx_http_core_module; root |
|
||||||
|
| 8.2 | Задание альтернативного пути для location | Подтверждено | ngx_http_core_module; alias |
|
||||||
|
| 8.3 | Проверка существования файлов и маршрутизация | Подтверждено | ngx_http_core_module; try_files |
|
||||||
|
| 8.4 | Ограничение доступа к произвольным каталогам ОС | Подтверждено | root; alias; location; права ФС |
|
||||||
|
| 9.1 | Исключение неиспользуемых модулей | Подтверждено | configure; load_module |
|
||||||
|
| 9.2 | Отключение неиспользуемых возможностей конфигурацией | Подтверждено | конфигурация nginx |
|
||||||
|
| 9.3 | Контроль целостности конфигурации и разрешённых директорий | Не применимо к nginx напрямую (внешняя мера) | afick или иной FIM |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
- **1. Идентификация и аутентификация**
|
||||||
|
- **1.1 Ограничение доступа по IP-адресу**
|
||||||
|
- Описание реализации: nginx позволяет ограничивать доступ к ресурсам по IP-адресам клиентов. Для этого используются правила разрешения и запрета доступа.
|
||||||
|
- Модуль / механизм: ngx_http_access_module; директивы allow, deny
|
||||||
|
- Комментарий: Подтверждено официальной документацией nginx: модуль предназначен для ограничения доступа по адресам клиентов.
|
||||||
|
- Проверка:
|
||||||
|
- **Статус:** Подтверждено
|
||||||
|
- **Ревью функции:** Описание реализации и заявленный механизм соответствуют документации nginx. Модуль `ngx_http_access_module` входит в стандартную сборку nginx.
|
||||||
|
- **Источник:** https://nginx.org/en/docs/http/ngx_http_access_module.html
|
||||||
|
- **Результат:** Модуль `ngx_http_access_module` входит в стандартную сборку nginx. Директивы `allow` и `deny` задают правила доступа по IP-адресу, сети CIDR, `all` или `unix:`. Правила обрабатываются последовательно; первое совпавшее правило определяет результат.
|
||||||
|
- **Пример конфигурации:**
|
||||||
|
```nginx
|
||||||
|
location /admin/ {
|
||||||
|
allow 192.168.1.0/24;
|
||||||
|
allow 10.0.0.1;
|
||||||
|
deny all;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
- **1.2 Аутентификация по имени пользователя и паролю**
|
||||||
|
- Описание реализации: nginx поддерживает HTTP Basic Authentication: пользователь вводит имя и пароль, nginx проверяет их по файлу пользователей.
|
||||||
|
- Модуль / механизм: ngx_http_auth_basic_module; директивы auth_basic, auth_basic_user_file
|
||||||
|
- Комментарий: Подтверждено официальной документацией nginx: модуль валидирует имя пользователя и пароль по протоколу HTTP Basic Authentication.
|
||||||
|
- Проверка:
|
||||||
|
- **Статус:** Подтверждено
|
||||||
|
- **Ревью функции:** Описание реализации и заявленный механизм соответствуют документации nginx. Модуль `ngx_http_auth_basic_module` реализует HTTP Basic Authentication.
|
||||||
|
- **Источник:** https://nginx.org/en/docs/http/ngx_http_auth_basic_module.html
|
||||||
|
- **Результат:** Модуль `ngx_http_auth_basic_module` реализует HTTP Basic Authentication. Директива `auth_basic` включает аутентификацию и задаёт текстовое сообщение для диалога; `auth_basic_user_file` указывает файл с парами «пользователь:хеш_пароля» (формат htpasswd).
|
||||||
|
- **Пример конфигурации:**
|
||||||
|
```nginx
|
||||||
|
location /secure/ {
|
||||||
|
auth_basic "Restricted Area";
|
||||||
|
auth_basic_user_file /etc/nginx/htpasswd;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
- **Примечание:** Файл паролей создаётся утилитой `htpasswd` (пакет apache2-utils или httpd-tools).
|
||||||
|
- **1.3 Аутентификация по клиентскому TLS-сертификату**
|
||||||
|
- Описание реализации: nginx может запрашивать и проверять клиентский сертификат при HTTPS-соединении.
|
||||||
|
- Модуль / механизм: ngx_http_ssl_module; директивы ssl_client_certificate, ssl_verify_client, ssl_verify_depth
|
||||||
|
- Комментарий: Реализуется через SSL/TLS-модуль nginx. Сам SSL-модуль требует включения при сборке и использует OpenSSL.
|
||||||
|
- Проверка:
|
||||||
|
- **Статус:** Подтверждено с оговорками
|
||||||
|
- **Ревью функции:** Описание и механизм в целом адекватны; учтены оговорки сборки, конфигурации или эксплуатации. Модуль `ngx_http_ssl_module` поддерживает проверку клиентских сертификатов.
|
||||||
|
- **Источник:** https://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_verify_client
|
||||||
|
- **Результат:** Модуль `ngx_http_ssl_module` поддерживает проверку клиентских сертификатов. Директива `ssl_verify_client on` требует обязательного предъявления и проверки сертификата; `ssl_client_certificate` задаёт файл доверенного CA; `ssl_verify_depth` ограничивает глубину цепочки. Модуль требует сборки с `--with-http_ssl_module` и библиотекой OpenSSL.
|
||||||
|
- **Пример конфигурации:**
|
||||||
|
```nginx
|
||||||
|
server {
|
||||||
|
listen 443 ssl;
|
||||||
|
ssl_certificate /etc/nginx/ssl/server.crt;
|
||||||
|
ssl_certificate_key /etc/nginx/ssl/server.key;
|
||||||
|
ssl_client_certificate /etc/nginx/ssl/ca.crt;
|
||||||
|
ssl_verify_client on;
|
||||||
|
ssl_verify_depth 2;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
- **Примечание:** Акцент на идентификации клиента; для контекста защиты канала см. также п. 3.3.
|
||||||
|
- **1.4 Авторизация через внешний сервис**
|
||||||
|
- Описание реализации: nginx может выполнять подзапрос во внешний сервис авторизации и разрешать или запрещать доступ по результату ответа.
|
||||||
|
- Модуль / механизм: ngx_http_auth_request_module; директивы auth_request, auth_request_set
|
||||||
|
- Комментарий: Модуль официально поддерживается, но в upstream nginx не собирается по умолчанию и должен включаться параметром сборки --with-http_auth_request_module.
|
||||||
|
- Проверка:
|
||||||
|
- **Статус:** Подтверждено с оговорками
|
||||||
|
- **Ревью функции:** Описание и механизм в целом адекватны; учтены оговорки сборки, конфигурации или эксплуатации. Модуль `ngx_http_auth_request_module` выполняет подзапрос к указанному URI;
|
||||||
|
- **Источник:** https://nginx.org/en/docs/http/ngx_http_auth_request_module.html
|
||||||
|
- **Результат:** Модуль `ngx_http_auth_request_module` выполняет подзапрос к указанному URI; доступ разрешается при ответе 2xx, запрещается при 401/403. Директива `auth_request_set` позволяет передать значения из заголовков ответа авторизационного сервиса в переменные nginx. В официальной сборке модуль включается флагом `--with-http_auth_request_module`; в большинстве дистрибутивных пакетов он уже присутствует.
|
||||||
|
- **Пример конфигурации:**
|
||||||
|
```nginx
|
||||||
|
location = /auth {
|
||||||
|
internal;
|
||||||
|
proxy_pass http://auth-service:8080/validate;
|
||||||
|
proxy_pass_request_body off;
|
||||||
|
proxy_set_header Content-Length "";
|
||||||
|
proxy_set_header X-Original-URI $request_uri;
|
||||||
|
}
|
||||||
|
|
||||||
|
location / {
|
||||||
|
auth_request /auth;
|
||||||
|
proxy_pass http://backend;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
- **Примечание:** См. `Требования безопасности для включения в ТУ — проверка.md` п. 4; `Минимизация поверхности атаки nginx — проверка.md` п. 4.
|
||||||
|
- **1.5 Комбинирование нескольких проверок доступа**
|
||||||
|
- Описание реализации: nginx позволяет комбинировать несколько механизмов проверки доступа, например ограничение по IP и Basic Authentication.
|
||||||
|
- Модуль / механизм: satisfy; совместно с access, auth_basic, auth_request
|
||||||
|
- Комментарий: В документации nginx указано, что одновременное ограничение доступа по адресу, паролю и подзапросу управляется директивой satisfy.
|
||||||
|
- Проверка:
|
||||||
|
- **Статус:** Подтверждено
|
||||||
|
- **Ревью функции:** Описание реализации и заявленный механизм соответствуют документации nginx. Директива `satisfy` управляет логикой комбинирования проверок `allow`/`deny`, `auth_basic` и `auth_request`.
|
||||||
|
- **Источник:** https://nginx.org/en/docs/http/ngx_http_core_module.html#satisfy
|
||||||
|
- **Результат:** Директива `satisfy` управляет логикой комбинирования проверок `allow`/`deny`, `auth_basic` и `auth_request`. Значение `all` (по умолчанию) требует прохождения всех проверок; значение `any` — достаточно одной успешной.
|
||||||
|
- **Пример конфигурации:**
|
||||||
|
```nginx
|
||||||
|
location /admin/ {
|
||||||
|
satisfy all;
|
||||||
|
allow 192.168.1.0/24;
|
||||||
|
deny all;
|
||||||
|
auth_basic "Admin Area";
|
||||||
|
auth_basic_user_file /etc/nginx/htpasswd;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
- **Примечание:** См. `Требования безопасности для включения в ТУ — проверка.md` п. 4; `Минимизация поверхности атаки nginx — проверка.md` п. 4.
|
||||||
|
|
||||||
|
- **2. Разграничение доступа к ресурсам**
|
||||||
|
- **2.1 Разделение правил по виртуальным серверам и путям**
|
||||||
|
- Описание реализации: nginx позволяет задавать разные правила обработки и доступа для разных виртуальных серверов и URL-путей.
|
||||||
|
- Модуль / механизм: ngx_http_core_module; блоки server, location
|
||||||
|
- Комментарий: Это базовый механизм конфигурации nginx. Используется для разделения публичных, служебных и закрытых разделов сайта.
|
||||||
|
- Проверка:
|
||||||
|
- **Статус:** Подтверждено
|
||||||
|
- **Ревью функции:** Описание реализации и заявленный механизм соответствуют документации nginx. Блоки `server` определяют виртуальные хосты (по `listen`, `server_name`), блоки `location` — правила для URI-префиксов, регулярных выражений и точных совпадений.
|
||||||
|
- **Источник:** https://nginx.org/en/docs/http/ngx_http_core_module.html#server , https://nginx.org/en/docs/http/ngx_http_core_module.html#location
|
||||||
|
- **Результат:** Блоки `server` определяют виртуальные хосты (по `listen`, `server_name`), блоки `location` — правила для URI-префиксов, регулярных выражений и точных совпадений. Это базовый механизм разграничения доступа и обработки запросов.
|
||||||
|
- **Пример конфигурации:**
|
||||||
|
```nginx
|
||||||
|
server {
|
||||||
|
listen 80;
|
||||||
|
server_name public.example.com;
|
||||||
|
location / {
|
||||||
|
root /var/www/public;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
server {
|
||||||
|
listen 80;
|
||||||
|
server_name admin.example.com;
|
||||||
|
location / {
|
||||||
|
allow 10.0.0.0/8;
|
||||||
|
deny all;
|
||||||
|
root /var/www/admin;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
- **2.2 Ограничение HTTP-методов**
|
||||||
|
- Описание реализации: nginx позволяет задавать отдельные правила доступа для методов, отличных от явно разрешённых.
|
||||||
|
- Модуль / механизм: ngx_http_core_module; директива limit_except
|
||||||
|
- Комментарий: Используется для ограничения методов вроде PUT, DELETE, если они не требуются приложению.
|
||||||
|
- Проверка:
|
||||||
|
- **Статус:** Подтверждено
|
||||||
|
- **Ревью функции:** Описание реализации и заявленный механизм соответствуют документации nginx. Директива `limit_except` задаёт методы, для которых применяются вложенные директивы доступа.
|
||||||
|
- **Источник:** https://nginx.org/en/docs/http/ngx_http_core_module.html#limit_except
|
||||||
|
- **Результат:** Директива `limit_except` задаёт методы, для которых применяются вложенные директивы доступа. Методы, не перечисленные в `limit_except`, обрабатываются без дополнительных ограничений внутри данного блока.
|
||||||
|
- **Минимальный аудит конфигурации:**
|
||||||
|
```bash
|
||||||
|
nginx -T 2>/dev/null | grep -E 'limit_except|request_method'
|
||||||
|
```
|
||||||
|
- **Пример конфигурации:**
|
||||||
|
```nginx
|
||||||
|
location /uploads/ {
|
||||||
|
limit_except GET HEAD {
|
||||||
|
deny all;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
- **2.3 Запрет доступа к служебным и скрытым файлам**
|
||||||
|
- Описание реализации: nginx позволяет запрещать доступ к отдельным путям и шаблонам URI через правила location и deny all.
|
||||||
|
- Модуль / механизм: location, регулярные выражения, deny all
|
||||||
|
- Комментарий: Это не отдельный модуль безопасности, а конфигурационный механизм безопасной настройки.
|
||||||
|
- Проверка:
|
||||||
|
- **Статус:** Подтверждено
|
||||||
|
- **Ревью функции:** Описание реализации и заявленный механизм соответствуют документации nginx. Комбинация `location` с регулярными выражениями и `deny all` позволяет блокировать доступ к скрытым файлам (`.
|
||||||
|
- **Источник:** https://nginx.org/en/docs/http/ngx_http_access_module.html , https://nginx.org/en/docs/http/ngx_http_core_module.html#location
|
||||||
|
- **Результат:** Комбинация `location` с регулярными выражениями и `deny all` позволяет блокировать доступ к скрытым файлам (`.git`, `.env`, `.htaccess` и т.п.). Это стандартный конфигурационный паттерн безопасности.
|
||||||
|
- **Пример конфигурации:**
|
||||||
|
```nginx
|
||||||
|
location ~ /\. {
|
||||||
|
deny all;
|
||||||
|
access_log off;
|
||||||
|
log_not_found off;
|
||||||
|
}
|
||||||
|
|
||||||
|
location ~* \.(bak|sql|log|conf)$ {
|
||||||
|
deny all;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
- **2.4 Запрет прямого доступа к внутренним ресурсам**
|
||||||
|
- Описание реализации: nginx поддерживает внутренние location-блоки, которые недоступны напрямую клиенту и могут использоваться только для внутренних перенаправлений.
|
||||||
|
- Модуль / механизм: ngx_http_core_module; директива internal
|
||||||
|
- Комментарий: Применяется для скрытия служебных маршрутов и файлов от прямого обращения пользователя.
|
||||||
|
- Проверка:
|
||||||
|
- **Статус:** Подтверждено
|
||||||
|
- **Ревью функции:** Описание реализации и заявленный механизм соответствуют документации nginx. Директива `internal` ограничивает доступ к location только для внутренних запросов (error_page, rewrite, auth_request, X-Accel-Redirect и др.
|
||||||
|
- **Источник:** https://nginx.org/en/docs/http/ngx_http_core_module.html#internal
|
||||||
|
- **Результат:** Директива `internal` ограничивает доступ к location только для внутренних запросов (error_page, rewrite, auth_request, X-Accel-Redirect и др.). Прямые клиентские запросы к такому location возвращают 404.
|
||||||
|
- **Пример конфигурации:**
|
||||||
|
```nginx
|
||||||
|
location /protected-files/ {
|
||||||
|
internal;
|
||||||
|
alias /var/data/files/;
|
||||||
|
}
|
||||||
|
|
||||||
|
location /download {
|
||||||
|
# Клиент обращается сюда; nginx внутренне отдаёт файл
|
||||||
|
rewrite ^ /protected-files/document.pdf last;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
- **3. Защита соединения и передаваемых данных**
|
||||||
|
- **3.1 Поддержка HTTPS/TLS**
|
||||||
|
- Описание реализации: nginx поддерживает HTTPS при наличии SSL-модуля. Можно задавать сертификаты, ключи, версии TLS и наборы шифров.
|
||||||
|
- Модуль / механизм: ngx_http_ssl_module; ssl_certificate, ssl_certificate_key, ssl_protocols, ssl_ciphers
|
||||||
|
- Комментарий: SSL-модуль nginx предоставляет поддержку HTTPS, требует OpenSSL и должен быть включён при сборке.
|
||||||
|
- Проверка:
|
||||||
|
- **Статус:** Подтверждено с оговорками
|
||||||
|
- **Ревью функции:** Описание и механизм в целом адекватны; учтены оговорки сборки, конфигурации или эксплуатации. Модуль `ngx_http_ssl_module` обеспечивает HTTPS.
|
||||||
|
- **Источник:** https://nginx.org/en/docs/http/ngx_http_ssl_module.html
|
||||||
|
- **Результат:** Модуль `ngx_http_ssl_module` обеспечивает HTTPS. Директивы `ssl_certificate` и `ssl_certificate_key` задают серверный сертификат и ключ; `ssl_protocols` и `ssl_ciphers` — параметры TLS. Модуль требует OpenSSL и включения при сборке (`--with-http_ssl_module`).
|
||||||
|
- **Пример конфигурации:**
|
||||||
|
```nginx
|
||||||
|
server {
|
||||||
|
listen 443 ssl;
|
||||||
|
server_name example.com;
|
||||||
|
ssl_certificate /etc/nginx/ssl/example.com.crt;
|
||||||
|
ssl_certificate_key /etc/nginx/ssl/example.com.key;
|
||||||
|
ssl_protocols TLSv1.2 TLSv1.3;
|
||||||
|
ssl_ciphers HIGH:!aNULL:!MD5;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
- **3.2 Ограничение версий TLS и шифров**
|
||||||
|
- Описание реализации: nginx позволяет задавать допустимые версии TLS и наборы шифров.
|
||||||
|
- Модуль / механизм: ngx_http_ssl_module; ssl_protocols, ssl_ciphers
|
||||||
|
- Комментарий: Для ТУ/ПМИ нужно отдельно фиксировать допустимую криптографическую политику.
|
||||||
|
- Проверка:
|
||||||
|
- **Статус:** Подтверждено
|
||||||
|
- **Ревью функции:** Описание реализации и заявленный механизм соответствуют документации nginx. Директива `ssl_protocols` задаёт разрешённые версии протокола (TLSv1.
|
||||||
|
- **Источник:** https://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_protocols , https://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_ciphers
|
||||||
|
- **Результат:** Директива `ssl_protocols` задаёт разрешённые версии протокола (TLSv1.2, TLSv1.3 и др.); `ssl_ciphers` — список шифронаборов в формате OpenSSL. Дополнительно доступны `ssl_prefer_server_ciphers` и параметры для TLS 1.3 (`ssl_conf_command` в новых версиях).
|
||||||
|
- **Пример конфигурации:**
|
||||||
|
```nginx
|
||||||
|
ssl_protocols TLSv1.2 TLSv1.3;
|
||||||
|
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256;
|
||||||
|
ssl_prefer_server_ciphers on;
|
||||||
|
```
|
||||||
|
- **Примечание:** Конкретная криптографическая политика должна быть зафиксирована в ТУ/ПМИ отдельно.
|
||||||
|
- **3.3 Проверка клиентского сертификата**
|
||||||
|
- Описание реализации: nginx может проверять клиентские TLS-сертификаты по доверенному центру сертификации.
|
||||||
|
- Модуль / механизм: ssl_client_certificate, ssl_verify_client
|
||||||
|
- Комментарий: Может использоваться как механизм строгой аутентификации клиента.
|
||||||
|
- Проверка:
|
||||||
|
- **Статус:** Подтверждено
|
||||||
|
- **Ревью функции:** Описание реализации и заявленный механизм соответствуют документации nginx. Директива `ssl_verify_client` поддерживает значения `on`, `off`, `optional`, `optional_no_ca`.
|
||||||
|
- **Источник:** https://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_verify_client
|
||||||
|
- **Результат:** Директива `ssl_verify_client` поддерживает значения `on`, `off`, `optional`, `optional_no_ca`. При `on` клиент обязан предъявить сертификат, подписанный доверенным CA из `ssl_client_certificate`. Режим `optional` запрашивает сертификат, но не прерывает соединение при его отсутствии.
|
||||||
|
- **Пример конфигурации:**
|
||||||
|
```nginx
|
||||||
|
server {
|
||||||
|
listen 443 ssl;
|
||||||
|
ssl_certificate /etc/nginx/ssl/server.crt;
|
||||||
|
ssl_certificate_key /etc/nginx/ssl/server.key;
|
||||||
|
ssl_client_certificate /etc/nginx/ssl/client-ca.crt;
|
||||||
|
ssl_verify_client optional;
|
||||||
|
ssl_verify_depth 3;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
- **Примечание:** В отличие от п. 1.3, здесь акцент на защите канала и политике доверия к клиентским сертификатам.
|
||||||
|
- **3.4 Принудительное использование HTTPS**
|
||||||
|
- Описание реализации: nginx может перенаправлять HTTP-запросы на HTTPS и добавлять заголовки безопасности.
|
||||||
|
- Модуль / механизм: return 301/308; add_header Strict-Transport-Security
|
||||||
|
- Комментарий: HSTS реализуется через HTTP-заголовок, а не отдельным модулем безопасности.
|
||||||
|
- Проверка:
|
||||||
|
- **Статус:** Подтверждено
|
||||||
|
- **Ревью функции:** Описание реализации и заявленный механизм соответствуют документации nginx. Редирект HTTP→HTTPS реализуется директивой `return` (301 или 308).
|
||||||
|
- **Источник:** https://nginx.org/en/docs/http/ngx_http_rewrite_module.html#return , https://nginx.org/en/docs/http/ngx_http_headers_module.html#add_header
|
||||||
|
- **Результат:** Редирект HTTP→HTTPS реализуется директивой `return` (301 или 308). Заголовок HSTS (`Strict-Transport-Security`) добавляется через `add_header` в HTTPS-блоке. Отдельного модуля HSTS в nginx нет.
|
||||||
|
- **Пример конфигурации:**
|
||||||
|
```nginx
|
||||||
|
server {
|
||||||
|
listen 80;
|
||||||
|
server_name example.com;
|
||||||
|
return 301 https://$host$request_uri;
|
||||||
|
}
|
||||||
|
|
||||||
|
server {
|
||||||
|
listen 443 ssl;
|
||||||
|
server_name example.com;
|
||||||
|
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
- **4. Регистрация событий и аудит**
|
||||||
|
- **4.1 Журналирование HTTP-запросов**
|
||||||
|
- Описание реализации: nginx ведёт журнал HTTP-запросов в настраиваемом формате.
|
||||||
|
- Модуль / механизм: ngx_http_log_module; access_log, log_format
|
||||||
|
- Комментарий: Официальный модуль nginx записывает request logs в заданном формате.
|
||||||
|
- Проверка:
|
||||||
|
- **Статус:** Подтверждено
|
||||||
|
- **Ревью функции:** Описание реализации и заявленный механизм соответствуют документации nginx. Модуль `ngx_http_log_module` записывает access log.
|
||||||
|
- **Источник:** https://nginx.org/en/docs/http/ngx_http_log_module.html
|
||||||
|
- **Результат:** Модуль `ngx_http_log_module` записывает access log. Директива `access_log` задаёт путь (или syslog) и формат; по умолчанию используется формат `combined`. Журналирование можно отключить (`access_log off`) на уровне server/location.
|
||||||
|
- **Пример конфигурации:**
|
||||||
|
```nginx
|
||||||
|
http {
|
||||||
|
access_log /var/log/nginx/access.log combined;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
- **4.2 Журналирование ошибок**
|
||||||
|
- Описание реализации: nginx ведёт журнал ошибок, где фиксируются проблемы обработки запросов, конфигурации и взаимодействия с backend.
|
||||||
|
- Модуль / механизм: error_log
|
||||||
|
- Комментарий: Официальная документация указывает, что nginx пишет error log и позволяет задавать место и уровень журналирования.
|
||||||
|
- Проверка:
|
||||||
|
- **Статус:** Подтверждено
|
||||||
|
- **Ревью функции:** Описание реализации и заявленный механизм соответствуют документации nginx. Директива `error_log` задаёт файл (или syslog) и уровень детализации: `debug`, `info`, `notice`, `warn`, `error`, `crit`, `alert`, `emerg`.
|
||||||
|
- **Источник:** https://nginx.org/en/docs/ngx_core_module.html#error_log
|
||||||
|
- **Результат:** Директива `error_log` задаёт файл (или syslog) и уровень детализации: `debug`, `info`, `notice`, `warn`, `error`, `crit`, `alert`, `emerg`. Уровень по умолчанию — `error`.
|
||||||
|
- **Пример конфигурации:**
|
||||||
|
```nginx
|
||||||
|
error_log /var/log/nginx/error.log warn;
|
||||||
|
```
|
||||||
|
- **4.3 Настройка формата журналов**
|
||||||
|
- Описание реализации: nginx позволяет задавать собственный формат access log с нужными полями.
|
||||||
|
- Модуль / механизм: log_format
|
||||||
|
- Комментарий: Для ПМИ можно проверять наличие обязательных полей в журнале.
|
||||||
|
- Проверка:
|
||||||
|
- **Статус:** Подтверждено
|
||||||
|
- **Ревью функции:** Описание реализации и заявленный механизм соответствуют документации nginx. Директива `log_format` определяет именованный формат с произвольным набором переменных (`$remote_addr`, `$request`, `$status`, `$body_bytes_sent`, `$http_user_agent` и др.
|
||||||
|
- **Источник:** https://nginx.org/en/docs/http/ngx_http_log_module.html#log_format
|
||||||
|
- **Результат:** Директива `log_format` определяет именованный формат с произвольным набором переменных (`$remote_addr`, `$request`, `$status`, `$body_bytes_sent`, `$http_user_agent` и др.). Формат применяется в `access_log`.
|
||||||
|
- **Пример конфигурации:**
|
||||||
|
```nginx
|
||||||
|
log_format audit '$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/audit.log audit;
|
||||||
|
```
|
||||||
|
- **4.4 Передача журналов в syslog**
|
||||||
|
- Описание реализации: nginx поддерживает запись access_log и error_log в syslog.
|
||||||
|
- Модуль / механизм: access_log syslog:...; error_log syslog:...
|
||||||
|
- Комментарий: Подтверждено официальной документацией nginx по syslog.
|
||||||
|
- Проверка:
|
||||||
|
- **Статус:** Подтверждено
|
||||||
|
- **Ревью функции:** Описание реализации и заявленный механизм соответствуют документации nginx. nginx поддерживает запись `access_log` и `error_log` в syslog с параметрами `server`, `facility`, `tag`, `severity`.
|
||||||
|
- **Источник:** https://nginx.org/en/docs/syslog.html
|
||||||
|
- **Результат:** nginx поддерживает запись `access_log` и `error_log` в syslog с параметрами `server`, `facility`, `tag`, `severity`. Формат: `syslog:server=address[,parameter=value]`.
|
||||||
|
- **Пример конфигурации:**
|
||||||
|
```nginx
|
||||||
|
error_log syslog:server=192.168.1.1:514,facility=local7,tag=nginx,severity=error;
|
||||||
|
|
||||||
|
access_log syslog:server=192.168.1.1:514,facility=local7,tag=nginx,severity=info combined;
|
||||||
|
```
|
||||||
|
- **Примечание:** См. ПМИ п. 14 в `Проверочные мероприятия для ПМИ — проверка.md`; `Контроль целостности хранимого кода и конфигурации — проверка.md` п. 13; `Минимально необходимые полномочия nginx — проверка.md` п. 5.
|
||||||
|
|
||||||
|
- **5. Ограничение нагрузки и защита от избыточных запросов**
|
||||||
|
- **5.1 Ограничение частоты запросов**
|
||||||
|
- Описание реализации: nginx может ограничивать частоту обработки запросов по заданному ключу, например по IP-адресу клиента.
|
||||||
|
- Модуль / механизм: ngx_http_limit_req_module; limit_req_zone, limit_req
|
||||||
|
- Комментарий: Модуль использует метод leaky bucket и официально предназначен для ограничения request rate.
|
||||||
|
- Проверка:
|
||||||
|
- **Статус:** Подтверждено
|
||||||
|
- **Ревью функции:** Описание реализации и заявленный механизм соответствуют документации nginx. Модуль `ngx_http_limit_req_module` реализует алгоритм leaky bucket.
|
||||||
|
- **Источник:** https://nginx.org/en/docs/http/ngx_http_limit_req_module.html
|
||||||
|
- **Результат:** Модуль `ngx_http_limit_req_module` реализует алгоритм leaky bucket. `limit_req_zone` определяет зону и ключ (например, `$binary_remote_addr`); `limit_req` применяет ограничение с параметрами `rate` и `burst`.
|
||||||
|
- **Пример конфигурации:**
|
||||||
|
```nginx
|
||||||
|
http {
|
||||||
|
limit_req_zone $binary_remote_addr zone=one:10m rate=10r/s;
|
||||||
|
|
||||||
|
server {
|
||||||
|
location / {
|
||||||
|
limit_req zone=one burst=20 nodelay;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
- **Примечание:** См. `Требования безопасности для включения в ТУ — проверка.md` п. 15; `Проверочные мероприятия для ПМИ — проверка.md` п. 15.
|
||||||
|
- **5.2 Ограничение количества соединений**
|
||||||
|
- Описание реализации: nginx может ограничивать количество соединений по заданному ключу, например по IP-адресу клиента.
|
||||||
|
- Модуль / механизм: ngx_http_limit_conn_module; limit_conn_zone, limit_conn
|
||||||
|
- Комментарий: Официальный модуль ограничивает количество соединений per defined key.
|
||||||
|
- Проверка:
|
||||||
|
- **Статус:** Подтверждено
|
||||||
|
- **Ревью функции:** Описание реализации и заявленный механизм соответствуют документации nginx. Модуль `ngx_http_limit_conn_module` ограничивает число одновременных соединений по ключу.
|
||||||
|
- **Источник:** https://nginx.org/en/docs/http/ngx_http_limit_conn_module.html
|
||||||
|
- **Результат:** Модуль `ngx_http_limit_conn_module` ограничивает число одновременных соединений по ключу. `limit_conn_zone` задаёт зону; `limit_conn` применяет лимит.
|
||||||
|
- **Пример конфигурации:**
|
||||||
|
```nginx
|
||||||
|
http {
|
||||||
|
limit_conn_zone $binary_remote_addr zone=addr:10m;
|
||||||
|
|
||||||
|
server {
|
||||||
|
location / {
|
||||||
|
limit_conn addr 10;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
- **Примечание:** См. `Требования безопасности для включения в ТУ — проверка.md` п. 16; `Проверочные мероприятия для ПМИ — проверка.md` п. 16.
|
||||||
|
- **5.3 Ограничение размера клиентского запроса**
|
||||||
|
- Описание реализации: nginx позволяет ограничивать максимальный размер тела клиентского запроса.
|
||||||
|
- Модуль / механизм: ngx_http_core_module; client_max_body_size
|
||||||
|
- Комментарий: Используется для защиты от чрезмерно больших запросов и нежелательных загрузок.
|
||||||
|
- Проверка:
|
||||||
|
- **Статус:** Подтверждено
|
||||||
|
- **Ревью функции:** Описание реализации и заявленный механизм соответствуют документации nginx. Директива `client_max_body_size` задаёт максимальный размер тела запроса.
|
||||||
|
- **Источник:** https://nginx.org/en/docs/http/ngx_http_core_module.html#client_max_body_size
|
||||||
|
- **Результат:** Директива `client_max_body_size` задаёт максимальный размер тела запроса. Значение по умолчанию — 1m. При превышении nginx возвращает 413 (Request Entity Too Large).
|
||||||
|
- **Пример конфигурации:**
|
||||||
|
```nginx
|
||||||
|
server {
|
||||||
|
client_max_body_size 10m;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
- **Примечание:** См. `Требования безопасности для включения в ТУ — проверка.md` п. 15; `Проверочные мероприятия для ПМИ — проверка.md` п. 15.
|
||||||
|
- **5.4 Ограничение скорости отдачи данных**
|
||||||
|
- Описание реализации: nginx позволяет ограничивать скорость передачи ответа клиенту.
|
||||||
|
- Модуль / механизм: ngx_http_core_module; limit_rate
|
||||||
|
- Комментарий: Используется для управления нагрузкой и потреблением ресурсов.
|
||||||
|
- Проверка:
|
||||||
|
- **Статус:** Подтверждено
|
||||||
|
- **Ревью функции:** Описание реализации и заявленный механизм соответствуют документации nginx. Директива `limit_rate` ограничивает скорость отдачи ответа клиенту (байт/с).
|
||||||
|
- **Источник:** https://nginx.org/en/docs/http/ngx_http_core_module.html#limit_rate
|
||||||
|
- **Результат:** Директива `limit_rate` ограничивает скорость отдачи ответа клиенту (байт/с). Дополнительно `limit_rate_after` позволяет отдавать начальный объём без ограничения.
|
||||||
|
- **Пример конфигурации:**
|
||||||
|
```nginx
|
||||||
|
location /downloads/ {
|
||||||
|
limit_rate 500k;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
- **Примечание:** См. `Требования безопасности для включения в ТУ — проверка.md` п. 16; `Проверочные мероприятия для ПМИ — проверка.md` п. 16.
|
||||||
|
- **5.5 Настройка таймаутов соединений**
|
||||||
|
- Описание реализации: nginx позволяет задавать таймауты чтения заголовков, тела запроса, отправки ответа и keepalive.
|
||||||
|
- Модуль / механизм: client_header_timeout, client_body_timeout, send_timeout, keepalive_timeout
|
||||||
|
- Комментарий: Снижает риск удержания ресурсов медленными или зависшими соединениями.
|
||||||
|
- Проверка:
|
||||||
|
- **Статус:** Подтверждено
|
||||||
|
- **Ревью функции:** Описание реализации и заявленный механизм соответствуют документации nginx. Директивы `client_header_timeout`, `client_body_timeout`, `send_timeout` и `keepalive_timeout` задают таймауты на разных этапах обработки соединения.
|
||||||
|
- **Источник:** https://nginx.org/en/docs/http/ngx_http_core_module.html
|
||||||
|
- **Результат:** Директивы `client_header_timeout`, `client_body_timeout`, `send_timeout` и `keepalive_timeout` задают таймауты на разных этапах обработки соединения. Значения по умолчанию: 60s для header/body/send, 75s для keepalive.
|
||||||
|
- **Пример конфигурации:**
|
||||||
|
```nginx
|
||||||
|
http {
|
||||||
|
client_header_timeout 10s;
|
||||||
|
client_body_timeout 10s;
|
||||||
|
send_timeout 10s;
|
||||||
|
keepalive_timeout 30s;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
- **6. Управление раскрытием информации**
|
||||||
|
- **6.1 Сокрытие версии nginx**
|
||||||
|
- Описание реализации: nginx позволяет отключить отображение версии сервера в стандартных ответах.
|
||||||
|
- Модуль / механизм: server_tokens off
|
||||||
|
- Комментарий: Важно: server_tokens off скрывает версию, но не всегда полностью скрывает сам факт использования nginx.
|
||||||
|
- Проверка:
|
||||||
|
- **Статус:** Подтверждено
|
||||||
|
- **Ревью функции:** Описание реализации и заявленный механизм соответствуют документации nginx. Директива `server_tokens off` убирает номер версии из заголовка `Server` и со страниц ошибок nginx.
|
||||||
|
- **Источник:** https://nginx.org/en/docs/http/ngx_http_core_module.html#server_tokens
|
||||||
|
- **Результат:** Директива `server_tokens off` убирает номер версии из заголовка `Server` и со страниц ошибок nginx. Заголовок `Server` по-прежнему содержит слово «nginx».
|
||||||
|
- **Минимальный аудит конфигурации:**
|
||||||
|
```bash
|
||||||
|
nginx -T 2>/dev/null | grep server_tokens
|
||||||
|
```
|
||||||
|
- **Пример конфигурации:**
|
||||||
|
```nginx
|
||||||
|
http {
|
||||||
|
server_tokens off;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
- **Примечание:** Для полного сокрытия идентификатора сервера требуются дополнительные меры (например, заголовки через `more_clear_headers` в сторонних модулях).
|
||||||
|
- **6.2 Управление страницами ошибок**
|
||||||
|
- Описание реализации: nginx позволяет задавать собственные страницы ошибок и внутренние перенаправления.
|
||||||
|
- Модуль / механизм: error_page
|
||||||
|
- Комментарий: Позволяет не раскрывать технические детали пользователю.
|
||||||
|
- Проверка:
|
||||||
|
- **Статус:** Подтверждено
|
||||||
|
- **Ревью функции:** Описание реализации и заявленный механизм соответствуют документации nginx. Директива `error_page` перенаправляет обработку указанных кодов ошибок на URI, именованный location или внешний адрес.
|
||||||
|
- **Источник:** https://nginx.org/en/docs/http/ngx_http_core_module.html#error_page
|
||||||
|
- **Результат:** Директива `error_page` перенаправляет обработку указанных кодов ошибок на URI, именованный location или внешний адрес. Позволяет показывать пользовательские страницы вместо стандартных сообщений nginx.
|
||||||
|
- **Пример конфигурации:**
|
||||||
|
```nginx
|
||||||
|
error_page 404 /custom_404.html;
|
||||||
|
error_page 500 502 503 504 /custom_50x.html;
|
||||||
|
|
||||||
|
location = /custom_404.html {
|
||||||
|
root /var/www/errors;
|
||||||
|
internal;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
- **6.3 Управление листингом директорий**
|
||||||
|
- Описание реализации: nginx может формировать листинг директорий через autoindex, если режим включён.
|
||||||
|
- Модуль / механизм: ngx_http_autoindex_module; autoindex
|
||||||
|
- Комментарий: Модуль официально формирует directory listing для запросов, оканчивающихся /, когда не найден индексный файл. Для безопасной конфигурации должен быть отключён, если не требуется.
|
||||||
|
- Проверка:
|
||||||
|
- **Статус:** Подтверждено
|
||||||
|
- **Ревью функции:** Описание реализации и заявленный механизм соответствуют документации nginx. Модуль `ngx_http_autoindex_module` включается директивой `autoindex on` и формирует HTML-листинг каталога при отсутствии индексного файла.
|
||||||
|
- **Источник:** https://nginx.org/en/docs/http/ngx_http_autoindex_module.html
|
||||||
|
- **Результат:** Модуль `ngx_http_autoindex_module` включается директивой `autoindex on` и формирует HTML-листинг каталога при отсутствии индексного файла. По умолчанию `autoindex off`. Для безопасной конфигурации рекомендуется явно отключать или не включать.
|
||||||
|
- **Минимальный аудит конфигурации:**
|
||||||
|
```bash
|
||||||
|
nginx -T 2>/dev/null | grep autoindex
|
||||||
|
```
|
||||||
|
- **Пример конфигурации:**
|
||||||
|
```nginx
|
||||||
|
location /public-files/ {
|
||||||
|
autoindex off;
|
||||||
|
root /var/www/files;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
- **7. Обратное проксирование и изоляция backend-сервисов**
|
||||||
|
- **7.1 Обратное проксирование HTTP/HTTPS**
|
||||||
|
- Описание реализации: nginx может принимать клиентские запросы и передавать их внутренним backend-сервисам.
|
||||||
|
- Модуль / механизм: ngx_http_proxy_module; proxy_pass
|
||||||
|
- Комментарий: Официальный модуль proxy передаёт запросы другому серверу.
|
||||||
|
- Проверка:
|
||||||
|
- **Статус:** Подтверждено
|
||||||
|
- **Ревью функции:** Описание реализации и заявленный механизм соответствуют документации nginx. Модуль `ngx_http_proxy_module` передаёт HTTP-запросы на backend через `proxy_pass`.
|
||||||
|
- **Источник:** https://nginx.org/en/docs/http/ngx_http_proxy_module.html
|
||||||
|
- **Результат:** Модуль `ngx_http_proxy_module` передаёт HTTP-запросы на backend через `proxy_pass`. Поддерживается проксирование на HTTP и HTTPS upstream.
|
||||||
|
- **Пример конфигурации:**
|
||||||
|
```nginx
|
||||||
|
location /api/ {
|
||||||
|
proxy_pass http://127.0.0.1:8080;
|
||||||
|
proxy_set_header Host $host;
|
||||||
|
proxy_set_header X-Real-IP $remote_addr;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
- **7.2 Балансировка и группы upstream**
|
||||||
|
- Описание реализации: nginx позволяет определять группы backend-серверов и использовать их для proxy_pass, fastcgi_pass, uwsgi_pass, scgi_pass, grpc_pass.
|
||||||
|
- Модуль / механизм: ngx_http_upstream_module; upstream
|
||||||
|
- Комментарий: Документация nginx описывает upstream как механизм групп серверов для разных pass-директив.
|
||||||
|
- Проверка:
|
||||||
|
- **Статус:** Подтверждено
|
||||||
|
- **Ревью функции:** Описание реализации и заявленный механизм соответствуют документации nginx. Блок `upstream` определяет группу backend-серверов с методами балансировки (round-robin по умолчанию, `least_conn`, `ip_hash`, `hash`).
|
||||||
|
- **Источник:** https://nginx.org/en/docs/http/ngx_http_upstream_module.html
|
||||||
|
- **Результат:** Блок `upstream` определяет группу backend-серверов с методами балансировки (round-robin по умолчанию, `least_conn`, `ip_hash`, `hash`). Используется с `proxy_pass`, `fastcgi_pass`, `uwsgi_pass`, `scgi_pass`, `grpc_pass`.
|
||||||
|
- **Пример конфигурации:**
|
||||||
|
```nginx
|
||||||
|
upstream backend {
|
||||||
|
server 192.168.1.10:8080;
|
||||||
|
server 192.168.1.11:8080;
|
||||||
|
keepalive 32;
|
||||||
|
}
|
||||||
|
|
||||||
|
server {
|
||||||
|
location / {
|
||||||
|
proxy_pass http://backend;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
- **7.3 Управление заголовками при проксировании**
|
||||||
|
- Описание реализации: nginx позволяет явно задавать заголовки, передаваемые backend-сервису.
|
||||||
|
- Модуль / механизм: proxy_set_header
|
||||||
|
- Комментарий: Важно для корректной передачи адреса клиента и исключения нежелательных/подменённых заголовков.
|
||||||
|
- Проверка:
|
||||||
|
- **Статус:** Подтверждено
|
||||||
|
- **Ревью функции:** Описание реализации и заявленный механизм соответствуют документации nginx. Директива `proxy_set_header` задаёт или переопределяет заголовки запроса к backend.
|
||||||
|
- **Источник:** https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_set_header
|
||||||
|
- **Результат:** Директива `proxy_set_header` задаёт или переопределяет заголовки запроса к backend. По умолчанию nginx передаёт ряд заголовков, но `Host` и `Connection` могут требовать явной настройки. `proxy_pass_request_headers` управляет передачей клиентских заголовков.
|
||||||
|
- **Пример конфигурации:**
|
||||||
|
```nginx
|
||||||
|
location / {
|
||||||
|
proxy_pass http://backend;
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
- **8. Управление статическим содержимым и директориями веб-приложений**
|
||||||
|
- **8.1 Задание корневой директории сайта**
|
||||||
|
- Описание реализации: nginx обслуживает файлы из директории, заданной директивой root.
|
||||||
|
- Модуль / механизм: ngx_http_core_module; root
|
||||||
|
- Комментарий: Используется для определения разрешённой области веб-контента.
|
||||||
|
- Проверка:
|
||||||
|
- **Статус:** Подтверждено
|
||||||
|
- **Ревью функции:** Описание реализации и заявленный механизм соответствуют документации nginx. Директива `root` задаёт корневую директорию для запросов в данном server/location.
|
||||||
|
- **Источник:** https://nginx.org/en/docs/http/ngx_http_core_module.html#root
|
||||||
|
- **Результат:** Директива `root` задаёт корневую директорию для запросов в данном server/location. Путь к файлу формируется как `root` + URI.
|
||||||
|
- **Пример конфигурации:**
|
||||||
|
```nginx
|
||||||
|
server {
|
||||||
|
root /var/www/example.com;
|
||||||
|
location / {
|
||||||
|
index index.html;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
- **8.2 Задание альтернативного пути для location**
|
||||||
|
- Описание реализации: nginx позволяет сопоставлять URI с другой директорией файловой системы через alias.
|
||||||
|
- Модуль / механизм: ngx_http_core_module; alias
|
||||||
|
- Комментарий: Требует осторожной настройки, чтобы не открыть произвольные каталоги ОС.
|
||||||
|
- Проверка:
|
||||||
|
- **Статус:** Подтверждено
|
||||||
|
- **Ревью функции:** Описание реализации и заявленный механизм соответствуют документации nginx. Директива `alias` заменяет часть URI на указанный путь файловой системы.
|
||||||
|
- **Источник:** https://nginx.org/en/docs/http/ngx_http_core_module.html#alias
|
||||||
|
- **Результат:** Директива `alias` заменяет часть URI на указанный путь файловой системы. При некорректной настройке (особенно с регулярными выражениями) возможен path traversal.
|
||||||
|
- **Пример конфигурации:**
|
||||||
|
```nginx
|
||||||
|
location /images/ {
|
||||||
|
alias /var/www/static/images/;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
- **Примечание:** Для location с регулярным выражением `alias` должен содержать захватывающие группы; завершающий слэш обязателен.
|
||||||
|
- **8.3 Проверка существования файлов и маршрутизация**
|
||||||
|
- Описание реализации: nginx позволяет проверять наличие файлов и выполнять внутреннюю маршрутизацию через try_files.
|
||||||
|
- Модуль / механизм: ngx_http_core_module; try_files
|
||||||
|
- Комментарий: Используется для контроля, какой файл или маршрут будет обработан.
|
||||||
|
- Проверка:
|
||||||
|
- **Статус:** Подтверждено
|
||||||
|
- **Ревью функции:** Описание реализации и заявленный механизм соответствуют документации nginx. Директива `try_files` проверяет существование файлов/каталогов в указанном порядке и выполняет внутреннее перенаправление на последний параметр при отсутствии совпадений.
|
||||||
|
- **Источник:** https://nginx.org/en/docs/http/ngx_http_core_module.html#try_files
|
||||||
|
- **Результат:** Директива `try_files` проверяет существование файлов/каталогов в указанном порядке и выполняет внутреннее перенаправление на последний параметр при отсутствии совпадений.
|
||||||
|
- **Пример конфигурации:**
|
||||||
|
```nginx
|
||||||
|
location / {
|
||||||
|
root /var/www/html;
|
||||||
|
try_files $uri $uri/ /index.html;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
- **8.4 Ограничение доступа к произвольным каталогам ОС**
|
||||||
|
- Описание реализации: nginx должен быть настроен так, чтобы обслуживать файлы только из разрешённых директорий.
|
||||||
|
- Модуль / механизм: root, alias, location, deny all, права ФС
|
||||||
|
- Комментарий: Это не отдельный модуль nginx, а требование безопасной конфигурации.
|
||||||
|
- Проверка:
|
||||||
|
- **Статус:** Подтверждено
|
||||||
|
- **Ревью функции:** Описание реализации и заявленный механизм соответствуют документации nginx. nginx обслуживает только те пути, которые явно заданы через `root`/`alias` в `location`.
|
||||||
|
- **Источник:** https://nginx.org/en/docs/http/ngx_http_core_module.html#root , https://nginx.org/en/docs/http/ngx_http_access_module.html
|
||||||
|
- **Результат:** nginx обслуживает только те пути, которые явно заданы через `root`/`alias` в `location`. Безопасная конфигурация ограничивает `location /`, запрещает доступ к системным путям и сочетается с правами файловой системы (процесс nginx не должен иметь доступ к чувствительным каталогам).
|
||||||
|
- **Пример конфигурации:**
|
||||||
|
```nginx
|
||||||
|
server {
|
||||||
|
root /var/www/site;
|
||||||
|
location / {
|
||||||
|
try_files $uri =404;
|
||||||
|
}
|
||||||
|
location ~ ^/(\.\.|etc|proc|sys) {
|
||||||
|
deny all;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
- **Примечание:** Дополнительно на уровне ОС следует ограничить права пользователя, от которого работает nginx. См. `Минимально необходимые полномочия nginx — проверка.md` п. 3; `Контроль выполнения кода — проверка.md` п. 14.
|
||||||
|
|
||||||
|
- **9. Минимизация поверхности атаки**
|
||||||
|
- **9.1 Исключение неиспользуемых модулей**
|
||||||
|
- Описание реализации: nginx может собираться с разным составом модулей; неиспользуемые модули могут быть исключены из сборки или не загружаться.
|
||||||
|
- Модуль / механизм: Параметры сборки; dynamic modules; load_module
|
||||||
|
- Комментарий: Это проектная мера снижения поверхности атаки.
|
||||||
|
- Проверка:
|
||||||
|
- **Статус:** Подтверждено
|
||||||
|
- **Ревью функции:** Описание реализации и заявленный механизм соответствуют документации nginx. При сборке nginx параметры `./configure` позволяют включать/отключать модули (`--without-http_autoindex_module`, `--with-http_ssl_module` и др.
|
||||||
|
- **Источник:** https://nginx.org/en/docs/configure.html , https://nginx.org/en/docs/ngx_core_module.html#load_module
|
||||||
|
- **Результат:** При сборке nginx параметры `./configure` позволяют включать/отключать модули (`--without-http_autoindex_module`, `--with-http_ssl_module` и др.). Динамические модули подключаются через `load_module` в конфигурации; неиспользуемые модули можно не загружать.
|
||||||
|
- **Пример конфигурации:**
|
||||||
|
```nginx
|
||||||
|
# Загрузка только необходимых динамических модулей
|
||||||
|
load_module modules/ngx_http_geoip_module.so;
|
||||||
|
|
||||||
|
# Статические модули определяются при сборке:
|
||||||
|
# ./configure --without-http_autoindex_module --with-http_ssl_module
|
||||||
|
```
|
||||||
|
- **Примечание:** См. `Минимизация поверхности атаки nginx — проверка.md` п. 1–2.
|
||||||
|
- **9.2 Отключение неиспользуемых возможностей конфигурацией**
|
||||||
|
- Описание реализации: Неиспользуемые возможности должны быть отключены в конфигурации: autoindex, лишние методы, лишние proxy/FastCGI-направления.
|
||||||
|
- Модуль / механизм: Конфигурация nginx
|
||||||
|
- Комментарий: Это не отдельная функция nginx, а требование безопасной эксплуатации.
|
||||||
|
- Проверка:
|
||||||
|
- **Статус:** Подтверждено
|
||||||
|
- **Ревью функции:** Описание реализации и заявленный механизм соответствуют документации nginx. Неиспользуемые возможности отключаются конфигурацией: `autoindex off`, ограничение методов через `limit_except`, удаление неиспользуемых `location` с `proxy_pass`/`fastcgi_pass`.
|
||||||
|
- **Источник:** https://nginx.org/en/docs/http/ngx_http_autoindex_module.html , https://nginx.org/en/docs/http/ngx_http_core_module.html#limit_except
|
||||||
|
- **Результат:** Неиспользуемые возможности отключаются конфигурацией: `autoindex off`, ограничение методов через `limit_except`, удаление неиспользуемых `location` с `proxy_pass`/`fastcgi_pass`. Это требование безопасной эксплуатации, а не отдельный модуль.
|
||||||
|
- **Пример конфигурации:**
|
||||||
|
```nginx
|
||||||
|
server {
|
||||||
|
autoindex off;
|
||||||
|
|
||||||
|
location / {
|
||||||
|
limit_except GET HEAD POST {
|
||||||
|
deny all;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Неиспользуемые направления не включаются в конфигурацию
|
||||||
|
# location /legacy-api/ { proxy_pass http://old-backend; }
|
||||||
|
}
|
||||||
|
```
|
||||||
|
- **Примечание:** См. `Минимизация поверхности атаки nginx — проверка.md` п. 4–10.
|
||||||
|
- **9.3 Контроль целостности конфигурации и разрешённых директорий**
|
||||||
|
- Описание реализации: Конфигурация nginx и разрешённые директории веб-контента должны контролироваться внешним механизмом целостности.
|
||||||
|
- Модуль / механизм: afick или иной утверждённый механизм
|
||||||
|
- Комментарий: nginx не выполняет контроль целостности сам. Это внешняя мера, требуемая для сертификационной логики.
|
||||||
|
- Проверка:
|
||||||
|
- **Статус:** Не применимо к nginx напрямую (внешняя мера)
|
||||||
|
- **Ревью функции:** Корректно отнесено к внешней мере: nginx не реализует функцию напрямую. nginx не реализует контроль целостности файлов (FIM).
|
||||||
|
- **Источник:** https://nginx.org/en/docs/ (функция FIM в nginx не описана)
|
||||||
|
- **Результат:** nginx не реализует контроль целостности файлов (FIM). Данное требование выполняется внешними средствами: afick, AIDE, OSSEC или иным утверждённым механизмом. Контролируемые объекты: `/etc/nginx/` (конфигурация), директории `root`/`alias` веб-контента.
|
||||||
|
- **Пример реализации:**
|
||||||
|
```
|
||||||
|
# /etc/afick.conf (фрагмент)
|
||||||
|
/etc/nginx/ R
|
||||||
|
/var/www/ R
|
||||||
|
```
|
||||||
|
- **Примечание:** См. `Минимизация поверхности атаки nginx — проверка.md` п. 4–10.
|
||||||
|
- **Примечание:** Для ПМИ проверяется наличие и работоспособность внешнего средства, а не конфигурация nginx. Статус отражает внешнюю меру (см. `Контроль целостности хранимого кода и конфигурации — проверка.md`; ПМИ п. 24; `Контроль выполнения кода — проверка.md` п. 15–16).
|
||||||
3
results/Dockerfile.test-runner
Normal file
3
results/Dockerfile.test-runner
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
FROM alpine:3.21
|
||||||
|
RUN apk add --no-cache bash curl openssl coreutils grep findutils wget
|
||||||
|
CMD ["sleep", "infinity"]
|
||||||
59
results/README.md
Normal file
59
results/README.md
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
# nginx PMI test stand
|
||||||
|
|
||||||
|
Воспроизводимый стенд для практических проверок из каталога [`docs/`](../docs/).
|
||||||
|
|
||||||
|
## Требования
|
||||||
|
|
||||||
|
- Docker Desktop (Windows)
|
||||||
|
- Свободные порты **8080** (HTTP) и **8443** (HTTPS)
|
||||||
|
|
||||||
|
## Быстрый запуск
|
||||||
|
|
||||||
|
```bat
|
||||||
|
cd c:\work\astro\nginx\results
|
||||||
|
run.bat
|
||||||
|
```
|
||||||
|
|
||||||
|
Скрипт:
|
||||||
|
|
||||||
|
1. Генерирует TLS-сертификаты и `htpasswd` (user / password)
|
||||||
|
2. Поднимает Docker Compose стенд
|
||||||
|
3. Выполняет 24 мероприятия ПМИ
|
||||||
|
4. Запускает аудиты полномочий, поверхности атаки и контроля кода
|
||||||
|
5. Проверяет целостность (SHA256 baseline вместо afick)
|
||||||
|
6. Сохраняет отчёты в `reports/`
|
||||||
|
|
||||||
|
## Структура
|
||||||
|
|
||||||
|
| Путь | Назначение |
|
||||||
|
|------|------------|
|
||||||
|
| `docker-compose.yml` | nginx, mock-backend, auth, syslog, test-runner |
|
||||||
|
| `nginx/` | Конфигурация стенда |
|
||||||
|
| `scripts/` | Генерация, тесты, аудит |
|
||||||
|
| `reports/` | Результаты прогонов (`YYYY-MM-DD_HH-MM-SS_*.log`) |
|
||||||
|
| `run.bat` | Оркестратор для Windows cmd |
|
||||||
|
|
||||||
|
## Ручной запуск
|
||||||
|
|
||||||
|
```bat
|
||||||
|
docker compose up -d
|
||||||
|
docker compose exec test-runner sh /scripts/run-pmi-tests.sh
|
||||||
|
docker compose exec nginx sh /scripts/run-audit-permissions.sh
|
||||||
|
docker compose down
|
||||||
|
```
|
||||||
|
|
||||||
|
## Ограничения стенда
|
||||||
|
|
||||||
|
- **FIM (п. 24):** checksum-скрипт, не afick
|
||||||
|
- **Syslog (п. 14):** локальный syslog-ng в Compose
|
||||||
|
- **mTLS/TLS:** самоподписанные сертификаты в `ssl/`
|
||||||
|
- **П. 1 (IP):** два интерфейса test-runner (`172.28.x` / `172.29.x`) вместо двух физических хостов
|
||||||
|
|
||||||
|
## Учётные данные
|
||||||
|
|
||||||
|
- Basic Auth: `user` / `password`
|
||||||
|
- HTTPS: самоподписанный сертификат (для curl используйте `-k`)
|
||||||
|
|
||||||
|
## Документация
|
||||||
|
|
||||||
|
Методика проверок: [`docs/Проверочные_мероприятия_для_ПМИ_—_проверка.md`](../docs/Проверочные_мероприятия_для_ПМИ_—_проверка.md)
|
||||||
109
results/docker-compose.yml
Normal file
109
results/docker-compose.yml
Normal file
@@ -0,0 +1,109 @@
|
|||||||
|
services:
|
||||||
|
nginx:
|
||||||
|
image: nginx:1.26-alpine
|
||||||
|
container_name: nginx-pmi
|
||||||
|
ports:
|
||||||
|
- "8080:80"
|
||||||
|
- "8443:443"
|
||||||
|
volumes:
|
||||||
|
- ./nginx/nginx.conf:/etc/nginx/nginx.conf:ro
|
||||||
|
- ./nginx/conf.d:/etc/nginx/conf.d:ro
|
||||||
|
- ./nginx/htpasswd:/etc/nginx/htpasswd:ro
|
||||||
|
- ./www:/usr/share/nginx/html:ro
|
||||||
|
- ./ssl:/etc/nginx/ssl:ro
|
||||||
|
- ./scripts:/scripts:ro
|
||||||
|
- ./fim-watch:/fim-watch
|
||||||
|
- ./reports:/reports
|
||||||
|
- nginx-cache:/var/cache/nginx
|
||||||
|
- nginx-logs:/var/log/nginx
|
||||||
|
depends_on:
|
||||||
|
- backend
|
||||||
|
- slow-backend
|
||||||
|
- auth-mock
|
||||||
|
- syslog-ng
|
||||||
|
networks:
|
||||||
|
allowed-net:
|
||||||
|
ipv4_address: 172.28.0.2
|
||||||
|
denied-net:
|
||||||
|
ipv4_address: 172.29.0.2
|
||||||
|
internal:
|
||||||
|
healthcheck:
|
||||||
|
test: ["CMD", "wget", "-q", "-O", "/dev/null", "http://127.0.0.1/public/index.html"]
|
||||||
|
interval: 5s
|
||||||
|
timeout: 3s
|
||||||
|
retries: 12
|
||||||
|
|
||||||
|
backend:
|
||||||
|
image: nginx:1.26-alpine
|
||||||
|
container_name: nginx-pmi-backend
|
||||||
|
volumes:
|
||||||
|
- ./mock/backend.conf:/etc/nginx/conf.d/default.conf:ro
|
||||||
|
networks:
|
||||||
|
- internal
|
||||||
|
|
||||||
|
slow-backend:
|
||||||
|
image: python:3.12-alpine
|
||||||
|
container_name: nginx-pmi-slow
|
||||||
|
command: ["python", "/app/slow-server.py"]
|
||||||
|
volumes:
|
||||||
|
- ./mock/slow-server.py:/app/slow-server.py:ro
|
||||||
|
networks:
|
||||||
|
- internal
|
||||||
|
|
||||||
|
auth-mock:
|
||||||
|
image: python:3.12-alpine
|
||||||
|
container_name: nginx-pmi-auth
|
||||||
|
command: ["python", "/app/auth-server.py"]
|
||||||
|
volumes:
|
||||||
|
- ./mock/auth-server.py:/app/auth-server.py:ro
|
||||||
|
- auth-mode:/auth-mode
|
||||||
|
networks:
|
||||||
|
- internal
|
||||||
|
|
||||||
|
syslog-ng:
|
||||||
|
image: balabit/syslog-ng:4.7.1
|
||||||
|
container_name: nginx-pmi-syslog
|
||||||
|
volumes:
|
||||||
|
- ./mock/syslog-ng.conf:/etc/syslog-ng/syslog-ng.conf:ro
|
||||||
|
- ./reports:/reports
|
||||||
|
networks:
|
||||||
|
- internal
|
||||||
|
|
||||||
|
test-runner:
|
||||||
|
build:
|
||||||
|
context: .
|
||||||
|
dockerfile: Dockerfile.test-runner
|
||||||
|
container_name: nginx-pmi-test-runner
|
||||||
|
volumes:
|
||||||
|
- ./scripts:/scripts:ro
|
||||||
|
- ./ssl:/ssl:ro
|
||||||
|
- ./reports:/reports
|
||||||
|
- auth-mode:/auth-mode
|
||||||
|
depends_on:
|
||||||
|
nginx:
|
||||||
|
condition: service_healthy
|
||||||
|
networks:
|
||||||
|
allowed-net:
|
||||||
|
ipv4_address: 172.28.0.20
|
||||||
|
denied-net:
|
||||||
|
ipv4_address: 172.29.0.20
|
||||||
|
internal:
|
||||||
|
|
||||||
|
networks:
|
||||||
|
allowed-net:
|
||||||
|
driver: bridge
|
||||||
|
ipam:
|
||||||
|
config:
|
||||||
|
- subnet: 172.28.0.0/16
|
||||||
|
denied-net:
|
||||||
|
driver: bridge
|
||||||
|
ipam:
|
||||||
|
config:
|
||||||
|
- subnet: 172.29.0.0/16
|
||||||
|
internal:
|
||||||
|
driver: bridge
|
||||||
|
|
||||||
|
volumes:
|
||||||
|
nginx-cache:
|
||||||
|
nginx-logs:
|
||||||
|
auth-mode:
|
||||||
1
results/fim-watch/config.snippet
Normal file
1
results/fim-watch/config.snippet
Normal file
@@ -0,0 +1 @@
|
|||||||
|
# FIM watch file for integrity test (PMI p.24 stand-in)
|
||||||
9
results/mock/auth-mock.conf
Normal file
9
results/mock/auth-mock.conf
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
server {
|
||||||
|
listen 9999;
|
||||||
|
server_name auth-mock;
|
||||||
|
|
||||||
|
location /validate {
|
||||||
|
default_type text/plain;
|
||||||
|
return 200 "auth-ok\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
31
results/mock/auth-server.py
Normal file
31
results/mock/auth-server.py
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
"""Mock auth service for auth_request PMI test."""
|
||||||
|
from http.server import BaseHTTPRequestHandler, ThreadingHTTPServer
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
MODE_FILE = Path("/auth-mode/mode")
|
||||||
|
|
||||||
|
|
||||||
|
def current_mode() -> int:
|
||||||
|
if MODE_FILE.exists():
|
||||||
|
try:
|
||||||
|
return int(MODE_FILE.read_text().strip())
|
||||||
|
except ValueError:
|
||||||
|
pass
|
||||||
|
return 200
|
||||||
|
|
||||||
|
|
||||||
|
class AuthHandler(BaseHTTPRequestHandler):
|
||||||
|
def do_GET(self):
|
||||||
|
code = current_mode()
|
||||||
|
self.send_response(code)
|
||||||
|
self.send_header("Content-Type", "text/plain")
|
||||||
|
self.end_headers()
|
||||||
|
self.wfile.write(f"auth-{code}\n".encode())
|
||||||
|
|
||||||
|
def log_message(self, fmt, *args):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
ThreadingHTTPServer(("0.0.0.0", 9999), AuthHandler).serve_forever()
|
||||||
14
results/mock/backend.conf
Normal file
14
results/mock/backend.conf
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
server {
|
||||||
|
listen 80;
|
||||||
|
server_name backend;
|
||||||
|
|
||||||
|
location /status {
|
||||||
|
default_type text/plain;
|
||||||
|
return 200 "backend-ok\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
location / {
|
||||||
|
default_type text/plain;
|
||||||
|
return 200 "backend-default\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
20
results/mock/slow-server.py
Normal file
20
results/mock/slow-server.py
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
"""HTTP backend that delays each response for limit_conn tests."""
|
||||||
|
from http.server import BaseHTTPRequestHandler, ThreadingHTTPServer
|
||||||
|
import time
|
||||||
|
|
||||||
|
|
||||||
|
class SlowHandler(BaseHTTPRequestHandler):
|
||||||
|
def do_GET(self):
|
||||||
|
time.sleep(5)
|
||||||
|
self.send_response(200)
|
||||||
|
self.send_header("Content-Type", "text/plain")
|
||||||
|
self.end_headers()
|
||||||
|
self.wfile.write(b"slow-ok\n")
|
||||||
|
|
||||||
|
def log_message(self, fmt, *args):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
ThreadingHTTPServer(("0.0.0.0", 8081), SlowHandler).serve_forever()
|
||||||
15
results/mock/syslog-ng.conf
Normal file
15
results/mock/syslog-ng.conf
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
@version: 4.7
|
||||||
|
@include "scl.conf"
|
||||||
|
|
||||||
|
source s_network {
|
||||||
|
network(ip(0.0.0.0) port(514) transport("udp"));
|
||||||
|
};
|
||||||
|
|
||||||
|
destination d_file {
|
||||||
|
file("/reports/nginx-syslog.log" template("$ISODATE $HOST $MSGHDR$MSG\n"));
|
||||||
|
};
|
||||||
|
|
||||||
|
log {
|
||||||
|
source(s_network);
|
||||||
|
destination(d_file);
|
||||||
|
};
|
||||||
186
results/nginx/conf.d/pmi.conf
Normal file
186
results/nginx/conf.d/pmi.conf
Normal file
@@ -0,0 +1,186 @@
|
|||||||
|
upstream approved_backend {
|
||||||
|
server backend:80;
|
||||||
|
}
|
||||||
|
|
||||||
|
upstream slow_upstream {
|
||||||
|
server slow-backend:8081;
|
||||||
|
}
|
||||||
|
|
||||||
|
# П.11: принудительный редирект HTTP -> HTTPS
|
||||||
|
server {
|
||||||
|
listen 80;
|
||||||
|
server_name redirect-test;
|
||||||
|
|
||||||
|
return 301 https://$host:8443$request_uri;
|
||||||
|
}
|
||||||
|
|
||||||
|
# Основной HTTP-сервер (ПМИ п. 1-2, 4-8, 12-23)
|
||||||
|
server {
|
||||||
|
listen 80 default_server;
|
||||||
|
server_name nginx-test;
|
||||||
|
|
||||||
|
root /usr/share/nginx/html/public;
|
||||||
|
index index.html;
|
||||||
|
|
||||||
|
error_page 404 /custom_404.html;
|
||||||
|
|
||||||
|
location = /custom_404.html {
|
||||||
|
root /usr/share/nginx/html/errors;
|
||||||
|
internal;
|
||||||
|
}
|
||||||
|
|
||||||
|
# П.1, П.6: ограничение по IP
|
||||||
|
location /admin/ {
|
||||||
|
allow 172.28.0.0/16;
|
||||||
|
deny all;
|
||||||
|
alias /usr/share/nginx/html/public/;
|
||||||
|
try_files /index.html =404;
|
||||||
|
}
|
||||||
|
|
||||||
|
# П.2: Basic Authentication
|
||||||
|
location /secure/ {
|
||||||
|
auth_basic "Restricted";
|
||||||
|
auth_basic_user_file /etc/nginx/htpasswd;
|
||||||
|
alias /usr/share/nginx/html/public/;
|
||||||
|
try_files /index.html =404;
|
||||||
|
}
|
||||||
|
|
||||||
|
# П.5: satisfy all (IP + пароль)
|
||||||
|
location /admin-combined/ {
|
||||||
|
satisfy all;
|
||||||
|
allow 172.28.0.0/16;
|
||||||
|
deny all;
|
||||||
|
auth_basic "Admin";
|
||||||
|
auth_basic_user_file /etc/nginx/htpasswd;
|
||||||
|
alias /usr/share/nginx/html/public/;
|
||||||
|
try_files /index.html =404;
|
||||||
|
}
|
||||||
|
|
||||||
|
# П.4: auth_request
|
||||||
|
location = /auth {
|
||||||
|
internal;
|
||||||
|
proxy_pass http://auth-mock:9999/validate;
|
||||||
|
proxy_pass_request_body off;
|
||||||
|
proxy_set_header Content-Length "";
|
||||||
|
}
|
||||||
|
|
||||||
|
location /auth-protected/ {
|
||||||
|
auth_request /auth;
|
||||||
|
proxy_pass http://approved_backend/;
|
||||||
|
}
|
||||||
|
|
||||||
|
# П.7: limit_except
|
||||||
|
location /api/ {
|
||||||
|
limit_except GET POST {
|
||||||
|
deny all;
|
||||||
|
}
|
||||||
|
proxy_pass http://approved_backend/;
|
||||||
|
}
|
||||||
|
|
||||||
|
# П.8: internal
|
||||||
|
location /protected/ {
|
||||||
|
internal;
|
||||||
|
alias /usr/share/nginx/html/protected/;
|
||||||
|
}
|
||||||
|
|
||||||
|
location /download {
|
||||||
|
rewrite ^ /protected/document.pdf last;
|
||||||
|
}
|
||||||
|
|
||||||
|
# П.13: error log через недоступный upstream
|
||||||
|
location /broken/ {
|
||||||
|
proxy_connect_timeout 2s;
|
||||||
|
proxy_read_timeout 2s;
|
||||||
|
proxy_pass http://127.0.0.1:59999/;
|
||||||
|
}
|
||||||
|
|
||||||
|
# П.12: access log
|
||||||
|
location /test-page {
|
||||||
|
default_type text/plain;
|
||||||
|
return 200 "test-page-ok\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
location /another-page {
|
||||||
|
default_type text/plain;
|
||||||
|
return 200 "another-page-ok\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
# П.15: limit_req
|
||||||
|
location = /rate-limit-check {
|
||||||
|
limit_req zone=pmi_uri burst=1 nodelay;
|
||||||
|
limit_req_status 503;
|
||||||
|
proxy_pass http://approved_backend/status;
|
||||||
|
}
|
||||||
|
|
||||||
|
location /rate-limit/ {
|
||||||
|
limit_req zone=pmi_uri burst=1 nodelay;
|
||||||
|
limit_req_status 503;
|
||||||
|
proxy_pass http://approved_backend/status;
|
||||||
|
}
|
||||||
|
|
||||||
|
# П.16: limit_conn
|
||||||
|
location /slow/ {
|
||||||
|
limit_conn pmi_conn 2;
|
||||||
|
proxy_pass http://slow_upstream/;
|
||||||
|
proxy_read_timeout 60s;
|
||||||
|
}
|
||||||
|
|
||||||
|
# П.17, П.18: upload
|
||||||
|
location /upload {
|
||||||
|
default_type text/plain;
|
||||||
|
return 200 "upload-ok\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
# П.21: autoindex off
|
||||||
|
location /files/ {
|
||||||
|
autoindex off;
|
||||||
|
alias /usr/share/nginx/html/files/;
|
||||||
|
}
|
||||||
|
|
||||||
|
location /public/ {
|
||||||
|
alias /usr/share/nginx/html/public/;
|
||||||
|
}
|
||||||
|
|
||||||
|
location / {
|
||||||
|
try_files $uri =404;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# П.9, П.10, П.11 (HSTS): HTTPS без клиентского сертификата
|
||||||
|
server {
|
||||||
|
listen 443 ssl;
|
||||||
|
server_name nginx-test;
|
||||||
|
|
||||||
|
ssl_certificate /etc/nginx/ssl/fullchain.crt;
|
||||||
|
ssl_certificate_key /etc/nginx/ssl/server.key;
|
||||||
|
ssl_protocols TLSv1.2 TLSv1.3;
|
||||||
|
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256;
|
||||||
|
ssl_prefer_server_ciphers on;
|
||||||
|
|
||||||
|
add_header Strict-Transport-Security "max-age=31536000" always;
|
||||||
|
|
||||||
|
root /usr/share/nginx/html/public;
|
||||||
|
index index.html;
|
||||||
|
|
||||||
|
location / {
|
||||||
|
try_files $uri =404;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# П.3: mTLS (клиентский сертификат)
|
||||||
|
server {
|
||||||
|
listen 443 ssl;
|
||||||
|
server_name nginx-test-mtls;
|
||||||
|
|
||||||
|
ssl_certificate /etc/nginx/ssl/fullchain.crt;
|
||||||
|
ssl_certificate_key /etc/nginx/ssl/server.key;
|
||||||
|
ssl_client_certificate /etc/nginx/ssl/ca.crt;
|
||||||
|
ssl_verify_client on;
|
||||||
|
ssl_verify_depth 2;
|
||||||
|
ssl_protocols TLSv1.2 TLSv1.3;
|
||||||
|
|
||||||
|
location / {
|
||||||
|
default_type text/plain;
|
||||||
|
return 200 "mtls-ok\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
1
results/nginx/htpasswd
Normal file
1
results/nginx/htpasswd
Normal file
@@ -0,0 +1 @@
|
|||||||
|
user:$apr1$279GWHiN$DLoGAZKGBUan4Xj7kLXjF/
|
||||||
43
results/nginx/nginx.conf
Normal file
43
results/nginx/nginx.conf
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
user nginx;
|
||||||
|
worker_processes auto;
|
||||||
|
error_log /reports/nginx-file-error.log warn;
|
||||||
|
pid /var/run/nginx.pid;
|
||||||
|
|
||||||
|
events {
|
||||||
|
worker_connections 1024;
|
||||||
|
}
|
||||||
|
|
||||||
|
http {
|
||||||
|
include /etc/nginx/mime.types;
|
||||||
|
default_type application/octet-stream;
|
||||||
|
|
||||||
|
server_tokens off;
|
||||||
|
autoindex off;
|
||||||
|
ssi off;
|
||||||
|
|
||||||
|
sendfile on;
|
||||||
|
keepalive_timeout 30s;
|
||||||
|
|
||||||
|
log_format pmi '$remote_addr - [$time_local] "$request" $status $body_bytes_sent';
|
||||||
|
|
||||||
|
limit_req_zone $binary_remote_addr zone=pmi_req:10m rate=2r/s;
|
||||||
|
limit_req_zone $request_uri zone=pmi_uri:10m rate=1r/m;
|
||||||
|
limit_conn_zone $binary_remote_addr zone=pmi_conn:10m;
|
||||||
|
|
||||||
|
client_body_temp_path /var/cache/nginx/client_temp;
|
||||||
|
proxy_temp_path /var/cache/nginx/proxy_temp;
|
||||||
|
fastcgi_temp_path /var/cache/nginx/fastcgi_temp;
|
||||||
|
|
||||||
|
client_body_timeout 5s;
|
||||||
|
client_header_timeout 5s;
|
||||||
|
send_timeout 10s;
|
||||||
|
client_max_body_size 1m;
|
||||||
|
|
||||||
|
access_log /reports/nginx-file-access.log pmi;
|
||||||
|
error_log /reports/nginx-file-error.log warn;
|
||||||
|
|
||||||
|
access_log syslog:server=syslog-ng:514,facility=local7,tag=nginx,severity=info pmi;
|
||||||
|
error_log syslog:server=syslog-ng:514,facility=local7,tag=nginx,severity=error;
|
||||||
|
|
||||||
|
include /etc/nginx/conf.d/*.conf;
|
||||||
|
}
|
||||||
140
results/reports/2026-06-14_06-37-41_audit.log
Normal file
140
results/reports/2026-06-14_06-37-41_audit.log
Normal file
@@ -0,0 +1,140 @@
|
|||||||
|
Permissions audit 2026-06-14T06:37:59+00:00
|
||||||
|
|
||||||
|
=== Worker user ===
|
||||||
|
user nginx;
|
||||||
|
1 root 0:00 nginx: master process nginx -g daemon off;
|
||||||
|
20 nginx 0:00 nginx: worker process
|
||||||
|
21 nginx 0:00 nginx: worker process
|
||||||
|
22 nginx 0:00 nginx: worker process
|
||||||
|
23 nginx 0:00 nginx: worker process
|
||||||
|
24 nginx 0:00 nginx: worker process
|
||||||
|
25 nginx 0:00 nginx: worker process
|
||||||
|
26 nginx 0:00 nginx: worker process
|
||||||
|
27 nginx 0:00 nginx: worker process
|
||||||
|
28 nginx 0:00 nginx: worker process
|
||||||
|
29 nginx 0:00 nginx: worker process
|
||||||
|
30 nginx 0:00 nginx: worker process
|
||||||
|
31 nginx 0:00 nginx: worker process
|
||||||
|
32 nginx 0:00 nginx: worker process
|
||||||
|
33 nginx 0:00 nginx: worker process
|
||||||
|
34 nginx 0:00 nginx: worker process
|
||||||
|
35 nginx 0:00 nginx: worker process
|
||||||
|
36 nginx 0:00 nginx: worker process
|
||||||
|
37 nginx 0:00 nginx: worker process
|
||||||
|
38 nginx 0:00 nginx: worker process
|
||||||
|
39 nginx 0:00 nginx: worker process
|
||||||
|
|
||||||
|
=== Config permissions ===
|
||||||
|
total 40
|
||||||
|
drwxr-xr-x 1 root root 4096 Jun 14 05:28 .
|
||||||
|
drwxr-xr-x 1 root root 4096 Jun 14 05:28 ..
|
||||||
|
drwxrwxrwx 1 root root 4096 Jun 14 04:56 conf.d
|
||||||
|
-rw-r--r-- 1 root root 1077 Feb 5 2025 fastcgi.conf
|
||||||
|
-rw-r--r-- 1 root root 1007 Feb 5 2025 fastcgi_params
|
||||||
|
-rw-r--r-- 1 root root 43 Jun 14 06:37 htpasswd
|
||||||
|
-rw-r--r-- 1 root root 5349 Feb 5 2025 mime.types
|
||||||
|
lrwxrwxrwx 1 root root 22 Apr 16 2025 modules -> /usr/lib/nginx/modules
|
||||||
|
-rwxrwxrwx 1 root root 1233 Jun 14 06:27 nginx.conf
|
||||||
|
-rw-r--r-- 1 root root 636 Feb 5 2025 scgi_params
|
||||||
|
drwxrwxrwx 1 root root 4096 Jun 14 06:37 ssl
|
||||||
|
-rw-r--r-- 1 root root 664 Feb 5 2025 uwsgi_params
|
||||||
|
-rwxrwxrwx 1 root root 1233 Jun 14 06:27 /etc/nginx/nginx.conf
|
||||||
|
FAIL: nginx can write nginx.conf
|
||||||
|
|
||||||
|
=== Web root permissions ===
|
||||||
|
total 0
|
||||||
|
drwxrwxrwx 1 root root 4096 Jun 14 04:56 .
|
||||||
|
drwxrwxrwx 1 root root 4096 Jun 14 04:55 ..
|
||||||
|
-rwxrwxrwx 1 root root 138 Jun 14 04:56 index.html
|
||||||
|
FAIL: nginx can write web root
|
||||||
|
|
||||||
|
=== TLS certificates and keys ===
|
||||||
|
total 40
|
||||||
|
drwxrwxrwx 1 root root 4096 Jun 14 06:37 .
|
||||||
|
drwxr-xr-x 1 root root 4096 Jun 14 05:28 ..
|
||||||
|
-rw-r--r-- 1 root root 1814 Jun 14 06:37 ca.crt
|
||||||
|
-rw------- 1 root root 3272 Jun 14 06:37 ca.key
|
||||||
|
-rw-r--r-- 1 root root 1448 Jun 14 06:37 client.crt
|
||||||
|
-rw------- 1 root root 1704 Jun 14 06:37 client.key
|
||||||
|
-rw-r--r-- 1 root root 3254 Jun 14 06:37 fullchain.crt
|
||||||
|
-rw-r--r-- 1 root root 1440 Jun 14 06:37 server.crt
|
||||||
|
-rw------- 1 root root 1704 Jun 14 06:37 server.key
|
||||||
|
-rw-r--r-- 1 root root 1131 Jun 14 06:37 untrusted.crt
|
||||||
|
-rw------- 1 root root 1704 Jun 14 06:37 untrusted.key
|
||||||
|
OK: nginx cannot read private key
|
||||||
|
|
||||||
|
=== htpasswd ===
|
||||||
|
-rw-r--r-- 1 root root 43 Jun 14 06:37 /etc/nginx/htpasswd
|
||||||
|
OK: nginx cannot write htpasswd
|
||||||
|
|
||||||
|
=== Logs ===
|
||||||
|
total 8
|
||||||
|
drwxr-xr-x 2 root root 4096 Jun 14 05:18 .
|
||||||
|
drwxr-xr-x 1 root root 4096 Apr 16 2025 ..
|
||||||
|
lrwxrwxrwx 1 root root 11 Apr 16 2025 access.log -> /dev/stdout
|
||||||
|
lrwxrwxrwx 1 root root 11 Apr 16 2025 error.log -> /dev/stderr
|
||||||
|
|
||||||
|
=== Temp/cache paths ===
|
||||||
|
total 28
|
||||||
|
drwxr-xr-x 7 root root 4096 Jun 14 05:18 .
|
||||||
|
drwxr-xr-x 1 root root 4096 Apr 16 2025 ..
|
||||||
|
drwx------ 2 nginx root 4096 Jun 14 05:18 client_temp
|
||||||
|
drwx------ 2 nginx root 4096 Jun 14 05:18 fastcgi_temp
|
||||||
|
drwx------ 2 nginx root 4096 Jun 14 05:18 proxy_temp
|
||||||
|
drwx------ 2 nginx root 4096 Jun 14 05:18 scgi_temp
|
||||||
|
drwx------ 2 nginx root 4096 Jun 14 05:18 uwsgi_temp
|
||||||
|
client_body_temp_path /var/cache/nginx/client_temp;
|
||||||
|
proxy_temp_path /var/cache/nginx/proxy_temp;
|
||||||
|
|
||||||
|
=== Attack surface audit 2026-06-14T06:38:00+00:00 ===
|
||||||
|
--- nginx -V ---
|
||||||
|
nginx version: nginx/1.26.3
|
||||||
|
built by gcc 13.2.1 20240309 (Alpine 13.2.1_git20240309)
|
||||||
|
built with OpenSSL 3.3.0 9 Apr 2024 (running with OpenSSL 3.3.3 11 Feb 2025)
|
||||||
|
TLS SNI support enabled
|
||||||
|
configure arguments: --prefix=/etc/nginx --sbin-path=/usr/sbin/nginx --modules-path=/usr/lib/nginx/modules --conf-path=/etc/nginx/nginx.conf --error-log-path=/var/log/nginx/error.log --http-log-path=/var/log/nginx/access.log --pid-path=/var/run/nginx.pid --lock-path=/var/run/nginx.lock --http-client-body-temp-path=/var/cache/nginx/client_temp --http-proxy-temp-path=/var/cache/nginx/proxy_temp --http-fastcgi-temp-path=/var/cache/nginx/fastcgi_temp --http-uwsgi-temp-path=/var/cache/nginx/uwsgi_temp --http-scgi-temp-path=/var/cache/nginx/scgi_temp --with-perl_modules_path=/usr/lib/perl5/vendor_perl --user=nginx --group=nginx --with-compat --with-file-aio --with-threads --with-http_addition_module --with-http_auth_request_module --with-http_dav_module --with-http_flv_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_mp4_module --with-http_random_index_module --with-http_realip_module --with-http_secure_link_module --with-http_slice_module --with-http_ssl_module --with-http_stub_status_module --with-http_sub_module --with-http_v2_module --with-http_v3_module --with-mail --with-mail_ssl_module --with-stream --with-stream_realip_module --with-stream_ssl_module --with-stream_ssl_preread_module --with-cc-opt='-Os -fstack-clash-protection -Wformat -Werror=format-security -fno-plt -g' --with-ld-opt='-Wl,--as-needed,-O1,--sort-common -Wl,-z,pack-relative-relocs'
|
||||||
|
--- load_module ---
|
||||||
|
(none)
|
||||||
|
--- optional modules in config ---
|
||||||
|
application/x-perl pl pm;
|
||||||
|
# П.4: auth_request
|
||||||
|
auth_request /auth;
|
||||||
|
--- autoindex ---
|
||||||
|
autoindex off;
|
||||||
|
# П.21: autoindex off
|
||||||
|
autoindex off;
|
||||||
|
--- limit_except / request_method ---
|
||||||
|
# П.7: limit_except
|
||||||
|
limit_except GET POST {
|
||||||
|
--- proxy_pass / upstream ---
|
||||||
|
upstream approved_backend {
|
||||||
|
upstream slow_upstream {
|
||||||
|
proxy_pass http://auth-mock:9999/validate;
|
||||||
|
proxy_pass_request_body off;
|
||||||
|
proxy_pass http://approved_backend/;
|
||||||
|
proxy_pass http://approved_backend/;
|
||||||
|
# П.13: error log через недоступный upstream
|
||||||
|
proxy_pass http://127.0.0.1:59999/;
|
||||||
|
proxy_pass http://approved_backend/status;
|
||||||
|
proxy_pass http://approved_backend/status;
|
||||||
|
proxy_pass http://slow_upstream/;
|
||||||
|
--- ssi ---
|
||||||
|
(ssi off)
|
||||||
|
|
||||||
|
=== Code execution control audit 2026-06-14T06:38:01+00:00 ===
|
||||||
|
application/x-perl pl pm;
|
||||||
|
root /usr/share/nginx/html/public;
|
||||||
|
root /usr/share/nginx/html/errors;
|
||||||
|
internal;
|
||||||
|
alias /usr/share/nginx/html/public/;
|
||||||
|
alias /usr/share/nginx/html/public/;
|
||||||
|
alias /usr/share/nginx/html/public/;
|
||||||
|
internal;
|
||||||
|
# П.8: internal
|
||||||
|
internal;
|
||||||
|
alias /usr/share/nginx/html/protected/;
|
||||||
|
alias /usr/share/nginx/html/files/;
|
||||||
|
alias /usr/share/nginx/html/public/;
|
||||||
|
root /usr/share/nginx/html/public;
|
||||||
|
--- SCRIPT_FILENAME ---
|
||||||
|
(no fastcgi)
|
||||||
7
results/reports/2026-06-14_06-37-41_fim.log
Normal file
7
results/reports/2026-06-14_06-37-41_fim.log
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
FIM checksum audit 2026-06-14T06:38:01+00:00
|
||||||
|
NOTE: SHA256 baseline substitute for afick on test stand only.
|
||||||
|
Baseline created (22 files)
|
||||||
|
PASS baseline check (no changes)
|
||||||
|
PASS tamper detected after file change (/fim-watch/config.snippet)
|
||||||
|
PASS baseline restored after revert
|
||||||
|
PASS #24 integrity control (checksum substitute for afick)
|
||||||
27
results/reports/2026-06-14_06-37-41_pmi.log
Normal file
27
results/reports/2026-06-14_06-37-41_pmi.log
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
=== PMI tests 2026-06-14T06:37:49+00:00 ===
|
||||||
|
|
||||||
|
PASS #1 IP allow/deny (allowed=200 denied=403)
|
||||||
|
PASS #2 Basic auth (401/401/200)
|
||||||
|
PASS #3 Client TLS certificate (400/200/400)
|
||||||
|
PASS #4 auth_request (200/401/403)
|
||||||
|
PASS #5 satisfy all matrix (200/401/403/403)
|
||||||
|
PASS #6 URL access rules (/public/ vs /admin/)
|
||||||
|
PASS #7 limit_except GET POST (PUT/DELETE=403)
|
||||||
|
PASS #8 internal location (direct=404 rewrite=200)
|
||||||
|
PASS #9 HTTPS TLS handshake
|
||||||
|
PASS #10 TLSv1.2 ok, TLSv1.1 rejected
|
||||||
|
PASS #11 HTTP redirect 301 + HSTS header
|
||||||
|
PASS #14 syslog receives nginx events
|
||||||
|
PASS #15 limit_req returns 503 (3) and 200 (2) in: 200 200 503 503 503
|
||||||
|
PASS #16 limit_conn returns 503 (200200503503503)
|
||||||
|
PASS #17 client_max_body_size (small=200 large=413)
|
||||||
|
PASS #18 client_body_timeout (curl exit 1)
|
||||||
|
PASS #19 server_tokens off
|
||||||
|
PASS #20 custom error_page 404
|
||||||
|
PASS #21 autoindex off (403, no listing)
|
||||||
|
PASS #22 proxy_pass to backend (200)
|
||||||
|
PASS #23 web root restriction (200/404)
|
||||||
|
|
||||||
|
=== Summary: PASS=21 FAIL=0 SKIP=0 ===
|
||||||
|
PASS #12 access_log contains test-page and another-page
|
||||||
|
PASS #13 error_log contains upstream error
|
||||||
69
results/reports/2026-06-14_06-37-41_summary.md
Normal file
69
results/reports/2026-06-14_06-37-41_summary.md
Normal file
@@ -0,0 +1,69 @@
|
|||||||
|
# Сводный отчёт nginx PMI stand
|
||||||
|
|
||||||
|
**Дата прогона:** 2026-06-14_06-37-41
|
||||||
|
**Стенд:** Docker Compose (`results/docker-compose.yml`)
|
||||||
|
|
||||||
|
## Результаты ПМИ
|
||||||
|
|
||||||
|
| Метрика | Значение |
|
||||||
|
|---------|----------|
|
||||||
|
| PASS | 23 |
|
||||||
|
| FAIL | 0 |
|
||||||
|
|
||||||
|
## Целостность (FIM stand-in)
|
||||||
|
|
||||||
|
| Метрика | Значение |
|
||||||
|
|---------|----------|
|
||||||
|
| PASS | 4 |
|
||||||
|
| FAIL | 0 |
|
||||||
|
|
||||||
|
> FIM выполнен через SHA256 baseline (`run-fim-checksum.sh`), не afick.
|
||||||
|
> Syslog проверялся локальным syslog-ng, не корпоративным SIEM.
|
||||||
|
|
||||||
|
## Файлы отчётов
|
||||||
|
|
||||||
|
- [`2026-06-14_06-37-41_pmi.log`](2026-06-14_06-37-41_pmi.log)
|
||||||
|
- [`2026-06-14_06-37-41_audit.log`](2026-06-14_06-37-41_audit.log)
|
||||||
|
- [`2026-06-14_06-37-41_fim.log`](2026-06-14_06-37-41_fim.log)
|
||||||
|
|
||||||
|
## PMI log excerpt
|
||||||
|
|
||||||
|
```
|
||||||
|
=== PMI tests 2026-06-14T06:37:49+00:00 ===
|
||||||
|
PASS #1 IP allow/deny (allowed=200 denied=403)
|
||||||
|
PASS #2 Basic auth (401/401/200)
|
||||||
|
PASS #3 Client TLS certificate (400/200/400)
|
||||||
|
PASS #4 auth_request (200/401/403)
|
||||||
|
PASS #5 satisfy all matrix (200/401/403/403)
|
||||||
|
PASS #6 URL access rules (/public/ vs /admin/)
|
||||||
|
PASS #7 limit_except GET POST (PUT/DELETE=403)
|
||||||
|
PASS #8 internal location (direct=404 rewrite=200)
|
||||||
|
PASS #9 HTTPS TLS handshake
|
||||||
|
PASS #10 TLSv1.2 ok, TLSv1.1 rejected
|
||||||
|
PASS #11 HTTP redirect 301 + HSTS header
|
||||||
|
PASS #14 syslog receives nginx events
|
||||||
|
PASS #15 limit_req returns 503 (3) and 200 (2) in: 200 200 503 503 503
|
||||||
|
PASS #16 limit_conn returns 503 (200200503503503)
|
||||||
|
PASS #17 client_max_body_size (small=200 large=413)
|
||||||
|
PASS #18 client_body_timeout (curl exit 1)
|
||||||
|
PASS #19 server_tokens off
|
||||||
|
PASS #20 custom error_page 404
|
||||||
|
PASS #21 autoindex off (403, no listing)
|
||||||
|
PASS #22 proxy_pass to backend (200)
|
||||||
|
PASS #23 web root restriction (200/404)
|
||||||
|
=== Summary: PASS=21 FAIL=0 SKIP=0 ===
|
||||||
|
PASS #12 access_log contains test-page and another-page
|
||||||
|
PASS #13 error_log contains upstream error
|
||||||
|
```
|
||||||
|
|
||||||
|
## FIM log excerpt
|
||||||
|
|
||||||
|
```
|
||||||
|
FIM checksum audit 2026-06-14T06:38:01+00:00
|
||||||
|
NOTE: SHA256 baseline substitute for afick on test stand only.
|
||||||
|
Baseline created (22 files)
|
||||||
|
PASS baseline check (no changes)
|
||||||
|
PASS tamper detected after file change (/fim-watch/config.snippet)
|
||||||
|
PASS baseline restored after revert
|
||||||
|
PASS #24 integrity control (checksum substitute for afick)
|
||||||
|
```
|
||||||
57
results/reports/nginx-file-access.log
Normal file
57
results/reports/nginx-file-access.log
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
127.0.0.1 - [14/Jun/2026:06:37:58 +0000] "GET /test-page HTTP/1.1" 200 13
|
||||||
|
127.0.0.1 - [14/Jun/2026:06:37:58 +0000] "GET /another-page HTTP/1.1" 200 16
|
||||||
|
127.0.0.1 - [14/Jun/2026:06:37:58 +0000] "GET /broken/ HTTP/1.1" 502 150
|
||||||
|
127.0.0.1 - [14/Jun/2026:06:37:59 +0000] "GET /public/index.html HTTP/1.1" 200 138
|
||||||
|
127.0.0.1 - [14/Jun/2026:06:38:04 +0000] "GET /public/index.html HTTP/1.1" 200 138
|
||||||
|
127.0.0.1 - [14/Jun/2026:06:38:09 +0000] "GET /public/index.html HTTP/1.1" 200 138
|
||||||
|
127.0.0.1 - [14/Jun/2026:06:38:14 +0000] "GET /public/index.html HTTP/1.1" 200 138
|
||||||
|
127.0.0.1 - [14/Jun/2026:06:38:19 +0000] "GET /public/index.html HTTP/1.1" 200 138
|
||||||
|
127.0.0.1 - [14/Jun/2026:06:38:24 +0000] "GET /public/index.html HTTP/1.1" 200 138
|
||||||
|
127.0.0.1 - [14/Jun/2026:06:38:29 +0000] "GET /public/index.html HTTP/1.1" 200 138
|
||||||
|
127.0.0.1 - [14/Jun/2026:06:38:34 +0000] "GET /public/index.html HTTP/1.1" 200 138
|
||||||
|
127.0.0.1 - [14/Jun/2026:06:38:39 +0000] "GET /public/index.html HTTP/1.1" 200 138
|
||||||
|
127.0.0.1 - [14/Jun/2026:06:38:44 +0000] "GET /public/index.html HTTP/1.1" 200 138
|
||||||
|
127.0.0.1 - [14/Jun/2026:06:38:49 +0000] "GET /public/index.html HTTP/1.1" 200 138
|
||||||
|
127.0.0.1 - [14/Jun/2026:06:38:54 +0000] "GET /public/index.html HTTP/1.1" 200 138
|
||||||
|
127.0.0.1 - [14/Jun/2026:06:39:00 +0000] "GET /public/index.html HTTP/1.1" 200 138
|
||||||
|
127.0.0.1 - [14/Jun/2026:06:39:05 +0000] "GET /public/index.html HTTP/1.1" 200 138
|
||||||
|
127.0.0.1 - [14/Jun/2026:06:39:10 +0000] "GET /public/index.html HTTP/1.1" 200 138
|
||||||
|
127.0.0.1 - [14/Jun/2026:06:39:15 +0000] "GET /public/index.html HTTP/1.1" 200 138
|
||||||
|
127.0.0.1 - [14/Jun/2026:06:39:20 +0000] "GET /public/index.html HTTP/1.1" 200 138
|
||||||
|
127.0.0.1 - [14/Jun/2026:06:39:25 +0000] "GET /public/index.html HTTP/1.1" 200 138
|
||||||
|
127.0.0.1 - [14/Jun/2026:06:39:30 +0000] "GET /public/index.html HTTP/1.1" 200 138
|
||||||
|
127.0.0.1 - [14/Jun/2026:06:39:35 +0000] "GET /public/index.html HTTP/1.1" 200 138
|
||||||
|
127.0.0.1 - [14/Jun/2026:06:39:40 +0000] "GET /public/index.html HTTP/1.1" 200 138
|
||||||
|
127.0.0.1 - [14/Jun/2026:06:39:45 +0000] "GET /public/index.html HTTP/1.1" 200 138
|
||||||
|
127.0.0.1 - [14/Jun/2026:06:39:50 +0000] "GET /public/index.html HTTP/1.1" 200 138
|
||||||
|
127.0.0.1 - [14/Jun/2026:06:39:55 +0000] "GET /public/index.html HTTP/1.1" 200 138
|
||||||
|
127.0.0.1 - [14/Jun/2026:06:40:00 +0000] "GET /public/index.html HTTP/1.1" 200 138
|
||||||
|
127.0.0.1 - [14/Jun/2026:06:40:05 +0000] "GET /public/index.html HTTP/1.1" 200 138
|
||||||
|
127.0.0.1 - [14/Jun/2026:06:40:10 +0000] "GET /public/index.html HTTP/1.1" 200 138
|
||||||
|
127.0.0.1 - [14/Jun/2026:06:40:15 +0000] "GET /public/index.html HTTP/1.1" 200 138
|
||||||
|
127.0.0.1 - [14/Jun/2026:06:40:21 +0000] "GET /public/index.html HTTP/1.1" 200 138
|
||||||
|
127.0.0.1 - [14/Jun/2026:06:40:26 +0000] "GET /public/index.html HTTP/1.1" 200 138
|
||||||
|
127.0.0.1 - [14/Jun/2026:06:40:31 +0000] "GET /public/index.html HTTP/1.1" 200 138
|
||||||
|
127.0.0.1 - [14/Jun/2026:06:40:36 +0000] "GET /public/index.html HTTP/1.1" 200 138
|
||||||
|
127.0.0.1 - [14/Jun/2026:06:40:41 +0000] "GET /public/index.html HTTP/1.1" 200 138
|
||||||
|
127.0.0.1 - [14/Jun/2026:06:40:46 +0000] "GET /public/index.html HTTP/1.1" 200 138
|
||||||
|
127.0.0.1 - [14/Jun/2026:06:40:51 +0000] "GET /public/index.html HTTP/1.1" 200 138
|
||||||
|
127.0.0.1 - [14/Jun/2026:06:40:56 +0000] "GET /public/index.html HTTP/1.1" 200 138
|
||||||
|
127.0.0.1 - [14/Jun/2026:06:41:01 +0000] "GET /public/index.html HTTP/1.1" 200 138
|
||||||
|
127.0.0.1 - [14/Jun/2026:06:41:06 +0000] "GET /public/index.html HTTP/1.1" 200 138
|
||||||
|
127.0.0.1 - [14/Jun/2026:06:41:11 +0000] "GET /public/index.html HTTP/1.1" 200 138
|
||||||
|
127.0.0.1 - [14/Jun/2026:06:41:16 +0000] "GET /public/index.html HTTP/1.1" 200 138
|
||||||
|
127.0.0.1 - [14/Jun/2026:06:41:21 +0000] "GET /public/index.html HTTP/1.1" 200 138
|
||||||
|
127.0.0.1 - [14/Jun/2026:06:41:26 +0000] "GET /public/index.html HTTP/1.1" 200 138
|
||||||
|
127.0.0.1 - [14/Jun/2026:06:41:31 +0000] "GET /public/index.html HTTP/1.1" 200 138
|
||||||
|
127.0.0.1 - [14/Jun/2026:06:41:36 +0000] "GET /public/index.html HTTP/1.1" 200 138
|
||||||
|
127.0.0.1 - [14/Jun/2026:06:41:42 +0000] "GET /public/index.html HTTP/1.1" 200 138
|
||||||
|
127.0.0.1 - [14/Jun/2026:06:41:47 +0000] "GET /public/index.html HTTP/1.1" 200 138
|
||||||
|
127.0.0.1 - [14/Jun/2026:06:41:52 +0000] "GET /public/index.html HTTP/1.1" 200 138
|
||||||
|
127.0.0.1 - [14/Jun/2026:06:41:57 +0000] "GET /public/index.html HTTP/1.1" 200 138
|
||||||
|
127.0.0.1 - [14/Jun/2026:06:42:02 +0000] "GET /public/index.html HTTP/1.1" 200 138
|
||||||
|
127.0.0.1 - [14/Jun/2026:06:42:07 +0000] "GET /public/index.html HTTP/1.1" 200 138
|
||||||
|
127.0.0.1 - [14/Jun/2026:06:42:12 +0000] "GET /public/index.html HTTP/1.1" 200 138
|
||||||
|
127.0.0.1 - [14/Jun/2026:06:42:17 +0000] "GET /public/index.html HTTP/1.1" 200 138
|
||||||
|
127.0.0.1 - [14/Jun/2026:06:42:22 +0000] "GET /public/index.html HTTP/1.1" 200 138
|
||||||
|
127.0.0.1 - [14/Jun/2026:06:42:27 +0000] "GET /public/index.html HTTP/1.1" 200 138
|
||||||
1
results/reports/nginx-file-error.log
Normal file
1
results/reports/nginx-file-error.log
Normal file
@@ -0,0 +1 @@
|
|||||||
|
2026/06/14 06:37:58 [error] 20#20: *70 connect() failed (111: Connection refused) while connecting to upstream, client: 127.0.0.1, server: nginx-test, request: "GET /broken/ HTTP/1.1", upstream: "http://127.0.0.1:59999/", host: "127.0.0.1"
|
||||||
130
results/reports/nginx-syslog.log
Normal file
130
results/reports/nginx-syslog.log
Normal file
@@ -0,0 +1,130 @@
|
|||||||
|
2026-06-14T06:37:49+00:00 nginx-pmi nginx: 172.28.0.20 - [14/Jun/2026:06:37:49 +0000] "GET /public/index.html HTTP/1.1" 200 138
|
||||||
|
2026-06-14T06:37:49+00:00 nginx-pmi nginx: 172.28.0.20 - [14/Jun/2026:06:37:49 +0000] "GET /admin/ HTTP/1.1" 200 138
|
||||||
|
2026-06-14T06:37:49+00:00 nginx-pmi nginx: 2026/06/14 06:37:49 [error] 22#22: *3 access forbidden by rule, client: 172.29.0.20, server: nginx-test, request: "GET /admin/ HTTP/1.1", host: "172.29.0.2"
|
||||||
|
2026-06-14T06:37:49+00:00 nginx-pmi nginx: 172.29.0.20 - [14/Jun/2026:06:37:49 +0000] "GET /admin/ HTTP/1.1" 403 146
|
||||||
|
2026-06-14T06:37:49+00:00 nginx-pmi nginx: 172.28.0.20 - [14/Jun/2026:06:37:49 +0000] "GET /secure/ HTTP/1.1" 401 172
|
||||||
|
2026-06-14T06:37:49+00:00 nginx-pmi nginx: 2026/06/14 06:37:49 [error] 25#25: *5 user "wrong" was not found in "/etc/nginx/htpasswd", client: 172.28.0.20, server: nginx-test, request: "GET /secure/ HTTP/1.1", host: "172.28.0.2"
|
||||||
|
2026-06-14T06:37:49+00:00 nginx-pmi nginx: 172.28.0.20 - [14/Jun/2026:06:37:49 +0000] "GET /secure/ HTTP/1.1" 401 172
|
||||||
|
2026-06-14T06:37:49+00:00 nginx-pmi nginx: 172.28.0.20 - [14/Jun/2026:06:37:49 +0000] "GET /secure/ HTTP/1.1" 200 138
|
||||||
|
2026-06-14T06:37:49+00:00 nginx-pmi nginx: 172.28.0.20 - [14/Jun/2026:06:37:49 +0000] "GET / HTTP/1.1" 400 230
|
||||||
|
2026-06-14T06:37:49+00:00 nginx-pmi nginx: 172.28.0.20 - [14/Jun/2026:06:37:49 +0000] "GET / HTTP/1.1" 200 8
|
||||||
|
2026-06-14T06:37:49+00:00 nginx-pmi nginx: 172.28.0.20 - [14/Jun/2026:06:37:49 +0000] "GET / HTTP/1.1" 400 208
|
||||||
|
2026-06-14T06:37:50+00:00 nginx-pmi nginx: 172.28.0.20 - [14/Jun/2026:06:37:50 +0000] "GET /auth-protected/status HTTP/1.1" 200 11
|
||||||
|
2026-06-14T06:37:50+00:00 nginx-pmi nginx: 172.28.0.20 - [14/Jun/2026:06:37:50 +0000] "GET /auth-protected/status HTTP/1.1" 401 172
|
||||||
|
2026-06-14T06:37:51+00:00 nginx-pmi nginx: 172.28.0.20 - [14/Jun/2026:06:37:51 +0000] "GET /auth-protected/status HTTP/1.1" 403 146
|
||||||
|
2026-06-14T06:37:51+00:00 nginx-pmi nginx: 172.28.0.20 - [14/Jun/2026:06:37:51 +0000] "GET /admin-combined/ HTTP/1.1" 200 138
|
||||||
|
2026-06-14T06:37:51+00:00 nginx-pmi nginx: 172.28.0.20 - [14/Jun/2026:06:37:51 +0000] "GET /admin-combined/ HTTP/1.1" 401 172
|
||||||
|
2026-06-14T06:37:51+00:00 nginx-pmi nginx: 2026/06/14 06:37:51 [error] 31#31: *19 access forbidden by rule, client: 172.29.0.20, server: nginx-test, request: "GET /admin-combined/ HTTP/1.1", host: "172.29.0.2"
|
||||||
|
2026-06-14T06:37:51+00:00 nginx-pmi nginx: 172.29.0.20 - [14/Jun/2026:06:37:51 +0000] "GET /admin-combined/ HTTP/1.1" 403 146
|
||||||
|
2026-06-14T06:37:51+00:00 nginx-pmi nginx: 2026/06/14 06:37:51 [error] 32#32: *20 access forbidden by rule, client: 172.29.0.20, server: nginx-test, request: "GET /admin-combined/ HTTP/1.1", host: "172.29.0.2"
|
||||||
|
2026-06-14T06:37:51+00:00 nginx-pmi nginx: 172.29.0.20 - [14/Jun/2026:06:37:51 +0000] "GET /admin-combined/ HTTP/1.1" 403 146
|
||||||
|
2026-06-14T06:37:51+00:00 nginx-pmi nginx: 172.28.0.20 - [14/Jun/2026:06:37:51 +0000] "GET /public/index.html HTTP/1.1" 200 138
|
||||||
|
2026-06-14T06:37:51+00:00 nginx-pmi nginx: 2026/06/14 06:37:51 [error] 34#34: *22 access forbidden by rule, client: 172.29.0.20, server: nginx-test, request: "GET /admin/ HTTP/1.1", host: "172.29.0.2"
|
||||||
|
2026-06-14T06:37:51+00:00 nginx-pmi nginx: 172.29.0.20 - [14/Jun/2026:06:37:51 +0000] "GET /admin/ HTTP/1.1" 403 146
|
||||||
|
2026-06-14T06:37:51+00:00 nginx-pmi nginx: 172.28.0.20 - [14/Jun/2026:06:37:51 +0000] "GET /api/status HTTP/1.1" 200 11
|
||||||
|
2026-06-14T06:37:51+00:00 nginx-pmi nginx: 172.28.0.20 - [14/Jun/2026:06:37:51 +0000] "POST /api/status HTTP/1.1" 200 11
|
||||||
|
2026-06-14T06:37:51+00:00 nginx-pmi nginx: 2026/06/14 06:37:51 [error] 37#37: *27 access forbidden by rule, client: 172.28.0.20, server: nginx-test, request: "PUT /api/status HTTP/1.1", host: "172.28.0.2"
|
||||||
|
2026-06-14T06:37:51+00:00 nginx-pmi nginx: 172.28.0.20 - [14/Jun/2026:06:37:51 +0000] "PUT /api/status HTTP/1.1" 403 146
|
||||||
|
2026-06-14T06:37:51+00:00 nginx-pmi nginx: 2026/06/14 06:37:51 [error] 38#38: *28 access forbidden by rule, client: 172.28.0.20, server: nginx-test, request: "DELETE /api/status HTTP/1.1", host: "172.28.0.2"
|
||||||
|
2026-06-14T06:37:51+00:00 nginx-pmi nginx: 172.28.0.20 - [14/Jun/2026:06:37:51 +0000] "DELETE /api/status HTTP/1.1" 403 146
|
||||||
|
2026-06-14T06:37:51+00:00 nginx-pmi nginx: 172.28.0.20 - [14/Jun/2026:06:37:51 +0000] "GET /protected/document.pdf HTTP/1.1" 404 138
|
||||||
|
2026-06-14T06:37:51+00:00 nginx-pmi nginx: 172.28.0.20 - [14/Jun/2026:06:37:51 +0000] "GET /download HTTP/1.1" 200 41
|
||||||
|
2026-06-14T06:37:51+00:00 nginx-pmi nginx: 172.28.0.20 - [14/Jun/2026:06:37:51 +0000] "" 400 0
|
||||||
|
2026-06-14T06:37:51+00:00 nginx-pmi nginx: 172.28.0.20 - [14/Jun/2026:06:37:51 +0000] "" 400 0
|
||||||
|
2026-06-14T06:37:52+00:00 nginx-pmi nginx: 172.28.0.20 - [14/Jun/2026:06:37:52 +0000] "\x15\x03\x03\x00\x02\x02F" 400 150
|
||||||
|
2026-06-14T06:37:52+00:00 nginx-pmi nginx: 172.28.0.20 - [14/Jun/2026:06:37:52 +0000] "HEAD / HTTP/1.1" 301 0
|
||||||
|
2026-06-14T06:37:52+00:00 nginx-pmi nginx: 172.28.0.20 - [14/Jun/2026:06:37:52 +0000] "HEAD / HTTP/1.1" 404 0
|
||||||
|
2026-06-14T06:37:52+00:00 nginx-pmi nginx: 172.28.0.20 - [14/Jun/2026:06:37:52 +0000] "GET /test-page HTTP/1.1" 200 13
|
||||||
|
2026-06-14T06:37:52+00:00 nginx-pmi nginx: 172.28.0.20 - [14/Jun/2026:06:37:52 +0000] "GET /another-page HTTP/1.1" 200 16
|
||||||
|
2026-06-14T06:37:52+00:00 nginx-pmi nginx: 2026/06/14 06:37:52 [error] 21#21: *38 connect() failed (111: Connection refused) while connecting to upstream, client: 172.28.0.20, server: nginx-test, request: "GET /broken/ HTTP/1.1", upstream: "http://127.0.0.1:59999/", host: "172.28.0.2"
|
||||||
|
2026-06-14T06:37:52+00:00 nginx-pmi nginx: 172.28.0.20 - [14/Jun/2026:06:37:52 +0000] "GET /broken/ HTTP/1.1" 502 150
|
||||||
|
2026-06-14T06:37:52+00:00 nginx-pmi nginx: 172.28.0.20 - [14/Jun/2026:06:37:52 +0000] "GET /syslog-probe-1781419072 HTTP/1.1" 404 138
|
||||||
|
2026-06-14T06:37:53+00:00 nginx-pmi nginx: 172.28.0.20 - [14/Jun/2026:06:37:53 +0000] "GET /rate-limit-check HTTP/1.1" 200 11
|
||||||
|
2026-06-14T06:37:53+00:00 nginx-pmi nginx: 172.28.0.20 - [14/Jun/2026:06:37:53 +0000] "GET /rate-limit-check HTTP/1.1" 200 11
|
||||||
|
2026-06-14T06:37:53+00:00 nginx-pmi nginx: 2026/06/14 06:37:53 [error] 21#21: *45 limiting requests, excess: 2.000 by zone "pmi_uri", client: 172.28.0.20, server: nginx-test, request: "GET /rate-limit-check HTTP/1.1", host: "172.28.0.2"
|
||||||
|
2026-06-14T06:37:53+00:00 nginx-pmi nginx: 172.28.0.20 - [14/Jun/2026:06:37:53 +0000] "GET /rate-limit-check HTTP/1.1" 503 190
|
||||||
|
2026-06-14T06:37:53+00:00 nginx-pmi nginx: 2026/06/14 06:37:53 [error] 21#21: *46 limiting requests, excess: 2.000 by zone "pmi_uri", client: 172.28.0.20, server: nginx-test, request: "GET /rate-limit-check HTTP/1.1", host: "172.28.0.2"
|
||||||
|
2026-06-14T06:37:53+00:00 nginx-pmi nginx: 172.28.0.20 - [14/Jun/2026:06:37:53 +0000] "GET /rate-limit-check HTTP/1.1" 503 190
|
||||||
|
2026-06-14T06:37:53+00:00 nginx-pmi nginx: 2026/06/14 06:37:53 [error] 21#21: *47 limiting requests, excess: 2.000 by zone "pmi_uri", client: 172.28.0.20, server: nginx-test, request: "GET /rate-limit-check HTTP/1.1", host: "172.28.0.2"
|
||||||
|
2026-06-14T06:37:53+00:00 nginx-pmi nginx: 172.28.0.20 - [14/Jun/2026:06:37:53 +0000] "GET /rate-limit-check HTTP/1.1" 503 190
|
||||||
|
2026-06-14T06:37:53+00:00 nginx-pmi nginx: 2026/06/14 06:37:53 [error] 21#21: *49 limiting connections by zone "pmi_conn", client: 172.28.0.20, server: nginx-test, request: "GET /slow/ HTTP/1.1", host: "172.28.0.2"
|
||||||
|
2026-06-14T06:37:53+00:00 nginx-pmi nginx: 2026/06/14 06:37:53 [error] 20#20: *53 limiting connections by zone "pmi_conn", client: 172.28.0.20, server: nginx-test, request: "GET /slow/ HTTP/1.1", host: "172.28.0.2"
|
||||||
|
2026-06-14T06:37:53+00:00 nginx-pmi nginx: 172.28.0.20 - [14/Jun/2026:06:37:53 +0000] "GET /slow/ HTTP/1.1" 503 190
|
||||||
|
2026-06-14T06:37:53+00:00 nginx-pmi nginx: 2026/06/14 06:37:53 [error] 22#22: *54 limiting connections by zone "pmi_conn", client: 172.28.0.20, server: nginx-test, request: "GET /slow/ HTTP/1.1", host: "172.28.0.2"
|
||||||
|
2026-06-14T06:37:53+00:00 nginx-pmi nginx: 172.28.0.20 - [14/Jun/2026:06:37:53 +0000] "GET /slow/ HTTP/1.1" 503 190
|
||||||
|
2026-06-14T06:37:53+00:00 nginx-pmi nginx: 172.28.0.20 - [14/Jun/2026:06:37:53 +0000] "GET /slow/ HTTP/1.1" 503 190
|
||||||
|
2026-06-14T06:37:54+00:00 nginx-pmi nginx: 127.0.0.1 - [14/Jun/2026:06:37:54 +0000] "GET /public/index.html HTTP/1.1" 200 138
|
||||||
|
2026-06-14T06:37:58+00:00 nginx-pmi nginx: 172.28.0.20 - [14/Jun/2026:06:37:58 +0000] "GET /slow/ HTTP/1.1" 200 18
|
||||||
|
2026-06-14T06:37:58+00:00 nginx-pmi nginx: 172.28.0.20 - [14/Jun/2026:06:37:58 +0000] "GET /slow/ HTTP/1.1" 200 18
|
||||||
|
2026-06-14T06:37:58+00:00 nginx-pmi nginx: 172.28.0.20 - [14/Jun/2026:06:37:58 +0000] "POST /upload HTTP/1.1" 200 10
|
||||||
|
2026-06-14T06:37:58+00:00 nginx-pmi nginx: 2026/06/14 06:37:58 [error] 21#21: *57 client intended to send too large body: 2097152 bytes, client: 172.28.0.20, server: nginx-test, request: "POST /upload HTTP/1.1", host: "172.28.0.2"
|
||||||
|
2026-06-14T06:37:58+00:00 nginx-pmi nginx: 172.28.0.20 - [14/Jun/2026:06:37:58 +0000] "POST /upload HTTP/1.1" 413 176
|
||||||
|
2026-06-14T06:37:58+00:00 nginx-pmi nginx: 172.28.0.20 - [14/Jun/2026:06:37:58 +0000] "POST /upload HTTP/1.1" 200 10
|
||||||
|
2026-06-14T06:37:58+00:00 nginx-pmi nginx: 172.28.0.20 - [14/Jun/2026:06:37:58 +0000] "HEAD /public/index.html HTTP/1.1" 200 0
|
||||||
|
2026-06-14T06:37:58+00:00 nginx-pmi nginx: 172.28.0.20 - [14/Jun/2026:06:37:58 +0000] "GET /nonexistent-page-19 HTTP/1.1" 404 138
|
||||||
|
2026-06-14T06:37:58+00:00 nginx-pmi nginx: 172.28.0.20 - [14/Jun/2026:06:37:58 +0000] "GET /nonexistent-page-20 HTTP/1.1" 404 138
|
||||||
|
2026-06-14T06:37:58+00:00 nginx-pmi nginx: 2026/06/14 06:37:58 [error] 20#20: *62 directory index of "/usr/share/nginx/html/files/" is forbidden, client: 172.28.0.20, server: nginx-test, request: "GET /files/ HTTP/1.1", host: "172.28.0.2"
|
||||||
|
2026-06-14T06:37:58+00:00 nginx-pmi nginx: 172.28.0.20 - [14/Jun/2026:06:37:58 +0000] "GET /files/ HTTP/1.1" 403 146
|
||||||
|
2026-06-14T06:37:58+00:00 nginx-pmi nginx: 2026/06/14 06:37:58 [error] 20#20: *63 directory index of "/usr/share/nginx/html/files/" is forbidden, client: 172.28.0.20, server: nginx-test, request: "GET /files/ HTTP/1.1", host: "172.28.0.2"
|
||||||
|
2026-06-14T06:37:58+00:00 nginx-pmi nginx: 172.28.0.20 - [14/Jun/2026:06:37:58 +0000] "GET /files/ HTTP/1.1" 403 146
|
||||||
|
2026-06-14T06:37:58+00:00 nginx-pmi nginx: 172.28.0.20 - [14/Jun/2026:06:37:58 +0000] "GET /api/status HTTP/1.1" 200 11
|
||||||
|
2026-06-14T06:37:58+00:00 nginx-pmi nginx: 172.28.0.20 - [14/Jun/2026:06:37:58 +0000] "GET /index.html HTTP/1.1" 200 138
|
||||||
|
2026-06-14T06:37:58+00:00 nginx-pmi nginx: 172.28.0.20 - [14/Jun/2026:06:37:58 +0000] "GET /etc/passwd HTTP/1.1" 404 138
|
||||||
|
2026-06-14T06:37:58+00:00 nginx-pmi nginx: 127.0.0.1 - [14/Jun/2026:06:37:58 +0000] "GET /test-page HTTP/1.1" 200 13
|
||||||
|
2026-06-14T06:37:58+00:00 nginx-pmi nginx: 127.0.0.1 - [14/Jun/2026:06:37:58 +0000] "GET /another-page HTTP/1.1" 200 16
|
||||||
|
2026-06-14T06:37:58+00:00 nginx-pmi nginx: 2026/06/14 06:37:58 [error] 20#20: *70 connect() failed (111: Connection refused) while connecting to upstream, client: 127.0.0.1, server: nginx-test, request: "GET /broken/ HTTP/1.1", upstream: "http://127.0.0.1:59999/", host: "127.0.0.1"
|
||||||
|
2026-06-14T06:37:58+00:00 nginx-pmi nginx: 127.0.0.1 - [14/Jun/2026:06:37:58 +0000] "GET /broken/ HTTP/1.1" 502 150
|
||||||
|
2026-06-14T06:37:59+00:00 nginx-pmi nginx: 127.0.0.1 - [14/Jun/2026:06:37:59 +0000] "GET /public/index.html HTTP/1.1" 200 138
|
||||||
|
2026-06-14T06:38:04+00:00 nginx-pmi nginx: 127.0.0.1 - [14/Jun/2026:06:38:04 +0000] "GET /public/index.html HTTP/1.1" 200 138
|
||||||
|
2026-06-14T06:38:09+00:00 nginx-pmi nginx: 127.0.0.1 - [14/Jun/2026:06:38:09 +0000] "GET /public/index.html HTTP/1.1" 200 138
|
||||||
|
2026-06-14T06:38:14+00:00 nginx-pmi nginx: 127.0.0.1 - [14/Jun/2026:06:38:14 +0000] "GET /public/index.html HTTP/1.1" 200 138
|
||||||
|
2026-06-14T06:38:19+00:00 nginx-pmi nginx: 127.0.0.1 - [14/Jun/2026:06:38:19 +0000] "GET /public/index.html HTTP/1.1" 200 138
|
||||||
|
2026-06-14T06:38:24+00:00 nginx-pmi nginx: 127.0.0.1 - [14/Jun/2026:06:38:24 +0000] "GET /public/index.html HTTP/1.1" 200 138
|
||||||
|
2026-06-14T06:38:29+00:00 nginx-pmi nginx: 127.0.0.1 - [14/Jun/2026:06:38:29 +0000] "GET /public/index.html HTTP/1.1" 200 138
|
||||||
|
2026-06-14T06:38:34+00:00 nginx-pmi nginx: 127.0.0.1 - [14/Jun/2026:06:38:34 +0000] "GET /public/index.html HTTP/1.1" 200 138
|
||||||
|
2026-06-14T06:38:39+00:00 nginx-pmi nginx: 127.0.0.1 - [14/Jun/2026:06:38:39 +0000] "GET /public/index.html HTTP/1.1" 200 138
|
||||||
|
2026-06-14T06:38:44+00:00 nginx-pmi nginx: 127.0.0.1 - [14/Jun/2026:06:38:44 +0000] "GET /public/index.html HTTP/1.1" 200 138
|
||||||
|
2026-06-14T06:38:49+00:00 nginx-pmi nginx: 127.0.0.1 - [14/Jun/2026:06:38:49 +0000] "GET /public/index.html HTTP/1.1" 200 138
|
||||||
|
2026-06-14T06:38:54+00:00 nginx-pmi nginx: 127.0.0.1 - [14/Jun/2026:06:38:54 +0000] "GET /public/index.html HTTP/1.1" 200 138
|
||||||
|
2026-06-14T06:39:00+00:00 nginx-pmi nginx: 127.0.0.1 - [14/Jun/2026:06:39:00 +0000] "GET /public/index.html HTTP/1.1" 200 138
|
||||||
|
2026-06-14T06:39:05+00:00 nginx-pmi nginx: 127.0.0.1 - [14/Jun/2026:06:39:05 +0000] "GET /public/index.html HTTP/1.1" 200 138
|
||||||
|
2026-06-14T06:39:10+00:00 nginx-pmi nginx: 127.0.0.1 - [14/Jun/2026:06:39:10 +0000] "GET /public/index.html HTTP/1.1" 200 138
|
||||||
|
2026-06-14T06:39:15+00:00 nginx-pmi nginx: 127.0.0.1 - [14/Jun/2026:06:39:15 +0000] "GET /public/index.html HTTP/1.1" 200 138
|
||||||
|
2026-06-14T06:39:20+00:00 nginx-pmi nginx: 127.0.0.1 - [14/Jun/2026:06:39:20 +0000] "GET /public/index.html HTTP/1.1" 200 138
|
||||||
|
2026-06-14T06:39:25+00:00 nginx-pmi nginx: 127.0.0.1 - [14/Jun/2026:06:39:25 +0000] "GET /public/index.html HTTP/1.1" 200 138
|
||||||
|
2026-06-14T06:39:30+00:00 nginx-pmi nginx: 127.0.0.1 - [14/Jun/2026:06:39:30 +0000] "GET /public/index.html HTTP/1.1" 200 138
|
||||||
|
2026-06-14T06:39:35+00:00 nginx-pmi nginx: 127.0.0.1 - [14/Jun/2026:06:39:35 +0000] "GET /public/index.html HTTP/1.1" 200 138
|
||||||
|
2026-06-14T06:39:40+00:00 nginx-pmi nginx: 127.0.0.1 - [14/Jun/2026:06:39:40 +0000] "GET /public/index.html HTTP/1.1" 200 138
|
||||||
|
2026-06-14T06:39:45+00:00 nginx-pmi nginx: 127.0.0.1 - [14/Jun/2026:06:39:45 +0000] "GET /public/index.html HTTP/1.1" 200 138
|
||||||
|
2026-06-14T06:39:50+00:00 nginx-pmi nginx: 127.0.0.1 - [14/Jun/2026:06:39:50 +0000] "GET /public/index.html HTTP/1.1" 200 138
|
||||||
|
2026-06-14T06:39:55+00:00 nginx-pmi nginx: 127.0.0.1 - [14/Jun/2026:06:39:55 +0000] "GET /public/index.html HTTP/1.1" 200 138
|
||||||
|
2026-06-14T06:40:00+00:00 nginx-pmi nginx: 127.0.0.1 - [14/Jun/2026:06:40:00 +0000] "GET /public/index.html HTTP/1.1" 200 138
|
||||||
|
2026-06-14T06:40:05+00:00 nginx-pmi nginx: 127.0.0.1 - [14/Jun/2026:06:40:05 +0000] "GET /public/index.html HTTP/1.1" 200 138
|
||||||
|
2026-06-14T06:40:10+00:00 nginx-pmi nginx: 127.0.0.1 - [14/Jun/2026:06:40:10 +0000] "GET /public/index.html HTTP/1.1" 200 138
|
||||||
|
2026-06-14T06:40:15+00:00 nginx-pmi nginx: 127.0.0.1 - [14/Jun/2026:06:40:15 +0000] "GET /public/index.html HTTP/1.1" 200 138
|
||||||
|
2026-06-14T06:40:21+00:00 nginx-pmi nginx: 127.0.0.1 - [14/Jun/2026:06:40:21 +0000] "GET /public/index.html HTTP/1.1" 200 138
|
||||||
|
2026-06-14T06:40:26+00:00 nginx-pmi nginx: 127.0.0.1 - [14/Jun/2026:06:40:26 +0000] "GET /public/index.html HTTP/1.1" 200 138
|
||||||
|
2026-06-14T06:40:31+00:00 nginx-pmi nginx: 127.0.0.1 - [14/Jun/2026:06:40:31 +0000] "GET /public/index.html HTTP/1.1" 200 138
|
||||||
|
2026-06-14T06:40:36+00:00 nginx-pmi nginx: 127.0.0.1 - [14/Jun/2026:06:40:36 +0000] "GET /public/index.html HTTP/1.1" 200 138
|
||||||
|
2026-06-14T06:40:41+00:00 nginx-pmi nginx: 127.0.0.1 - [14/Jun/2026:06:40:41 +0000] "GET /public/index.html HTTP/1.1" 200 138
|
||||||
|
2026-06-14T06:40:46+00:00 nginx-pmi nginx: 127.0.0.1 - [14/Jun/2026:06:40:46 +0000] "GET /public/index.html HTTP/1.1" 200 138
|
||||||
|
2026-06-14T06:40:51+00:00 nginx-pmi nginx: 127.0.0.1 - [14/Jun/2026:06:40:51 +0000] "GET /public/index.html HTTP/1.1" 200 138
|
||||||
|
2026-06-14T06:40:56+00:00 nginx-pmi nginx: 127.0.0.1 - [14/Jun/2026:06:40:56 +0000] "GET /public/index.html HTTP/1.1" 200 138
|
||||||
|
2026-06-14T06:41:01+00:00 nginx-pmi nginx: 127.0.0.1 - [14/Jun/2026:06:41:01 +0000] "GET /public/index.html HTTP/1.1" 200 138
|
||||||
|
2026-06-14T06:41:06+00:00 nginx-pmi nginx: 127.0.0.1 - [14/Jun/2026:06:41:06 +0000] "GET /public/index.html HTTP/1.1" 200 138
|
||||||
|
2026-06-14T06:41:11+00:00 nginx-pmi nginx: 127.0.0.1 - [14/Jun/2026:06:41:11 +0000] "GET /public/index.html HTTP/1.1" 200 138
|
||||||
|
2026-06-14T06:41:16+00:00 nginx-pmi nginx: 127.0.0.1 - [14/Jun/2026:06:41:16 +0000] "GET /public/index.html HTTP/1.1" 200 138
|
||||||
|
2026-06-14T06:41:21+00:00 nginx-pmi nginx: 127.0.0.1 - [14/Jun/2026:06:41:21 +0000] "GET /public/index.html HTTP/1.1" 200 138
|
||||||
|
2026-06-14T06:41:26+00:00 nginx-pmi nginx: 127.0.0.1 - [14/Jun/2026:06:41:26 +0000] "GET /public/index.html HTTP/1.1" 200 138
|
||||||
|
2026-06-14T06:41:31+00:00 nginx-pmi nginx: 127.0.0.1 - [14/Jun/2026:06:41:31 +0000] "GET /public/index.html HTTP/1.1" 200 138
|
||||||
|
2026-06-14T06:41:36+00:00 nginx-pmi nginx: 127.0.0.1 - [14/Jun/2026:06:41:36 +0000] "GET /public/index.html HTTP/1.1" 200 138
|
||||||
|
2026-06-14T06:41:42+00:00 nginx-pmi nginx: 127.0.0.1 - [14/Jun/2026:06:41:42 +0000] "GET /public/index.html HTTP/1.1" 200 138
|
||||||
|
2026-06-14T06:41:47+00:00 nginx-pmi nginx: 127.0.0.1 - [14/Jun/2026:06:41:47 +0000] "GET /public/index.html HTTP/1.1" 200 138
|
||||||
|
2026-06-14T06:41:52+00:00 nginx-pmi nginx: 127.0.0.1 - [14/Jun/2026:06:41:52 +0000] "GET /public/index.html HTTP/1.1" 200 138
|
||||||
|
2026-06-14T06:41:57+00:00 nginx-pmi nginx: 127.0.0.1 - [14/Jun/2026:06:41:57 +0000] "GET /public/index.html HTTP/1.1" 200 138
|
||||||
|
2026-06-14T06:42:02+00:00 nginx-pmi nginx: 127.0.0.1 - [14/Jun/2026:06:42:02 +0000] "GET /public/index.html HTTP/1.1" 200 138
|
||||||
|
2026-06-14T06:42:07+00:00 nginx-pmi nginx: 127.0.0.1 - [14/Jun/2026:06:42:07 +0000] "GET /public/index.html HTTP/1.1" 200 138
|
||||||
|
2026-06-14T06:42:12+00:00 nginx-pmi nginx: 127.0.0.1 - [14/Jun/2026:06:42:12 +0000] "GET /public/index.html HTTP/1.1" 200 138
|
||||||
|
2026-06-14T06:42:17+00:00 nginx-pmi nginx: 127.0.0.1 - [14/Jun/2026:06:42:17 +0000] "GET /public/index.html HTTP/1.1" 200 138
|
||||||
|
2026-06-14T06:42:22+00:00 nginx-pmi nginx: 127.0.0.1 - [14/Jun/2026:06:42:22 +0000] "GET /public/index.html HTTP/1.1" 200 138
|
||||||
|
2026-06-14T06:42:27+00:00 nginx-pmi nginx: 127.0.0.1 - [14/Jun/2026:06:42:27 +0000] "GET /public/index.html HTTP/1.1" 200 138
|
||||||
84
results/run.bat
Normal file
84
results/run.bat
Normal file
@@ -0,0 +1,84 @@
|
|||||||
|
@echo off
|
||||||
|
setlocal EnableExtensions
|
||||||
|
cd /d "%~dp0"
|
||||||
|
|
||||||
|
echo [%date% %time%] nginx PMI stand - start
|
||||||
|
|
||||||
|
for /f %%i in ('docker run --rm alpine date +%%Y-%%m-%%d_%%H-%%M-%%S') do set TS=%%i
|
||||||
|
set REPORTS=%CD%\reports
|
||||||
|
set PMI_LOG=%TS%_pmi.log
|
||||||
|
set AUDIT_LOG=%TS%_audit.log
|
||||||
|
set FIM_LOG=%TS%_fim.log
|
||||||
|
|
||||||
|
echo Timestamp: %TS%
|
||||||
|
|
||||||
|
echo.
|
||||||
|
echo [1/8] Generate TLS certificates...
|
||||||
|
if not exist ssl mkdir ssl
|
||||||
|
docker run --rm --entrypoint sh -v "%CD%/ssl:/ssl" -v "%CD%/scripts/gen-certs.sh:/gen-certs.sh:ro" alpine/openssl /gen-certs.sh
|
||||||
|
if errorlevel 1 goto :fail
|
||||||
|
|
||||||
|
echo.
|
||||||
|
echo [2/8] Generate htpasswd...
|
||||||
|
docker run --rm --entrypoint sh -v "%CD%/nginx:/out" -v "%CD%/scripts/gen-htpasswd.sh:/gen-htpasswd.sh:ro" alpine/openssl /gen-htpasswd.sh
|
||||||
|
if errorlevel 1 goto :fail
|
||||||
|
|
||||||
|
echo.
|
||||||
|
echo [3/8] Build and start containers...
|
||||||
|
docker compose build
|
||||||
|
if errorlevel 1 goto :fail
|
||||||
|
docker compose up -d
|
||||||
|
if errorlevel 1 goto :fail
|
||||||
|
docker compose restart nginx syslog-ng
|
||||||
|
if errorlevel 1 goto :fail
|
||||||
|
|
||||||
|
echo.
|
||||||
|
echo [4/8] Wait for nginx...
|
||||||
|
docker compose exec -T test-runner sh /scripts/wait-ready.sh
|
||||||
|
if errorlevel 1 goto :fail
|
||||||
|
|
||||||
|
echo.
|
||||||
|
echo [5/8] Run PMI tests...
|
||||||
|
docker compose exec -T -e REPORT=/reports/%PMI_LOG% test-runner sh /scripts/run-pmi-tests.sh
|
||||||
|
set PMI_RC=%ERRORLEVEL%
|
||||||
|
|
||||||
|
docker compose exec -T -e REPORT=/reports/%PMI_LOG% nginx sh /scripts/run-pmi-log-checks.sh
|
||||||
|
if errorlevel 1 set PMI_RC=1
|
||||||
|
|
||||||
|
echo.
|
||||||
|
echo [6/8] Run audits...
|
||||||
|
docker compose exec -T -e REPORT=/reports/%AUDIT_LOG% nginx sh /scripts/run-audit-permissions.sh
|
||||||
|
docker compose exec -T -e REPORT=/reports/%AUDIT_LOG% nginx sh /scripts/run-audit-attack-surface.sh
|
||||||
|
docker compose exec -T -e REPORT=/reports/%AUDIT_LOG% nginx sh /scripts/run-audit-code-control.sh
|
||||||
|
|
||||||
|
echo.
|
||||||
|
echo [7/8] Run FIM checksum (afick stand-in)...
|
||||||
|
docker compose exec -T -e REPORT=/reports/%FIM_LOG% nginx sh /scripts/run-fim-checksum.sh
|
||||||
|
set FIM_RC=%ERRORLEVEL%
|
||||||
|
|
||||||
|
echo.
|
||||||
|
echo [8/8] Generate summary...
|
||||||
|
docker compose exec -T -e REPORTS_DIR=/reports test-runner sh /scripts/generate-summary.sh %TS%
|
||||||
|
|
||||||
|
echo.
|
||||||
|
echo Done. Reports in: %REPORTS%
|
||||||
|
echo %PMI_LOG%
|
||||||
|
echo %AUDIT_LOG%
|
||||||
|
echo %FIM_LOG%
|
||||||
|
echo %TS%_summary.md
|
||||||
|
|
||||||
|
if not "%PMI_RC%"=="0" (
|
||||||
|
echo PMI tests: FAILED
|
||||||
|
exit /b 1
|
||||||
|
)
|
||||||
|
if not "%FIM_RC%"=="0" (
|
||||||
|
echo FIM check: FAILED
|
||||||
|
exit /b 1
|
||||||
|
)
|
||||||
|
|
||||||
|
echo All checks completed successfully.
|
||||||
|
exit /b 0
|
||||||
|
|
||||||
|
:fail
|
||||||
|
echo ERROR: step failed.
|
||||||
|
exit /b 1
|
||||||
31
results/scripts/gen-certs.sh
Normal file
31
results/scripts/gen-certs.sh
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
set -eu
|
||||||
|
|
||||||
|
SSL_DIR="${SSL_DIR:-/ssl}"
|
||||||
|
cd "$SSL_DIR"
|
||||||
|
|
||||||
|
openssl genrsa -out ca.key 4096
|
||||||
|
openssl req -x509 -new -nodes -key ca.key -sha256 -days 3650 \
|
||||||
|
-subj "/CN=PMI Test CA" -out ca.crt
|
||||||
|
|
||||||
|
openssl genrsa -out server.key 2048
|
||||||
|
openssl req -new -key server.key -subj "/CN=nginx-test" -out server.csr
|
||||||
|
openssl x509 -req -in server.csr -CA ca.crt -CAkey ca.key -CAcreateserial \
|
||||||
|
-out server.crt -days 825 -sha256
|
||||||
|
|
||||||
|
openssl genrsa -out client.key 2048
|
||||||
|
openssl req -new -key client.key -subj "/CN=trusted-client" -out client.csr
|
||||||
|
openssl x509 -req -in client.csr -CA ca.crt -CAkey ca.key -CAcreateserial \
|
||||||
|
-out client.crt -days 825 -sha256
|
||||||
|
|
||||||
|
openssl genrsa -out untrusted.key 2048
|
||||||
|
openssl req -x509 -new -nodes -key untrusted.key -sha256 -days 365 \
|
||||||
|
-subj "/CN=untrusted-client" -out untrusted.crt
|
||||||
|
|
||||||
|
chmod 600 ca.key server.key client.key untrusted.key
|
||||||
|
chmod 644 ca.crt server.crt client.crt untrusted.crt
|
||||||
|
cat server.crt ca.crt > fullchain.crt
|
||||||
|
chmod 644 fullchain.crt
|
||||||
|
rm -f server.csr client.csr ca.srl
|
||||||
|
|
||||||
|
echo "Certificates generated in $SSL_DIR"
|
||||||
7
results/scripts/gen-htpasswd.sh
Normal file
7
results/scripts/gen-htpasswd.sh
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
set -eu
|
||||||
|
|
||||||
|
OUT="${OUT:-/out/htpasswd}"
|
||||||
|
hash=$(openssl passwd -apr1 'password')
|
||||||
|
echo "user:$hash" > "$OUT"
|
||||||
|
echo "Created $OUT (user:password)"
|
||||||
69
results/scripts/generate-summary.sh
Normal file
69
results/scripts/generate-summary.sh
Normal file
@@ -0,0 +1,69 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# Build summary markdown from report logs.
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
TS="${1:-unknown}"
|
||||||
|
REPORTS="${REPORTS_DIR:-/reports}"
|
||||||
|
OUT="$REPORTS/${TS}_summary.md"
|
||||||
|
|
||||||
|
pmi="$REPORTS/${TS}_pmi.log"
|
||||||
|
audit="$REPORTS/${TS}_audit.log"
|
||||||
|
fim="$REPORTS/${TS}_fim.log"
|
||||||
|
|
||||||
|
count_status() {
|
||||||
|
local file="$1" status="$2"
|
||||||
|
local n=0
|
||||||
|
if [ -f "$file" ]; then
|
||||||
|
n=$(grep -c "^${status} " "$file" 2>/dev/null) || n=0
|
||||||
|
fi
|
||||||
|
echo "$n"
|
||||||
|
}
|
||||||
|
|
||||||
|
pass_pmi=$(count_status "$pmi" PASS)
|
||||||
|
fail_pmi=$(count_status "$pmi" FAIL)
|
||||||
|
pass_fim=$(count_status "$fim" PASS)
|
||||||
|
fail_fim=$(count_status "$fim" FAIL)
|
||||||
|
|
||||||
|
{
|
||||||
|
echo "# Сводный отчёт nginx PMI stand"
|
||||||
|
echo ""
|
||||||
|
echo "**Дата прогона:** $TS"
|
||||||
|
echo "**Стенд:** Docker Compose (\`results/docker-compose.yml\`)"
|
||||||
|
echo ""
|
||||||
|
echo "## Результаты ПМИ"
|
||||||
|
echo ""
|
||||||
|
echo "| Метрика | Значение |"
|
||||||
|
echo "|---------|----------|"
|
||||||
|
echo "| PASS | $pass_pmi |"
|
||||||
|
echo "| FAIL | $fail_pmi |"
|
||||||
|
echo ""
|
||||||
|
echo "## Целостность (FIM stand-in)"
|
||||||
|
echo ""
|
||||||
|
echo "| Метрика | Значение |"
|
||||||
|
echo "|---------|----------|"
|
||||||
|
echo "| PASS | $pass_fim |"
|
||||||
|
echo "| FAIL | $fail_fim |"
|
||||||
|
echo ""
|
||||||
|
echo "> FIM выполнен через SHA256 baseline (\`run-fim-checksum.sh\`), не afick."
|
||||||
|
echo "> Syslog проверялся локальным syslog-ng, не корпоративным SIEM."
|
||||||
|
echo ""
|
||||||
|
echo "## Файлы отчётов"
|
||||||
|
echo ""
|
||||||
|
echo "- [\`${TS}_pmi.log\`](${TS}_pmi.log)"
|
||||||
|
echo "- [\`${TS}_audit.log\`](${TS}_audit.log)"
|
||||||
|
echo "- [\`${TS}_fim.log\`](${TS}_fim.log)"
|
||||||
|
echo ""
|
||||||
|
echo "## PMI log excerpt"
|
||||||
|
echo ""
|
||||||
|
echo '```'
|
||||||
|
[ -f "$pmi" ] && grep -E '^(PASS|FAIL|SKIP|===)' "$pmi" || echo "(no pmi log)"
|
||||||
|
echo '```'
|
||||||
|
echo ""
|
||||||
|
echo "## FIM log excerpt"
|
||||||
|
echo ""
|
||||||
|
echo '```'
|
||||||
|
[ -f "$fim" ] && cat "$fim" || echo "(no fim log)"
|
||||||
|
echo '```'
|
||||||
|
} > "$OUT"
|
||||||
|
|
||||||
|
echo "Summary written: $OUT"
|
||||||
26
results/scripts/run-audit-attack-surface.sh
Normal file
26
results/scripts/run-audit-attack-surface.sh
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
# Audit: attack surface minimization (docs/Минимизация_поверхности_атаки_nginx)
|
||||||
|
set -eu
|
||||||
|
|
||||||
|
REPORT="${REPORT:-/reports/audit.log}"
|
||||||
|
|
||||||
|
{
|
||||||
|
echo ""
|
||||||
|
echo "=== Attack surface audit $(date -Iseconds) ==="
|
||||||
|
echo "--- nginx -V ---"
|
||||||
|
nginx -V 2>&1
|
||||||
|
echo "--- load_module ---"
|
||||||
|
nginx -T 2>/dev/null | grep load_module || echo "(none)"
|
||||||
|
echo "--- optional modules in config ---"
|
||||||
|
nginx -T 2>/dev/null | grep -E 'dav_methods|perl|js_import|js_content|xslt_stylesheet|auth_request' || echo "(none found)"
|
||||||
|
echo "--- autoindex ---"
|
||||||
|
nginx -T 2>/dev/null | grep autoindex || echo "(default off)"
|
||||||
|
echo "--- limit_except / request_method ---"
|
||||||
|
nginx -T 2>/dev/null | grep -E 'limit_except|request_method' || true
|
||||||
|
echo "--- proxy_pass / upstream ---"
|
||||||
|
nginx -T 2>/dev/null | grep -E 'proxy_pass|upstream' || true
|
||||||
|
echo "--- ssi ---"
|
||||||
|
nginx -T 2>/dev/null | grep -i 'ssi on' || echo "(ssi off)"
|
||||||
|
} >> "$REPORT"
|
||||||
|
|
||||||
|
echo "Attack surface audit appended -> $REPORT"
|
||||||
15
results/scripts/run-audit-code-control.sh
Normal file
15
results/scripts/run-audit-code-control.sh
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
# Audit: code execution control (docs/Контроль_выполнения_кода)
|
||||||
|
set -eu
|
||||||
|
|
||||||
|
REPORT="${REPORT:-/reports/audit.log}"
|
||||||
|
|
||||||
|
{
|
||||||
|
echo ""
|
||||||
|
echo "=== Code execution control audit $(date -Iseconds) ==="
|
||||||
|
nginx -T 2>/dev/null | grep -E 'fastcgi_pass|uwsgi_pass|scgi_pass|grpc_pass|perl|js_import|internal|^\s*root\s|alias' || true
|
||||||
|
echo "--- SCRIPT_FILENAME ---"
|
||||||
|
nginx -T 2>/dev/null | grep SCRIPT_FILENAME || echo "(no fastcgi)"
|
||||||
|
} >> "$REPORT"
|
||||||
|
|
||||||
|
echo "Code control audit appended -> $REPORT"
|
||||||
56
results/scripts/run-audit-permissions.sh
Normal file
56
results/scripts/run-audit-permissions.sh
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
# Audit: minimal permissions (docs/Минимально_необходимые_полномочия_nginx)
|
||||||
|
set -eu
|
||||||
|
|
||||||
|
REPORT="${REPORT:-/reports/audit.log}"
|
||||||
|
|
||||||
|
section() { echo "" >> "$REPORT"; echo "=== $1 ===" >> "$REPORT"; echo "=== $1 ==="; }
|
||||||
|
|
||||||
|
: > "$REPORT"
|
||||||
|
echo "Permissions audit $(date -Iseconds)" >> "$REPORT"
|
||||||
|
|
||||||
|
section "Worker user"
|
||||||
|
nginx -T 2>/dev/null | grep '^user ' >> "$REPORT" || true
|
||||||
|
ps aux | grep 'nginx:' >> "$REPORT" || true
|
||||||
|
|
||||||
|
section "Config permissions"
|
||||||
|
ls -la /etc/nginx/ >> "$REPORT"
|
||||||
|
namei -l /etc/nginx/nginx.conf >> "$REPORT" 2>/dev/null || ls -l /etc/nginx/nginx.conf >> "$REPORT"
|
||||||
|
if su -s /bin/sh nginx -c 'test -w /etc/nginx/nginx.conf' 2>/dev/null; then
|
||||||
|
echo "FAIL: nginx can write nginx.conf" >> "$REPORT"
|
||||||
|
else
|
||||||
|
echo "OK: nginx cannot write nginx.conf" >> "$REPORT"
|
||||||
|
fi
|
||||||
|
|
||||||
|
section "Web root permissions"
|
||||||
|
ls -la /usr/share/nginx/html/public/ >> "$REPORT"
|
||||||
|
if su -s /bin/sh nginx -c 'test -w /usr/share/nginx/html/public/index.html' 2>/dev/null; then
|
||||||
|
echo "FAIL: nginx can write web root" >> "$REPORT"
|
||||||
|
else
|
||||||
|
echo "OK: nginx cannot write web root" >> "$REPORT"
|
||||||
|
fi
|
||||||
|
|
||||||
|
section "TLS certificates and keys"
|
||||||
|
ls -la /etc/nginx/ssl/ >> "$REPORT"
|
||||||
|
if su -s /bin/sh nginx -c 'cat /etc/nginx/ssl/server.key' 2>/dev/null; then
|
||||||
|
echo "FAIL: nginx can read private key" >> "$REPORT"
|
||||||
|
else
|
||||||
|
echo "OK: nginx cannot read private key" >> "$REPORT"
|
||||||
|
fi
|
||||||
|
|
||||||
|
section "htpasswd"
|
||||||
|
ls -la /etc/nginx/htpasswd >> "$REPORT" 2>/dev/null || true
|
||||||
|
if su -s /bin/sh nginx -c 'test -w /etc/nginx/htpasswd' 2>/dev/null; then
|
||||||
|
echo "FAIL: nginx can write htpasswd" >> "$REPORT"
|
||||||
|
else
|
||||||
|
echo "OK: nginx cannot write htpasswd" >> "$REPORT"
|
||||||
|
fi
|
||||||
|
|
||||||
|
section "Logs"
|
||||||
|
ls -la /var/log/nginx/ >> "$REPORT"
|
||||||
|
|
||||||
|
section "Temp/cache paths"
|
||||||
|
ls -la /var/cache/nginx/ >> "$REPORT" 2>/dev/null || echo "cache dir not yet created" >> "$REPORT"
|
||||||
|
nginx -T 2>/dev/null | grep -E 'client_body_temp_path|proxy_temp_path' >> "$REPORT" || true
|
||||||
|
|
||||||
|
echo "Audit permissions complete -> $REPORT"
|
||||||
45
results/scripts/run-fim-checksum.sh
Normal file
45
results/scripts/run-fim-checksum.sh
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
# FIM substitute: SHA256 baseline (docs/Контроль_целостности; PMI p.24)
|
||||||
|
# Note: stand-in for afick, not a certification tool.
|
||||||
|
set -eu
|
||||||
|
|
||||||
|
REPORT="${REPORT:-/reports/fim.log}"
|
||||||
|
BASELINE="${BASELINE:-/tmp/fim-baseline.sha256}"
|
||||||
|
PATHS="/etc/nginx /usr/share/nginx/html /fim-watch"
|
||||||
|
WATCH_FILE="/fim-watch/config.snippet"
|
||||||
|
|
||||||
|
checksum() {
|
||||||
|
find $PATHS -type f 2>/dev/null | sort | xargs sha256sum 2>/dev/null
|
||||||
|
}
|
||||||
|
|
||||||
|
: > "$REPORT"
|
||||||
|
echo "FIM checksum audit $(date -Iseconds)" >> "$REPORT"
|
||||||
|
echo "NOTE: SHA256 baseline substitute for afick on test stand only." >> "$REPORT"
|
||||||
|
|
||||||
|
checksum > "$BASELINE"
|
||||||
|
echo "Baseline created ($(wc -l < "$BASELINE") files)" >> "$REPORT"
|
||||||
|
|
||||||
|
if checksum | diff -q "$BASELINE" - > /dev/null 2>&1; then
|
||||||
|
echo "PASS baseline check (no changes)" >> "$REPORT"
|
||||||
|
else
|
||||||
|
echo "FAIL unexpected baseline diff before tamper test" >> "$REPORT"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "# tamper $(date +%s)" >> "$WATCH_FILE"
|
||||||
|
if checksum | diff -q "$BASELINE" - > /dev/null 2>&1; then
|
||||||
|
echo "FAIL tamper not detected" >> "$REPORT"
|
||||||
|
exit 1
|
||||||
|
else
|
||||||
|
echo "PASS tamper detected after file change ($WATCH_FILE)" >> "$REPORT"
|
||||||
|
fi
|
||||||
|
|
||||||
|
printf '# FIM watch file for integrity test (PMI p.24 stand-in)\n' > "$WATCH_FILE"
|
||||||
|
if checksum | diff -q "$BASELINE" - > /dev/null 2>&1; then
|
||||||
|
echo "PASS baseline restored after revert" >> "$REPORT"
|
||||||
|
else
|
||||||
|
echo "WARN baseline differs after revert (review manually)" >> "$REPORT"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "PASS #24 integrity control (checksum substitute for afick)" >> "$REPORT"
|
||||||
|
echo "FIM checksum complete -> $REPORT"
|
||||||
33
results/scripts/run-pmi-log-checks.sh
Normal file
33
results/scripts/run-pmi-log-checks.sh
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
# Log checks for PMI items 12 and 13 (runs inside nginx container).
|
||||||
|
set -eu
|
||||||
|
|
||||||
|
REPORT="${REPORT:-/reports/pmi.log}"
|
||||||
|
ACCESS_LOG="/reports/nginx-file-access.log"
|
||||||
|
ERROR_LOG="/reports/nginx-file-error.log"
|
||||||
|
|
||||||
|
: > "$ACCESS_LOG"
|
||||||
|
: > "$ERROR_LOG"
|
||||||
|
|
||||||
|
curl -s --max-time 5 http://127.0.0.1/test-page > /dev/null
|
||||||
|
curl -s --max-time 5 http://127.0.0.1/another-page > /dev/null
|
||||||
|
curl -s --max-time 5 http://127.0.0.1/broken/ > /dev/null || true
|
||||||
|
sleep 1
|
||||||
|
|
||||||
|
if grep -q '/test-page' "$ACCESS_LOG" && grep -q '/another-page' "$ACCESS_LOG"; then
|
||||||
|
echo "PASS #12 access_log contains test-page and another-page" >> "$REPORT"
|
||||||
|
echo "PASS #12 access_log contains test-page and another-page"
|
||||||
|
else
|
||||||
|
echo "FAIL #12 access_log missing expected entries" >> "$REPORT"
|
||||||
|
echo "FAIL #12 access_log missing expected entries"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if grep -qE 'connect\(\) failed|Connection refused|upstream' "$ERROR_LOG"; then
|
||||||
|
echo "PASS #13 error_log contains upstream error" >> "$REPORT"
|
||||||
|
echo "PASS #13 error_log contains upstream error"
|
||||||
|
else
|
||||||
|
echo "FAIL #13 error_log missing upstream error" >> "$REPORT"
|
||||||
|
echo "FAIL #13 error_log missing upstream error"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
291
results/scripts/run-pmi-tests.sh
Normal file
291
results/scripts/run-pmi-tests.sh
Normal file
@@ -0,0 +1,291 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
set -uo pipefail
|
||||||
|
|
||||||
|
NGINX_A="http://172.28.0.2"
|
||||||
|
NGINX_D="http://172.29.0.2"
|
||||||
|
HTTPS="https://172.28.0.2"
|
||||||
|
TLS_HOST="172.28.0.2:443"
|
||||||
|
ALLOWED_IF="172.28.0.20"
|
||||||
|
DENIED_IF="172.29.0.20"
|
||||||
|
SSL="/ssl"
|
||||||
|
REPORT="${REPORT:-/reports/pmi.log}"
|
||||||
|
AUTH_MODE="/auth-mode/mode"
|
||||||
|
|
||||||
|
PASS=0
|
||||||
|
FAIL=0
|
||||||
|
SKIP=0
|
||||||
|
|
||||||
|
log() { echo "$@" | tee -a "$REPORT"; }
|
||||||
|
|
||||||
|
pass() { log "PASS #$1 $2"; PASS=$((PASS + 1)); }
|
||||||
|
fail() { log "FAIL #$1 $2"; FAIL=$((FAIL + 1)); }
|
||||||
|
skip() { log "SKIP #$1 $2"; SKIP=$((SKIP + 1)); }
|
||||||
|
|
||||||
|
http_code() {
|
||||||
|
local iface="$1" url="$2"
|
||||||
|
shift 2
|
||||||
|
curl -s -o /dev/null -w '%{http_code}' --interface "$iface" --connect-timeout 10 "$url" "$@"
|
||||||
|
}
|
||||||
|
|
||||||
|
set_auth_mode() {
|
||||||
|
echo "$1" > "$AUTH_MODE"
|
||||||
|
sleep 0.5
|
||||||
|
}
|
||||||
|
|
||||||
|
: > "$REPORT"
|
||||||
|
log "=== PMI tests $(date -Iseconds) ==="
|
||||||
|
log ""
|
||||||
|
|
||||||
|
# --- 1. IP allow/deny ---
|
||||||
|
c1=$(http_code "$ALLOWED_IF" "$NGINX_A/admin/")
|
||||||
|
c2=$(http_code "$DENIED_IF" "$NGINX_D/admin/")
|
||||||
|
if [ "$c1" = "200" ] && [ "$c2" = "403" ]; then
|
||||||
|
pass 1 "IP allow/deny (allowed=$c1 denied=$c2)"
|
||||||
|
else
|
||||||
|
fail 1 "IP allow/deny (allowed=$c1 denied=$c2, expected 200/403)"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# --- 2. Basic auth ---
|
||||||
|
c_no=$(http_code "$ALLOWED_IF" "$NGINX_A/secure/")
|
||||||
|
c_wrong=$(http_code "$ALLOWED_IF" "$NGINX_A/secure/" -u 'wrong:wrong')
|
||||||
|
c_ok=$(http_code "$ALLOWED_IF" "$NGINX_A/secure/" -u 'user:password')
|
||||||
|
if [ "$c_no" = "401" ] && [ "$c_wrong" = "401" ] && [ "$c_ok" = "200" ]; then
|
||||||
|
pass 2 "Basic auth (401/401/200)"
|
||||||
|
else
|
||||||
|
fail 2 "Basic auth ($c_no/$c_wrong/$c_ok expected 401/401/200)"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# --- 3. mTLS ---
|
||||||
|
c3_no=$(curl -sk -o /dev/null -w '%{http_code}' --interface "$ALLOWED_IF" \
|
||||||
|
--resolve nginx-test-mtls:443:172.28.0.2 https://nginx-test-mtls/)
|
||||||
|
c3_ok=$(curl -sk -o /dev/null -w '%{http_code}' --interface "$ALLOWED_IF" \
|
||||||
|
--resolve nginx-test-mtls:443:172.28.0.2 --cert "$SSL/client.crt" --key "$SSL/client.key" --cacert "$SSL/ca.crt" \
|
||||||
|
https://nginx-test-mtls/)
|
||||||
|
c3_bad=$(curl -sk -o /dev/null -w '%{http_code}' --interface "$ALLOWED_IF" \
|
||||||
|
--resolve nginx-test-mtls:443:172.28.0.2 --cert "$SSL/untrusted.crt" --key "$SSL/untrusted.key" --cacert "$SSL/ca.crt" \
|
||||||
|
https://nginx-test-mtls/)
|
||||||
|
if [ "$c3_no" = "400" ] && [ "$c3_ok" = "200" ] && [ "$c3_bad" = "400" ]; then
|
||||||
|
pass 3 "Client TLS certificate (400/200/400)"
|
||||||
|
else
|
||||||
|
fail 3 "Client TLS certificate ($c3_no/$c3_ok/$c3_bad expected 400/200/400)"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# --- 4. auth_request ---
|
||||||
|
set_auth_mode 200
|
||||||
|
c4a=$(http_code "$ALLOWED_IF" "$NGINX_A/auth-protected/status")
|
||||||
|
set_auth_mode 401
|
||||||
|
c4b=$(http_code "$ALLOWED_IF" "$NGINX_A/auth-protected/status")
|
||||||
|
set_auth_mode 403
|
||||||
|
c4c=$(http_code "$ALLOWED_IF" "$NGINX_A/auth-protected/status")
|
||||||
|
set_auth_mode 200
|
||||||
|
if [ "$c4a" = "200" ] && [ "$c4b" = "401" ] && [ "$c4c" = "403" ]; then
|
||||||
|
pass 4 "auth_request (200/401/403)"
|
||||||
|
else
|
||||||
|
fail 4 "auth_request ($c4a/$c4b/$c4c expected 200/401/403)"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# --- 5. satisfy all ---
|
||||||
|
c5a=$(http_code "$ALLOWED_IF" "$NGINX_A/admin-combined/" -u 'user:password')
|
||||||
|
c5b=$(http_code "$ALLOWED_IF" "$NGINX_A/admin-combined/")
|
||||||
|
c5c=$(http_code "$DENIED_IF" "$NGINX_D/admin-combined/" -u 'user:password')
|
||||||
|
c5d=$(http_code "$DENIED_IF" "$NGINX_D/admin-combined/")
|
||||||
|
if [ "$c5a" = "200" ] && [ "$c5b" = "401" ] && [ "$c5c" = "403" ] && [ "$c5d" = "403" ]; then
|
||||||
|
pass 5 "satisfy all matrix (200/401/403/403)"
|
||||||
|
else
|
||||||
|
fail 5 "satisfy all ($c5a/$c5b/$c5c/$c5d expected 200/401/403/403)"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# --- 6. URL separation ---
|
||||||
|
c6a=$(http_code "$ALLOWED_IF" "$NGINX_A/public/index.html")
|
||||||
|
c6b=$(http_code "$DENIED_IF" "$NGINX_D/admin/")
|
||||||
|
if [ "$c6a" = "200" ] && [ "$c6b" = "403" ]; then
|
||||||
|
pass 6 "URL access rules (/public/ vs /admin/)"
|
||||||
|
else
|
||||||
|
fail 6 "URL access ($c6a/$c6b expected 200/403)"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# --- 7. limit_except ---
|
||||||
|
c7g=$(http_code "$ALLOWED_IF" "$NGINX_A/api/status" -X GET)
|
||||||
|
c7p=$(http_code "$ALLOWED_IF" "$NGINX_A/api/status" -X POST)
|
||||||
|
c7u=$(http_code "$ALLOWED_IF" "$NGINX_A/api/status" -X PUT)
|
||||||
|
c7d=$(http_code "$ALLOWED_IF" "$NGINX_A/api/status" -X DELETE)
|
||||||
|
if [ "$c7g" = "200" ] && [ "$c7p" = "200" ] && [ "$c7u" = "403" ] && [ "$c7d" = "403" ]; then
|
||||||
|
pass 7 "limit_except GET POST (PUT/DELETE=403)"
|
||||||
|
else
|
||||||
|
fail 7 "limit_except ($c7g/$c7p/$c7u/$c7d expected 200/200/403/403)"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# --- 8. internal ---
|
||||||
|
c8a=$(http_code "$ALLOWED_IF" "$NGINX_A/protected/document.pdf")
|
||||||
|
c8b=$(http_code "$ALLOWED_IF" "$NGINX_A/download")
|
||||||
|
if [ "$c8a" = "404" ] && [ "$c8b" = "200" ]; then
|
||||||
|
pass 8 "internal location (direct=404 rewrite=200)"
|
||||||
|
else
|
||||||
|
fail 8 "internal ($c8a/$c8b expected 404/200)"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# --- 9. TLS connection ---
|
||||||
|
s9=$(echo | openssl s_client -connect "$TLS_HOST" -servername nginx-test 2>&1 || true)
|
||||||
|
if echo "$s9" | grep -qE "Verify return code: (0|18|19|21)|SSL-Session:"; then
|
||||||
|
pass 9 "HTTPS TLS handshake"
|
||||||
|
else
|
||||||
|
fail 9 "HTTPS TLS handshake failed"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# --- 10. TLS versions ---
|
||||||
|
s10ok=$(echo | openssl s_client -connect "$TLS_HOST" -servername nginx-test -tls1_2 2>&1 || true)
|
||||||
|
s10bad=$(echo | openssl s_client -connect "$TLS_HOST" -servername nginx-test -tls1_1 2>&1 || true)
|
||||||
|
if echo "$s10ok" | grep -q "Protocol : TLSv1.2" && echo "$s10bad" | grep -qi "alert protocol version\|no protocols available\|wrong version"; then
|
||||||
|
pass 10 "TLSv1.2 ok, TLSv1.1 rejected"
|
||||||
|
else
|
||||||
|
fail 10 "TLS version policy"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# --- 11. HTTPS redirect + HSTS ---
|
||||||
|
h11=$(curl -sI --interface "$ALLOWED_IF" -H "Host: redirect-test" "$NGINX_A/" | tr -d '\r')
|
||||||
|
hsts=$(curl -skI --interface "$ALLOWED_IF" "$HTTPS/" -H "Host: nginx-test" | tr -d '\r')
|
||||||
|
ok11=0
|
||||||
|
echo "$h11" | grep -q "301" && ok11=$((ok11 + 1))
|
||||||
|
echo "$h11" | grep -qi "location: https://" && ok11=$((ok11 + 1))
|
||||||
|
echo "$hsts" | grep -qi "strict-transport-security:" && ok11=$((ok11 + 1))
|
||||||
|
if [ "$ok11" -eq 3 ]; then
|
||||||
|
pass 11 "HTTP redirect 301 + HSTS header"
|
||||||
|
else
|
||||||
|
fail 11 "Redirect/HSTS (checks $ok11/3)"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# --- 12-13. access/error logs (detailed check in run-pmi-log-checks.sh) ---
|
||||||
|
curl -s --interface "$ALLOWED_IF" "$NGINX_A/test-page" > /dev/null
|
||||||
|
curl -s --interface "$ALLOWED_IF" "$NGINX_A/another-page" > /dev/null
|
||||||
|
curl -s --max-time 5 --interface "$ALLOWED_IF" "$NGINX_A/broken/" > /dev/null || true
|
||||||
|
|
||||||
|
# --- 14. syslog ---
|
||||||
|
curl -s --interface "$ALLOWED_IF" "$NGINX_A/syslog-probe-$(date +%s)" > /dev/null || true
|
||||||
|
ok14=0
|
||||||
|
for _ in 1 2 3 4 5; do
|
||||||
|
sleep 1
|
||||||
|
if [ -f /reports/nginx-syslog.log ] && grep -q "nginx" /reports/nginx-syslog.log 2>/dev/null; then
|
||||||
|
ok14=1
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
if [ "$ok14" -eq 1 ]; then
|
||||||
|
pass 14 "syslog receives nginx events"
|
||||||
|
else
|
||||||
|
fail 14 "syslog log missing or empty (/reports/nginx-syslog.log)"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# --- 15. limit_req ---
|
||||||
|
count503=0
|
||||||
|
count200=0
|
||||||
|
codes15=""
|
||||||
|
for i in $(seq 1 5); do
|
||||||
|
c=$(http_code "$ALLOWED_IF" "$NGINX_A/rate-limit-check")
|
||||||
|
codes15="$codes15 $c"
|
||||||
|
[ "$c" = "503" ] && count503=$((count503 + 1))
|
||||||
|
[ "$c" = "200" ] && count200=$((count200 + 1))
|
||||||
|
done
|
||||||
|
if [ "$count503" -gt 0 ] && [ "$count200" -gt 0 ]; then
|
||||||
|
pass 15 "limit_req returns 503 ($count503) and 200 ($count200) in:$codes15"
|
||||||
|
elif [ "$count503" -gt 0 ]; then
|
||||||
|
pass 15 "limit_req returns 503 ($count503 of 5 in:$codes15)"
|
||||||
|
else
|
||||||
|
fail 15 "limit_req no 503 in:$codes15"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# --- 16. limit_conn ---
|
||||||
|
pids=""
|
||||||
|
for i in 1 2 3 4 5; do
|
||||||
|
curl -s -o /tmp/s16_$i -w '%{http_code}' --interface "$ALLOWED_IF" --max-time 25 "$NGINX_A/slow/" > /tmp/c16_$i &
|
||||||
|
pids="$pids $!"
|
||||||
|
done
|
||||||
|
for p in $pids; do wait "$p" 2>/dev/null || true; done
|
||||||
|
codes16=$(cat /tmp/c16_* 2>/dev/null | tr '\n' ' ')
|
||||||
|
if echo "$codes16" | grep -q "503"; then
|
||||||
|
pass 16 "limit_conn returns 503 ($codes16)"
|
||||||
|
else
|
||||||
|
fail 16 "limit_conn no 503 in: $codes16"
|
||||||
|
fi
|
||||||
|
rm -f /tmp/c16_* /tmp/s16_* 2>/dev/null || true
|
||||||
|
|
||||||
|
# --- 17. client_max_body_size ---
|
||||||
|
dd if=/dev/zero of=/tmp/pmi-small bs=1024 count=100 status=none 2>/dev/null
|
||||||
|
dd if=/dev/zero of=/tmp/pmi-large bs=1M count=2 status=none 2>/dev/null
|
||||||
|
c17s=$(curl -s -o /dev/null -w '%{http_code}' --interface "$ALLOWED_IF" -X POST -T /tmp/pmi-small "$NGINX_A/upload")
|
||||||
|
c17l=$(curl -s -o /dev/null -w '%{http_code}' --interface "$ALLOWED_IF" -X POST -T /tmp/pmi-large "$NGINX_A/upload")
|
||||||
|
if [ "$c17s" = "200" ] && [ "$c17l" = "413" ]; then
|
||||||
|
pass 17 "client_max_body_size (small=$c17s large=$c17l)"
|
||||||
|
else
|
||||||
|
fail 17 "client_max_body_size ($c17s/$c17l expected 200/413)"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# --- 18. client_body_timeout ---
|
||||||
|
if dd if=/dev/zero bs=1K count=800 2>/dev/null | curl -s -o /dev/null -w '%{http_code}' \
|
||||||
|
--interface "$ALLOWED_IF" --limit-rate 1K -m 30 -X POST -d @- "$NGINX_A/upload" | grep -qv 200; then
|
||||||
|
pass 18 "client_body_timeout (slow upload rejected/timed out)"
|
||||||
|
else
|
||||||
|
# curl may return 000 on timeout
|
||||||
|
ec=$?
|
||||||
|
if [ "$ec" -ne 0 ]; then
|
||||||
|
pass 18 "client_body_timeout (curl exit $ec)"
|
||||||
|
else
|
||||||
|
fail 18 "client_body_timeout (upload unexpectedly succeeded quickly)"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# --- 19. server_tokens off ---
|
||||||
|
hdr=$(curl -sI --interface "$ALLOWED_IF" "$NGINX_A/public/index.html" | tr -d '\r')
|
||||||
|
body=$(curl -s --interface "$ALLOWED_IF" "$NGINX_A/nonexistent-page-19")
|
||||||
|
if echo "$hdr" | grep -i "^server: nginx$" && ! echo "$hdr" | grep -q "nginx/"; then
|
||||||
|
if ! echo "$body" | grep -q "nginx/"; then
|
||||||
|
pass 19 "server_tokens off"
|
||||||
|
else
|
||||||
|
fail 19 "server_tokens off (version in error body)"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
fail 19 "server_tokens off (Server header: $(echo "$hdr" | grep -i ^server:))"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# --- 20. error_page ---
|
||||||
|
b20=$(curl -s --interface "$ALLOWED_IF" "$NGINX_A/nonexistent-page-20")
|
||||||
|
if echo "$b20" | grep -q "Custom 404"; then
|
||||||
|
pass 20 "custom error_page 404"
|
||||||
|
else
|
||||||
|
fail 20 "custom error_page (body missing Custom 404)"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# --- 21. autoindex off ---
|
||||||
|
c21=$(http_code "$ALLOWED_IF" "$NGINX_A/files/")
|
||||||
|
body21=$(curl -s --interface "$ALLOWED_IF" "$NGINX_A/files/")
|
||||||
|
if [ "$c21" = "403" ] && ! echo "$body21" | grep -qi "<title>Index of"; then
|
||||||
|
pass 21 "autoindex off (403, no listing)"
|
||||||
|
else
|
||||||
|
fail 21 "autoindex ($c21, listing=$(echo "$body21" | head -1))"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# --- 22. proxy_pass ---
|
||||||
|
c22=$(http_code "$ALLOWED_IF" "$NGINX_A/api/status")
|
||||||
|
if [ "$c22" = "200" ]; then
|
||||||
|
pass 22 "proxy_pass to backend ($c22)"
|
||||||
|
else
|
||||||
|
fail 22 "proxy_pass ($c22 expected 200)"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# --- 23. path traversal ---
|
||||||
|
c23a=$(http_code "$ALLOWED_IF" "$NGINX_A/index.html")
|
||||||
|
c23b=$(http_code "$ALLOWED_IF" "$NGINX_A/../../../etc/passwd")
|
||||||
|
if [ "$c23a" = "200" ] && [ "$c23b" = "404" ]; then
|
||||||
|
pass 23 "web root restriction ($c23a/$c23b)"
|
||||||
|
else
|
||||||
|
fail 23 "web root ($c23a/$c23b expected 200/404)"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# --- 24. FIM (run-fim-checksum.sh) ---
|
||||||
|
|
||||||
|
log ""
|
||||||
|
log "=== Summary: PASS=$PASS FAIL=$FAIL SKIP=$SKIP ==="
|
||||||
|
|
||||||
|
if [ "$FAIL" -gt 0 ]; then
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
exit 0
|
||||||
14
results/scripts/wait-ready.sh
Normal file
14
results/scripts/wait-ready.sh
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
set -eu
|
||||||
|
|
||||||
|
echo "Waiting for nginx..."
|
||||||
|
for i in $(seq 1 30); do
|
||||||
|
if wget -q -O /dev/null http://nginx/public/index.html 2>/dev/null; then
|
||||||
|
echo "nginx is ready"
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
sleep 2
|
||||||
|
done
|
||||||
|
|
||||||
|
echo "nginx not ready after 60s" >&2
|
||||||
|
exit 1
|
||||||
30
results/ssl/ca.crt
Normal file
30
results/ssl/ca.crt
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
-----BEGIN CERTIFICATE-----
|
||||||
|
MIIFDTCCAvWgAwIBAgIUZZIrRtH2O6qauuDjnP2jwFNtdfQwDQYJKoZIhvcNAQEL
|
||||||
|
BQAwFjEUMBIGA1UEAwwLUE1JIFRlc3QgQ0EwHhcNMjYwNjE0MDYzNzQzWhcNMzYw
|
||||||
|
NjExMDYzNzQzWjAWMRQwEgYDVQQDDAtQTUkgVGVzdCBDQTCCAiIwDQYJKoZIhvcN
|
||||||
|
AQEBBQADggIPADCCAgoCggIBAJ+Uha/JdxrEvoogtY2gGdpmWWoSDZuh3F5uKLjw
|
||||||
|
k4F39PQ1hAeO3YBpcmPkY6CpwZMYvkoZU1Fd8B404FTDSg2zpV/gulgr0fncMjPg
|
||||||
|
xpqzRnuOaB7jEuWV1f6IHlRn+NDv/HEZEobhrDdL9/EIrx5SFQFgWuB+EMxwJI8I
|
||||||
|
oNYhMF6d9GRvyXNos49a9BDfkNH6TDktIK/w/z2ASQYxoAj5bQK7B+jcKf84FA6x
|
||||||
|
FrWYmW+v0d0Gp3ghtjVnvRSF11YK4OkAFJtNCh8v3scFqSBDqC4Lo9g8hKnDQCio
|
||||||
|
5IgjQy7zV48BJ/ZEqoL66qDcVZyi202A+MKaj2naCmKhqMWFiuJdY6Y0QxXn02jD
|
||||||
|
gRiyWq0bElnyDUhqJEC/A4NoMAxjYBBZMRXU2/3rbKodUlLMYH5hWGbWkQzWoiWb
|
||||||
|
jzvks7gXRcTFFr2nJG4RbfTRRlUI7t5utvcmyX6Czw1QEyE67vJ/KkW0hvDuLznc
|
||||||
|
OgX9dc9mWBlU16kWlCn19g4o4qzw4155HEc2Ro7jr7gATRilKVb70yXq877LUlN7
|
||||||
|
/jrTb+lMFr9e9dzsY0YS3xpjx2dn8TsXuaVjY+VWMRXrHmgs661Ur10SVe6K1AN/
|
||||||
|
jaLo6vRXF8XqPVxIjg/uiInIwsxJNjOpOK/aqjmmH02pmPlUTgtURoZ0GXvJNNAd
|
||||||
|
kD53AgMBAAGjUzBRMB0GA1UdDgQWBBSqDA68B/rOcM63XMAFkyJKxaNzjjAfBgNV
|
||||||
|
HSMEGDAWgBSqDA68B/rOcM63XMAFkyJKxaNzjjAPBgNVHRMBAf8EBTADAQH/MA0G
|
||||||
|
CSqGSIb3DQEBCwUAA4ICAQCRnXhE1VX2++3RT8fTtsH+WYNOo5zcHTqKlqQd922+
|
||||||
|
i3LX0QHoy/8v8ZHVfPvD2swFGB9gkq5YimS5qPtSm8p0WkGscIeMqOaxGsUBcEzK
|
||||||
|
XTjDYBoPorBx3+JpVp4jERz0umKo1H3QRwDKGADp3y+I+JcsxO64LOv15tkSYhmZ
|
||||||
|
sqhs6fr9hnqbYFyARiFMvMZX5zLKDbqtHSOOZUVeo3QKXKu5+mwYBTOO5NTcsiR7
|
||||||
|
FoWVpIlAvT0ST/YtfLyl8YIRfhJn2RXjNXDSXWkNlDwz6WEAaKtr/SyD0OCMQGqk
|
||||||
|
BmjSTPAgbh4VpLTA1HFf47fQp7tMXmNpRR+MMqmT5Q41jLr8/jZDns+yjCaXHulK
|
||||||
|
1N1axdHdDBAfZiwgfSmeCm4dhZfWEmgLwm2zNdbqR7hxDmpmf0YRuzthABeRs9+q
|
||||||
|
NfnY1z6vLYV+guei239l5AuopwyMjkXbZvl4+CxZ4iIA5abPoax5Ij3T1blQSS/t
|
||||||
|
eTOd/7YIacg7RmixFp6D7IJUehRADGEVFT//Kiao3K9Csa0fbSKUIcS5b6aIJv8R
|
||||||
|
s6ho7anoyE8ZmNU1yS/nOKzg59TVG6dMx49eWIwzCdRnihMhYadJ8GsxLluuH5dh
|
||||||
|
BqTFPmA4ejtrtORFO+b457EUM3Ay2wlaYQj+e4Qp7znQP5IugsX4nXQfPr7FrJ2J
|
||||||
|
8Q==
|
||||||
|
-----END CERTIFICATE-----
|
||||||
52
results/ssl/ca.key
Normal file
52
results/ssl/ca.key
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
-----BEGIN PRIVATE KEY-----
|
||||||
|
MIIJQgIBADANBgkqhkiG9w0BAQEFAASCCSwwggkoAgEAAoICAQCflIWvyXcaxL6K
|
||||||
|
ILWNoBnaZllqEg2bodxebii48JOBd/T0NYQHjt2AaXJj5GOgqcGTGL5KGVNRXfAe
|
||||||
|
NOBUw0oNs6Vf4LpYK9H53DIz4Maas0Z7jmge4xLlldX+iB5UZ/jQ7/xxGRKG4aw3
|
||||||
|
S/fxCK8eUhUBYFrgfhDMcCSPCKDWITBenfRkb8lzaLOPWvQQ35DR+kw5LSCv8P89
|
||||||
|
gEkGMaAI+W0Cuwfo3Cn/OBQOsRa1mJlvr9HdBqd4IbY1Z70UhddWCuDpABSbTQof
|
||||||
|
L97HBakgQ6guC6PYPISpw0AoqOSII0Mu81ePASf2RKqC+uqg3FWcottNgPjCmo9p
|
||||||
|
2gpioajFhYriXWOmNEMV59Now4EYslqtGxJZ8g1IaiRAvwODaDAMY2AQWTEV1Nv9
|
||||||
|
62yqHVJSzGB+YVhm1pEM1qIlm4875LO4F0XExRa9pyRuEW300UZVCO7ebrb3Jsl+
|
||||||
|
gs8NUBMhOu7yfypFtIbw7i853DoF/XXPZlgZVNepFpQp9fYOKOKs8ONeeRxHNkaO
|
||||||
|
46+4AE0YpSlW+9Ml6vO+y1JTe/4602/pTBa/XvXc7GNGEt8aY8dnZ/E7F7mlY2Pl
|
||||||
|
VjEV6x5oLOutVK9dElXuitQDf42i6Or0VxfF6j1cSI4P7oiJyMLMSTYzqTiv2qo5
|
||||||
|
ph9NqZj5VE4LVEaGdBl7yTTQHZA+dwIDAQABAoICADC2IHzBTacRKWx2gZTiqyGc
|
||||||
|
nmyfaCH6rY7xp2KUpSIfINmuwEeiV4DML0vIupSfXORu6B8sTd+HgjVmRJf7KM63
|
||||||
|
6KI0sg0aCzVu/rARS+6LDNfIZ4YOIIWOUE0q9b8kIbJ9nxxS3/HmTzBt8xhTY0kp
|
||||||
|
GxpZdEQUl0IgdThoFNhoNyCarLA/40lkS3NV+yxvYgCGm9/UI6cxNGhskV3fpg83
|
||||||
|
PAxaVRbCpdsvHghCDEGQfD24eKI0Vsh32evBZ9ks5cdw+KiHCsNBJ/bPIPy1gKPF
|
||||||
|
oz+y8+ecyY4ceKgwrdnUkbxyMWcInk8xNK9Ysmg5+bQfjjvBQ637ig1wrjzfRenR
|
||||||
|
QiSM57HXZ/5AIYQaT9B73x5nQWJINeI9rk0bv50Q7J7k/eu3XYCe9gLaEA2raAv+
|
||||||
|
dkGnT3aPAo/59IYmEO7YUDXGwcmbeWtuzSdM9QVGNkvyBlknc64QYrXOLMEtiVk8
|
||||||
|
cbkBI2c0wMh0Z3KBV4e6/qwBZ7NzHlVyWrcaEG7dsGierfLBgoqvGQKiNmBDwy1X
|
||||||
|
Zmh6n7qXeA1XJgp/OqF3TsIzL9STQ48g0MQl9eXJLhXXCZ1oeXh0UPob/TOneM4G
|
||||||
|
reKGa5aum3TEpt8QPHZB3jXJf4ZUvmlzcGamaOSohwYSuCXp1oGtCxhQ8LXobZP8
|
||||||
|
O3tGHWIfH120JsNaCCsBAoIBAQDgTrTsQ8txjK0hKlB8TyH08mkh+UitiM/UOLOG
|
||||||
|
XToa++HceR/rudbgWU0BaKCwZp2rNWro6WGUKb9D/3KPxS8tbPnKhDuEAgRjoUHO
|
||||||
|
QbuLr6OHWabtoGKu99KsQ/KIj5iDDpdPJaCE+eZXphjiGProqlSUBFzAQOsQBpW7
|
||||||
|
rO2KJSgT/UrNglXSSb4VL9O1Bu9HF4NO2MrEuhgMI5j5+TniRFEvFyQc9NaktAcS
|
||||||
|
umn9g5eQdZtyBNA4cxWm3z+XtXQ0+yCZ7UUMF1E0ZnZlfsy9a0M+NaiVG8Ls1wdo
|
||||||
|
B35o+TAYX8vGVuYRmxcsXY5M538OkbBGfNydcOpGWZWIC3D3AoIBAQC2IJpUSkQx
|
||||||
|
MH7CY66XbqLV1COXo+Sf8s/kFr5Y+lNGtP5r3WWAeqMipc7Rvc+4BBfWa0AjBr24
|
||||||
|
HqffibS3AmhtbOBt58FqgPxeCFxWq8Q3bZaKCa2fDDH1GkPaTGiXzPPEIuGK/4jw
|
||||||
|
8vpfQTZCxqvdxrgn2hROB7FCJUrDme1klo/Dvum9/I13CHoa/6ytaDZprfZQ9Bh8
|
||||||
|
/fgyJORwhlG6o+c5SrN+Zzb611N94lP+Jto7LU0u/fRbNGYFp9yjiaR39cFia5/i
|
||||||
|
sXyW1r6ZM0NFbpL2510LXGkhB96bAqmQFjQ+4rVOnOV/CFXAf0hp/ufhIlb2y9lB
|
||||||
|
yXvnTiaFc76BAoIBACZlEo8Go8JSBCiTJ6e/m95jyB8qnoglzP1Un1Y2iwWna+fj
|
||||||
|
S9V7wA4y+v1svWS0i/SMdjpcCHnmE3k+NovpgsPRzYgezlkwRzQOnEcD9WhZrjIy
|
||||||
|
5GH0fC/a99LI5rD9c2uribbgh/N7GzSRl9zLzdcZoNSdUosOEa5ykhrH5Pkqlwuk
|
||||||
|
5bL7xljyinjx8Nkh0L9ohO9wKHU4LXmWdk8DnCbg7sySt3nFZyBWOIe6JP5iEgWG
|
||||||
|
PA9uR34CJQilWitLwhJ3kgMHHDSPoTTI/ScuZzldLOtvH+Y2FE2aGQhzj+3ECbmC
|
||||||
|
XE0c/tCwrWzIrtz3G0aRJY1LPjAs7c0Q9ImO+80CggEBAI1rqYq0FFmBx5wYHTUX
|
||||||
|
Qrf5Px37tIaC2+zHwEyFLG7mEf0d8DggglZgG8V/tzCzdPMZWrcX/+9dVotceYf2
|
||||||
|
BbKabXbKE8UonU5C/biLLhTAMrnDJB8xMAWbvH5hAIKHMe3mC+6L2AEJG2Ml1wVp
|
||||||
|
EYFnUg4X59ZjYL/1ByX1e4G067NaplPRLOP2ICKgz6vjFQVggLiBohZEexoszXmW
|
||||||
|
wxXDOcOh/tizOtzyoLFKMmBSOPjkh19q8Ph1KpdPriMKuTwxB1XuLjuwCAd0fpGl
|
||||||
|
XaInZ1TzeKteuX9dhfwlyBbLNwxxq8l8STQn+7Y637b2qYWGzbJbvbq4wk5sv7q2
|
||||||
|
koECggEAGevA2ceMhM5DyLjZUaMNkVWd3GefO9kmpNA6yu0ashfIR0Elnt/go6Mh
|
||||||
|
pVwTPA+tUllidjY4IHR2sWv2OCNGETek2Ke+xbDHOQJ9kz6NehLAuJoXZusTB3pX
|
||||||
|
xxCe+YxgiFX9nkIdrx+F/nmHm7CQtVy6dBuNBEHgOUmEuXBM2GxVGx1HmcELVCwx
|
||||||
|
a9uL7EDFhbnPArFvrICA6R7BGe944XkBEw8Oi4RLvTasytFVijNkav5AQ3vUSKIN
|
||||||
|
/e+Il56iV+HVcTfrOIDbJy5MiiWpWIYxgB/97y9I9tN5tTWEJxWRhrqwHqkeaP9G
|
||||||
|
VX8MV5cZIQylsYzuupzaYcIqOTLowg==
|
||||||
|
-----END PRIVATE KEY-----
|
||||||
24
results/ssl/client.crt
Normal file
24
results/ssl/client.crt
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
-----BEGIN CERTIFICATE-----
|
||||||
|
MIID/zCCAeegAwIBAgIUHLNAeqUKFk+dccHcoEJuHnC/AGQwDQYJKoZIhvcNAQEL
|
||||||
|
BQAwFjEUMBIGA1UEAwwLUE1JIFRlc3QgQ0EwHhcNMjYwNjE0MDYzNzQzWhcNMjgw
|
||||||
|
OTE2MDYzNzQzWjAZMRcwFQYDVQQDDA50cnVzdGVkLWNsaWVudDCCASIwDQYJKoZI
|
||||||
|
hvcNAQEBBQADggEPADCCAQoCggEBAPUDSiryiTv+BJlk2OEYheL0HvJDDT973aJu
|
||||||
|
QVEQHrebTjpsNrfqw+B8J0kx8y7sRKKQMsW1oxi6ltzZZES7WHcZKTiReevlgWWA
|
||||||
|
Z1We2OK3e2z/xFgtTKnnfZ2lJSSjhYcsADLPUQmt+9kKvfzvvR3VFcO3mEs8UWVx
|
||||||
|
beacnsbiIFVJOP0DS2R63J1blpVGH2u5dICdNWlVmo2mAGXtAwRkxm4mQUademic
|
||||||
|
rgrEOmOftJcwQYXgr9Si8H4P21U4VRZdLhS3vU73npLSqC6P2GoAiAQjdDDQMEfK
|
||||||
|
j6EYud9pt5rapnBSFPyfMAAZt+V7eXIgQfqumSNiEiB8ckgVK3sCAwEAAaNCMEAw
|
||||||
|
HQYDVR0OBBYEFC8RXtw9o19b0W3uc0Dg35rQLQufMB8GA1UdIwQYMBaAFKoMDrwH
|
||||||
|
+s5wzrdcwAWTIkrFo3OOMA0GCSqGSIb3DQEBCwUAA4ICAQB1PK/Bcw5lIyRIbfql
|
||||||
|
ZumaC3cla3IcoCJipSSnUeqOknFkPgSLqxM0b99k+FL7Hc7o7JQJeUwdGGf5StQ9
|
||||||
|
vAMdj1TaEkEK2TR4nWdbX3yLH2jnoouhCfxPOk6ci9D9hfd85v0UDtjvzxStrRlq
|
||||||
|
Fy+mmTEe7yTlr8CzWzC/MAm2VuozZI2yhTJiIXL7bB2R3FvlnpH5pxXccbYyYPZy
|
||||||
|
7AIEQj0psMnA6egyNATM8D8sGpAv1nC3QXdYmXg1SmkZkmivbjrYqnyJmQnJTMOQ
|
||||||
|
p8EzKmzMCtlfxT4nvzsSuLalepcpeRz5ap6zyU9vjVW3f3FRVi3axYvs+BhX4Bu7
|
||||||
|
2KC054npZp3S9mTRgvB+6GJrxfZ3xqmqWjhxWEo77A6bF50xAoEextuxKDTYZdeF
|
||||||
|
Gm8sKjxzdjArS3QB5yp+inl2OqmqQ/EuP24NGWZplO22W+qwkDd23Hj+CQuqgbYA
|
||||||
|
DDbDvGltXFO0Kh9qtc6JabOIOetP8qhzfgxSyU3PNmcyd9hoCNZEjfNyYGcAJhk6
|
||||||
|
afJ21r7DZzSckIGaYCe5nrTIdDTLvG8u1+IGMFdVPInd8S0uyE2j2tZ0oCL0p31f
|
||||||
|
88+RJSbicgIMK+mTg3G0OLjDFzlDe4/P5dW4Xr5xz2/1o8qlTu/piNF6bIggEPP2
|
||||||
|
/8VHHblhHtH6lA8SuB6lm8y/BA==
|
||||||
|
-----END CERTIFICATE-----
|
||||||
28
results/ssl/client.key
Normal file
28
results/ssl/client.key
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
-----BEGIN PRIVATE KEY-----
|
||||||
|
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQD1A0oq8ok7/gSZ
|
||||||
|
ZNjhGIXi9B7yQw0/e92ibkFREB63m046bDa36sPgfCdJMfMu7ESikDLFtaMYupbc
|
||||||
|
2WREu1h3GSk4kXnr5YFlgGdVntjit3ts/8RYLUyp532dpSUko4WHLAAyz1EJrfvZ
|
||||||
|
Cr38770d1RXDt5hLPFFlcW3mnJ7G4iBVSTj9A0tketydW5aVRh9ruXSAnTVpVZqN
|
||||||
|
pgBl7QMEZMZuJkFGnXponK4KxDpjn7SXMEGF4K/UovB+D9tVOFUWXS4Ut71O956S
|
||||||
|
0qguj9hqAIgEI3Qw0DBHyo+hGLnfabea2qZwUhT8nzAAGbfle3lyIEH6rpkjYhIg
|
||||||
|
fHJIFSt7AgMBAAECggEAPnehQEPn81C3UXihxvoeoJeHEFNCHG5zOoeLxaQrgLpq
|
||||||
|
/oA6jzeeyyw8Q/AlRVBdy2iiWUAPHi3satBOPSvayTq0BMUqZZd1HzDWp8DBIUSQ
|
||||||
|
hmDLaYPbKPJpV3kUeDvsvmLchhfPXH1sWZDgkY16FRIP4396p6vwQMHjuEk0PhZH
|
||||||
|
WOjeK0g96k5HaflYqIyC9GiTi8O2PUjMm3Ftr9nl7XaGyIfukLVjjaM4isVwD2/R
|
||||||
|
ypSf4RWcFw1T9ieLJmNLM/0WbEgPuTWouF1G5JOPKQ7gAUDtzo7gT8qs927U+OKW
|
||||||
|
NYWH/wUolJB5TTHkU4W/uw54wU6SMzVSR+5CQeJx8QKBgQD+eqF4ft/vD1fNVUNl
|
||||||
|
Zgq7Ld5qGKPbaHuYqk2nelRPKp063GiHJFbrKfnt6qWpSjtOKkgtGBLhAoZz9OyK
|
||||||
|
NvqvsJJQEs1CDNx0i6BGY3xRXWZU6Erws7X82Z3hOsHd16HGoMWah75tYygemTSA
|
||||||
|
OyEktEaINC6AJ7vCpvcDKAyvWQKBgQD2eizUZHv9eKnfzDY+DkoACv8vDIiqOX44
|
||||||
|
bWsNaejtWF7iEj5Qws+GqhnuMjLW084//nc/j+6L328oqSLOfdpXUSpy++sAl+3Q
|
||||||
|
mTzH9N2Caa1pTCd2VfJOidg4RcUOzw3F+/h+0tGHAB2UXyPTpJ8iVpVR5t5r9yMj
|
||||||
|
nzPsS9NK8wKBgALGvbo90B2gkjmoQ3r4uQc/wdxwdmEva6HHwd8g44iVk2+P9gf7
|
||||||
|
aoNYSuTAmZwWNj1tEqqDR7lyuJrNQkNjxCpkh8Qd4GVnFISk/VOnRDTzCunEOwUT
|
||||||
|
QNoIWcOaS4ErGBW9rUo5TueMnGRxEXSQsJTg7qAPya4WQOMnxSwgpLrJAoGAeUE3
|
||||||
|
prFcciEXaRr8oGDFNOo0CgBfh2bLWpUxsiKlTYZI/2y8LVz5XSV3pkAZ1KfUcpUM
|
||||||
|
Mz/qufMMq3MxxWYSsRwkBvc58EvN2e5ZAYHMK2kzv3aQf13e25ZiwaRJQnTIMNs5
|
||||||
|
r6KlI4YCB0kaxfbZtrnjsawjRfgJ2G9sytWut9MCgYEAmaLhWDhS50JXO27uybQP
|
||||||
|
M/g0E8OuNeXLPrRwPNOYhzKYHR5mmz8iGrjWIMKl6pP3so3AgezRiAAoPbsDg1WD
|
||||||
|
Nfy61bnPyauNZOHozuYCyzWHt2TrXSiZw8C3oTPLdDzg0fVMtUHDpeNb3HiB1gz9
|
||||||
|
ApYXJxXwLAjx9b+OzYZssxQ=
|
||||||
|
-----END PRIVATE KEY-----
|
||||||
54
results/ssl/fullchain.crt
Normal file
54
results/ssl/fullchain.crt
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
-----BEGIN CERTIFICATE-----
|
||||||
|
MIID+zCCAeOgAwIBAgIUHLNAeqUKFk+dccHcoEJuHnC/AGMwDQYJKoZIhvcNAQEL
|
||||||
|
BQAwFjEUMBIGA1UEAwwLUE1JIFRlc3QgQ0EwHhcNMjYwNjE0MDYzNzQzWhcNMjgw
|
||||||
|
OTE2MDYzNzQzWjAVMRMwEQYDVQQDDApuZ2lueC10ZXN0MIIBIjANBgkqhkiG9w0B
|
||||||
|
AQEFAAOCAQ8AMIIBCgKCAQEAkyZzCULOJgtzNHMf8Mfmks0UYRlsEBF6cC6uokIP
|
||||||
|
VUOkN1TYENKWAoc5LBJgJbPlXoOAd488jIybX6097iV9Rh0bW2g/LDEZZxWhOiEK
|
||||||
|
t0yfkgv++kgSW3E0CRNskn3IfSRy33KNRHIBVANgCfYAzbvPgu1hd57g/4lEuOCi
|
||||||
|
ZmP0dECATohqXPtFmcOTI1XVWLg135E+78EJJabn9UAaVBg+D2vlNhIXXahSva5Z
|
||||||
|
zPOvKrokGYu2xq2bITif1TNW0oCKV8nyUOMI/SOs0Aqoh0s6LynzWLXVTS15km5n
|
||||||
|
kst5WYSbqSPLnvdNC+F6vcBHQzpPTgA/HadGWnsmypLIqQIDAQABo0IwQDAdBgNV
|
||||||
|
HQ4EFgQUKvi6Yan9WEZMPrlKGVpPzu3LZmkwHwYDVR0jBBgwFoAUqgwOvAf6znDO
|
||||||
|
t1zABZMiSsWjc44wDQYJKoZIhvcNAQELBQADggIBAIj0SXcXLMKylfCEkF2IHZ7a
|
||||||
|
MtiVcOjrMKRrfwvufgSd5dEL813axbDas5Eq9asbM/epd7x/t+oWTnRlZAOet6nO
|
||||||
|
92etE/+EolWThOMFlRxr+c6i88O0nqqsdUypS7mE/egw3CAktEFJhjzyTmS2EMaq
|
||||||
|
44n4rdwVc3yNeLKzZIKs0haSzbKyeqhJNt+x9CgBSpS5hGtCBPSILcMu2XvtugqA
|
||||||
|
l0PhMA5T5WE8uUVqzAhETRcZWh/X9wcbpRUJ3EPFbqGoleLUmgRH36k04mp/P11d
|
||||||
|
HXmbZkXFMRS4+ovj6nW6SqcHXa53frlcYinarhX5TWLViwD49iEgoBfv4V9aRDzB
|
||||||
|
auOoRculc6F+euI6dCbJiHUt2PAa/SRCA3i37VOqmrjlQ4L6fe+cNc/+PY6n4EyK
|
||||||
|
sOPX/OPs1XLAXOpZQ5/JDgBdBNIxZFtT6KDKFGoHLRt7KNN78VRowX4DRwwhN/CR
|
||||||
|
f7tgKk3m57IxtHNmq++wPiofmPyY+d1vCe0S+0aKf6lblxdG2Cuo+n0D1DnXL0Vv
|
||||||
|
2EFDpGyW+5V9G5Toxc5Dmvy5MpHFF/7Wtq8dMty9c91G6PCgHB7Yw/MOfWa6thbm
|
||||||
|
dSWOA0Wxdinneaq6NI2e7p4zEKkibnnHr/YY2wgI5MC5pNJUYVDqnkzrNLcDi6yA
|
||||||
|
QADElgz27j8zOConcqRz
|
||||||
|
-----END CERTIFICATE-----
|
||||||
|
-----BEGIN CERTIFICATE-----
|
||||||
|
MIIFDTCCAvWgAwIBAgIUZZIrRtH2O6qauuDjnP2jwFNtdfQwDQYJKoZIhvcNAQEL
|
||||||
|
BQAwFjEUMBIGA1UEAwwLUE1JIFRlc3QgQ0EwHhcNMjYwNjE0MDYzNzQzWhcNMzYw
|
||||||
|
NjExMDYzNzQzWjAWMRQwEgYDVQQDDAtQTUkgVGVzdCBDQTCCAiIwDQYJKoZIhvcN
|
||||||
|
AQEBBQADggIPADCCAgoCggIBAJ+Uha/JdxrEvoogtY2gGdpmWWoSDZuh3F5uKLjw
|
||||||
|
k4F39PQ1hAeO3YBpcmPkY6CpwZMYvkoZU1Fd8B404FTDSg2zpV/gulgr0fncMjPg
|
||||||
|
xpqzRnuOaB7jEuWV1f6IHlRn+NDv/HEZEobhrDdL9/EIrx5SFQFgWuB+EMxwJI8I
|
||||||
|
oNYhMF6d9GRvyXNos49a9BDfkNH6TDktIK/w/z2ASQYxoAj5bQK7B+jcKf84FA6x
|
||||||
|
FrWYmW+v0d0Gp3ghtjVnvRSF11YK4OkAFJtNCh8v3scFqSBDqC4Lo9g8hKnDQCio
|
||||||
|
5IgjQy7zV48BJ/ZEqoL66qDcVZyi202A+MKaj2naCmKhqMWFiuJdY6Y0QxXn02jD
|
||||||
|
gRiyWq0bElnyDUhqJEC/A4NoMAxjYBBZMRXU2/3rbKodUlLMYH5hWGbWkQzWoiWb
|
||||||
|
jzvks7gXRcTFFr2nJG4RbfTRRlUI7t5utvcmyX6Czw1QEyE67vJ/KkW0hvDuLznc
|
||||||
|
OgX9dc9mWBlU16kWlCn19g4o4qzw4155HEc2Ro7jr7gATRilKVb70yXq877LUlN7
|
||||||
|
/jrTb+lMFr9e9dzsY0YS3xpjx2dn8TsXuaVjY+VWMRXrHmgs661Ur10SVe6K1AN/
|
||||||
|
jaLo6vRXF8XqPVxIjg/uiInIwsxJNjOpOK/aqjmmH02pmPlUTgtURoZ0GXvJNNAd
|
||||||
|
kD53AgMBAAGjUzBRMB0GA1UdDgQWBBSqDA68B/rOcM63XMAFkyJKxaNzjjAfBgNV
|
||||||
|
HSMEGDAWgBSqDA68B/rOcM63XMAFkyJKxaNzjjAPBgNVHRMBAf8EBTADAQH/MA0G
|
||||||
|
CSqGSIb3DQEBCwUAA4ICAQCRnXhE1VX2++3RT8fTtsH+WYNOo5zcHTqKlqQd922+
|
||||||
|
i3LX0QHoy/8v8ZHVfPvD2swFGB9gkq5YimS5qPtSm8p0WkGscIeMqOaxGsUBcEzK
|
||||||
|
XTjDYBoPorBx3+JpVp4jERz0umKo1H3QRwDKGADp3y+I+JcsxO64LOv15tkSYhmZ
|
||||||
|
sqhs6fr9hnqbYFyARiFMvMZX5zLKDbqtHSOOZUVeo3QKXKu5+mwYBTOO5NTcsiR7
|
||||||
|
FoWVpIlAvT0ST/YtfLyl8YIRfhJn2RXjNXDSXWkNlDwz6WEAaKtr/SyD0OCMQGqk
|
||||||
|
BmjSTPAgbh4VpLTA1HFf47fQp7tMXmNpRR+MMqmT5Q41jLr8/jZDns+yjCaXHulK
|
||||||
|
1N1axdHdDBAfZiwgfSmeCm4dhZfWEmgLwm2zNdbqR7hxDmpmf0YRuzthABeRs9+q
|
||||||
|
NfnY1z6vLYV+guei239l5AuopwyMjkXbZvl4+CxZ4iIA5abPoax5Ij3T1blQSS/t
|
||||||
|
eTOd/7YIacg7RmixFp6D7IJUehRADGEVFT//Kiao3K9Csa0fbSKUIcS5b6aIJv8R
|
||||||
|
s6ho7anoyE8ZmNU1yS/nOKzg59TVG6dMx49eWIwzCdRnihMhYadJ8GsxLluuH5dh
|
||||||
|
BqTFPmA4ejtrtORFO+b457EUM3Ay2wlaYQj+e4Qp7znQP5IugsX4nXQfPr7FrJ2J
|
||||||
|
8Q==
|
||||||
|
-----END CERTIFICATE-----
|
||||||
24
results/ssl/server.crt
Normal file
24
results/ssl/server.crt
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
-----BEGIN CERTIFICATE-----
|
||||||
|
MIID+zCCAeOgAwIBAgIUHLNAeqUKFk+dccHcoEJuHnC/AGMwDQYJKoZIhvcNAQEL
|
||||||
|
BQAwFjEUMBIGA1UEAwwLUE1JIFRlc3QgQ0EwHhcNMjYwNjE0MDYzNzQzWhcNMjgw
|
||||||
|
OTE2MDYzNzQzWjAVMRMwEQYDVQQDDApuZ2lueC10ZXN0MIIBIjANBgkqhkiG9w0B
|
||||||
|
AQEFAAOCAQ8AMIIBCgKCAQEAkyZzCULOJgtzNHMf8Mfmks0UYRlsEBF6cC6uokIP
|
||||||
|
VUOkN1TYENKWAoc5LBJgJbPlXoOAd488jIybX6097iV9Rh0bW2g/LDEZZxWhOiEK
|
||||||
|
t0yfkgv++kgSW3E0CRNskn3IfSRy33KNRHIBVANgCfYAzbvPgu1hd57g/4lEuOCi
|
||||||
|
ZmP0dECATohqXPtFmcOTI1XVWLg135E+78EJJabn9UAaVBg+D2vlNhIXXahSva5Z
|
||||||
|
zPOvKrokGYu2xq2bITif1TNW0oCKV8nyUOMI/SOs0Aqoh0s6LynzWLXVTS15km5n
|
||||||
|
kst5WYSbqSPLnvdNC+F6vcBHQzpPTgA/HadGWnsmypLIqQIDAQABo0IwQDAdBgNV
|
||||||
|
HQ4EFgQUKvi6Yan9WEZMPrlKGVpPzu3LZmkwHwYDVR0jBBgwFoAUqgwOvAf6znDO
|
||||||
|
t1zABZMiSsWjc44wDQYJKoZIhvcNAQELBQADggIBAIj0SXcXLMKylfCEkF2IHZ7a
|
||||||
|
MtiVcOjrMKRrfwvufgSd5dEL813axbDas5Eq9asbM/epd7x/t+oWTnRlZAOet6nO
|
||||||
|
92etE/+EolWThOMFlRxr+c6i88O0nqqsdUypS7mE/egw3CAktEFJhjzyTmS2EMaq
|
||||||
|
44n4rdwVc3yNeLKzZIKs0haSzbKyeqhJNt+x9CgBSpS5hGtCBPSILcMu2XvtugqA
|
||||||
|
l0PhMA5T5WE8uUVqzAhETRcZWh/X9wcbpRUJ3EPFbqGoleLUmgRH36k04mp/P11d
|
||||||
|
HXmbZkXFMRS4+ovj6nW6SqcHXa53frlcYinarhX5TWLViwD49iEgoBfv4V9aRDzB
|
||||||
|
auOoRculc6F+euI6dCbJiHUt2PAa/SRCA3i37VOqmrjlQ4L6fe+cNc/+PY6n4EyK
|
||||||
|
sOPX/OPs1XLAXOpZQ5/JDgBdBNIxZFtT6KDKFGoHLRt7KNN78VRowX4DRwwhN/CR
|
||||||
|
f7tgKk3m57IxtHNmq++wPiofmPyY+d1vCe0S+0aKf6lblxdG2Cuo+n0D1DnXL0Vv
|
||||||
|
2EFDpGyW+5V9G5Toxc5Dmvy5MpHFF/7Wtq8dMty9c91G6PCgHB7Yw/MOfWa6thbm
|
||||||
|
dSWOA0Wxdinneaq6NI2e7p4zEKkibnnHr/YY2wgI5MC5pNJUYVDqnkzrNLcDi6yA
|
||||||
|
QADElgz27j8zOConcqRz
|
||||||
|
-----END CERTIFICATE-----
|
||||||
28
results/ssl/server.key
Normal file
28
results/ssl/server.key
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
-----BEGIN PRIVATE KEY-----
|
||||||
|
MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQCTJnMJQs4mC3M0
|
||||||
|
cx/wx+aSzRRhGWwQEXpwLq6iQg9VQ6Q3VNgQ0pYChzksEmAls+Veg4B3jzyMjJtf
|
||||||
|
rT3uJX1GHRtbaD8sMRlnFaE6IQq3TJ+SC/76SBJbcTQJE2ySfch9JHLfco1EcgFU
|
||||||
|
A2AJ9gDNu8+C7WF3nuD/iUS44KJmY/R0QIBOiGpc+0WZw5MjVdVYuDXfkT7vwQkl
|
||||||
|
puf1QBpUGD4Pa+U2EhddqFK9rlnM868quiQZi7bGrZshOJ/VM1bSgIpXyfJQ4wj9
|
||||||
|
I6zQCqiHSzovKfNYtdVNLXmSbmeSy3lZhJupI8ue900L4Xq9wEdDOk9OAD8dp0Za
|
||||||
|
eybKksipAgMBAAECggEACLHaKhcsMqkftMmY/s4fr0IWZ5lhXlQGDyMMVxKTsNxR
|
||||||
|
vkzmr8cdrYcQx1b2SZaxts4K39BTHyk/aghvcxxRz2bbYwvhGwrzVGO9tn9Vey4N
|
||||||
|
dLX9lODVfYPjc6YrQWmqGHji9RXh8oQmVMZBR71lNULZGK75liBJbQKkUKSXUU4/
|
||||||
|
h6M8iv0v9m7Itrrg8v1LEkDCwmlvviII0wODEKNtOcUt9TEhkrVLT6wqJgAkOVEm
|
||||||
|
J8f6tIkREUCslHQ+Ls/wcGjAtr1Z8c3Dx/onIKosbRl04/ahcfX9fGaYqWiONH7w
|
||||||
|
m6/29tsac8nkGbsJ3oHXdPt6Zy8QVm3TeX110T1aPQKBgQDOIkqwW1NuZitk+bT4
|
||||||
|
D0L7aBVTKhtJEq9Oe9g6qnhdmd0VNyhH69oYpvlUUXJ4pqfSSeUFfUDjfNTIVi0M
|
||||||
|
5HmsU8HdipP0CceX8YERSOn7uNnjoBfdKpxyBT+FzDLQhLBoFM9yEc7/3ttjPN93
|
||||||
|
0RmDVK42rBK4E11V8qJNaaB+jQKBgQC2v1dfArjE9v/idt2DiTO4RWjbooNjAn71
|
||||||
|
u9Dz1L/YomIX7Il8FLqoRfhTWxvwkRCJpYpsW9cpXN7KLfX8abZh7GPHUTFBG9pT
|
||||||
|
E6ZTIQOXnfnyWVskhmytWKkZ/YSrzeYyHEWdwXtk2qJrJy6YVnucHlkZ3IH74zlv
|
||||||
|
UZmvIKqpjQKBgCiAimZee2UsxAgCHHHFJecaC16c3mGcPz/Pi6vzRNU3Xz5E6TBA
|
||||||
|
gkjnvgO4QSK9tCnYhRxwAOjx5Sk77XwkBFg82NG74dhId6Q+Opr31am1J3LXSPkW
|
||||||
|
30h0CYgzmCRqffLla+FA6IhT9I1qL4puVnH8mIJ7iu4KOAOkOgm14GgdAoGAFba4
|
||||||
|
f+6H28dpchQjj9x+i7eblPVDXUFPqo0Nb9tojCoHM8aEM30XDKV7sxPRRw1FhMVp
|
||||||
|
pCRpdV22jxlU8A/zfsEive0UyCKyF0rvaVMz5RD9QOGDJdzfDt3JAfCQkgVeA7g+
|
||||||
|
QVda/QnJYKgALlOgTlWAysTboP1HtsVgWGGuRYUCgYBIrhX5D1vXLxheLFz+w7LI
|
||||||
|
Y0aZQ3dvgRj7gOYQYp5tFcziqFUMly3XzMQO9YibSGJmilrtdhjteGGcBc7vmnSy
|
||||||
|
BiL79mBRz6SsmZRoEvF302TKae+pnJ+h3z1mtptYOm3zq1v9pHSKVXDwXvKSpM+5
|
||||||
|
9GVIWzBHS9ljJ0rN4ICZWw==
|
||||||
|
-----END PRIVATE KEY-----
|
||||||
19
results/ssl/untrusted.crt
Normal file
19
results/ssl/untrusted.crt
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
-----BEGIN CERTIFICATE-----
|
||||||
|
MIIDFzCCAf+gAwIBAgIUKtZLCLBMCJ4MQ4lG8yfujsMKbEcwDQYJKoZIhvcNAQEL
|
||||||
|
BQAwGzEZMBcGA1UEAwwQdW50cnVzdGVkLWNsaWVudDAeFw0yNjA2MTQwNjM3NDNa
|
||||||
|
Fw0yNzA2MTQwNjM3NDNaMBsxGTAXBgNVBAMMEHVudHJ1c3RlZC1jbGllbnQwggEi
|
||||||
|
MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC7w8FTPXsENWLUSSmfA9J9uVY3
|
||||||
|
+pUEuzcaL3GYNFN7KBxdURdE7D9PE9qmZRLKIvQA/oeSMqOovWeDad0zj/x2+Rcw
|
||||||
|
9q9SMPF5k5WVXTZtFA7QGPh4ZlnxNsVTD5jUUjlL7RBaNudQq7xiiCn906MG7+e3
|
||||||
|
6EIf7fRWetwHktTwT4IL6jttHT1HlpTTTW5jUV/htUbXAny/UE78j2jnfyWlU5RP
|
||||||
|
GJNMhYnC2bjKlbDitio/FWcwM9cbgCnqBFsSYU0SXmAdc8LeCta4D/U3ZZks3I19
|
||||||
|
oV7x0yOz9EApGE/vRII5AhtI9thmbLKKdiQsjX3euV3Ob0uM7nLcD9L214KrAgMB
|
||||||
|
AAGjUzBRMB0GA1UdDgQWBBSpDQPnd0AN3OINmHVw4dUD1IkVHzAfBgNVHSMEGDAW
|
||||||
|
gBSpDQPnd0AN3OINmHVw4dUD1IkVHzAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3
|
||||||
|
DQEBCwUAA4IBAQAJqyA96YOZAVp0C6ef7WqFgulTXWBbDw16j80SWZFfZqXEmmYR
|
||||||
|
4lgLy/Rf7IMZYbxOhLZnG7aHYhh+DVGdC1pDja80dthHRrLBjK1W7PlBktsS4f7H
|
||||||
|
GuDeBYpnV9LojemuFt0q63KYHmNm8Bs/zzyi5DfpVUr4EqoJns9Sy5jBP42tqzMX
|
||||||
|
AaFUoQ0lWB7XVK9RCdHWvWg4etJE+APvOp3OHHC0JpGF/1DfytOg9lnlwxH+rGOH
|
||||||
|
lwaIPRwtZl1o0zxwxs2ZxSzmNNq82xVKV8dfS4T+vS+YFTm8uB5zohK/uE1rsfz2
|
||||||
|
KnBW3RHFfSpBZd0RF2Z9nS7P1lRcG0xjgAAV
|
||||||
|
-----END CERTIFICATE-----
|
||||||
28
results/ssl/untrusted.key
Normal file
28
results/ssl/untrusted.key
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
-----BEGIN PRIVATE KEY-----
|
||||||
|
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQC7w8FTPXsENWLU
|
||||||
|
SSmfA9J9uVY3+pUEuzcaL3GYNFN7KBxdURdE7D9PE9qmZRLKIvQA/oeSMqOovWeD
|
||||||
|
ad0zj/x2+Rcw9q9SMPF5k5WVXTZtFA7QGPh4ZlnxNsVTD5jUUjlL7RBaNudQq7xi
|
||||||
|
iCn906MG7+e36EIf7fRWetwHktTwT4IL6jttHT1HlpTTTW5jUV/htUbXAny/UE78
|
||||||
|
j2jnfyWlU5RPGJNMhYnC2bjKlbDitio/FWcwM9cbgCnqBFsSYU0SXmAdc8LeCta4
|
||||||
|
D/U3ZZks3I19oV7x0yOz9EApGE/vRII5AhtI9thmbLKKdiQsjX3euV3Ob0uM7nLc
|
||||||
|
D9L214KrAgMBAAECggEAU35oXNIFfmkY8eo4wleqRbLhJpJcqpZvmcrIGhUGnEjJ
|
||||||
|
WCuji8f8HPdorr5aPR2O4FROx9GR2gqjWZn9PZ0E+IiqaeEANC3EazoX9avV9GpL
|
||||||
|
bfj0oGFvFGa1F0rjvGJ1zQ/1ShCJCuPbKPuApLj0ETUkFrEGmnkvQjdu2UVPQC5v
|
||||||
|
1Shry2UisYKnUSgYGY58mpio0TzccQ/X7EhwZWTbT2ueiztqJ/STniL6mMMl8PVk
|
||||||
|
wWHtFID0bD1UYIvQgQX1Bo/abqRvjZoIP3UnBRKZB9u5SStpYkUPYOOEXUlOOQH4
|
||||||
|
mjDc2uE2qjPGRivNT283AwltVJYgjw2cKEdfMS1xmQKBgQDekt9ofQFSxNKSAFXv
|
||||||
|
7C6mdjD8vU377vKXmaL/Jo/esCGSUOMQ0hNV9NPzz1Msnng4OsTzsc2guTniJoo/
|
||||||
|
xXkm7JhPI3mVCqHrJauw6OqcIslqQ3Nwsm6X10BVjCKF5yGpOUzcPKOVLuYTVffR
|
||||||
|
8Ml4Zjv1mFhL4xJ23inryjIF+QKBgQDX9prFM2F5h1f8csGU7iIPRhfCOVBzkVS5
|
||||||
|
wvFcjnhos2IRUrhMKlWjoOsHEsco3j0dBeBU3hMRi3Hk2iJ8aeMRGZPdB6Ng4Eu8
|
||||||
|
O5E8BngWsvP5PjkQfxouNjwKwc4MYvTguAykX9MwkFz+I4aR6N8NL4FKfBSArKEa
|
||||||
|
21lCoyomwwKBgGx63VSKCMkUkSUD8N69GIedd4bXpVizP53QDfeaDekVo2cy8VjT
|
||||||
|
awUsDNn6JKnMmv+c9T1pXbWGUcX9zsgCMWhdTGbV/X487moztBjHjQGImu6l7W/y
|
||||||
|
J6DuErcfU/w7iNZ3zRRSodAmSZEHB4BVgXyjJ3ouRGrIQ8mXworfw73RAoGBAI1Z
|
||||||
|
HGdhf7TY/p9+RHFDgwtYJwi6FovtXPTQQMUBgpGUhuUrrPA87RxRoEJa6fs3qewr
|
||||||
|
Am7JgtWC3SKaGuQvMazpfru12hr38tnaau5MlaDVs5U4QoUni20fliC8RC4bPocu
|
||||||
|
LygOh91LP3Iesl8heYvZwdeMaqblVfSMCFnzDQ2dAoGAGZSkN8AGM3krNLEXNvSL
|
||||||
|
5j53GGBIf12jkfbV4mbMUGsfE7317HTqiM0/nKUYW/0BkdVltNs8fdrSBDnmUfGf
|
||||||
|
QEUT6g0PWOkoKdraAtQouTEpDZczL31fDIvc/omxzeTTT3GMbZIyPRqnJDDd0MyP
|
||||||
|
AeTHeMvO931CDI8/iSgsDpM=
|
||||||
|
-----END PRIVATE KEY-----
|
||||||
5
results/www/errors/custom_404.html
Normal file
5
results/www/errors/custom_404.html
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="ru">
|
||||||
|
<head><meta charset="utf-8"><title>404</title></head>
|
||||||
|
<body><h1>Custom 404 page</h1></body>
|
||||||
|
</html>
|
||||||
1
results/www/files/sample-file.txt
Normal file
1
results/www/files/sample-file.txt
Normal file
@@ -0,0 +1 @@
|
|||||||
|
sample-file.txt
|
||||||
1
results/www/protected/document.pdf
Normal file
1
results/www/protected/document.pdf
Normal file
@@ -0,0 +1 @@
|
|||||||
|
PDF test document for internal download.
|
||||||
5
results/www/public/index.html
Normal file
5
results/www/public/index.html
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="ru">
|
||||||
|
<head><meta charset="utf-8"><title>Public</title></head>
|
||||||
|
<body><h1>Public index</h1></body>
|
||||||
|
</html>
|
||||||
Reference in New Issue
Block a user