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

View File

@@ -0,0 +1,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` п. 12; функции 9.3 в `функции безопасности — проверка.md`. См. условное отключение в `Минимизация поверхности атаки nginx — проверка.md` п. 5 (WebDAV). См. классификацию п. 13 в `Выполнение кода — проверка.md`. См. классификацию п. 14 в `Выполнение кода — проверка.md`. См. классификацию п. 15 в `Выполнение кода — проверка.md`.
- **Примечание:** Статус отражает внешнюю меру. См. `Контроль целостности хранимого кода и конфигурации — проверка.md` п. 12; функции 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` п. 34; функции 9.3 в `функции безопасности — проверка.md`.
- **Примечание:** Статус отражает внешнюю меру. См. `Контроль целостности хранимого кода и конфигурации — проверка.md` п. 34; функции 9.3 в `функции безопасности — проверка.md`.

View File

@@ -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` п. 34.
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 (п. 34); отдельная запись нужна, если 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 (п. 34), либо явно:
/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` п. 67.
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`.

View 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
```
- **Примечание:** См. п. 12 в `Контроль целостности хранимого кода и конфигурации — проверка.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 файлов
```
- **Примечание:** См. п. 34 в `Контроль целостности хранимого кода и конфигурации — проверка.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 в нужной группе
```
- **Примечание:** См. п. 13 в `Контроль выполнения кода — проверка.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
```
- **Примечание:** См. п. 1213 в `Минимизация поверхности атаки nginx — проверка.md`; п. 4 в `Контроль выполнения кода — проверка.md`.

View File

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

View 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` п. 1516.

View 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` п. 115.

View 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` п. 12.
- **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` п. 410.
- **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` п. 410.
- **Примечание:** Для ПМИ проверяется наличие и работоспособность внешнего средства, а не конфигурация nginx. Статус отражает внешнюю меру (см. `Контроль целостности хранимого кода и конфигурации — проверка.md`; ПМИ п. 24; `Контроль выполнения кода — проверка.md` п. 1516).

View 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
View 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
View 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:

View File

@@ -0,0 +1 @@
# FIM watch file for integrity test (PMI p.24 stand-in)

View File

@@ -0,0 +1,9 @@
server {
listen 9999;
server_name auth-mock;
location /validate {
default_type text/plain;
return 200 "auth-ok\n";
}
}

View 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
View 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";
}
}

View 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()

View 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);
};

View 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
View File

@@ -0,0 +1 @@
user:$apr1$279GWHiN$DLoGAZKGBUan4Xj7kLXjF/

43
results/nginx/nginx.conf Normal file
View 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;
}

View 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)

View 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)

View 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

View 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)
```

View 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

View 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"

View 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
View 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

View 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"

View 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)"

View 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"

View 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"

View 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"

View 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"

View 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"

View 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

View 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

View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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-----

View 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>

View File

@@ -0,0 +1 @@
sample-file.txt

View File

@@ -0,0 +1 @@
PDF test document for internal download.

View 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>