From fcc9139361700a8b87aae5dff7462130e91e4346 Mon Sep 17 00:00:00 2001 From: Redsandyg Date: Mon, 15 Jun 2026 06:31:35 +0300 Subject: [PATCH] init --- docs/Контроль_выполнения_кода_—_проверка.md | 451 +++++++++++ ...остности_хранимого_кода_и_конфигурации_—_проверка.md | 356 +++++++++ ...льно_необходимые_полномочия_nginx_—_проверка.md | 339 ++++++++ ...мизация_поверхности_атаки_nginx_—_проверка.md | 408 ++++++++++ ...оверочные_мероприятия_для_ПМИ_—_проверка.md | 664 ++++++++++++++++ ...ния_безопасности_для_включения_в_ТУ_—_проверка.md | 547 +++++++++++++ docs/функции безопасности — проверка.md | 743 ++++++++++++++++++ results/Dockerfile.test-runner | 3 + results/README.md | 59 ++ results/docker-compose.yml | 109 +++ results/fim-watch/config.snippet | 1 + results/mock/auth-mock.conf | 9 + results/mock/auth-server.py | 31 + results/mock/backend.conf | 14 + results/mock/slow-server.py | 20 + results/mock/syslog-ng.conf | 15 + results/nginx/conf.d/pmi.conf | 186 +++++ results/nginx/htpasswd | 1 + results/nginx/nginx.conf | 43 + results/reports/2026-06-14_06-37-41_audit.log | 140 ++++ results/reports/2026-06-14_06-37-41_fim.log | 7 + results/reports/2026-06-14_06-37-41_pmi.log | 27 + .../reports/2026-06-14_06-37-41_summary.md | 69 ++ results/reports/nginx-file-access.log | 57 ++ results/reports/nginx-file-error.log | 1 + results/reports/nginx-syslog.log | 130 +++ results/run.bat | 84 ++ results/scripts/gen-certs.sh | 31 + results/scripts/gen-htpasswd.sh | 7 + results/scripts/generate-summary.sh | 69 ++ results/scripts/run-audit-attack-surface.sh | 26 + results/scripts/run-audit-code-control.sh | 15 + results/scripts/run-audit-permissions.sh | 56 ++ results/scripts/run-fim-checksum.sh | 45 ++ results/scripts/run-pmi-log-checks.sh | 33 + results/scripts/run-pmi-tests.sh | 291 +++++++ results/scripts/wait-ready.sh | 14 + results/ssl/ca.crt | 30 + results/ssl/ca.key | 52 ++ results/ssl/client.crt | 24 + results/ssl/client.key | 28 + results/ssl/fullchain.crt | 54 ++ results/ssl/server.crt | 24 + results/ssl/server.key | 28 + results/ssl/untrusted.crt | 19 + results/ssl/untrusted.key | 28 + results/www/errors/custom_404.html | 5 + results/www/files/sample-file.txt | 1 + results/www/protected/document.pdf | 1 + results/www/public/index.html | 5 + 50 files changed, 5400 insertions(+) create mode 100644 docs/Контроль_выполнения_кода_—_проверка.md create mode 100644 docs/Контроль_целостности_хранимого_кода_и_конфигурации_—_проверка.md create mode 100644 docs/Минимально_необходимые_полномочия_nginx_—_проверка.md create mode 100644 docs/Минимизация_поверхности_атаки_nginx_—_проверка.md create mode 100644 docs/Проверочные_мероприятия_для_ПМИ_—_проверка.md create mode 100644 docs/Требования_безопасности_для_включения_в_ТУ_—_проверка.md create mode 100644 docs/функции безопасности — проверка.md create mode 100644 results/Dockerfile.test-runner create mode 100644 results/README.md create mode 100644 results/docker-compose.yml create mode 100644 results/fim-watch/config.snippet create mode 100644 results/mock/auth-mock.conf create mode 100644 results/mock/auth-server.py create mode 100644 results/mock/backend.conf create mode 100644 results/mock/slow-server.py create mode 100644 results/mock/syslog-ng.conf create mode 100644 results/nginx/conf.d/pmi.conf create mode 100644 results/nginx/htpasswd create mode 100644 results/nginx/nginx.conf create mode 100644 results/reports/2026-06-14_06-37-41_audit.log create mode 100644 results/reports/2026-06-14_06-37-41_fim.log create mode 100644 results/reports/2026-06-14_06-37-41_pmi.log create mode 100644 results/reports/2026-06-14_06-37-41_summary.md create mode 100644 results/reports/nginx-file-access.log create mode 100644 results/reports/nginx-file-error.log create mode 100644 results/reports/nginx-syslog.log create mode 100644 results/run.bat create mode 100644 results/scripts/gen-certs.sh create mode 100644 results/scripts/gen-htpasswd.sh create mode 100644 results/scripts/generate-summary.sh create mode 100644 results/scripts/run-audit-attack-surface.sh create mode 100644 results/scripts/run-audit-code-control.sh create mode 100644 results/scripts/run-audit-permissions.sh create mode 100644 results/scripts/run-fim-checksum.sh create mode 100644 results/scripts/run-pmi-log-checks.sh create mode 100644 results/scripts/run-pmi-tests.sh create mode 100644 results/scripts/wait-ready.sh create mode 100644 results/ssl/ca.crt create mode 100644 results/ssl/ca.key create mode 100644 results/ssl/client.crt create mode 100644 results/ssl/client.key create mode 100644 results/ssl/fullchain.crt create mode 100644 results/ssl/server.crt create mode 100644 results/ssl/server.key create mode 100644 results/ssl/untrusted.crt create mode 100644 results/ssl/untrusted.key create mode 100644 results/www/errors/custom_404.html create mode 100644 results/www/files/sample-file.txt create mode 100644 results/www/protected/document.pdf create mode 100644 results/www/public/index.html diff --git a/docs/Контроль_выполнения_кода_—_проверка.md b/docs/Контроль_выполнения_кода_—_проверка.md new file mode 100644 index 0000000..d34a63d --- /dev/null +++ b/docs/Контроль_выполнения_кода_—_проверка.md @@ -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. + - Проверка: + - **Статус:** Реализуемо + - **Ревью меры контроля:** Требование адекватно. Дополнительно: запретить `` в SSI-файлах (выполнение shell-команд). По умолчанию `ssi off`. + - **Источник:** https://nginx.org/en/docs/http/ngx_http_ssi_module.html + - **Пример реализации контроля:** + ```nginx + http { + ssi off; # по умолчанию отключено + } + + location /ssi-approved/ { + ssi on; + root /var/www/html; + } + ``` + - **Проверка эффективности контроля:** + ```bash + nginx -T 2>/dev/null | grep -i ssi + grep -r '#exec' /var/www/html/ 2>/dev/null + # ssi on только в утверждённых location; нет exec в SSI-файлах + ``` + - **Примечание:** См. условное отключение в `Минимизация поверхности атаки nginx — проверка.md` п. 9 (SSI). См. классификацию п. 9 в `Выполнение кода — проверка.md`. + +9. **Механизм:** XSLT + - **Риск:** Выполнение логики преобразования XML с использованием XSLT-стилей. + - **Требование:** Разрешить XSLT-преобразования только с утверждёнными XSLT-файлами, если функция используется. + - **Что контролировать:** xslt_stylesheet; XSLT-файлы. + - Проверка: + - **Статус:** Реализуемо с оговорками + - **Ревью меры контроля:** Требование корректно. XSLT-файлы — объекты FIM. Рекомендуется не использовать модуль, если не требуется. + - **Источник:** https://nginx.org/en/docs/http/ngx_http_xslt_module.html + - **Пример реализации контроля:** + ```nginx + location /api/xml { + proxy_pass http://backend; + xslt_stylesheet /etc/nginx/xslt/approved-transform.xslt; + } + ``` + - **Проверка эффективности контроля:** + ```bash + nginx -T 2>/dev/null | grep xslt_stylesheet + ls -la /etc/nginx/xslt/ + # Все XSLT-файлы в утверждённом перечне + ``` + - **Примечание:** См. условное отключение в `Минимизация поверхности атаки nginx — проверка.md` п. 8 (XSLT). См. классификацию п. 10 в `Выполнение кода — проверка.md`. + +10. **Механизм:** Динамические модули nginx + - **Риск:** Загрузка неразрешённого .so-модуля, выполняемого в процессе nginx. + - **Требование:** Разрешить загрузку только модулей из утверждённого перечня. + - **Что контролировать:** load_module; директории модулей; .so-файлы. + - Проверка: + - **Статус:** Реализуемо + - **Ревью меры контроля:** Требование полностью адекватно риску. Организационный белый список `load_module` + FIM на каталог модулей. + - **Источник:** https://nginx.org/en/docs/ngx_core_module.html#load_module + - **Пример реализации контроля:** + ```nginx + # В nginx.conf — только утверждённые модули + load_module modules/ngx_http_geoip_module.so; + # load_module /path/to/unapproved.so; # запрещено + ``` + - **Проверка эффективности контроля:** + ```bash + nginx -T 2>/dev/null | grep load_module + ls -la /usr/lib/nginx/modules/ + # Сверить с утверждённым перечнем в эксплуатационной документации + afick -c /etc/afick.conf --check + ``` + - **Примечание:** См. условное отключение в `Минимизация поверхности атаки nginx — проверка.md` п. 3 (динамические модули). См. классификацию п. 11 в `Выполнение кода — проверка.md`. + +11. **Механизм:** Сторонние динамические модули + - **Риск:** Подключение стороннего кода без контроля поставки и целостности. + - **Требование:** Запретить сторонние модули либо допускать только после включения в утверждённый список. + - **Что контролировать:** load_module; пакет модуля; путь к .so. + - Проверка: + - **Статус:** Реализуемо с оговорками + - **Ревью меры контроля:** Требование корректно. Сочетание организационного запрета, процедуры включения в белый список, контроля пакета (подпись, репозиторий) и FIM на `.so`. + - **Источник:** https://nginx.org/en/docs/ngx_core_module.html#load_module + - **Пример реализации контроля:** + ```nginx + # Политика: только модули из дистрибутивного пакета nginx + # load_module modules/ngx_http_js_module.so; # только после утверждения + ``` + - **Проверка эффективности контроля:** + ```bash + nginx -T 2>/dev/null | grep load_module + rpm -V nginx 2>/dev/null || dpkg -V nginx 2>/dev/null + # Проверка целостности пакета и отсутствия посторонних .so + find /usr/lib/nginx/modules/ -name '*.so' -newer /etc/nginx/nginx.conf + ``` + - **Примечание:** Процедура утверждения сторонних модулей — организационная мера. См. условное отключение в `Минимизация поверхности атаки nginx — проверка.md` п. 7 (Perl). См. условное отключение в `Минимизация поверхности атаки nginx — проверка.md` п. 9 (SSI). См. условное отключение в `Минимизация поверхности атаки nginx — проверка.md` п. 8 (XSLT). См. условное отключение в `Минимизация поверхности атаки nginx — проверка.md` п. 3 (динамические модули). См. условное отключение в `Минимизация поверхности атаки nginx — проверка.md` п. 3 (сторонние модули). См. классификацию п. 8 в `Выполнение кода — проверка.md`. См. классификацию п. 9 в `Выполнение кода — проверка.md`. См. классификацию п. 10 в `Выполнение кода — проверка.md`. См. классификацию п. 11 в `Выполнение кода — проверка.md`. См. классификацию п. 12 в `Выполнение кода — проверка.md`. + - **Примечание:** Процедура утверждения сторонних модулей — организационная мера. См. условное отключение в `Минимизация поверхности атаки nginx — проверка.md` п. 3 (сторонние модули). См. классификацию п. 12 в `Выполнение кода — проверка.md`. + +12. **Механизм:** WebDAV + - **Риск:** Загрузка файла, который затем может быть обработан как код внешним обработчиком. + - **Требование:** Запретить WebDAV в базовой конфигурации либо ограничить загрузку в директории, не передаваемые обработчикам кода. + - **Что контролировать:** dav_methods; права на директории; location WebDAV. + - Проверка: + - **Статус:** Реализуемо + - **Ревью меры контроля:** Требование адекватно косвенному риску. WebDAV не должен пересекаться с каталогами, обрабатываемыми FastCGI/uWSGI. Upload-директория — только статика, без `.php`/скриптов. + - **Источник:** https://nginx.org/en/docs/http/ngx_http_dav_module.html + - **Пример реализации контроля:** + ```nginx + # WebDAV не включён в базовой конфигурации + # При необходимости — изолированный location: + location /uploads/ { + root /var/www/static-only; + dav_methods PUT; + # Нет fastcgi_pass / uwsgi_pass в этом location + } + ``` + - **Проверка эффективности контроля:** + ```bash + nginx -T 2>/dev/null | grep -E 'dav_methods|dav_access' + # dav_methods отсутствует вне утверждённых location + # upload-директория не содержит исполняемых расширений + ``` + - **Примечание:** См. условное отключение в `Минимизация поверхности атаки nginx — проверка.md` п. 5 (WebDAV). См. классификацию п. 13 в `Выполнение кода — проверка.md`. + +13. **Механизм:** Внутренние перенаправления + - **Риск:** Перенаправление запроса к обработчику кода в обход ожидаемой логики доступа. + - **Требование:** Контролировать внутренние маршруты и исключить передачу в обработку файлов из неразрешённых директорий. + - **Что контролировать:** try_files; error_page; internal; named location. + - Проверка: + - **Статус:** Реализуемо + - **Ревью меры контроля:** Требование корректно. Аудит цепочек `try_files` → FastCGI, `error_page` → internal location, `rewrite` на обход `root`. + - **Источник:** https://nginx.org/en/docs/http/ngx_http_core_module.html#try_files , https://nginx.org/en/docs/http/ngx_http_core_module.html#internal + - **Пример реализации контроля:** + ```nginx + location / { + root /var/www/app/public; + try_files $uri $uri/ =404; + } + + location ~ \.php$ { + try_files $uri =404; + fastcgi_pass unix:/run/php/php-fpm.sock; + include fastcgi_params; + fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; + } + ``` + - **Проверка эффективности контроля:** + ```bash + nginx -T 2>/dev/null | grep -E 'try_files|error_page|rewrite|internal' + # Все try_files перед FastCGI содержат =404 + # internal location не ведут за пределы root + ``` + - **Примечание:** См. классификацию п. 14 в `Выполнение кода — проверка.md`. + +14. **Механизм:** root / alias + - **Риск:** Ошибка настройки может открыть произвольный каталог ОС или передать файл во внешний обработчик. + - **Требование:** Разрешить обслуживание и обработку файлов только из утверждённых директорий. + - **Что контролировать:** root; alias; location; права ФС. + - Проверка: + - **Статус:** Реализуемо + - **Ревью меры контроля:** Требование полностью адекватно. Контроль конфигурации + права ФС (nginx не должен читать `/etc`, `/root` и т.д.). Осторожность с `alias` и regex location. + - **Источник:** https://nginx.org/en/docs/http/ngx_http_core_module.html#root , https://nginx.org/en/docs/http/ngx_http_core_module.html#alias + - **Пример реализации контроля:** + ```nginx + server { + root /var/www/app/public; + + location / { + try_files $uri =404; + } + + location ~ /\. { + deny all; + } + } + ``` + - **Проверка эффективности контроля:** + ```bash + nginx -T 2>/dev/null | grep -E '^\s*(root|alias)\s' + namei -l /var/www/app/public + # root/alias только на утверждённые пути + # права: каталоги 755, файлы 644, владелец не root для web-контента + ``` + - **Примечание:** См. классификацию п. 15 в `Выполнение кода — проверка.md`. + +15. **Механизм:** Конфигурация nginx + - **Риск:** Изменение конфигурации может разрешить выполнение/передачу неразрешённого кода. + - **Требование:** Поставить конфигурацию nginx на контроль целостности и ограничить права изменения. + - **Что контролировать:** /etc/nginx/nginx.conf; подключаемые конфигурации. + - Проверка: + - **Статус:** Требует внешних/организационных мер + - **Ревью меры контроля:** Требование корректно. nginx не обеспечивает FIM самостоятельно. Необходимы: afick/AIDE, ограничение прав записи (`chmod 644`, владелец root), разделение ролей (изменение конфигурации — только администратор). + - **Источник:** Внешняя мера (FIM); https://nginx.org/en/docs/ + - **Пример реализации контроля:** + ``` + # /etc/afick.conf (фрагмент) + /etc/nginx/ R + + # Права доступа + # chmod 644 /etc/nginx/nginx.conf + # chmod 644 /etc/nginx/conf.d/*.conf + # chown root:root /etc/nginx/ + ``` + - **Проверка эффективности контроля:** + ```bash + afick -c /etc/afick.conf --check + ls -la /etc/nginx/nginx.conf /etc/nginx/conf.d/ + # Только root может изменять конфигурацию + stat -c '%a %U' /etc/nginx/nginx.conf + ``` + - **Примечание:** Изменение конфигурации — через процедуру Change Management с повторным `nginx -t`. Статус отражает внешнюю меру. См. `Контроль целостности хранимого кода и конфигурации — проверка.md` п. 1–2; функции 9.3 в `функции безопасности — проверка.md`. См. условное отключение в `Минимизация поверхности атаки nginx — проверка.md` п. 5 (WebDAV). См. классификацию п. 13 в `Выполнение кода — проверка.md`. См. классификацию п. 14 в `Выполнение кода — проверка.md`. См. классификацию п. 15 в `Выполнение кода — проверка.md`. + - **Примечание:** Статус отражает внешнюю меру. См. `Контроль целостности хранимого кода и конфигурации — проверка.md` п. 1–2; функции 9.3 в `функции безопасности — проверка.md`. + +16. **Механизм:** Файлы веб-приложений + - **Риск:** Изменение файлов приложения может привести к выполнению неразрешённого кода. + - **Требование:** Поставить разрешённые директории веб-приложений на контроль целостности. + - **Что контролировать:** web-root; директории приложений; исполняемые скрипты. + - Проверка: + - **Статус:** Требует внешних/организационных мер + - **Ревью меры контроля:** Требование адекватно. Контроль целостности web-root и скриптов (.php, .py и др.) — внешнее средство (afick). nginx не отслеживает изменения файлов приложения. + - **Источник:** Внешняя мера (FIM) + - **Пример реализации контроля:** + ``` + # /etc/afick.conf (фрагмент) + /var/www/ R + ``` + - **Проверка эффективности контроля:** + ```bash + afick -c /etc/afick.conf --check + find /var/www -name '*.php' -o -name '*.py' | head -20 + # Сверить перечень скриптов с утверждённым + # После тестового изменения файла — afick должен зафиксировать нарушение + ``` + - **Примечание:** Дополняет конфигурационный контроль (п. 1, 14); не заменяет его. Статус отражает внешнюю меру. См. `Контроль целостности хранимого кода и конфигурации — проверка.md` п. 3–4; функции 9.3 в `функции безопасности — проверка.md`. + - **Примечание:** Статус отражает внешнюю меру. См. `Контроль целостности хранимого кода и конфигурации — проверка.md` п. 3–4; функции 9.3 в `функции безопасности — проверка.md`. diff --git a/docs/Контроль_целостности_хранимого_кода_и_конфигурации_—_проверка.md b/docs/Контроль_целостности_хранимого_кода_и_конфигурации_—_проверка.md new file mode 100644 index 0000000..8d2ec28 --- /dev/null +++ b/docs/Контроль_целостности_хранимого_кода_и_конфигурации_—_проверка.md @@ -0,0 +1,356 @@ +# Контроль целостности хранимого кода и конфигурации — результаты проверки + +**Дата проверки:** 10.06.2026 +**Объект проверки:** внешний FIM (afick или аналог) + пути, связанные с nginx +**Метод:** ревью мер контроля, примеры конфигурации FIM и прав доступа, команды верификации (без настройки afick на стенде) + +## Сводная таблица + +| № | Объект контроля | Статус | Механизм | +|---|-----------------|--------|----------| +| 1 | Основной конфигурационный файл nginx | Обязательно | afick | +| 2 | Подключаемые конфигурационные файлы nginx | Обязательно | afick | +| 3 | Разрешённые директории веб-приложений | Обязательно | afick | +| 4 | Директории статического веб-контента | Обязательно | afick | +| 5 | Динамические .so-модули nginx | Обязательно | afick | +| 6 | Файлы njs | Условно (если используется njs) | afick | +| 7 | Perl-файлы | Условно (если используется Perl) | afick | +| 8 | XSLT-файлы | Условно (если используется XSLT) | afick | +| 9 | SSI-файлы | Условно (если включён SSI) | afick | +| 10 | Файлы WebDAV upload | Условно (если включён WebDAV) | afick | +| 11 | Сертификаты и ключи TLS | Обязательно | afick + права ФС | +| 12 | Файлы паролей Basic Authentication | Условно (если используется auth_basic) | afick + права ФС | +| 13 | Файлы журналов nginx | Комбинированная мера | права ФС + syslog | + +--- + +1. **Основной конфигурационный файл nginx** + - *Причина контроля*: Конфигурация определяет правила доступа, маршрутизацию, передачу запросов обработчикам и загрузку модулей. + - *Механизм контроля*: afick или иной утверждённый механизм контроля целостности. + - *Ожидаемый результат*: Несанкционированное изменение конфигурации выявляется. + - Проверка: + - **Статус:** Обязательно + - **Ревью меры контроля:** Причина и механизм полностью адекватны. Изменение `nginx.conf` может включить `load_module`, `proxy_pass` на произвольный backend или ослабить `allow`/`deny`. FIM — единственный корректный способ контроля; nginx сам целостность не проверяет. + - **Источник:** Внешнее средство FIM; https://nginx.org/en/docs/ (встроенный FIM не описан) + - **Связь с nginx:** главный файл конфигурации, директива `include` подключает остальные файлы + - **Контролируемые пути (пример):** `/etc/nginx/nginx.conf` + - **Пример реализации:** + ``` + # /etc/afick.conf (фрагмент) + /etc/nginx/nginx.conf R + + # Права доступа + # chown root:root /etc/nginx/nginx.conf + # chmod 644 /etc/nginx/nginx.conf + ``` + - **Проверка эффективности контроля:** + ```bash + afick -c /etc/afick.conf --check + ls -la /etc/nginx/nginx.conf + # Тест: echo "# test" >> /etc/nginx/nginx.conf + afick -c /etc/afick.conf --check + # Ожидание: отчёт о нарушении; затем восстановить файл + ``` + - **Примечание:** См. также функции 9.3 в `функции безопасности — проверка.md`; `Контроль выполнения кода — проверка.md` п. 15; `Минимально необходимые полномочия nginx — проверка.md` п. 2. + +2. **Подключаемые конфигурационные файлы nginx** + - *Причина*: Через подключаемые файлы могут быть добавлены новые location, proxy_pass, fastcgi_pass или load_module. + - *Механизм*: afick или иной утверждённый механизм контроля целостности. + - *Результат*: Изменение подключаемой конфигурации выявляется. + - Проверка: + - **Статус:** Обязательно + - **Ревью меры контроля:** Причина корректна: атака часто идёт через новый файл в `conf.d/` или `sites-enabled/`, а не через правку основного `nginx.conf`. Механизм достаточен. + - **Источник:** Внешнее средство FIM + - **Связь с nginx:** `include /etc/nginx/conf.d/*.conf;`, `include /etc/nginx/sites-enabled/*;` + - **Контролируемые пути (пример):** `/etc/nginx/conf.d/`, `/etc/nginx/sites-enabled/` + - **Пример реализации:** + ``` + # /etc/afick.conf (фрагмент) + /etc/nginx/conf.d/ R + /etc/nginx/sites-enabled/ R + ``` + - **Проверка эффективности контроля:** + ```bash + afick -c /etc/afick.conf --check + ls -la /etc/nginx/conf.d/ + # Тест: создать /etc/nginx/conf.d/evil.conf с proxy_pass + afick -c /etc/afick.conf --check + ``` + - **Примечание:** См. права и полномочия в `Минимально необходимые полномочия nginx — проверка.md` п. 2. + +3. **Разрешённые директории веб-приложений** + - *Причина*: В этих директориях хранится код или контент, который может быть передан внешнему обработчику. + - *Механизм*: afick или иной утверждённый механизм контроля целостности. + - *Результат*: Изменение файлов веб-приложений выявляется. + - Проверка: + - **Статус:** Обязательно + - **Ревью меры контроля:** Причина и механизм адекватны. Изменение `.php`, `.py` и других скриптов — прямой риск выполнения кода через FastCGI/uWSGI. Пути должны соответствовать `root`/`alias` в конфигурации nginx. + - **Источник:** Внешнее средство FIM + - **Связь с nginx:** директивы `root`, `alias`, `fastcgi_param SCRIPT_FILENAME` + - **Контролируемые пути (пример):** `/var/www/app/`, `/var/www/app/public/` + - **Пример реализации:** + ``` + # /etc/afick.conf (фрагмент) + /var/www/app/ R + ``` + - **Проверка эффективности контроля:** + ```bash + nginx -T 2>/dev/null | grep -E '^\s*root\s|^\s*alias\s' + afick -c /etc/afick.conf --check + find /var/www/app -name '*.php' -o -name '*.py' | head -10 + # Сверить пути с утверждённым перечнем в эксплуатационной документации + ``` + - **Примечание:** См. права и полномочия в `Минимально необходимые полномочия nginx — проверка.md` п. 3. + +4. **Директории статического веб-контента** + - *Причина*: Статические файлы могут быть изменены для подмены содержимого сайта. + - *Механизм*: afick или иной утверждённый механизм контроля целостности. + - *Результат*: Изменение статического контента выявляется, если он включён в область контроля. + - Проверка: + - **Статус:** Обязательно + - **Ревью меры контроля:** Причина корректна (подмена HTML, JS, вредоносные вложения). Может быть объединена с п. 3 одной записью `/var/www/ R`, если статика и приложение в одном дереве каталогов. + - **Источник:** Внешнее средство FIM + - **Связь с nginx:** `root` для статических `location` + - **Контролируемые пути (пример):** `/var/www/html/` + - **Пример реализации:** + ``` + # Вариант 1: отдельная запись + /var/www/html/ R + + # Вариант 2: объединение с п. 3 + /var/www/ R + ``` + - **Проверка эффективности контроля:** + ```bash + afick -c /etc/afick.conf --check + # Тест: изменить index.html в web-root + afick -c /etc/afick.conf --check + ``` + - **Примечание:** См. права и полномочия в `Минимально необходимые полномочия nginx — проверка.md` п. 3. См. `Минимизация поверхности атаки nginx — проверка.md` п. 3–4. + +5. **Динамические .so-модули nginx** + - *Причина*: Динамические модули выполняются в процессе nginx и расширяют функциональность сервера. + - *Механизм*: afick или иной утверждённый механизм контроля целостности. + - *Результат*: Подмена или изменение модуля выявляется. + - Проверка: + - **Статус:** Обязательно + - **Ревью меры контроля:** Причина и механизм полностью адекватны. Подмена `.so` — выполнение произвольного нативного кода в процессе nginx. FIM обязателен в сочетании с белым списком в `load_module`. + - **Источник:** Внешнее средство FIM; https://nginx.org/en/docs/ngx_core_module.html#load_module + - **Связь с nginx:** `load_module modules/...so;` + - **Контролируемые пути (пример):** `/usr/lib/nginx/modules/` + - **Пример реализации:** + ``` + # /etc/afick.conf (фрагмент) + /usr/lib/nginx/modules/ R + ``` + - **Проверка эффективности контроля:** + ```bash + nginx -T 2>/dev/null | grep load_module + ls -la /usr/lib/nginx/modules/ + afick -c /etc/afick.conf --check + rpm -V nginx 2>/dev/null || dpkg -V nginx 2>/dev/null + ``` + - **Примечание:** См. права и полномочия в `Минимально необходимые полномочия nginx — проверка.md` п. 10. + +6. **Файлы njs** + - *Причина*: При использовании njs JavaScript-файлы могут выполняться внутри nginx. + - *Механизм*: afick или иной утверждённый механизм контроля целостности. + - *Результат*: Изменение njs-кода выявляется. + - Проверка: + - **Статус:** Условно (если используется njs) + - **Ревью меры контроля:** Причина корректна при наличии njs. Если `js_import` не используется — объект не включается в область контроля. Механизм достаточен. + - **Источник:** Внешнее средство FIM; https://nginx.org/en/docs/njs/ + - **Связь с nginx:** `js_import`, `js_content`, `js_set` + - **Контролируемые пути (пример):** `/etc/nginx/njs/` + - **Пример реализации:** + ``` + # /etc/afick.conf (фрагмент) — только при использовании njs + /etc/nginx/njs/ R + ``` + - **Проверка эффективности контроля:** + ```bash + nginx -T 2>/dev/null | grep -E 'js_import|load_module.*js' + # Если njs не используется — записи в afick и директивы js_* отсутствуют + afick -c /etc/afick.conf --check + ``` + - **Примечание:** См. права и полномочия в `Минимально необходимые полномочия nginx — проверка.md` п. 6. + +7. **Perl-файлы** + - *Причина*: При использовании Perl-модуля Perl-код может выполняться внутри nginx. + - *Механизм*: afick или иной утверждённый механизм контроля целостности. + - *Результат*: Изменение Perl-кода выявляется. + - Проверка: + - **Статус:** Условно (если используется Perl) + - **Ревью меры контроля:** Причина корректна. Рекомендация: не использовать Perl-модуль; при наличии — обязательный FIM на Perl-файлы. + - **Источник:** Внешнее средство FIM; https://nginx.org/en/docs/http/ngx_http_perl_module.html + - **Связь с nginx:** `perl_modules`, `perl_require`, `perl` + - **Контролируемые пути (пример):** `/etc/nginx/perl/` + - **Пример реализации:** + ``` + # /etc/afick.conf (фрагмент) — только при использовании Perl + /etc/nginx/perl/ R + ``` + - **Проверка эффективности контроля:** + ```bash + nginx -V 2>&1 | grep -i perl + nginx -T 2>/dev/null | grep -E 'perl|perl_require' + # Ожидание для безопасной конфигурации: отсутствие Perl + ``` + - **Примечание:** См. права и полномочия в `Минимально необходимые полномочия nginx — проверка.md` п. 7. + +8. **XSLT-файлы** + - *Причина*: XSLT-файлы управляют логикой преобразования XML-ответов. + - *Механизм*: afick или иной утверждённый механизм контроля целостности. + - *Результат*: Изменение XSLT-файлов выявляется. + - Проверка: + - **Статус:** Условно (если используется XSLT) + - **Ревью меры контроля:** Причина и механизм адекватны при использовании `xslt_stylesheet`. Иначе объект исключается из области контроля. + - **Источник:** Внешнее средство FIM; https://nginx.org/en/docs/http/ngx_http_xslt_module.html + - **Связь с nginx:** `xslt_stylesheet` + - **Контролируемые пути (пример):** `/etc/nginx/xslt/` + - **Пример реализации:** + ``` + # /etc/afick.conf (фрагмент) — только при использовании XSLT + /etc/nginx/xslt/ R + ``` + - **Проверка эффективности контроля:** + ```bash + nginx -T 2>/dev/null | grep xslt_stylesheet + afick -c /etc/afick.conf --check + ``` + - **Примечание:** См. права и полномочия в `Минимально необходимые полномочия nginx — проверка.md` п. 8. + +9. **SSI-файлы** + - *Причина*: SSI-команды могут влиять на формирование ответа. + - *Механизм*: afick или иной утверждённый механизм контроля целостности. + - *Результат*: Изменение SSI-файлов выявляется. + - Проверка: + - **Статус:** Условно (если включён SSI) + - **Ревью меры контроля:** Причина корректна. SSI-файлы обычно находятся в web-root (п. 3–4); отдельная запись нужна, если SSI включён в выделенном location. Дополнительно контролировать отсутствие `` в файлах. + - **Источник:** Внешнее средство FIM; https://nginx.org/en/docs/http/ngx_http_ssi_module.html + - **Связь с nginx:** `ssi on` в `location` + - **Контролируемые пути (пример):** каталоги с `ssi on` внутри web-root, например `/var/www/html/ssi/` + - **Пример реализации:** + ``` + # Покрывается записью web-root (п. 3–4), либо явно: + /var/www/html/ssi/ R + ``` + - **Проверка эффективности контроля:** + ```bash + nginx -T 2>/dev/null | grep -i 'ssi on' + grep -r '#exec' /var/www/html/ 2>/dev/null + # exec в SSI не должен присутствовать + ``` + - **Примечание:** См. права и полномочия в `Минимально необходимые полномочия nginx — проверка.md` п. 3. + +10. **Файлы, доступные для загрузки через WebDAV** + - *Причина*: Загруженные файлы могут стать источником риска при попадании в обработку внешним интерпретатором. + - *Механизм*: afick или иной утверждённый механизм контроля целостности. + - *Результат*: Несанкционированные изменения или появление файлов выявляются, если директория включена в контроль. + - Проверка: + - **Статус:** Условно (если включён WebDAV) + - **Ревью меры контроля:** Причина корректна. FIM на upload-директорию выявляет появление новых файлов (в т.ч. `.php`). Рекомендация: upload-директория не должна пересекаться с FastCGI `root`. + - **Источник:** Внешнее средство FIM; https://nginx.org/en/docs/http/ngx_http_dav_module.html + - **Связь с nginx:** `dav_methods`, `location` с WebDAV + - **Контролируемые пути (пример):** `/var/www/uploads/` + - **Пример реализации:** + ``` + # /etc/afick.conf (фрагмент) — только при использовании WebDAV + /var/www/uploads/ R + ``` + - **Проверка эффективности контроля:** + ```bash + nginx -T 2>/dev/null | grep dav_methods + # Тест: загрузить файл через WebDAV, затем afick --check + afick -c /etc/afick.conf --check + ``` + - **Примечание:** См. права и полномочия в `Минимально необходимые полномочия nginx — проверка.md` п. 4. + +11. **Сертификаты и ключи TLS** + - *Причина*: Подмена сертификатов или ключей может нарушить доверие к защищённому соединению. + - *Механизм*: afick или иной утверждённый механизм контроля целостности + ограничение прав доступа. + - *Результат*: Изменение сертификатов/ключей выявляется. + - Проверка: + - **Статус:** Обязательно + - **Ревью меры контроля:** Причина и комбинированный механизм (FIM + права) полностью адекватны. Приватные ключи — `chmod 600`, владелец root; сертификаты — `644`. + - **Источник:** Внешнее средство FIM; https://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_certificate + - **Связь с nginx:** `ssl_certificate`, `ssl_certificate_key`, `ssl_client_certificate` + - **Контролируемые пути (пример):** `/etc/nginx/ssl/`, `/etc/ssl/nginx/` + - **Пример реализации:** + ``` + # /etc/afick.conf (фрагмент) + /etc/nginx/ssl/ R + + # Права доступа + # chmod 600 /etc/nginx/ssl/*.key + # chmod 644 /etc/nginx/ssl/*.crt + # chown root:root /etc/nginx/ssl/ + ``` + - **Проверка эффективности контроля:** + ```bash + afick -c /etc/afick.conf --check + ls -la /etc/nginx/ssl/ + stat -c '%a %U %n' /etc/nginx/ssl/* + # Ключи: 600, сертификаты: 644, владелец root + ``` + - **Примечание:** См. права и полномочия в `Минимально необходимые полномочия nginx — проверка.md` п. 6–7. + +12. **Файлы паролей Basic Authentication** + - *Причина*: Изменение файла пользователей может привести к несанкционированному доступу. + - *Механизм*: afick или иной утверждённый механизм контроля целостности + ограничение прав доступа. + - *Результат*: Изменение файла пользователей выявляется. + - Проверка: + - **Статус:** Условно (если используется auth_basic) + - **Ревью меры контроля:** Причина и механизм корректны. FIM + `chmod 640`, владелец root, группа nginx (или без доступа для others). + - **Источник:** Внешнее средство FIM; https://nginx.org/en/docs/http/ngx_http_auth_basic_module.html#auth_basic_user_file + - **Связь с nginx:** `auth_basic_user_file` + - **Контролируемые пути (пример):** `/etc/nginx/htpasswd`, `/etc/nginx/htpasswd.d/` + - **Пример реализации:** + ``` + # /etc/afick.conf (фрагмент) — при использовании auth_basic + /etc/nginx/htpasswd R + + # chmod 640 /etc/nginx/htpasswd + # chown root:root /etc/nginx/htpasswd + ``` + - **Проверка эффективности контроля:** + ```bash + nginx -T 2>/dev/null | grep auth_basic_user_file + ls -la /etc/nginx/htpasswd + afick -c /etc/afick.conf --check + ``` + - **Примечание:** См. права и полномочия в `Минимально необходимые полномочия nginx — проверка.md` п. 8. + +13. **Файлы журналов nginx** + - *Причина*: Журналы содержат события доступа и ошибок, важные для анализа безопасности. + - *Механизм*: Контроль прав доступа; защита от несанкционированного изменения; централизованное журналирование. + - *Результат*: Несанкционированное изменение или удаление журналов затруднено/выявляется. + - Проверка: + - **Статус:** Комбинированная мера + - **Ревью меры контроля:** Причина корректна. Классический FIM на активно пишущиеся log-файлы неприменим (ложные срабатывания при каждой записи). Корректный подход: строгие права (`adm`/`root`), передача в syslog (см. ПМИ п. 14), ротация logrotate, опционально `chattr +a` (append-only). Механизм в исходнике описан верно. + - **Источник:** Внешняя мера; https://nginx.org/en/docs/ngx_core_module.html#error_log , https://nginx.org/en/docs/syslog.html + - **Связь с nginx:** `access_log`, `error_log` + - **Контролируемые пути (пример):** `/var/log/nginx/access.log`, `/var/log/nginx/error.log` + - **Пример реализации:** + ``` + # Права доступа (не afick на сами log-файлы) + # chown root:adm /var/log/nginx/ + # chmod 750 /var/log/nginx/ + # chmod 640 /var/log/nginx/*.log + + # Централизованное журналирование в nginx.conf: + # access_log syslog:server=192.168.1.1:514,... combined; + # error_log syslog:server=192.168.1.1:514,...; + + # Опционально append-only (осторожно с ротацией): + # chattr +a /var/log/nginx/access.log + ``` + - **Проверка эффективности контроля:** + ```bash + ls -la /var/log/nginx/ + stat -c '%a %U:%G' /var/log/nginx/access.log + # Попытка удаления от непривилегированного пользователя должна завершиться отказом + nginx -T 2>/dev/null | grep -E 'access_log|error_log' + # При syslog — проверить наличие записей на приёмнике (journalctl -t nginx) + ``` + - **Примечание:** Статус — комбинированная мера. См. `Минимально необходимые полномочия nginx — проверка.md` п. 5; ПМИ п. 14 в `Проверочные мероприятия для ПМИ — проверка.md`; функции 4.4 и 9.3 в `функции безопасности — проверка.md`. diff --git a/docs/Минимально_необходимые_полномочия_nginx_—_проверка.md b/docs/Минимально_необходимые_полномочия_nginx_—_проверка.md new file mode 100644 index 0000000..c895070 --- /dev/null +++ b/docs/Минимально_необходимые_полномочия_nginx_—_проверка.md @@ -0,0 +1,339 @@ +# Минимально необходимые полномочия nginx — результаты проверки + +**Дата проверки:** 10.06.2026 +**Объект проверки:** полномочия процесса nginx и доступ к ресурсам ОС +**Метод:** ревью модели полномочий, подтверждение по документации nginx и практикам ОС, примеры прав доступа и команды аудита (без практической настройки на стенде) + +## Сводная таблица + +| № | Объект полномочий | Статус | Уровень | +|---|-------------------|--------|---------| +| 1 | Worker-процессы nginx | Реализуемо | процесс | +| 2 | Конфигурация nginx | Реализуемо | ФС | +| 3 | Директории веб-контента | Реализуемо | ФС | +| 4 | Директории загрузки файлов | Условно (если используется) | ФС | +| 5 | Журналы nginx | Комбинированная мера | ФС / syslog | +| 6 | TLS-сертификаты | Реализуемо | ФС | +| 7 | TLS-ключи | Реализуемо | ФС | +| 8 | Файл пользователей Basic Auth | Условно (если используется) | ФС | +| 9 | Unix-сокеты backend | Реализуемо | ФС / процесс | +| 10 | Динамические модули nginx | Комбинированная мера | ФС + FIM | +| 11 | Временные директории nginx | Реализуемо | ФС | +| 12 | Сетевые соединения к backend | Комбинированная мера | сеть / конфигурация | + +--- + +1. **Worker-процессы nginx** + - Необходимые полномочия: выполнение от непривилегированного пользователя, заданного в конфигурации; повышенные права master-процесса допускаются только для запуска службы и системных операций. + - Запрещено: работа worker-процессов с избыточными правами root. + - Комментарий: master-процесс может стартовать с повышенными правами для привязки к портам, worker-процессы должны работать с минимальными правами. + - Проверка: + - **Статус:** Реализуемо + - **Ревью полномочий:** Модель полномочий корректна и соответствует архитектуре nginx. Master (root) выполняет bind к портам <1024, чтение TLS-ключей при reload, fork worker-процессов. Worker работает от пользователя из директивы `user` с минимальными правами. Запрет worker от root — обязательное требование; `worker_processes` на привилегии не влияет. + - **Источник:** https://nginx.org/en/docs/ngx_core_module.html#user + - **Пример реализации:** + ```nginx + # /etc/nginx/nginx.conf + user nginx nginx; + # или: user www-data www-data; + worker_processes auto; + ``` + - **Проверка эффективности:** + ```bash + nginx -T 2>/dev/null | grep '^user ' + ps aux | grep 'nginx:' + # Master — root; worker — UID пользователя из user (не 0) + id nginx 2>/dev/null || id www-data + ``` + - **Примечание:** См. п. 15 в `Минимизация поверхности атаки nginx — проверка.md`. + +2. **Конфигурация nginx** + - Необходимые полномочия: чтение конфигурации nginx. + - Запрещено: запись в конфигурацию от имени пользователя nginx. + - Комментарий: изменение конфигурации должно быть доступно только администратору. + - Проверка: + - **Статус:** Реализуемо + - **Ревью полномочий:** Требования адекватны. Master читает конфигурацию при старте/reload (от root); worker не должен иметь прав на запись в `/etc/nginx/`. Владелец — root, права на файлы — `644`, на каталоги — `755`. Изменения — только администратором; контроль целостности — FIM. + - **Источник:** https://nginx.org/en/docs/ngx_core_module.html#include + - **Пример реализации:** + ``` + chown -R root:root /etc/nginx/ + find /etc/nginx -type f -exec chmod 644 {} \; + find /etc/nginx -type d -exec chmod 755 {} \; + ``` + - **Проверка эффективности:** + ```bash + ls -la /etc/nginx/ + namei -l /etc/nginx/nginx.conf + # Пользователь nginx не имеет write на /etc/nginx/ + sudo -u nginx test -w /etc/nginx/nginx.conf && echo FAIL || echo OK + ``` + - **Примечание:** См. п. 1–2 в `Контроль целостности хранимого кода и конфигурации — проверка.md`. + +3. **Директории веб-контента** + - Необходимые полномочия: чтение файлов, которые должны обслуживаться пользователям. + - Запрещено: запись в web-root, если nginx не должен изменять контент. + - Комментарий: для статического сайта nginx обычно нужны только права чтения. + - Проверка: + - **Статус:** Реализуемо + - **Ревью полномочий:** Требования корректны. Worker нужен только `read`/`execute` (traverse) на каталоги и `read` на файлы. Запись в web-root для статического сайта запрещена — снижает риск подмены контента при компрометации worker. Каталоги — `755`, файлы — `644`; без world-writable (`777`, `666`). + - **Источник:** https://nginx.org/en/docs/http/ngx_http_core_module.html#root + - **Пример реализации:** + ``` + chown -R root:www-data /var/www/html/ + find /var/www/html -type d -exec chmod 755 {} \; + find /var/www/html -type f -exec chmod 644 {} \; + # nginx (www-data) — только чтение, без write + ``` + - **Проверка эффективности:** + ```bash + nginx -T 2>/dev/null | grep -E '^\s*root\s|^\s*alias\s' + namei -l /var/www/html/index.html + ls -la /var/www/html/ + sudo -u nginx test -w /var/www/html/index.html && echo FAIL || echo OK + find /var/www -perm -0002 -type f 2>/dev/null + # Не должно быть world-writable файлов + ``` + - **Примечание:** См. п. 3–4 в `Контроль целостности хранимого кода и конфигурации — проверка.md`; п. 14 в `Минимизация поверхности атаки nginx — проверка.md`. + +4. **Директории загрузки файлов** + - Необходимые полномочия: запись только в специально выделенные директории (если функция загрузки нужна). + - Запрещено: запись в директории, передаваемые обработчикам кода, если это не предусмотрено. + - Комментарий: нужно исключить загрузку исполняемого кода в директории обработки. + - Проверка: + - **Статус:** Условно (если используется) + - **Ревью полномочий:** Требования адекватны при использовании WebDAV или иной загрузки. Write — только в выделенный каталог (`/var/www/uploads/`), изолированный от FastCGI `root`. Запрет исполняемых расширений (`.php`, `.py`) в upload-директории. Без WebDAV — запись worker в web-root не нужна. + - **Источник:** https://nginx.org/en/docs/http/ngx_http_dav_module.html + - **Пример реализации:** + ``` + mkdir -p /var/www/uploads + chown nginx:nginx /var/www/uploads + chmod 750 /var/www/uploads + # Нет fastcgi_pass в location /uploads/ + ``` + ```nginx + location /uploads/ { + root /var/www/static-only; + dav_methods PUT; + } + ``` + - **Проверка эффективности:** + ```bash + nginx -T 2>/dev/null | grep dav_methods + ls -la /var/www/uploads/ 2>/dev/null + # Upload-каталог не пересекается с root для .php + find /var/www/uploads -name '*.php' -o -name '*.py' 2>/dev/null + ``` + - **Примечание:** См. п. 10 в `Контроль целостности хранимого кода и конфигурации — проверка.md`; п. 5 в `Минимизация поверхности атаки nginx — проверка.md`. + +5. **Журналы nginx** + - Необходимые полномочия: права на запись текущих журналов или передачу событий в syslog. + - Запрещено: изменение, удаление и подмена архивных журналов (ограничить правами ОС и/или централизованным журналированием). + - Комментарий: для аудита важна защита журналов от подмены и удаления. + - Проверка: + - **Статус:** Комбинированная мера + - **Ревью полномочий:** Модель корректна. Активные журналы — write для пользователя nginx (или группа `adm`); архивы после logrotate — read-only для nginx (`chmod 440`, владелец root:adm). Централизованное журналирование через syslog снимает зависимость от локальных файлов. Worker не должен удалять/перезаписывать архивы. + - **Источник:** https://nginx.org/en/docs/ngx_core_module.html#error_log , https://nginx.org/en/docs/syslog.html + - **Пример реализации:** + ``` + chown root:adm /var/log/nginx/ + chmod 750 /var/log/nginx/ + chmod 640 /var/log/nginx/access.log /var/log/nginx/error.log + ``` + ```nginx + # Альтернатива: централизованное журналирование + # access_log syslog:server=192.168.1.1:514,facility=local7,tag=nginx,severity=info combined; + # error_log syslog:server=192.168.1.1:514,facility=local7,tag=nginx; + ``` + - **Проверка эффективности:** + ```bash + ls -la /var/log/nginx/ + stat -c '%a %U:%G' /var/log/nginx/*.log + sudo -u nginx rm /var/log/nginx/access.log.1 2>&1 + # Ожидание: отказ в удалении архива + nginx -T 2>/dev/null | grep -E 'access_log|error_log' + ``` + - **Примечание:** См. п. 13 в `Контроль целостности хранимого кода и конфигурации — проверка.md`; п. 14 в `Проверочные мероприятия для ПМИ — проверка.md`. + +6. **TLS-сертификаты** + - Необходимые полномочия: минимальные права для чтения сертификатов на этапе запуска/перезагрузки конфигурации. + - Запрещено: запись/изменение сертификатов от имени nginx. + - Комментарий: сертификаты должны изменяться только администратором. + - Проверка: + - **Статус:** Реализуемо + - **Ревью полномочий:** Требования корректны. Сертификаты (публичная часть) — `644`, владелец root. Master читает при старте/reload; worker не нуждается в write. Обновление сертификатов — администратором, с последующим `nginx -s reload`. + - **Источник:** https://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_certificate + - **Пример реализации:** + ``` + chown root:root /etc/nginx/ssl/ + chmod 644 /etc/nginx/ssl/*.crt + chmod 755 /etc/nginx/ssl/ + ``` + - **Проверка эффективности:** + ```bash + ls -la /etc/nginx/ssl/ + stat -c '%a %U:%G %n' /etc/nginx/ssl/*.crt + sudo -u nginx test -w /etc/nginx/ssl/server.crt && echo FAIL || echo OK + ``` + - **Примечание:** См. п. 11 в `Контроль целостности хранимого кода и конфигурации — проверка.md`. + +7. **TLS-ключи** + - Необходимые полномочия: минимальные права для чтения закрытых ключей на этапе запуска/перезагрузки конфигурации. + - Запрещено: доступ к закрытым ключам для неуполномоченных пользователей/процессов. + - Комментарий: доступ к закрытым ключам должен быть ограничен только необходимыми системными пользователями/процессами. + - Проверка: + - **Статус:** Реализуемо + - **Ревью полномочий:** Требования полностью адекватны. Закрытые ключи читает **master-процесс** (root) при старте и `nginx -s reload`; worker обычно не обращается к ключам напрямую. Права — `600`, владелец root:root. Пользователь nginx и прочие — без read. Запись nginx на ключи запрещена. + - **Источник:** https://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_certificate_key + - **Пример реализации:** + ``` + chmod 600 /etc/nginx/ssl/*.key + chown root:root /etc/nginx/ssl/*.key + ``` + - **Проверка эффективности:** + ```bash + stat -c '%a %U:%G %n' /etc/nginx/ssl/*.key + # Ожидание: 600 root root + sudo -u nginx cat /etc/nginx/ssl/server.key 2>&1 + # Ожидание: Permission denied + getfacl /etc/nginx/ssl/server.key 2>/dev/null + ``` + - **Примечание:** См. п. 11 в `Контроль целостности хранимого кода и конфигурации — проверка.md`. + +8. **Файл пользователей Basic Auth** + - Необходимые полномочия: чтение файла для проверки паролей. + - Запрещено: запись в файл пользователей от имени nginx. + - Комментарий: изменение учётных данных должно выполняться администратором. + - Проверка: + - **Статус:** Условно (если используется) + - **Ревью полномочий:** Требования корректны при использовании `auth_basic`. Worker нужен read; write — только root (администратор). Рекомендуемые права — `640`, владелец root:root (или root:nginx при необходимости read для worker через группу). + - **Источник:** https://nginx.org/en/docs/http/ngx_http_auth_basic_module.html#auth_basic_user_file + - **Пример реализации:** + ``` + chown root:root /etc/nginx/htpasswd + chmod 640 /etc/nginx/htpasswd + # Обновление: htpasswd от root, затем nginx -s reload + ``` + - **Проверка эффективности:** + ```bash + nginx -T 2>/dev/null | grep auth_basic_user_file + ls -la /etc/nginx/htpasswd + sudo -u nginx test -w /etc/nginx/htpasswd && echo FAIL || echo OK + ``` + - **Примечание:** См. п. 12 в `Контроль целостности хранимого кода и конфигурации — проверка.md`. + +9. **Unix-сокеты backend** + - Необходимые полномочия: доступ только к сокетам тех backend, которые используются конфигурацией. + - Запрещено: доступ к произвольным сокетам и сервисам ОС. + - Комментарий: например, socket PHP-FPM/uWSGI должен быть доступен только при необходимости. + - Проверка: + - **Статус:** Реализуемо + - **Ревью полномочий:** Требования адекватны. Доступ к Unix-сокету — через группу: пользователь nginx в группе `www-data`/`php-fpm`, сокет с правами `660` и группой `www-data`. Не использовать world-readable сокеты (`777`). Доступ только к сокетам из `fastcgi_pass`/`uwsgi_pass` в конфигурации. + - **Источник:** https://nginx.org/en/docs/http/ngx_http_fastcgi_module.html#fastcgi_pass , https://nginx.org/en/docs/http/ngx_http_uwsgi_module.html#uwsgi_pass + - **Пример реализации:** + ``` + # PHP-FPM pool: listen.owner = www-data, listen.group = www-data, listen.mode = 0660 + usermod -aG www-data nginx + ``` + ```nginx + location ~ \.php$ { + fastcgi_pass unix:/run/php/php-fpm.sock; + } + ``` + - **Проверка эффективности:** + ```bash + nginx -T 2>/dev/null | grep -E 'fastcgi_pass|uwsgi_pass|scgi_pass' + namei -l /run/php/php-fpm.sock + ls -la /run/php/ + groups nginx 2>/dev/null || groups www-data + # Сокет не world-writable; nginx в нужной группе + ``` + - **Примечание:** См. п. 1–3 в `Контроль выполнения кода — проверка.md`. + +10. **Динамические модули nginx** + - Необходимые полномочия: чтение разрешённых .so-модулей. + - Запрещено: запись/подмена .so-модулей от имени nginx. + - Комментарий: модули выполняются в процессе nginx, поэтому требуют контроля целостности. + - Проверка: + - **Статус:** Комбинированная мера + - **Ревью полномочий:** Требования корректны. Master загружает `.so` при старте (read); каталог `/usr/lib/nginx/modules/` — root:root, `755`, файлы `644`. Пользователь nginx не имеет write. Подмена модулей предотвращается FIM и организационным белым списком `load_module`. + - **Источник:** https://nginx.org/en/docs/ngx_core_module.html#load_module + - **Пример реализации:** + ``` + chown -R root:root /usr/lib/nginx/modules/ + chmod 755 /usr/lib/nginx/modules/ + chmod 644 /usr/lib/nginx/modules/*.so + ``` + ```nginx + load_module modules/ngx_http_geoip_module.so; + ``` + - **Проверка эффективности:** + ```bash + ls -la /usr/lib/nginx/modules/ + nginx -T 2>/dev/null | grep load_module + sudo -u nginx test -w /usr/lib/nginx/modules/ngx_http_geoip_module.so && echo FAIL || echo OK + afick -c /etc/afick.conf --check + ``` + - **Примечание:** См. п. 5 в `Контроль целостности хранимого кода и конфигурации — проверка.md`; п. 3 в `Минимизация поверхности атаки nginx — проверка.md`. + +11. **Временные директории nginx** + - Необходимые полномочия: запись во временные директории, необходимые для buffering/client body. + - Запрещено: запись в произвольные системные директории. + - Комментарий: временные директории должны быть ограничены и контролируемы правами. + - Проверка: + - **Статус:** Реализуемо + - **Ревью полномочий:** Требования адекватны. По умолчанию nginx использует `client_body_temp_path`, `proxy_temp_path`, `fastcgi_temp_path` под `/var/cache/nginx` или compile-time пути. Явно задать пути в конфигурации; каталог — владелец nginx:nginx, `700` или `750`. Не использовать world-writable `/tmp`. + - **Источник:** https://nginx.org/en/docs/http/ngx_http_core_module.html#client_body_temp_path , https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_temp_path + - **Пример реализации:** + ```nginx + http { + client_body_temp_path /var/cache/nginx/client_temp; + proxy_temp_path /var/cache/nginx/proxy_temp; + fastcgi_temp_path /var/cache/nginx/fastcgi_temp; + } + ``` + ``` + mkdir -p /var/cache/nginx/{client_temp,proxy_temp,fastcgi_temp} + chown -R nginx:nginx /var/cache/nginx/ + chmod 750 /var/cache/nginx/ + ``` + - **Проверка эффективности:** + ```bash + nginx -T 2>/dev/null | grep -E 'client_body_temp_path|proxy_temp_path|fastcgi_temp_path' + ls -la /var/cache/nginx/ + find /var/cache/nginx -perm -0002 2>/dev/null + # Нет world-writable каталогов + ``` + - **Примечание:** При `proxy_buffering off` часть temp-файлов не создаётся; пути всё равно зафиксировать в ЭД. + +12. **Сетевые соединения к backend** + - Необходимые полномочия: исходящие соединения только к утверждённым backend-сервисам (при проксировании). + - Запрещено: произвольные исходящие соединения, если они не нужны. + - Комментарий: ограничивается архитектурой, межсетевыми правилами и конфигурацией. + - Проверка: + - **Статус:** Комбинированная мера + - **Ревью полномочий:** Требования корректны, но nginx **не имеет встроенного egress-filter**. Ограничение исходящих соединений — комбинация: (1) конфигурация с белым списком `upstream`/`proxy_pass`; (2) файрвол/nftables на хосте; (3) сегментация сети. Без проксирования исходящие соединения nginx минимальны (DNS при resolver, syslog при централизованном журналировании). + - **Источник:** https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_pass , https://nginx.org/en/docs/http/ngx_http_upstream_module.html + - **Пример реализации:** + ```nginx + upstream approved_backend { + server 127.0.0.1:8080; + server 10.0.0.5:8080; + } + + location /api/ { + proxy_pass http://approved_backend; + } + ``` + ``` + # nftables (фрагмент): исходящие от nginx только к утверждённым адресам + # ip saddr @nginx_workers ip daddr { 10.0.0.5, 127.0.0.1 } tcp dport 8080 accept + ``` + - **Проверка эффективности:** + ```bash + nginx -T 2>/dev/null | grep -E 'proxy_pass|fastcgi_pass|uwsgi_pass|grpc_pass|resolver' + ss -tnp | grep nginx + # Сверить активные соединения с утверждённым перечнем backend + nft list ruleset 2>/dev/null | grep -i nginx + ``` + - **Примечание:** См. п. 12–13 в `Минимизация поверхности атаки nginx — проверка.md`; п. 4 в `Контроль выполнения кода — проверка.md`. diff --git a/docs/Минимизация_поверхности_атаки_nginx_—_проверка.md b/docs/Минимизация_поверхности_атаки_nginx_—_проверка.md new file mode 100644 index 0000000..8e97481 --- /dev/null +++ b/docs/Минимизация_поверхности_атаки_nginx_—_проверка.md @@ -0,0 +1,408 @@ +# Минимизация поверхности атаки nginx — результаты проверки + +**Дата проверки:** 10.06.2026 +**Объект проверки:** upstream nginx + меры минимизации поверхности атаки +**Метод:** ревью мер минимизации, подтверждение по документации nginx, примеры реализации и команды аудита (без практической настройки на стенде) + +## Сводная таблица + +| № | Объект минимизации | Статус | Уровень | +|---|-------------------|--------|---------| +| 1 | Состав обязательных модулей | Организационная мера | сборка / поставка | +| 2 | Состав необязательных модулей | Организационная мера | сборка / поставка | +| 3 | Динамические модули | Комбинированная мера | конфигурация + FIM | +| 4 | Auth Request | Условно (если используется) | конфигурация | +| 5 | WebDAV | Условно (если используется) | конфигурация | +| 6 | njs | Условно (если используется) | сборка / конфигурация | +| 7 | Perl module | Условно (если используется) | сборка / конфигурация | +| 8 | XSLT | Условно (если используется) | конфигурация | +| 9 | SSI | Условно (если используется) | конфигурация | +| 10 | Autoindex | Реализуемо | конфигурация | +| 11 | Лишние HTTP-методы | Реализуемо | конфигурация | +| 12 | Reverse proxy / upstream | Реализуемо | конфигурация | +| 13 | FastCGI/uWSGI/SCGI/gRPC | Реализуемо | конфигурация | +| 14 | Права файловой системы | Комбинированная мера | ОС | +| 15 | Пользователь и группа nginx | Реализуемо | конфигурация / процесс | + +--- + +1. **Состав обязательных модулей** + - Что необходимо определить: Какие модули нужны для базовой работы nginx как веб-сервера. + - Возможное решение: Оставить обязательные модули в базовой поставке. + - Риск / комментарий: Нужно не нарушить штатные сценарии эксплуатации. + - Проверка: + - **Статус:** Организационная мера + - **Ревью меры минимизации:** Задача и решение корректны. nginx не предоставляет runtime-API для отключения встроенных модулей — минимизация выполняется на этапе сборки (`./configure`) или выбора пакета поставки. Базовый набор: `http`, `core`, `events`, `ngx_http_core_module`, `ngx_http_static_module`, `ngx_http_log_module`, `ngx_http_access_module`. Риск «нарушить штатные сценарии» учтён: перечень обязательных модулей фиксируется в ТУ/эксплуатационной документации. + - **Источник:** https://nginx.org/en/docs/configure.html , https://nginx.org/en/docs/ + - **Пример реализации:** + ``` + # Сборка с минимальным набором HTTP-модулей + ./configure \ + --with-http_ssl_module \ + --with-http_realip_module \ + --with-http_gzip_static_module \ + --with-http_stub_status_module + + # В ТУ/ЭД: перечень обязательных модулей из вывода nginx -V + ``` + - **Проверка эффективности:** + ```bash + nginx -V 2>&1 + # Сверить --with-* / --add-module с утверждённым перечнем в ТУ + rpm -qi nginx 2>/dev/null || dpkg -s nginx 2>/dev/null + ``` + - **Примечание:** См. п. 24 в `Требования безопасности для включения в ТУ — проверка.md`. + +2. **Состав необязательных модулей** + - Что необходимо определить: Какие модули не нужны для базовой роли веб-сервера. + - Возможное решение: Вынести в отдельные пакеты или не загружать по умолчанию. + - Риск / комментарий: Возможны риски совместимости с существующими конфигурациями. + - Проверка: + - **Статус:** Организационная мера + - **Ревью меры минимизации:** Решение адекватно. Необязательные модули (Perl, njs, XSLT, WebDAV, auth_request, stream и др.) исключаются при сборке (`--without-http_perl_module`, `--without-http_dav_module`) или поставляются отдельными пакетами (`nginx-module-perl`, `nginx-module-njs`). Риск совместимости снимается документированием: при обновлении поставки проверять `nginx -t` и наличие директив в конфигурации. + - **Источник:** https://nginx.org/en/docs/configure.html + - **Пример реализации:** + ``` + # Исключение при сборке + ./configure \ + --without-http_perl_module \ + --without-http_dav_module \ + --without-http_xslt_module \ + --without-http_auth_request_module + + # Или: базовый пакет nginx без модулей-расширений; + # опциональные модули — отдельные RPM/DEB, не устанавливаются по умолчанию + ``` + - **Проверка эффективности:** + ```bash + nginx -V 2>&1 | grep -E 'perl|dav|xslt|auth_request|njs' + # Ожидание: отсутствие неутверждённых модулей в выводе + dpkg -l 'nginx-module-*' 2>/dev/null || rpm -qa 'nginx-module-*' 2>/dev/null + ``` + - **Примечание:** См. п. 24 в `Требования безопасности для включения в ТУ — проверка.md`. + +3. **Динамические модули** + - Что необходимо определить: Какие .so-модули разрешены к загрузке. + - Возможное решение: Разрешить только утверждённый перечень модулей. + - Риск / комментарий: Неразрешённый модуль может выполнять код в процессе nginx. + - Проверка: + - **Статус:** Комбинированная мера + - **Ревью меры минимизации:** Решение полностью адекватно риску. Белый список `load_module` в конфигурации + FIM на каталог `.so` + организационный запрет сторонних модулей без процедуры утверждения. + - **Источник:** https://nginx.org/en/docs/ngx_core_module.html#load_module + - **Пример реализации:** + ```nginx + # /etc/nginx/nginx.conf — только утверждённые модули + load_module modules/ngx_http_geoip_module.so; + # load_module /path/to/unapproved.so; # запрещено + ``` + ``` + # /etc/afick.conf (фрагмент) + /usr/lib/nginx/modules/ R + ``` + - **Проверка эффективности:** + ```bash + nginx -T 2>/dev/null | grep load_module + ls -la /usr/lib/nginx/modules/ + # Сверить с утверждённым перечнем в эксплуатационной документации + afick -c /etc/afick.conf --check + ``` + - **Примечание:** См. п. 5 в `Контроль целостности хранимого кода и конфигурации — проверка.md`; п. 10–11 в `Контроль выполнения кода — проверка.md`. + +4. **Auth Request** + - Что необходимо определить: Требуется ли авторизация через внешний сервис в базовой поставке. + - Возможное решение: Оставить только при наличии обоснованных сценариев. + - Риск / комментарий: Модуль не является обязательным для простого веб-сервера. + - Проверка: + - **Статус:** Условно (если используется) + - **Ревью меры минимизации:** Решение корректно. `ngx_http_auth_request_module` не нужен для статического веб-сервера с `auth_basic`. Включается только при сценарии делегированной авторизации (OAuth-шлюз, внешний IdP). Риск минимален при отсутствии модуля в сборке и директив в конфигурации. + - **Источник:** https://nginx.org/en/docs/http/ngx_http_auth_request_module.html + - **Пример реализации:** + ```nginx + # Базовая конфигурация — auth_request не используется + # При необходимости (после утверждения сценария): + # location /protected/ { + # auth_request /auth; + # proxy_pass http://backend; + # } + ``` + - **Проверка эффективности:** + ```bash + nginx -V 2>&1 | grep auth_request + nginx -T 2>/dev/null | grep -E 'auth_request|auth_request_set' + # Ожидание для минимальной поставки: отсутствие директив + ``` + - **Примечание:** См. п. 4 в `Требования безопасности для включения в ТУ — проверка.md`. + +5. **WebDAV** + - Что необходимо определить: Требуется ли возможность записи/изменения файлов через HTTP. + - Возможное решение: Отключить или не включать в базовую конфигурацию, если не требуется. + - Риск / комментарий: Может позволить загрузку файлов, которые затем попадут в обработку. + - Проверка: + - **Статус:** Условно (если используется) + - **Ревью меры минимизации:** Решение адекватно. WebDAV не включается в базовую конфигурацию. При необходимости — изолированный `location` без пересечения с FastCGI/uWSGI и без исполняемых расширений в upload-каталоге. + - **Источник:** https://nginx.org/en/docs/http/ngx_http_dav_module.html + - **Пример реализации:** + ```nginx + # WebDAV не включён в базовой конфигурации + # При необходимости — изолированный location: + # location /uploads/ { + # root /var/www/static-only; + # dav_methods PUT; + # # Нет fastcgi_pass / uwsgi_pass + # } + ``` + - **Проверка эффективности:** + ```bash + nginx -T 2>/dev/null | grep -E 'dav_methods|dav_access|create_full_put_path' + # Ожидание: dav_methods отсутствует вне утверждённых location + ``` + - **Примечание:** См. п. 10 в `Контроль целостности хранимого кода и конфигурации — проверка.md`; п. 12 в `Контроль выполнения кода — проверка.md`. + +6. **njs** + - Что необходимо определить: Требуется ли серверная JavaScript-логика внутри nginx. + - Возможное решение: Не включать или не загружать без обоснованной необходимости. + - Риск / комментарий: Выполняет логику внутри процесса nginx. + - Проверка: + - **Статус:** Условно (если используется) + - **Ревью меры минимизации:** Решение корректно. njs выполняет JavaScript в процессе worker — для базового веб-сервера не требуется. Не загружать `ngx_http_js_module.so`, не использовать `js_import`/`js_content` без утверждённого сценария. + - **Источник:** https://nginx.org/en/docs/njs/ + - **Пример реализации:** + ```nginx + # Базовая конфигурация — njs не используется + # load_module modules/ngx_http_js_module.so; # только после утверждения + ``` + - **Проверка эффективности:** + ```bash + nginx -V 2>&1 | grep -i njs + nginx -T 2>/dev/null | grep -E 'js_import|js_content|js_set|load_module.*js' + # Ожидание: отсутствие njs в минимальной поставке + ``` + - **Примечание:** См. п. 6 в `Контроль целостности хранимого кода и конфигурации — проверка.md`; п. 6 в `Контроль выполнения кода — проверка.md`. + +7. **Perl module** + - Что необходимо определить: Требуется ли Perl-логика внутри nginx. + - Возможное решение: Не включать или не загружать без обоснованной необходимости. + - Риск / комментарий: Выполняет логику внутри процесса nginx. + - Проверка: + - **Статус:** Условно (если используется) + - **Ревью меры минимизации:** Решение полностью адекватно. Perl-модуль — наиболее рискованный встроенный интерпретатор. Рекомендация: не собирать (`--without-http_perl_module`), не устанавливать пакет `nginx-module-perl`. + - **Источник:** https://nginx.org/en/docs/http/ngx_http_perl_module.html + - **Пример реализации:** + ``` + # Сборка без Perl + ./configure --without-http_perl_module + + # Конфигурация — директивы perl/perl_require отсутствуют + ``` + - **Проверка эффективности:** + ```bash + nginx -V 2>&1 | grep -i perl + nginx -T 2>/dev/null | grep -E 'perl|perl_require|perl_modules' + # Ожидание: Perl отсутствует + ``` + - **Примечание:** См. п. 7 в `Контроль целостности хранимого кода и конфигурации — проверка.md`; п. 7 в `Контроль выполнения кода — проверка.md`. + +8. **XSLT** + - Что необходимо определить: Требуется ли преобразование XML через XSLT. + - Возможное решение: Оставить только при наличии сценариев эксплуатации. + - Риск / комментарий: Добавляет дополнительную поверхность обработки данных. + - Проверка: + - **Статус:** Условно (если используется) + - **Ревью меры минимизации:** Решение корректно. XSLT-модуль не нужен для типового веб-сервера. При использовании — только утверждённые `.xslt` в FIM-области. + - **Источник:** https://nginx.org/en/docs/http/ngx_http_xslt_module.html + - **Пример реализации:** + ```nginx + # Базовая конфигурация — XSLT не используется + # xslt_stylesheet отсутствует + ``` + - **Проверка эффективности:** + ```bash + nginx -V 2>&1 | grep xslt + nginx -T 2>/dev/null | grep xslt_stylesheet + # Ожидание: xslt_stylesheet отсутствует + ``` + - **Примечание:** См. п. 8 в `Контроль целостности хранимого кода и конфигурации — проверка.md`. + +9. **SSI** + - Что необходимо определить: Требуется ли обработка SSI-команд. + - Возможное решение: Отключить в конфигурации, если не требуется. + - Риск / комментарий: Может влиять на формирование ответа. + - Проверка: + - **Статус:** Условно (если используется) + - **Ревью меры минимизации:** Решение адекватно. По умолчанию `ssi off`. При включении — запрет ``, контроль SSI-файлов через FIM (web-root). + - **Источник:** https://nginx.org/en/docs/http/ngx_http_ssi_module.html + - **Пример реализации:** + ```nginx + http { + ssi off; # явно в базовой конфигурации + } + ``` + - **Проверка эффективности:** + ```bash + nginx -T 2>/dev/null | grep -i 'ssi on' + # Ожидание: ssi on отсутствует вне утверждённых location + grep -r '#exec' /var/www/ 2>/dev/null + ``` + - **Примечание:** См. п. 9 в `Контроль целостности хранимого кода и конфигурации — проверка.md`; п. 8 в `Контроль выполнения кода — проверка.md`. + +10. **Autoindex** + - Что необходимо определить: Требуется ли листинг директорий. + - Возможное решение: Отключить по умолчанию. + - Риск / комментарий: Раскрывает структуру директорий и файлов. + - Проверка: + - **Статус:** Реализуемо + - **Ревью меры минимизации:** Решение полностью адекватно. `autoindex off` — значение по умолчанию; явное указание в `http {}` обеспечивает однозначность аудита. При отсутствии `index` — 403, не листинг. + - **Источник:** https://nginx.org/en/docs/http/ngx_http_autoindex_module.html + - **Пример реализации:** + ```nginx + http { + autoindex off; + } + ``` + - **Проверка эффективности:** + ```bash + nginx -T 2>/dev/null | grep autoindex + # Ожидание: autoindex off или директива отсутствует (default off) + curl -s -o /dev/null -w '%{http_code}' http://localhost/no-index-dir/ + # Ожидание: 403 + ``` + - **Примечание:** См. п. 21 в `Проверочные мероприятия для ПМИ — проверка.md`; п. 21 в `Требования безопасности для включения в ТУ — проверка.md`. + +11. **Лишние HTTP-методы** + - Что необходимо определить: Какие методы реально нужны приложениям. + - Возможное решение: Ограничить PUT, DELETE и другие методы, если они не требуются. + - Риск / комментарий: Ненужные методы расширяют поверхность атаки. + - Проверка: + - **Статус:** Реализуемо + - **Ревью меры минимизации:** Решение корректно. Для статического веб-сервера достаточно GET, HEAD, POST (если есть формы). PUT, DELETE, PATCH, OPTIONS — блокировать, если не требуются API/WebDAV. + - **Источник:** https://nginx.org/en/docs/http/ngx_http_limit_except_module.html + - **Пример реализации:** + ```nginx + location / { + limit_except GET HEAD POST { + deny all; + } + root /var/www/html; + } + + # Альтернатива для глобального ограничения: + # if ($request_method !~ ^(GET|HEAD|POST)$) { + # return 405; + # } + ``` + - **Проверка эффективности:** + ```bash + nginx -T 2>/dev/null | grep -E 'limit_except|request_method' + curl -s -o /dev/null -w '%{http_code}' -X DELETE http://localhost/ + # Ожидание: 403 или 405 + ``` + - **Примечание:** См. п. 7 в `Требования безопасности для включения в ТУ — проверка.md`. + +12. **Reverse proxy / upstream** + - Что необходимо определить: Какие backend-направления разрешены. + - Возможное решение: Разрешить только утверждённые backend-сервисы. + - Риск / комментарий: Неверная настройка может открыть доступ к внутренним сервисам. + - Проверка: + - **Статус:** Реализуемо + - **Ревью меры минимизации:** Решение адекватно риску SSRF и доступа к внутренним сервисам. Белый список `upstream` с фиксированными адресами; запрет произвольных `proxy_pass http://$variable` без валидации. + - **Источник:** https://nginx.org/en/docs/http/ngx_http_proxy_module.html , https://nginx.org/en/docs/http/ngx_http_upstream_module.html + - **Пример реализации:** + ```nginx + upstream approved_backend { + server 127.0.0.1:8080; + server 10.0.0.5:8080; + } + + location /api/ { + proxy_pass http://approved_backend; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + } + ``` + - **Проверка эффективности:** + ```bash + nginx -T 2>/dev/null | grep -E 'proxy_pass|upstream' + # Сверить все proxy_pass с утверждённым перечнем backend + # Нет proxy_pass на 127.0.0.1:22, 169.254.169.254 и т.п. + ``` + - **Примечание:** См. п. 4 в `Контроль выполнения кода — проверка.md`. + +13. **FastCGI/uWSGI/SCGI/gRPC** + - Что необходимо определить: Какие внешние обработчики допустимы. + - Возможное решение: Разрешить только утверждённые обработчики и маршруты. + - Риск / комментарий: Ошибка маршрутизации может привести к обработке неразрешённого кода. + - Проверка: + - **Статус:** Реализуемо + - **Ревью меры минимизации:** Решение полностью адекватно. Включать только необходимые протоколы; фиксированные `*_pass` на утверждённые сокеты/адреса; `try_files $uri =404` перед FastCGI; безопасный `SCRIPT_FILENAME`. + - **Источник:** https://nginx.org/en/docs/http/ngx_http_fastcgi_module.html , https://nginx.org/en/docs/http/ngx_http_uwsgi_module.html , https://nginx.org/en/docs/http/ngx_http_scgi_module.html , https://nginx.org/en/docs/http/ngx_http_grpc_module.html + - **Пример реализации:** + ```nginx + # Только FastCGI — утверждённый PHP-FPM + location ~ \.php$ { + try_files $uri =404; + fastcgi_pass unix:/run/php/php-fpm.sock; + include fastcgi_params; + fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; + } + # uwsgi_pass, scgi_pass, grpc_pass — только при утверждённом сценарии + ``` + - **Проверка эффективности:** + ```bash + nginx -T 2>/dev/null | grep -E 'fastcgi_pass|uwsgi_pass|scgi_pass|grpc_pass' + nginx -T 2>/dev/null | grep SCRIPT_FILENAME + # Все *_pass — из утверждённого перечня + # SCRIPT_FILENAME = $document_root$fastcgi_script_name + ``` + - **Примечание:** См. п. 1–5 в `Контроль выполнения кода — проверка.md`. + +14. **Права файловой системы** + - Что необходимо определить: Какие права нужны nginx для чтения/записи. + - Возможное решение: Выдать минимально необходимые права. + - Риск / комментарий: Избыточные права повышают риск компрометации. + - Проверка: + - **Статус:** Комбинированная мера + - **Ревью меры минимизации:** Решение корректно. Worker-процесс должен иметь доступ только на чтение к web-root и конфигурации; запись — только в журналы, кэш, upload (если WebDAV). Ключи TLS — `600`, конфигурация — `644 root:root`, web-root — `755`/`644`, без world-writable. + - **Источник:** https://nginx.org/en/docs/ngx_core_module.html#user + - **Пример реализации:** + ``` + # Минимальные права + chown -R root:root /etc/nginx/ + chmod 644 /etc/nginx/nginx.conf + chown -R root:www-data /var/www/html/ + chmod -R 755 /var/www/html/ + find /var/www/html -type f -exec chmod 644 {} \; + chmod 600 /etc/nginx/ssl/*.key + chown root:adm /var/log/nginx/ + chmod 750 /var/log/nginx/ + ``` + - **Проверка эффективности:** + ```bash + namei -l /var/www/html/index.html + ls -la /etc/nginx/ /var/www/ /var/log/nginx/ + stat -c '%a %U:%G %n' /etc/nginx/ssl/* + # Нет каталогов с mode 777; ключи — 600 + ``` + - **Примечание:** Детальный FIM — в `Контроль целостности хранимого кода и конфигурации — проверка.md` п. 3–4, 11. Здесь акцент на минимальных правах для worker. + +15. **Пользователь и группа nginx** + - Что необходимо определить: От чьего имени выполняются worker-процессы. + - Возможное решение: Запускать worker-процессы от непривилегированного пользователя. + - Риск / комментарий: Избыточные полномочия процесса повышают ущерб при компрометации. + - Проверка: + - **Статус:** Реализуемо + - **Ревью меры минимизации:** Решение полностью адекватно. Master — root (для привязки к портам <1024), worker — непривилегированный пользователь (`nginx`, `www-data`). Директива `user` в конфигурации обязательна для однозначности. + - **Источник:** https://nginx.org/en/docs/ngx_core_module.html#user + - **Пример реализации:** + ```nginx + # /etc/nginx/nginx.conf + user nginx nginx; + # или: user www-data www-data; + ``` + - **Проверка эффективности:** + ```bash + nginx -T 2>/dev/null | grep '^user ' + ps aux | grep 'nginx: worker' + # Worker-процессы — не root (UID != 0) + id nginx 2>/dev/null || id www-data + ``` + - **Примечание:** Master-процесс остаётся root — это штатное поведение nginx для bind к 80/443. diff --git a/docs/Проверочные_мероприятия_для_ПМИ_—_проверка.md b/docs/Проверочные_мероприятия_для_ПМИ_—_проверка.md new file mode 100644 index 0000000..3aee4c3 --- /dev/null +++ b/docs/Проверочные_мероприятия_для_ПМИ_—_проверка.md @@ -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 | curl -s -o /dev/null -w "%{http_code}" -X POST -d @- http://nginx-test/upload + + # Больше лимита + dd if=/dev/zero bs=1M count=2 2>/dev/null | curl -s -o /dev/null -w "%{http_code}" -X POST -d @- http://nginx-test/upload + ``` + - **Проверка признака выполнения:** Малый запрос — 200/204; большой — 413 Request Entity Too Large. + +18. **Проверяемое требование:** Настройка таймаутов + - **Настройка / механизм:** client_header_timeout; client_body_timeout; send_timeout; keepalive_timeout + - **Действия испытателя:** Настроить таймауты. Смоделировать медленную отправку заголовков/тела запроса. + - **Ожидаемый результат:** Медленные соединения закрываются по таймауту. + - **Признак выполнения:** Соединение разрывается после заданного времени. + - Проверка: + - **Статус:** Пригодно с оговорками + - **Ревью мероприятия:** Мероприятие корректно по смыслу, но воспроизведение медленной отправки заголовков требует специальных инструментов (`nc`, скрипт на Python) или модулей; `curl --limit-rate` подходит для тела запроса (`client_body_timeout`). + - **Источник:** https://nginx.org/en/docs/http/ngx_http_core_module.html#client_body_timeout + - **Пример конфигурации:** + ```nginx + client_header_timeout 5s; + client_body_timeout 5s; + ``` + - **Примеры команд испытания:** + ```bash + # Медленная отправка тела (превышение client_body_timeout) + dd if=/dev/zero bs=1K count=1000 2>/dev/null | curl --limit-rate 1K -m 30 -X POST -d @- http://nginx-test/upload + ``` + - **Проверка признака выполнения:** curl завершается с ошибкой (timeout/connection reset) примерно через заданный `client_body_timeout`. + +19. **Проверяемое требование:** Сокрытие версии nginx + - **Настройка / механизм:** server_tokens off + - **Действия испытателя:** Выполнить запрос и проверить заголовки/страницы ошибок. + - **Ожидаемый результат:** Версия nginx не раскрывается в ответах. + - **Признак выполнения:** В ответе отсутствует номер версии nginx. + - Проверка: + - **Статус:** Пригодно для ПМИ + - **Ревью мероприятия:** Мероприятие корректно. `server_tokens off` убирает версию, но заголовок `Server: nginx` остаётся — это соответствует документации. + - **Источник:** https://nginx.org/en/docs/http/ngx_http_core_module.html#server_tokens + - **Пример конфигурации:** + ```nginx + http { + server_tokens off; + } + ``` + - **Примеры команд испытания:** + ```bash + curl -I http://nginx-test/ + curl http://nginx-test/nonexistent-page + ``` + - **Проверка признака выполнения:** Заголовок `Server: nginx` без номера версии (не `nginx/1.24.0`); в теле ошибки 404 нет номера версии. + +20. **Проверяемое требование:** Управление страницами ошибок + - **Настройка / механизм:** error_page + - **Действия испытателя:** Настроить пользовательскую страницу ошибки. Вызвать ошибку 404/403/500. + - **Ожидаемый результат:** Отображается настроенная страница ошибки без раскрытия лишних деталей. + - **Признак выполнения:** Пользователь видит заданную страницу ошибки. + - Проверка: + - **Статус:** Пригодно для ПМИ + - **Ревью мероприятия:** Мероприятие корректно и воспроизводимо. + - **Источник:** https://nginx.org/en/docs/http/ngx_http_core_module.html#error_page + - **Пример конфигурации:** + ```nginx + error_page 404 /custom_404.html; + + location = /custom_404.html { + root /var/www/errors; + internal; + } + ``` + - **Примеры команд испытания:** + ```bash + curl http://nginx-test/nonexistent-page + ``` + - **Проверка признака выполнения:** Тело ответа содержит текст/разметку из `/var/www/errors/custom_404.html`, а не стандартную страницу nginx. + +21. **Проверяемое требование:** Отключение листинга директорий + - **Настройка / механизм:** autoindex off + - **Действия испытателя:** Обратиться к директории без индексного файла. + - **Ожидаемый результат:** Листинг директории не отображается. + - **Признак выполнения:** Сервер возвращает отказ или штатную ошибку, но не список файлов. + - Проверка: + - **Статус:** Пригодно для ПМИ + - **Ревью мероприятия:** Мероприятие корректно. `autoindex off` — значение по умолчанию; при отсутствии index.html ожидается 403. + - **Источник:** https://nginx.org/en/docs/http/ngx_http_autoindex_module.html + - **Пример конфигурации:** + ```nginx + location /files/ { + autoindex off; + root /var/www/html; + } + ``` + - **Примеры команд испытания:** + ```bash + curl http://nginx-test/files/ + ``` + - **Проверка признака выполнения:** Ответ 403 Forbidden (или 404), в теле нет HTML-листинга с перечнем файлов. + +22. **Проверяемое требование:** Обратное проксирование backend + - **Настройка / механизм:** proxy_pass + - **Действия испытателя:** Настроить proxy_pass на backend. Если архитектурой предусмотрена изоляция backend-сервиса, проверить, что пользовательский доступ к backend выполняется через nginx, а прямой доступ к backend ограничен сетевыми правилами/настройками инфраструктуры. + - **Ожидаемый результат:** Запрос проходит через nginx; прямой доступ к backend ограничен, если это предусмотрено архитектурой. + - **Признак выполнения:** Backend обслуживается через nginx согласно настройке. + - Проверка: + - **Статус:** Пригодно с оговорками + - **Ревью мероприятия:** Проверка proxy_pass через nginx — корректна. Проверка сетевой изоляции backend — отдельное инфраструктурное мероприятие (firewall, bind только на 127.0.0.1); в протоколе разделить результаты. + - **Источник:** https://nginx.org/en/docs/http/ngx_http_proxy_module.html + - **Пример конфигурации:** + ```nginx + location /api/ { + proxy_pass http://127.0.0.1:8080/; + } + ``` + - **Примеры команд испытания:** + ```bash + # Через nginx — успех + curl http://nginx-test/api/status + + # Прямой доступ к backend (с испытательной машины, если backend на 127.0.0.1 — недоступен) + curl http://127.0.0.1:8080/status + ``` + - **Проверка признака выполнения:** Запрос через nginx возвращает ответ backend; прямой доступ с внешней сети к порту 8080 — отказ (если изоляция настроена). + +23. **Проверяемое требование:** Ограничение директорий веб-контента + - **Настройка / механизм:** root; alias; location; try_files + - **Действия испытателя:** Настроить разрешённую директорию веб-контента. Выполнить запрос к файлу внутри и вне разрешённой директории. + - **Ожидаемый результат:** Файлы внутри разрешённой директории доступны, вне директории не обслуживаются. + - **Признак выполнения:** Доступ к произвольным каталогам ОС отсутствует. + - Проверка: + - **Статус:** Пригодно для ПМИ + - **Ревью мероприятия:** Мероприятие корректно. Для «вне директории» использовать path traversal (`/../etc/passwd`) или запрос к URI вне `root`. + - **Источник:** https://nginx.org/en/docs/http/ngx_http_core_module.html#root + - **Пример конфигурации:** + ```nginx + server { + root /var/www/app/public; + + location / { + try_files $uri =404; + } + } + ``` + - **Примеры команд испытания:** + ```bash + # Файл внутри root + curl -s -o /dev/null -w "%{http_code}" http://nginx-test/index.html + + # Попытка path traversal + curl -s -o /dev/null -w "%{http_code}" http://nginx-test/../../../etc/passwd + ``` + - **Проверка признака выполнения:** Легитимный файл — 200; traversal — 404 (содержимое `/etc/passwd` не отдаётся). + +24. **Проверяемое требование:** Контроль целостности + - **Настройка / механизм:** afick или иной механизм + - **Действия испытателя:** Настроить контроль целостности для конфигурации, web-root и модулей. Изменить контролируемый файл. + - **Ожидаемый результат:** Изменение обнаруживается механизмом контроля целостности. + - **Признак выполнения:** Средство контроля фиксирует нарушение целостности. + - Проверка: + - **Статус:** Требует внешних средств + - **Ревью мероприятия:** Мероприятие корректно. nginx не выполняет FIM; испытание относится к внешнему средству (afick, AIDE). В протоколе указать версию и конфигурацию FIM. + - **Источник:** https://nginx.org/en/docs/ (функция FIM в nginx не описана) + - **Пример конфигурации внешнего средства (afick):** + ``` + # /etc/afick.conf (фрагмент) + /etc/nginx/ R + /var/www/ R + /usr/lib/nginx/modules/ R + ``` + - **Примеры команд испытания:** + ```bash + # Базовая проверка (без изменений) + afick -c /etc/afick.conf --check + + # Изменить контролируемый файл + echo "# test change" >> /etc/nginx/nginx.conf + + # Повторная проверка + afick -c /etc/afick.conf --check + ``` + - **Проверка признака выполнения:** Отчёт afick содержит запись об изменении `/etc/nginx/nginx.conf`. После испытания восстановить файл из эталона. + - **Примечание:** Не относится к функциям nginx; включается в ПМИ как проектное/инфраструктурное мероприятие. Статус отражает внешнюю меру. См. `Контроль целостности хранимого кода и конфигурации — проверка.md` (весь документ); функции 9.3 в `функции безопасности — проверка.md`; `Контроль выполнения кода — проверка.md` п. 15–16. diff --git a/docs/Требования_безопасности_для_включения_в_ТУ_—_проверка.md b/docs/Требования_безопасности_для_включения_в_ТУ_—_проверка.md new file mode 100644 index 0000000..def102e --- /dev/null +++ b/docs/Требования_безопасности_для_включения_в_ТУ_—_проверка.md @@ -0,0 +1,547 @@ +# Требования безопасности для включения в ТУ — результаты проверки + +**Дата проверки:** 10.06.2026 +**Объект проверки:** upstream nginx (официальная документация nginx.org) +**Метод:** анализ официальной документации, примеры конфигурации и вывод о пригодности требований для включения в ТУ (без практических тестов на работающем экземпляре) + +## Сводная таблица + +| № | Требование | Статус | Механизм nginx | +|---|------------|--------|----------------| +| 1 | Ограничение доступа по IP-адресу | Подтверждено | ngx_http_access_module; allow; deny | +| 2 | Аутентификация по имени пользователя и паролю | Подтверждено | ngx_http_auth_basic_module | +| 3 | Аутентификация по клиентскому TLS-сертификату | Подтверждено с оговорками | ngx_http_ssl_module | +| 4 | Авторизация через внешний сервис | Подтверждено с оговорками | ngx_http_auth_request_module | +| 5 | Комбинирование механизмов доступа | Подтверждено | satisfy | +| 6 | Разграничение доступа по URL и виртуальным серверам | Подтверждено | server; location | +| 7 | Ограничение HTTP-методов | Подтверждено | limit_except | +| 8 | Запрет прямого доступа к внутренним ресурсам | Подтверждено | internal | +| 9 | Защита соединения с использованием TLS | Подтверждено с оговорками | ngx_http_ssl_module | +| 10 | Ограничение версий TLS и наборов шифров | Подтверждено | ssl_protocols; ssl_ciphers | +| 11 | Принудительное использование HTTPS | Подтверждено | return; add_header (HSTS) | +| 12 | Журналирование HTTP-запросов | Подтверждено | access_log; log_format | +| 13 | Журналирование ошибок | Подтверждено | error_log | +| 14 | Передача журналов во внешнюю систему | Подтверждено | syslog | +| 15 | Ограничение частоты запросов | Подтверждено | ngx_http_limit_req_module | +| 16 | Ограничение количества соединений | Подтверждено | ngx_http_limit_conn_module | +| 17 | Ограничение размера клиентского запроса | Подтверждено | client_max_body_size | +| 18 | Настройка таймаутов соединений | Подтверждено | client_*_timeout; send_timeout; keepalive_timeout | +| 19 | Сокрытие версии веб-сервера | Подтверждено | server_tokens off | +| 20 | Управление страницами ошибок | Подтверждено | error_page | +| 21 | Управление листингом директорий | Подтверждено | autoindex off | +| 22 | Обратное проксирование backend-сервисов | Подтверждено | proxy_pass; proxy_set_header | +| 23 | Управление директориями веб-контента | Подтверждено | root; alias; location; try_files | +| 24 | Минимизация поверхности атаки | Подтверждено с оговорками | configure; load_module; конфигурация | + +--- + +1. **Ограничение доступа по IP-адресу** + - Требование для ТУ: Веб-сервер должен обеспечивать возможность ограничения доступа к защищаемым ресурсам по IP-адресу клиента. + - Механизм nginx: ngx_http_access_module; allow; deny + - Комментарий: Проверяется через настройку разрешённых и запрещённых IP-адресов. + - Проверка: + - **Статус:** Подтверждено + - **Ревью требования:** Формулировка требования согласуется с возможностями nginx. + - **Вывод для ТУ:** Требование может быть включено в ТУ — nginx обеспечивает ограничение доступа по IP-адресу клиента. + - **Источник:** https://nginx.org/en/docs/http/ngx_http_access_module.html + - **Результат:** Модуль `ngx_http_access_module` входит в стандартную сборку nginx. Директивы `allow` и `deny` позволяют задавать правила доступа по IP-адресу, сети CIDR или `all`, что полностью соответствует формулировке требования. + - **Пример конфигурации:** + ```nginx + location /admin/ { + allow 192.168.1.0/24; + allow 10.0.0.1; + deny all; + } + ``` + +2. **Аутентификация по имени пользователя и паролю** + - Требование для ТУ: Веб-сервер должен обеспечивать возможность аутентификации пользователей по имени пользователя и паролю при доступе к защищаемым ресурсам. + - Механизм nginx: ngx_http_auth_basic_module; auth_basic; auth_basic_user_file + - Комментарий: Реализуется через HTTP Basic Authentication. + - Проверка: + - **Статус:** Подтверждено + - **Ревью требования:** Формулировка требования согласуется с возможностями nginx. + - **Вывод для ТУ:** Требование может быть включено в ТУ — nginx поддерживает аутентификацию по имени пользователя и паролю. + - **Источник:** https://nginx.org/en/docs/http/ngx_http_auth_basic_module.html + - **Результат:** Модуль `ngx_http_auth_basic_module` реализует HTTP Basic Authentication. Директивы `auth_basic` и `auth_basic_user_file` обеспечивают проверку учётных данных пользователя при доступе к защищаемым ресурсам. + - **Пример конфигурации:** + ```nginx + location /secure/ { + auth_basic "Restricted Area"; + auth_basic_user_file /etc/nginx/htpasswd; + } + ``` + +3. **Аутентификация по клиентскому TLS-сертификату** + - Требование для ТУ: Веб-сервер должен обеспечивать возможность проверки клиентского TLS-сертификата при доступе к защищаемым ресурсам. + - Механизм nginx: ngx_http_ssl_module; ssl_client_certificate; ssl_verify_client + - Комментарий: Применяется при использовании HTTPS и доверенного центра сертификации. + - Проверка: + - **Статус:** Подтверждено с оговорками + - **Ревью требования:** Описание и механизм в целом адекватны; учтены оговорки сборки, конфигурации или эксплуатации. + - **Вывод для ТУ:** Требование может быть включено в ТУ — nginx обеспечивает проверку клиентского TLS-сертификата при использовании HTTPS. + - **Источник:** https://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_verify_client + - **Результат:** Модуль `ngx_http_ssl_module` поддерживает проверку клиентских сертификатов через `ssl_verify_client` и `ssl_client_certificate`. Требуется сборка с SSL-модулем и настроенный HTTPS. + - **Пример конфигурации:** + ```nginx + server { + listen 443 ssl; + ssl_certificate /etc/nginx/ssl/server.crt; + ssl_certificate_key /etc/nginx/ssl/server.key; + ssl_client_certificate /etc/nginx/ssl/ca.crt; + ssl_verify_client on; + } + ``` + - **Примечание:** В ТУ следует указать требование наличия SSL-модуля и доверенного CA. + +4. **Авторизация через внешний сервис** + - Требование для ТУ: Веб-сервер должен обеспечивать возможность принятия решения о доступе на основании ответа внешнего сервиса авторизации. + - Механизм nginx: ngx_http_auth_request_module; auth_request + - Комментарий: Наличие модуля зависит от состава сборки nginx. + - Проверка: + - **Статус:** Подтверждено с оговорками + - **Ревью требования:** Описание и механизм в целом адекватны; учтены оговорки сборки, конфигурации или эксплуатации. + - **Вывод для ТУ:** Требование может быть включено в ТУ при условии наличия модуля `auth_request` в поставке nginx. + - **Источник:** https://nginx.org/en/docs/http/ngx_http_auth_request_module.html + - **Результат:** Модуль `ngx_http_auth_request_module` выполняет подзапрос к внешнему сервису авторизации и разрешает или запрещает доступ по коду ответа (2xx — разрешено, 401/403 — запрещено). Состав сборки nginx должен быть зафиксирован в ТУ. + - **Пример конфигурации:** + ```nginx + location = /auth { + internal; + proxy_pass http://auth-service:8080/validate; + proxy_pass_request_body off; + proxy_set_header Content-Length ""; + } + + location / { + auth_request /auth; + } + ``` + - **Примечание:** В ТУ указать требование включения `--with-http_auth_request_module` или подтверждение наличия модуля в дистрибутивном пакете. + +5. **Комбинирование механизмов доступа** + - Требование для ТУ: Веб-сервер должен обеспечивать возможность совместного применения нескольких механизмов контроля доступа. + - Механизм nginx: satisfy; allow; deny; auth_basic; auth_request + - Комментарий: Например, доступ по IP или по паролю. + - Проверка: + - **Статус:** Подтверждено + - **Ревью требования:** Формулировка требования согласуется с возможностями nginx. + - **Вывод для ТУ:** Требование может быть включено в ТУ — nginx позволяет комбинировать механизмы контроля доступа. + - **Источник:** https://nginx.org/en/docs/http/ngx_http_core_module.html#satisfy + - **Результат:** Директива `satisfy` управляет логикой совместного применения `allow`/`deny`, `auth_basic` и `auth_request`. Значение `any` позволяет доступ при успехе любой проверки; `all` — при успехе всех. + - **Пример конфигурации:** + ```nginx + location /admin/ { + satisfy any; + allow 10.0.0.0/8; + deny all; + auth_basic "Admin"; + auth_basic_user_file /etc/nginx/htpasswd; + } + ``` + +6. **Разграничение доступа по URL и виртуальным серверам** + - Требование для ТУ: Веб-сервер должен обеспечивать возможность задания разных правил доступа для разных виртуальных серверов и разделов сайта. + - Механизм nginx: server; location + - Комментарий: Используется для разделения публичных, служебных и закрытых ресурсов. + - Проверка: + - **Статус:** Подтверждено + - **Ревью требования:** Формулировка требования согласуется с возможностями nginx. + - **Вывод для ТУ:** Требование может быть включено в ТУ — nginx поддерживает разграничение по виртуальным серверам и URL. + - **Источник:** https://nginx.org/en/docs/http/ngx_http_core_module.html#server , https://nginx.org/en/docs/http/ngx_http_core_module.html#location + - **Результат:** Блоки `server` определяют виртуальные хосты, блоки `location` — правила для URI-путей. Это базовый механизм nginx для задания разных правил доступа на разных серверах и разделах сайта. + - **Пример конфигурации:** + ```nginx + server { + listen 80; + server_name public.example.com; + location / { root /var/www/public; } + } + + server { + listen 80; + server_name admin.example.com; + location / { + allow 10.0.0.0/8; + deny all; + root /var/www/admin; + } + } + ``` + +7. **Ограничение HTTP-методов** + - Требование для ТУ: Веб-сервер должен обеспечивать возможность ограничения использования HTTP-методов для защищаемых ресурсов. + - Механизм nginx: limit_except + - Комментарий: Позволяет ограничивать методы PUT, DELETE и другие методы, если они не требуются. + - Проверка: + - **Статус:** Подтверждено + - **Ревью требования:** Формулировка требования согласуется с возможностями nginx. + - **Вывод для ТУ:** Требование может быть включено в ТУ — nginx позволяет ограничивать HTTP-методы. + - **Источник:** https://nginx.org/en/docs/http/ngx_http_core_module.html#limit_except + - **Результат:** Директива `limit_except` задаёт методы, для которых применяются вложенные правила доступа. Методы, не перечисленные в блоке, обрабатываются без дополнительных ограничений. + - **Пример конфигурации:** + ```nginx + location /uploads/ { + limit_except GET HEAD { + deny all; + } + } + ``` + - **Минимальный аудит конфигурации:** + ```bash + nginx -T 2>/dev/null | grep -E 'limit_except|request_method' + ``` + - **Примечание:** См. `Минимизация поверхности атаки nginx — проверка.md` п. 11; `Проверочные мероприятия для ПМИ — проверка.md` п. 7. + +8. **Запрет прямого доступа к внутренним ресурсам** + - Требование для ТУ: Веб-сервер должен обеспечивать возможность запрета прямого доступа пользователя к внутренним ресурсам. + - Механизм nginx: internal + - Комментарий: Внутренние location-блоки доступны только для внутренних перенаправлений. + - Проверка: + - **Статус:** Подтверждено + - **Ревью требования:** Формулировка требования согласуется с возможностями nginx. + - **Вывод для ТУ:** Требование может быть включено в ТУ — nginx обеспечивает запрет прямого доступа к внутренним ресурсам. + - **Источник:** https://nginx.org/en/docs/http/ngx_http_core_module.html#internal + - **Результат:** Директива `internal` ограничивает доступ к location только для внутренних запросов (error_page, rewrite, X-Accel-Redirect и др.). Прямые клиентские запросы возвращают 404. + - **Пример конфигурации:** + ```nginx + location /protected/ { + internal; + alias /var/data/files/; + } + ``` + +9. **Защита соединения с использованием TLS** + - Требование для ТУ: Веб-сервер должен обеспечивать возможность защиты сетевого соединения с использованием TLS. + - Механизм nginx: ngx_http_ssl_module; ssl_certificate; ssl_certificate_key + - Комментарий: Используется для HTTPS-соединений. + - Проверка: + - **Статус:** Подтверждено с оговорками + - **Ревью требования:** Описание и механизм в целом адекватны; учтены оговорки сборки, конфигурации или эксплуатации. Модуль `ngx_http_ssl_module` обеспечивает HTTPS через `ssl_certificate` и `ssl_certificate_key`. + - **Вывод для ТУ:** Требование может быть включено в ТУ — nginx обеспечивает защиту соединения с использованием TLS. + - **Источник:** https://nginx.org/en/docs/http/ngx_http_ssl_module.html + - **Результат:** Модуль `ngx_http_ssl_module` обеспечивает HTTPS через `ssl_certificate` и `ssl_certificate_key`. Требуется сборка с `--with-http_ssl_module` и библиотека OpenSSL. + - **Пример конфигурации:** + ```nginx + server { + listen 443 ssl; + server_name example.com; + ssl_certificate /etc/nginx/ssl/example.com.crt; + ssl_certificate_key /etc/nginx/ssl/example.com.key; + } + ``` + +10. **Ограничение версий TLS и наборов шифров** + - Требование для ТУ: Веб-сервер должен обеспечивать возможность задания допустимых версий TLS и наборов шифров. + - Механизм nginx: ssl_protocols; ssl_ciphers + - Комментарий: Конкретные допустимые значения должны определяться политикой безопасности. + - Проверка: + - **Статус:** Подтверждено + - **Ревью требования:** Формулировка требования согласуется с возможностями nginx. Директивы `ssl_protocols` и `ssl_ciphers` позволяют ограничить версии протокола и наборы шифров. + - **Вывод для ТУ:** Требование может быть включено в ТУ — nginx позволяет задавать допустимые версии TLS и шифры; конкретные значения фиксируются в политике безопасности ТУ. + - **Источник:** https://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_protocols , https://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_ciphers + - **Результат:** Директивы `ssl_protocols` и `ssl_ciphers` позволяют ограничить версии протокола и наборы шифров. Формулировка требования ТУ корректна: nginx обеспечивает возможность задания, а конкретные значения определяются политикой. + - **Минимальный аудит конфигурации:** + ```bash +nginx -T 2>/dev/null | grep -E 'limit_except|request_method' + ``` + - **Пример конфигурации:** + ```nginx + ssl_protocols TLSv1.2 TLSv1.3; + ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256; + ssl_prefer_server_ciphers on; + ``` + - **Примечание:** В ТУ отдельно зафиксировать допустимую криптографическую политику (версии TLS, список шифров). См. `Минимизация поверхности атаки nginx — проверка.md` п. 11; `Проверочные мероприятия для ПМИ — проверка.md` п. 7. + +11. **Принудительное использование HTTPS** + - Требование для ТУ: Веб-сервер должен обеспечивать возможность перенаправления HTTP-запросов на HTTPS. + - Механизм nginx: return 301/308; Strict-Transport-Security + - Комментарий: HSTS реализуется через HTTP-заголовок. + - Проверка: + - **Статус:** Подтверждено + - **Ревью требования:** Формулировка требования согласуется с возможностями nginx. Редирект HTTP→HTTPS реализуется директивой `return 301` или `308`. + - **Вывод для ТУ:** Требование может быть включено в ТУ — nginx обеспечивает перенаправление HTTP на HTTPS и заголовок HSTS. + - **Источник:** https://nginx.org/en/docs/http/ngx_http_rewrite_module.html#return , https://nginx.org/en/docs/http/ngx_http_headers_module.html#add_header + - **Результат:** Редирект HTTP→HTTPS реализуется директивой `return 301` или `308`. Заголовок `Strict-Transport-Security` добавляется через `add_header` в HTTPS-блоке. + - **Пример конфигурации:** + ```nginx + server { + listen 80; + server_name example.com; + return 301 https://$host$request_uri; + } + + server { + listen 443 ssl; + server_name example.com; + add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always; + } + ``` + +12. **Журналирование HTTP-запросов** + - Требование для ТУ: Веб-сервер должен обеспечивать регистрацию HTTP-запросов пользователей. + - Механизм nginx: access_log; log_format + - Комментарий: В журнале должны фиксироваться параметры, необходимые для анализа событий. + - Проверка: + - **Статус:** Подтверждено + - **Ревью требования:** Формулировка требования согласуется с возможностями nginx. Модуль `ngx_http_log_module` записывает access log. + - **Вывод для ТУ:** Требование может быть включено в ТУ — nginx обеспечивает регистрацию HTTP-запросов в настраиваемом формате. + - **Источник:** https://nginx.org/en/docs/http/ngx_http_log_module.html + - **Результат:** Модуль `ngx_http_log_module` записывает access log. Директива `log_format` позволяет задать поля, необходимые для анализа событий безопасности (IP, время, запрос, статус, user-agent и др.). + - **Пример конфигурации:** + ```nginx + log_format security '$remote_addr - $remote_user [$time_local] ' + '"$request" $status $body_bytes_sent ' + '"$http_referer" "$http_user_agent"'; + + access_log /var/log/nginx/access.log security; + ``` + +13. **Журналирование ошибок** + - Требование для ТУ: Веб-сервер должен обеспечивать регистрацию ошибок обработки запросов и ошибок конфигурации. + - Механизм nginx: error_log + - Комментарий: Используется для диагностики и анализа событий безопасности. + - Проверка: + - **Статус:** Подтверждено + - **Ревью требования:** Формулировка требования согласуется с возможностями nginx. Директива `error_log` задаёт файл журнала и уровень детализации (`warn`, `error`, `crit` и др. + - **Вывод для ТУ:** Требование может быть включено в ТУ — nginx обеспечивает регистрацию ошибок. + - **Источник:** https://nginx.org/en/docs/ngx_core_module.html#error_log + - **Результат:** Директива `error_log` задаёт файл журнала и уровень детализации (`warn`, `error`, `crit` и др.). Ошибки обработки запросов, конфигурации и взаимодействия с backend фиксируются в error log. + - **Пример конфигурации:** + ```nginx + error_log /var/log/nginx/error.log warn; + ``` + +14. **Передача журналов во внешнюю систему** + - Требование для ТУ: Веб-сервер должен обеспечивать возможность передачи журналов во внешнюю систему журналирования. + - Механизм nginx: syslog в access_log/error_log + - Комментарий: Используется для централизованного сбора событий. + - Проверка: + - **Статус:** Подтверждено + - **Ревью требования:** Формулировка требования согласуется с возможностями nginx. nginx поддерживает запись `access_log` и `error_log` в syslog с параметрами `server`, `facility`, `tag`, `severity`, что обеспечивает централизованный сбор событий во внешней системе журналирования. + - **Вывод для ТУ:** Требование может быть включено в ТУ — nginx поддерживает передачу журналов в syslog. + - **Источник:** https://nginx.org/en/docs/syslog.html + - **Результат:** nginx поддерживает запись `access_log` и `error_log` в syslog с параметрами `server`, `facility`, `tag`, `severity`, что обеспечивает централизованный сбор событий во внешней системе журналирования. + - **Пример конфигурации:** + ```nginx + error_log syslog:server=192.168.1.1:514,facility=local7,tag=nginx,severity=error; + access_log syslog:server=192.168.1.1:514,facility=local7,tag=nginx,severity=info security; + ``` + +15. **Ограничение частоты запросов** + - Требование для ТУ: Веб-сервер должен обеспечивать возможность ограничения частоты запросов от клиента. + - Механизм nginx: limit_req_zone; limit_req + - Комментарий: Снижает риск избыточной нагрузки и злоупотреблений. + - Проверка: + - **Статус:** Подтверждено + - **Ревью требования:** Формулировка требования согласуется с возможностями nginx. Модуль `ngx_http_limit_req_module` реализует ограничение частоты запросов по ключу (например, IP-адрес клиента) с использованием алгоритма leaky bucket. + - **Вывод для ТУ:** Требование может быть включено в ТУ — nginx обеспечивает ограничение частоты запросов. + - **Источник:** https://nginx.org/en/docs/http/ngx_http_limit_req_module.html + - **Результат:** Модуль `ngx_http_limit_req_module` реализует ограничение частоты запросов по ключу (например, IP-адрес клиента) с использованием алгоритма leaky bucket. + - **Пример конфигурации:** + ```nginx + http { + limit_req_zone $binary_remote_addr zone=one:10m rate=10r/s; + + server { + location / { + limit_req zone=one burst=20 nodelay; + } + } + } + ``` + +16. **Ограничение количества соединений** + - Требование для ТУ: Веб-сервер должен обеспечивать возможность ограничения количества одновременных соединений. + - Механизм nginx: limit_conn_zone; limit_conn + - Комментарий: Снижает риск исчерпания ресурсов. + - Проверка: + - **Статус:** Подтверждено + - **Ревью требования:** Формулировка требования согласуется с возможностями nginx. Модуль `ngx_http_limit_conn_module` ограничивает число одновременных соединений по заданному ключу, что соответствует требованию ТУ. + - **Вывод для ТУ:** Требование может быть включено в ТУ — nginx обеспечивает ограничение количества соединений. + - **Источник:** https://nginx.org/en/docs/http/ngx_http_limit_conn_module.html + - **Результат:** Модуль `ngx_http_limit_conn_module` ограничивает число одновременных соединений по заданному ключу, что соответствует требованию ТУ. + - **Пример конфигурации:** + ```nginx + http { + limit_conn_zone $binary_remote_addr zone=addr:10m; + + server { + location / { + limit_conn addr 10; + } + } + } + ``` + +17. **Ограничение размера клиентского запроса** + - Требование для ТУ: Веб-сервер должен обеспечивать возможность ограничения размера тела клиентского запроса. + - Механизм nginx: client_max_body_size + - Комментарий: Используется для защиты от чрезмерно больших запросов и нежелательных загрузок. + - Проверка: + - **Статус:** Подтверждено + - **Ревью требования:** Формулировка требования согласуется с возможностями nginx. Директива `client_max_body_size` задаёт максимальный размер тела запроса. + - **Вывод для ТУ:** Требование может быть включено в ТУ — nginx обеспечивает ограничение размера тела запроса. + - **Источник:** https://nginx.org/en/docs/http/ngx_http_core_module.html#client_max_body_size + - **Результат:** Директива `client_max_body_size` задаёт максимальный размер тела запроса. При превышении nginx возвращает 413 (Request Entity Too Large). + - **Пример конфигурации:** + ```nginx + server { + client_max_body_size 10m; + } + ``` + +18. **Настройка таймаутов соединений** + - Требование для ТУ: Веб-сервер должен обеспечивать возможность настройки таймаутов обработки клиентских соединений. + - Механизм nginx: client_header_timeout; client_body_timeout; send_timeout; keepalive_timeout + - Комментарий: Снижает риск удержания ресурсов медленными соединениями. + - Проверка: + - **Статус:** Подтверждено + - **Ревью требования:** Формулировка требования согласуется с возможностями nginx. Директивы `client_header_timeout`, `client_body_timeout`, `send_timeout` и `keepalive_timeout` позволяют задавать таймауты на разных этапах обработки клиентского соединения. + - **Вывод для ТУ:** Требование может быть включено в ТУ — nginx обеспечивает настройку таймаутов соединений. + - **Источник:** https://nginx.org/en/docs/http/ngx_http_core_module.html + - **Результат:** Директивы `client_header_timeout`, `client_body_timeout`, `send_timeout` и `keepalive_timeout` позволяют задавать таймауты на разных этапах обработки клиентского соединения. + - **Пример конфигурации:** + ```nginx + http { + client_header_timeout 10s; + client_body_timeout 10s; + send_timeout 10s; + keepalive_timeout 30s; + } + ``` + +19. **Сокрытие версии веб-сервера** + - Требование для ТУ: Веб-сервер должен обеспечивать возможность отключения раскрытия версии nginx в ответах сервера. + - Механизм nginx: server_tokens off + - Комментарий: Снижает объём информации, доступной внешнему пользователю. + - Проверка: + - **Статус:** Подтверждено + - **Ревью требования:** Формулировка требования согласуется с возможностями nginx. Директива `server_tokens off` убирает номер версии из заголовка `Server` и со страниц ошибок nginx. + - **Вывод для ТУ:** Требование может быть включено в ТУ — nginx позволяет отключить раскрытие версии. + - **Источник:** https://nginx.org/en/docs/http/ngx_http_core_module.html#server_tokens + - **Результат:** Директива `server_tokens off` убирает номер версии из заголовка `Server` и со страниц ошибок nginx. + - **Минимальный аудит конфигурации:** + ```bash +nginx -T 2>/dev/null | grep server_tokens + ``` + - **Пример конфигурации:** + ```nginx + http { + server_tokens off; + } + ``` + +20. **Управление страницами ошибок** + - Требование для ТУ: Веб-сервер должен обеспечивать возможность настройки пользовательских страниц ошибок. + - Механизм nginx: error_page + - Комментарий: Позволяет не раскрывать технические детали пользователю. + - Проверка: + - **Статус:** Подтверждено + - **Ревью требования:** Формулировка требования согласуется с возможностями nginx. Директива `error_page` перенаправляет обработку указанных кодов ошибок на пользовательские страницы, скрывая технические детали nginx. + - **Вывод для ТУ:** Требование может быть включено в ТУ — nginx обеспечивает настройку пользовательских страниц ошибок. + - **Источник:** https://nginx.org/en/docs/http/ngx_http_core_module.html#error_page + - **Результат:** Директива `error_page` перенаправляет обработку указанных кодов ошибок на пользовательские страницы, скрывая технические детали nginx. + - **Пример конфигурации:** + ```nginx + error_page 404 /custom_404.html; + error_page 500 502 503 504 /custom_50x.html; + + location = /custom_404.html { + root /var/www/errors; + internal; + } + ``` + +21. **Управление листингом директорий** + - Требование для ТУ: Веб-сервер должен обеспечивать возможность отключения листинга директорий. + - Механизм nginx: autoindex off + - Комментарий: В безопасной конфигурации листинг директорий должен быть отключён, если не требуется. + - Проверка: + - **Статус:** Подтверждено + - **Ревью требования:** Формулировка требования согласуется с возможностями nginx. По умолчанию `autoindex off`. Директива `autoindex off` явно отключает формирование листинга каталога, что соответствует требованию безопасной конфигурации. + - **Вывод для ТУ:** Требование может быть включено в ТУ — nginx позволяет отключить листинг директорий. + - **Источник:** https://nginx.org/en/docs/http/ngx_http_autoindex_module.html + - **Результат:** По умолчанию `autoindex off`. Директива `autoindex off` явно отключает формирование листинга каталога, что соответствует требованию безопасной конфигурации. + - **Минимальный аудит конфигурации:** + ```bash +nginx -T 2>/dev/null | grep autoindex + ``` + - **Пример конфигурации:** + ```nginx + server { + autoindex off; + root /var/www/html; + } + ``` + - **Примечание:** См. `Минимизация поверхности атаки nginx — проверка.md` п. 10; `Проверочные мероприятия для ПМИ — проверка.md` п. 21. + +22. **Обратное проксирование backend-сервисов** + - Требование для ТУ: Веб-сервер должен обеспечивать возможность изоляции backend-сервисов через обратное проксирование. + - Механизм nginx: proxy_pass; proxy_set_header + - Комментарий: Backend-сервисы не должны быть доступны напрямую, если это предусмотрено архитектурой. + - Проверка: + - **Статус:** Подтверждено + - **Ревью требования:** Формулировка требования согласуется с возможностями nginx. Модуль `ngx_http_proxy_module` передаёт запросы на внутренние backend-сервисы. + - **Вывод для ТУ:** Требование может быть включено в ТУ — nginx обеспечивает изоляцию backend через обратное проксирование. + - **Источник:** https://nginx.org/en/docs/http/ngx_http_proxy_module.html + - **Результат:** Модуль `ngx_http_proxy_module` передаёт запросы на внутренние backend-сервисы. `proxy_set_header` позволяет корректно передавать адрес клиента. Backend может быть недоступен напрямую извне при правильной сетевой архитектуре. + - **Пример конфигурации:** + ```nginx + location /api/ { + proxy_pass http://127.0.0.1:8080; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + } + ``` + +23. **Управление директориями веб-контента** + - Требование для ТУ: Веб-сервер должен обеспечивать возможность задания разрешённых директорий веб-контента. + - Механизм nginx: root; alias; location; try_files + - Комментарий: Требует безопасной настройки, чтобы исключить доступ к произвольным каталогам ОС. + - Проверка: + - **Статус:** Подтверждено + - **Ревью требования:** Формулировка требования согласуется с возможностями nginx. Директивы `root`, `alias`, `location` и `try_files` позволяют ограничить область обслуживаемого контента. + - **Вывод для ТУ:** Требование может быть включено в ТУ — nginx позволяет задавать разрешённые директории веб-контента через конфигурацию. + - **Источник:** https://nginx.org/en/docs/http/ngx_http_core_module.html#root , https://nginx.org/en/docs/http/ngx_http_core_module.html#alias + - **Результат:** Директивы `root`, `alias`, `location` и `try_files` позволяют ограничить область обслуживаемого контента. Встроенного allowlist нет — перечень разрешённых директорий фиксируется в ТУ и реализуется конфигурацией. + - **Пример конфигурации:** + ```nginx + server { + root /var/www/app/public; + + location / { + try_files $uri =404; + } + + location ~ /\. { + deny all; + } + } + ``` + - **Примечание:** В ТУ зафиксировать перечень разрешённых директорий веб-контента. См. `Минимизация поверхности атаки nginx — проверка.md` п. 10; `Проверочные мероприятия для ПМИ — проверка.md` п. 21. + +24. **Минимизация поверхности атаки** + - Требование для ТУ: Поставка и конфигурация веб-сервера должны обеспечивать возможность минимизации поверхности атаки за счёт исключения, отделения или незагрузки неиспользуемых модулей и функциональных возможностей. + - Механизм nginx: параметры сборки; dynamic modules; load_module; конфигурация nginx + - Комментарий: Конкретные меры определяются по составу поставки и целевой конфигурации. + - Проверка: + - **Статус:** Подтверждено с оговорками + - **Ревью требования:** Описание и механизм в целом адекватны; учтены оговорки сборки, конфигурации или эксплуатации. nginx позволяет исключать модули при сборке (`. + - **Вывод для ТУ:** Требование может быть включено в ТУ как проектно-эксплуатационное — nginx предоставляет механизмы минимизации поверхности атаки; конкретные меры фиксируются в ТУ по составу поставки. + - **Источник:** https://nginx.org/en/docs/configure.html , https://nginx.org/en/docs/ngx_core_module.html#load_module + - **Результат:** nginx позволяет исключать модули при сборке (`./configure --without-...`), не загружать неиспользуемые динамические модули (`load_module`) и отключать возможности конфигурацией (`autoindex off`, удаление лишних `location`). Конкретный перечень мер определяется целевой конфигурацией и должен быть зафиксирован в ТУ. + - **Пример конфигурации:** + ```nginx + # Загрузка только утверждённых динамических модулей + # load_module modules/ngx_http_geoip_module.so; + + http { + autoindex off; + server_tokens off; + # Неиспользуемые proxy/fastcgi-направления не включаются + } + ``` + - **Примечание:** В ТУ указать: состав модулей поставки, запрет загрузки неутверждённых `.so`, перечень отключённых возможностей конфигурации. См. `Минимизация поверхности атаки nginx — проверка.md` п. 1–15. diff --git a/docs/функции безопасности — проверка.md b/docs/функции безопасности — проверка.md new file mode 100644 index 0000000..b6a2e6d --- /dev/null +++ b/docs/функции безопасности — проверка.md @@ -0,0 +1,743 @@ +# Функции безопасности nginx — результаты проверки + +**Дата проверки:** 10.06.2026 +**Объект проверки:** upstream nginx (официальная документация nginx.org) +**Метод:** анализ официальной документации и составление примеров конфигурации (без практических тестов на работающем экземпляре) + +## Сводная таблица + +| № | Функция безопасности | Статус | Модуль / механизм | +|---|---------------------|--------|-------------------| +| 1.1 | Ограничение доступа по IP-адресу | Подтверждено | ngx_http_access_module; allow; deny | +| 1.2 | Аутентификация по имени пользователя и паролю | Подтверждено | ngx_http_auth_basic_module; auth_basic; auth_basic_user_file | +| 1.3 | Аутентификация по клиентскому TLS-сертификату | Подтверждено с оговорками | ngx_http_ssl_module; ssl_verify_client | +| 1.4 | Авторизация через внешний сервис | Подтверждено с оговорками | ngx_http_auth_request_module; auth_request | +| 1.5 | Комбинирование нескольких проверок доступа | Подтверждено | satisfy; access; auth_basic; auth_request | +| 2.1 | Разделение правил по виртуальным серверам и путям | Подтверждено | ngx_http_core_module; server; location | +| 2.2 | Ограничение HTTP-методов | Подтверждено | ngx_http_core_module; limit_except | +| 2.3 | Запрет доступа к служебным и скрытым файлам | Подтверждено | location; deny all | +| 2.4 | Запрет прямого доступа к внутренним ресурсам | Подтверждено | ngx_http_core_module; internal | +| 3.1 | Поддержка HTTPS/TLS | Подтверждено с оговорками | ngx_http_ssl_module; ssl_certificate | +| 3.2 | Ограничение версий TLS и шифров | Подтверждено | ngx_http_ssl_module; ssl_protocols; ssl_ciphers | +| 3.3 | Проверка клиентского сертификата | Подтверждено | ssl_client_certificate; ssl_verify_client | +| 3.4 | Принудительное использование HTTPS | Подтверждено | return 301/308; Strict-Transport-Security | +| 4.1 | Журналирование HTTP-запросов | Подтверждено | ngx_http_log_module; access_log | +| 4.2 | Журналирование ошибок | Подтверждено | error_log | +| 4.3 | Настройка формата журналов | Подтверждено | log_format | +| 4.4 | Передача журналов в syslog | Подтверждено | access_log syslog; error_log syslog | +| 5.1 | Ограничение частоты запросов | Подтверждено | ngx_http_limit_req_module; limit_req | +| 5.2 | Ограничение количества соединений | Подтверждено | ngx_http_limit_conn_module; limit_conn | +| 5.3 | Ограничение размера клиентского запроса | Подтверждено | ngx_http_core_module; client_max_body_size | +| 5.4 | Ограничение скорости отдачи данных | Подтверждено | ngx_http_core_module; limit_rate | +| 5.5 | Настройка таймаутов соединений | Подтверждено | client_*_timeout; send_timeout; keepalive_timeout | +| 6.1 | Сокрытие версии nginx | Подтверждено | server_tokens off | +| 6.2 | Управление страницами ошибок | Подтверждено | error_page | +| 6.3 | Управление листингом директорий | Подтверждено | ngx_http_autoindex_module; autoindex | +| 7.1 | Обратное проксирование HTTP/HTTPS | Подтверждено | ngx_http_proxy_module; proxy_pass | +| 7.2 | Балансировка и группы upstream | Подтверждено | ngx_http_upstream_module; upstream | +| 7.3 | Управление заголовками при проксировании | Подтверждено | proxy_set_header | +| 8.1 | Задание корневой директории сайта | Подтверждено | ngx_http_core_module; root | +| 8.2 | Задание альтернативного пути для location | Подтверждено | ngx_http_core_module; alias | +| 8.3 | Проверка существования файлов и маршрутизация | Подтверждено | ngx_http_core_module; try_files | +| 8.4 | Ограничение доступа к произвольным каталогам ОС | Подтверждено | root; alias; location; права ФС | +| 9.1 | Исключение неиспользуемых модулей | Подтверждено | configure; load_module | +| 9.2 | Отключение неиспользуемых возможностей конфигурацией | Подтверждено | конфигурация nginx | +| 9.3 | Контроль целостности конфигурации и разрешённых директорий | Не применимо к nginx напрямую (внешняя мера) | afick или иной FIM | + +--- + +- **1. Идентификация и аутентификация** + - **1.1 Ограничение доступа по IP-адресу** + - Описание реализации: nginx позволяет ограничивать доступ к ресурсам по IP-адресам клиентов. Для этого используются правила разрешения и запрета доступа. + - Модуль / механизм: ngx_http_access_module; директивы allow, deny + - Комментарий: Подтверждено официальной документацией nginx: модуль предназначен для ограничения доступа по адресам клиентов. + - Проверка: + - **Статус:** Подтверждено + - **Ревью функции:** Описание реализации и заявленный механизм соответствуют документации nginx. Модуль `ngx_http_access_module` входит в стандартную сборку nginx. + - **Источник:** https://nginx.org/en/docs/http/ngx_http_access_module.html + - **Результат:** Модуль `ngx_http_access_module` входит в стандартную сборку nginx. Директивы `allow` и `deny` задают правила доступа по IP-адресу, сети CIDR, `all` или `unix:`. Правила обрабатываются последовательно; первое совпавшее правило определяет результат. + - **Пример конфигурации:** + ```nginx + location /admin/ { + allow 192.168.1.0/24; + allow 10.0.0.1; + deny all; + } + ``` + - **1.2 Аутентификация по имени пользователя и паролю** + - Описание реализации: nginx поддерживает HTTP Basic Authentication: пользователь вводит имя и пароль, nginx проверяет их по файлу пользователей. + - Модуль / механизм: ngx_http_auth_basic_module; директивы auth_basic, auth_basic_user_file + - Комментарий: Подтверждено официальной документацией nginx: модуль валидирует имя пользователя и пароль по протоколу HTTP Basic Authentication. + - Проверка: + - **Статус:** Подтверждено + - **Ревью функции:** Описание реализации и заявленный механизм соответствуют документации nginx. Модуль `ngx_http_auth_basic_module` реализует HTTP Basic Authentication. + - **Источник:** https://nginx.org/en/docs/http/ngx_http_auth_basic_module.html + - **Результат:** Модуль `ngx_http_auth_basic_module` реализует HTTP Basic Authentication. Директива `auth_basic` включает аутентификацию и задаёт текстовое сообщение для диалога; `auth_basic_user_file` указывает файл с парами «пользователь:хеш_пароля» (формат htpasswd). + - **Пример конфигурации:** + ```nginx + location /secure/ { + auth_basic "Restricted Area"; + auth_basic_user_file /etc/nginx/htpasswd; + } + ``` + - **Примечание:** Файл паролей создаётся утилитой `htpasswd` (пакет apache2-utils или httpd-tools). + - **1.3 Аутентификация по клиентскому TLS-сертификату** + - Описание реализации: nginx может запрашивать и проверять клиентский сертификат при HTTPS-соединении. + - Модуль / механизм: ngx_http_ssl_module; директивы ssl_client_certificate, ssl_verify_client, ssl_verify_depth + - Комментарий: Реализуется через SSL/TLS-модуль nginx. Сам SSL-модуль требует включения при сборке и использует OpenSSL. + - Проверка: + - **Статус:** Подтверждено с оговорками + - **Ревью функции:** Описание и механизм в целом адекватны; учтены оговорки сборки, конфигурации или эксплуатации. Модуль `ngx_http_ssl_module` поддерживает проверку клиентских сертификатов. + - **Источник:** https://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_verify_client + - **Результат:** Модуль `ngx_http_ssl_module` поддерживает проверку клиентских сертификатов. Директива `ssl_verify_client on` требует обязательного предъявления и проверки сертификата; `ssl_client_certificate` задаёт файл доверенного CA; `ssl_verify_depth` ограничивает глубину цепочки. Модуль требует сборки с `--with-http_ssl_module` и библиотекой OpenSSL. + - **Пример конфигурации:** + ```nginx + server { + listen 443 ssl; + ssl_certificate /etc/nginx/ssl/server.crt; + ssl_certificate_key /etc/nginx/ssl/server.key; + ssl_client_certificate /etc/nginx/ssl/ca.crt; + ssl_verify_client on; + ssl_verify_depth 2; + } + ``` + - **Примечание:** Акцент на идентификации клиента; для контекста защиты канала см. также п. 3.3. + - **1.4 Авторизация через внешний сервис** + - Описание реализации: nginx может выполнять подзапрос во внешний сервис авторизации и разрешать или запрещать доступ по результату ответа. + - Модуль / механизм: ngx_http_auth_request_module; директивы auth_request, auth_request_set + - Комментарий: Модуль официально поддерживается, но в upstream nginx не собирается по умолчанию и должен включаться параметром сборки --with-http_auth_request_module. + - Проверка: + - **Статус:** Подтверждено с оговорками + - **Ревью функции:** Описание и механизм в целом адекватны; учтены оговорки сборки, конфигурации или эксплуатации. Модуль `ngx_http_auth_request_module` выполняет подзапрос к указанному URI; + - **Источник:** https://nginx.org/en/docs/http/ngx_http_auth_request_module.html + - **Результат:** Модуль `ngx_http_auth_request_module` выполняет подзапрос к указанному URI; доступ разрешается при ответе 2xx, запрещается при 401/403. Директива `auth_request_set` позволяет передать значения из заголовков ответа авторизационного сервиса в переменные nginx. В официальной сборке модуль включается флагом `--with-http_auth_request_module`; в большинстве дистрибутивных пакетов он уже присутствует. + - **Пример конфигурации:** + ```nginx + location = /auth { + internal; + proxy_pass http://auth-service:8080/validate; + proxy_pass_request_body off; + proxy_set_header Content-Length ""; + proxy_set_header X-Original-URI $request_uri; + } + + location / { + auth_request /auth; + proxy_pass http://backend; + } + ``` + - **Примечание:** См. `Требования безопасности для включения в ТУ — проверка.md` п. 4; `Минимизация поверхности атаки nginx — проверка.md` п. 4. + - **1.5 Комбинирование нескольких проверок доступа** + - Описание реализации: nginx позволяет комбинировать несколько механизмов проверки доступа, например ограничение по IP и Basic Authentication. + - Модуль / механизм: satisfy; совместно с access, auth_basic, auth_request + - Комментарий: В документации nginx указано, что одновременное ограничение доступа по адресу, паролю и подзапросу управляется директивой satisfy. + - Проверка: + - **Статус:** Подтверждено + - **Ревью функции:** Описание реализации и заявленный механизм соответствуют документации nginx. Директива `satisfy` управляет логикой комбинирования проверок `allow`/`deny`, `auth_basic` и `auth_request`. + - **Источник:** https://nginx.org/en/docs/http/ngx_http_core_module.html#satisfy + - **Результат:** Директива `satisfy` управляет логикой комбинирования проверок `allow`/`deny`, `auth_basic` и `auth_request`. Значение `all` (по умолчанию) требует прохождения всех проверок; значение `any` — достаточно одной успешной. + - **Пример конфигурации:** + ```nginx + location /admin/ { + satisfy all; + allow 192.168.1.0/24; + deny all; + auth_basic "Admin Area"; + auth_basic_user_file /etc/nginx/htpasswd; + } + ``` + - **Примечание:** См. `Требования безопасности для включения в ТУ — проверка.md` п. 4; `Минимизация поверхности атаки nginx — проверка.md` п. 4. + +- **2. Разграничение доступа к ресурсам** + - **2.1 Разделение правил по виртуальным серверам и путям** + - Описание реализации: nginx позволяет задавать разные правила обработки и доступа для разных виртуальных серверов и URL-путей. + - Модуль / механизм: ngx_http_core_module; блоки server, location + - Комментарий: Это базовый механизм конфигурации nginx. Используется для разделения публичных, служебных и закрытых разделов сайта. + - Проверка: + - **Статус:** Подтверждено + - **Ревью функции:** Описание реализации и заявленный механизм соответствуют документации nginx. Блоки `server` определяют виртуальные хосты (по `listen`, `server_name`), блоки `location` — правила для URI-префиксов, регулярных выражений и точных совпадений. + - **Источник:** https://nginx.org/en/docs/http/ngx_http_core_module.html#server , https://nginx.org/en/docs/http/ngx_http_core_module.html#location + - **Результат:** Блоки `server` определяют виртуальные хосты (по `listen`, `server_name`), блоки `location` — правила для URI-префиксов, регулярных выражений и точных совпадений. Это базовый механизм разграничения доступа и обработки запросов. + - **Пример конфигурации:** + ```nginx + server { + listen 80; + server_name public.example.com; + location / { + root /var/www/public; + } + } + + server { + listen 80; + server_name admin.example.com; + location / { + allow 10.0.0.0/8; + deny all; + root /var/www/admin; + } + } + ``` + - **2.2 Ограничение HTTP-методов** + - Описание реализации: nginx позволяет задавать отдельные правила доступа для методов, отличных от явно разрешённых. + - Модуль / механизм: ngx_http_core_module; директива limit_except + - Комментарий: Используется для ограничения методов вроде PUT, DELETE, если они не требуются приложению. + - Проверка: + - **Статус:** Подтверждено + - **Ревью функции:** Описание реализации и заявленный механизм соответствуют документации nginx. Директива `limit_except` задаёт методы, для которых применяются вложенные директивы доступа. + - **Источник:** https://nginx.org/en/docs/http/ngx_http_core_module.html#limit_except + - **Результат:** Директива `limit_except` задаёт методы, для которых применяются вложенные директивы доступа. Методы, не перечисленные в `limit_except`, обрабатываются без дополнительных ограничений внутри данного блока. + - **Минимальный аудит конфигурации:** + ```bash +nginx -T 2>/dev/null | grep -E 'limit_except|request_method' + ``` + - **Пример конфигурации:** + ```nginx + location /uploads/ { + limit_except GET HEAD { + deny all; + } + } + ``` + - **2.3 Запрет доступа к служебным и скрытым файлам** + - Описание реализации: nginx позволяет запрещать доступ к отдельным путям и шаблонам URI через правила location и deny all. + - Модуль / механизм: location, регулярные выражения, deny all + - Комментарий: Это не отдельный модуль безопасности, а конфигурационный механизм безопасной настройки. + - Проверка: + - **Статус:** Подтверждено + - **Ревью функции:** Описание реализации и заявленный механизм соответствуют документации nginx. Комбинация `location` с регулярными выражениями и `deny all` позволяет блокировать доступ к скрытым файлам (`. + - **Источник:** https://nginx.org/en/docs/http/ngx_http_access_module.html , https://nginx.org/en/docs/http/ngx_http_core_module.html#location + - **Результат:** Комбинация `location` с регулярными выражениями и `deny all` позволяет блокировать доступ к скрытым файлам (`.git`, `.env`, `.htaccess` и т.п.). Это стандартный конфигурационный паттерн безопасности. + - **Пример конфигурации:** + ```nginx + location ~ /\. { + deny all; + access_log off; + log_not_found off; + } + + location ~* \.(bak|sql|log|conf)$ { + deny all; + } + ``` + - **2.4 Запрет прямого доступа к внутренним ресурсам** + - Описание реализации: nginx поддерживает внутренние location-блоки, которые недоступны напрямую клиенту и могут использоваться только для внутренних перенаправлений. + - Модуль / механизм: ngx_http_core_module; директива internal + - Комментарий: Применяется для скрытия служебных маршрутов и файлов от прямого обращения пользователя. + - Проверка: + - **Статус:** Подтверждено + - **Ревью функции:** Описание реализации и заявленный механизм соответствуют документации nginx. Директива `internal` ограничивает доступ к location только для внутренних запросов (error_page, rewrite, auth_request, X-Accel-Redirect и др. + - **Источник:** https://nginx.org/en/docs/http/ngx_http_core_module.html#internal + - **Результат:** Директива `internal` ограничивает доступ к location только для внутренних запросов (error_page, rewrite, auth_request, X-Accel-Redirect и др.). Прямые клиентские запросы к такому location возвращают 404. + - **Пример конфигурации:** + ```nginx + location /protected-files/ { + internal; + alias /var/data/files/; + } + + location /download { + # Клиент обращается сюда; nginx внутренне отдаёт файл + rewrite ^ /protected-files/document.pdf last; + } + ``` + +- **3. Защита соединения и передаваемых данных** + - **3.1 Поддержка HTTPS/TLS** + - Описание реализации: nginx поддерживает HTTPS при наличии SSL-модуля. Можно задавать сертификаты, ключи, версии TLS и наборы шифров. + - Модуль / механизм: ngx_http_ssl_module; ssl_certificate, ssl_certificate_key, ssl_protocols, ssl_ciphers + - Комментарий: SSL-модуль nginx предоставляет поддержку HTTPS, требует OpenSSL и должен быть включён при сборке. + - Проверка: + - **Статус:** Подтверждено с оговорками + - **Ревью функции:** Описание и механизм в целом адекватны; учтены оговорки сборки, конфигурации или эксплуатации. Модуль `ngx_http_ssl_module` обеспечивает HTTPS. + - **Источник:** https://nginx.org/en/docs/http/ngx_http_ssl_module.html + - **Результат:** Модуль `ngx_http_ssl_module` обеспечивает HTTPS. Директивы `ssl_certificate` и `ssl_certificate_key` задают серверный сертификат и ключ; `ssl_protocols` и `ssl_ciphers` — параметры TLS. Модуль требует OpenSSL и включения при сборке (`--with-http_ssl_module`). + - **Пример конфигурации:** + ```nginx + server { + listen 443 ssl; + server_name example.com; + ssl_certificate /etc/nginx/ssl/example.com.crt; + ssl_certificate_key /etc/nginx/ssl/example.com.key; + ssl_protocols TLSv1.2 TLSv1.3; + ssl_ciphers HIGH:!aNULL:!MD5; + } + ``` + - **3.2 Ограничение версий TLS и шифров** + - Описание реализации: nginx позволяет задавать допустимые версии TLS и наборы шифров. + - Модуль / механизм: ngx_http_ssl_module; ssl_protocols, ssl_ciphers + - Комментарий: Для ТУ/ПМИ нужно отдельно фиксировать допустимую криптографическую политику. + - Проверка: + - **Статус:** Подтверждено + - **Ревью функции:** Описание реализации и заявленный механизм соответствуют документации nginx. Директива `ssl_protocols` задаёт разрешённые версии протокола (TLSv1. + - **Источник:** https://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_protocols , https://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_ciphers + - **Результат:** Директива `ssl_protocols` задаёт разрешённые версии протокола (TLSv1.2, TLSv1.3 и др.); `ssl_ciphers` — список шифронаборов в формате OpenSSL. Дополнительно доступны `ssl_prefer_server_ciphers` и параметры для TLS 1.3 (`ssl_conf_command` в новых версиях). + - **Пример конфигурации:** + ```nginx + ssl_protocols TLSv1.2 TLSv1.3; + ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256; + ssl_prefer_server_ciphers on; + ``` + - **Примечание:** Конкретная криптографическая политика должна быть зафиксирована в ТУ/ПМИ отдельно. + - **3.3 Проверка клиентского сертификата** + - Описание реализации: nginx может проверять клиентские TLS-сертификаты по доверенному центру сертификации. + - Модуль / механизм: ssl_client_certificate, ssl_verify_client + - Комментарий: Может использоваться как механизм строгой аутентификации клиента. + - Проверка: + - **Статус:** Подтверждено + - **Ревью функции:** Описание реализации и заявленный механизм соответствуют документации nginx. Директива `ssl_verify_client` поддерживает значения `on`, `off`, `optional`, `optional_no_ca`. + - **Источник:** https://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_verify_client + - **Результат:** Директива `ssl_verify_client` поддерживает значения `on`, `off`, `optional`, `optional_no_ca`. При `on` клиент обязан предъявить сертификат, подписанный доверенным CA из `ssl_client_certificate`. Режим `optional` запрашивает сертификат, но не прерывает соединение при его отсутствии. + - **Пример конфигурации:** + ```nginx + server { + listen 443 ssl; + ssl_certificate /etc/nginx/ssl/server.crt; + ssl_certificate_key /etc/nginx/ssl/server.key; + ssl_client_certificate /etc/nginx/ssl/client-ca.crt; + ssl_verify_client optional; + ssl_verify_depth 3; + } + ``` + - **Примечание:** В отличие от п. 1.3, здесь акцент на защите канала и политике доверия к клиентским сертификатам. + - **3.4 Принудительное использование HTTPS** + - Описание реализации: nginx может перенаправлять HTTP-запросы на HTTPS и добавлять заголовки безопасности. + - Модуль / механизм: return 301/308; add_header Strict-Transport-Security + - Комментарий: HSTS реализуется через HTTP-заголовок, а не отдельным модулем безопасности. + - Проверка: + - **Статус:** Подтверждено + - **Ревью функции:** Описание реализации и заявленный механизм соответствуют документации nginx. Редирект HTTP→HTTPS реализуется директивой `return` (301 или 308). + - **Источник:** https://nginx.org/en/docs/http/ngx_http_rewrite_module.html#return , https://nginx.org/en/docs/http/ngx_http_headers_module.html#add_header + - **Результат:** Редирект HTTP→HTTPS реализуется директивой `return` (301 или 308). Заголовок HSTS (`Strict-Transport-Security`) добавляется через `add_header` в HTTPS-блоке. Отдельного модуля HSTS в nginx нет. + - **Пример конфигурации:** + ```nginx + server { + listen 80; + server_name example.com; + return 301 https://$host$request_uri; + } + + server { + listen 443 ssl; + server_name example.com; + add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always; + } + ``` + +- **4. Регистрация событий и аудит** + - **4.1 Журналирование HTTP-запросов** + - Описание реализации: nginx ведёт журнал HTTP-запросов в настраиваемом формате. + - Модуль / механизм: ngx_http_log_module; access_log, log_format + - Комментарий: Официальный модуль nginx записывает request logs в заданном формате. + - Проверка: + - **Статус:** Подтверждено + - **Ревью функции:** Описание реализации и заявленный механизм соответствуют документации nginx. Модуль `ngx_http_log_module` записывает access log. + - **Источник:** https://nginx.org/en/docs/http/ngx_http_log_module.html + - **Результат:** Модуль `ngx_http_log_module` записывает access log. Директива `access_log` задаёт путь (или syslog) и формат; по умолчанию используется формат `combined`. Журналирование можно отключить (`access_log off`) на уровне server/location. + - **Пример конфигурации:** + ```nginx + http { + access_log /var/log/nginx/access.log combined; + } + ``` + - **4.2 Журналирование ошибок** + - Описание реализации: nginx ведёт журнал ошибок, где фиксируются проблемы обработки запросов, конфигурации и взаимодействия с backend. + - Модуль / механизм: error_log + - Комментарий: Официальная документация указывает, что nginx пишет error log и позволяет задавать место и уровень журналирования. + - Проверка: + - **Статус:** Подтверждено + - **Ревью функции:** Описание реализации и заявленный механизм соответствуют документации nginx. Директива `error_log` задаёт файл (или syslog) и уровень детализации: `debug`, `info`, `notice`, `warn`, `error`, `crit`, `alert`, `emerg`. + - **Источник:** https://nginx.org/en/docs/ngx_core_module.html#error_log + - **Результат:** Директива `error_log` задаёт файл (или syslog) и уровень детализации: `debug`, `info`, `notice`, `warn`, `error`, `crit`, `alert`, `emerg`. Уровень по умолчанию — `error`. + - **Пример конфигурации:** + ```nginx + error_log /var/log/nginx/error.log warn; + ``` + - **4.3 Настройка формата журналов** + - Описание реализации: nginx позволяет задавать собственный формат access log с нужными полями. + - Модуль / механизм: log_format + - Комментарий: Для ПМИ можно проверять наличие обязательных полей в журнале. + - Проверка: + - **Статус:** Подтверждено + - **Ревью функции:** Описание реализации и заявленный механизм соответствуют документации nginx. Директива `log_format` определяет именованный формат с произвольным набором переменных (`$remote_addr`, `$request`, `$status`, `$body_bytes_sent`, `$http_user_agent` и др. + - **Источник:** https://nginx.org/en/docs/http/ngx_http_log_module.html#log_format + - **Результат:** Директива `log_format` определяет именованный формат с произвольным набором переменных (`$remote_addr`, `$request`, `$status`, `$body_bytes_sent`, `$http_user_agent` и др.). Формат применяется в `access_log`. + - **Пример конфигурации:** + ```nginx + log_format audit '$remote_addr - $remote_user [$time_local] ' + '"$request" $status $body_bytes_sent ' + '"$http_referer" "$http_user_agent" ' + '$request_time $upstream_response_time'; + + access_log /var/log/nginx/audit.log audit; + ``` + - **4.4 Передача журналов в syslog** + - Описание реализации: nginx поддерживает запись access_log и error_log в syslog. + - Модуль / механизм: access_log syslog:...; error_log syslog:... + - Комментарий: Подтверждено официальной документацией nginx по syslog. + - Проверка: + - **Статус:** Подтверждено + - **Ревью функции:** Описание реализации и заявленный механизм соответствуют документации nginx. nginx поддерживает запись `access_log` и `error_log` в syslog с параметрами `server`, `facility`, `tag`, `severity`. + - **Источник:** https://nginx.org/en/docs/syslog.html + - **Результат:** nginx поддерживает запись `access_log` и `error_log` в syslog с параметрами `server`, `facility`, `tag`, `severity`. Формат: `syslog:server=address[,parameter=value]`. + - **Пример конфигурации:** + ```nginx + error_log syslog:server=192.168.1.1:514,facility=local7,tag=nginx,severity=error; + + access_log syslog:server=192.168.1.1:514,facility=local7,tag=nginx,severity=info combined; + ``` + - **Примечание:** См. ПМИ п. 14 в `Проверочные мероприятия для ПМИ — проверка.md`; `Контроль целостности хранимого кода и конфигурации — проверка.md` п. 13; `Минимально необходимые полномочия nginx — проверка.md` п. 5. + +- **5. Ограничение нагрузки и защита от избыточных запросов** + - **5.1 Ограничение частоты запросов** + - Описание реализации: nginx может ограничивать частоту обработки запросов по заданному ключу, например по IP-адресу клиента. + - Модуль / механизм: ngx_http_limit_req_module; limit_req_zone, limit_req + - Комментарий: Модуль использует метод leaky bucket и официально предназначен для ограничения request rate. + - Проверка: + - **Статус:** Подтверждено + - **Ревью функции:** Описание реализации и заявленный механизм соответствуют документации nginx. Модуль `ngx_http_limit_req_module` реализует алгоритм leaky bucket. + - **Источник:** https://nginx.org/en/docs/http/ngx_http_limit_req_module.html + - **Результат:** Модуль `ngx_http_limit_req_module` реализует алгоритм leaky bucket. `limit_req_zone` определяет зону и ключ (например, `$binary_remote_addr`); `limit_req` применяет ограничение с параметрами `rate` и `burst`. + - **Пример конфигурации:** + ```nginx + http { + limit_req_zone $binary_remote_addr zone=one:10m rate=10r/s; + + server { + location / { + limit_req zone=one burst=20 nodelay; + } + } + } + ``` + - **Примечание:** См. `Требования безопасности для включения в ТУ — проверка.md` п. 15; `Проверочные мероприятия для ПМИ — проверка.md` п. 15. + - **5.2 Ограничение количества соединений** + - Описание реализации: nginx может ограничивать количество соединений по заданному ключу, например по IP-адресу клиента. + - Модуль / механизм: ngx_http_limit_conn_module; limit_conn_zone, limit_conn + - Комментарий: Официальный модуль ограничивает количество соединений per defined key. + - Проверка: + - **Статус:** Подтверждено + - **Ревью функции:** Описание реализации и заявленный механизм соответствуют документации nginx. Модуль `ngx_http_limit_conn_module` ограничивает число одновременных соединений по ключу. + - **Источник:** https://nginx.org/en/docs/http/ngx_http_limit_conn_module.html + - **Результат:** Модуль `ngx_http_limit_conn_module` ограничивает число одновременных соединений по ключу. `limit_conn_zone` задаёт зону; `limit_conn` применяет лимит. + - **Пример конфигурации:** + ```nginx + http { + limit_conn_zone $binary_remote_addr zone=addr:10m; + + server { + location / { + limit_conn addr 10; + } + } + } + ``` + - **Примечание:** См. `Требования безопасности для включения в ТУ — проверка.md` п. 16; `Проверочные мероприятия для ПМИ — проверка.md` п. 16. + - **5.3 Ограничение размера клиентского запроса** + - Описание реализации: nginx позволяет ограничивать максимальный размер тела клиентского запроса. + - Модуль / механизм: ngx_http_core_module; client_max_body_size + - Комментарий: Используется для защиты от чрезмерно больших запросов и нежелательных загрузок. + - Проверка: + - **Статус:** Подтверждено + - **Ревью функции:** Описание реализации и заявленный механизм соответствуют документации nginx. Директива `client_max_body_size` задаёт максимальный размер тела запроса. + - **Источник:** https://nginx.org/en/docs/http/ngx_http_core_module.html#client_max_body_size + - **Результат:** Директива `client_max_body_size` задаёт максимальный размер тела запроса. Значение по умолчанию — 1m. При превышении nginx возвращает 413 (Request Entity Too Large). + - **Пример конфигурации:** + ```nginx + server { + client_max_body_size 10m; + } + ``` + - **Примечание:** См. `Требования безопасности для включения в ТУ — проверка.md` п. 15; `Проверочные мероприятия для ПМИ — проверка.md` п. 15. + - **5.4 Ограничение скорости отдачи данных** + - Описание реализации: nginx позволяет ограничивать скорость передачи ответа клиенту. + - Модуль / механизм: ngx_http_core_module; limit_rate + - Комментарий: Используется для управления нагрузкой и потреблением ресурсов. + - Проверка: + - **Статус:** Подтверждено + - **Ревью функции:** Описание реализации и заявленный механизм соответствуют документации nginx. Директива `limit_rate` ограничивает скорость отдачи ответа клиенту (байт/с). + - **Источник:** https://nginx.org/en/docs/http/ngx_http_core_module.html#limit_rate + - **Результат:** Директива `limit_rate` ограничивает скорость отдачи ответа клиенту (байт/с). Дополнительно `limit_rate_after` позволяет отдавать начальный объём без ограничения. + - **Пример конфигурации:** + ```nginx + location /downloads/ { + limit_rate 500k; + } + ``` + - **Примечание:** См. `Требования безопасности для включения в ТУ — проверка.md` п. 16; `Проверочные мероприятия для ПМИ — проверка.md` п. 16. + - **5.5 Настройка таймаутов соединений** + - Описание реализации: nginx позволяет задавать таймауты чтения заголовков, тела запроса, отправки ответа и keepalive. + - Модуль / механизм: client_header_timeout, client_body_timeout, send_timeout, keepalive_timeout + - Комментарий: Снижает риск удержания ресурсов медленными или зависшими соединениями. + - Проверка: + - **Статус:** Подтверждено + - **Ревью функции:** Описание реализации и заявленный механизм соответствуют документации nginx. Директивы `client_header_timeout`, `client_body_timeout`, `send_timeout` и `keepalive_timeout` задают таймауты на разных этапах обработки соединения. + - **Источник:** https://nginx.org/en/docs/http/ngx_http_core_module.html + - **Результат:** Директивы `client_header_timeout`, `client_body_timeout`, `send_timeout` и `keepalive_timeout` задают таймауты на разных этапах обработки соединения. Значения по умолчанию: 60s для header/body/send, 75s для keepalive. + - **Пример конфигурации:** + ```nginx + http { + client_header_timeout 10s; + client_body_timeout 10s; + send_timeout 10s; + keepalive_timeout 30s; + } + ``` + +- **6. Управление раскрытием информации** + - **6.1 Сокрытие версии nginx** + - Описание реализации: nginx позволяет отключить отображение версии сервера в стандартных ответах. + - Модуль / механизм: server_tokens off + - Комментарий: Важно: server_tokens off скрывает версию, но не всегда полностью скрывает сам факт использования nginx. + - Проверка: + - **Статус:** Подтверждено + - **Ревью функции:** Описание реализации и заявленный механизм соответствуют документации nginx. Директива `server_tokens off` убирает номер версии из заголовка `Server` и со страниц ошибок nginx. + - **Источник:** https://nginx.org/en/docs/http/ngx_http_core_module.html#server_tokens + - **Результат:** Директива `server_tokens off` убирает номер версии из заголовка `Server` и со страниц ошибок nginx. Заголовок `Server` по-прежнему содержит слово «nginx». + - **Минимальный аудит конфигурации:** + ```bash +nginx -T 2>/dev/null | grep server_tokens + ``` + - **Пример конфигурации:** + ```nginx + http { + server_tokens off; + } + ``` + - **Примечание:** Для полного сокрытия идентификатора сервера требуются дополнительные меры (например, заголовки через `more_clear_headers` в сторонних модулях). + - **6.2 Управление страницами ошибок** + - Описание реализации: nginx позволяет задавать собственные страницы ошибок и внутренние перенаправления. + - Модуль / механизм: error_page + - Комментарий: Позволяет не раскрывать технические детали пользователю. + - Проверка: + - **Статус:** Подтверждено + - **Ревью функции:** Описание реализации и заявленный механизм соответствуют документации nginx. Директива `error_page` перенаправляет обработку указанных кодов ошибок на URI, именованный location или внешний адрес. + - **Источник:** https://nginx.org/en/docs/http/ngx_http_core_module.html#error_page + - **Результат:** Директива `error_page` перенаправляет обработку указанных кодов ошибок на URI, именованный location или внешний адрес. Позволяет показывать пользовательские страницы вместо стандартных сообщений nginx. + - **Пример конфигурации:** + ```nginx + error_page 404 /custom_404.html; + error_page 500 502 503 504 /custom_50x.html; + + location = /custom_404.html { + root /var/www/errors; + internal; + } + ``` + - **6.3 Управление листингом директорий** + - Описание реализации: nginx может формировать листинг директорий через autoindex, если режим включён. + - Модуль / механизм: ngx_http_autoindex_module; autoindex + - Комментарий: Модуль официально формирует directory listing для запросов, оканчивающихся /, когда не найден индексный файл. Для безопасной конфигурации должен быть отключён, если не требуется. + - Проверка: + - **Статус:** Подтверждено + - **Ревью функции:** Описание реализации и заявленный механизм соответствуют документации nginx. Модуль `ngx_http_autoindex_module` включается директивой `autoindex on` и формирует HTML-листинг каталога при отсутствии индексного файла. + - **Источник:** https://nginx.org/en/docs/http/ngx_http_autoindex_module.html + - **Результат:** Модуль `ngx_http_autoindex_module` включается директивой `autoindex on` и формирует HTML-листинг каталога при отсутствии индексного файла. По умолчанию `autoindex off`. Для безопасной конфигурации рекомендуется явно отключать или не включать. + - **Минимальный аудит конфигурации:** + ```bash +nginx -T 2>/dev/null | grep autoindex + ``` + - **Пример конфигурации:** + ```nginx + location /public-files/ { + autoindex off; + root /var/www/files; + } + ``` + +- **7. Обратное проксирование и изоляция backend-сервисов** + - **7.1 Обратное проксирование HTTP/HTTPS** + - Описание реализации: nginx может принимать клиентские запросы и передавать их внутренним backend-сервисам. + - Модуль / механизм: ngx_http_proxy_module; proxy_pass + - Комментарий: Официальный модуль proxy передаёт запросы другому серверу. + - Проверка: + - **Статус:** Подтверждено + - **Ревью функции:** Описание реализации и заявленный механизм соответствуют документации nginx. Модуль `ngx_http_proxy_module` передаёт HTTP-запросы на backend через `proxy_pass`. + - **Источник:** https://nginx.org/en/docs/http/ngx_http_proxy_module.html + - **Результат:** Модуль `ngx_http_proxy_module` передаёт HTTP-запросы на backend через `proxy_pass`. Поддерживается проксирование на HTTP и HTTPS upstream. + - **Пример конфигурации:** + ```nginx + location /api/ { + proxy_pass http://127.0.0.1:8080; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + } + ``` + - **7.2 Балансировка и группы upstream** + - Описание реализации: nginx позволяет определять группы backend-серверов и использовать их для proxy_pass, fastcgi_pass, uwsgi_pass, scgi_pass, grpc_pass. + - Модуль / механизм: ngx_http_upstream_module; upstream + - Комментарий: Документация nginx описывает upstream как механизм групп серверов для разных pass-директив. + - Проверка: + - **Статус:** Подтверждено + - **Ревью функции:** Описание реализации и заявленный механизм соответствуют документации nginx. Блок `upstream` определяет группу backend-серверов с методами балансировки (round-robin по умолчанию, `least_conn`, `ip_hash`, `hash`). + - **Источник:** https://nginx.org/en/docs/http/ngx_http_upstream_module.html + - **Результат:** Блок `upstream` определяет группу backend-серверов с методами балансировки (round-robin по умолчанию, `least_conn`, `ip_hash`, `hash`). Используется с `proxy_pass`, `fastcgi_pass`, `uwsgi_pass`, `scgi_pass`, `grpc_pass`. + - **Пример конфигурации:** + ```nginx + upstream backend { + server 192.168.1.10:8080; + server 192.168.1.11:8080; + keepalive 32; + } + + server { + location / { + proxy_pass http://backend; + } + } + ``` + - **7.3 Управление заголовками при проксировании** + - Описание реализации: nginx позволяет явно задавать заголовки, передаваемые backend-сервису. + - Модуль / механизм: proxy_set_header + - Комментарий: Важно для корректной передачи адреса клиента и исключения нежелательных/подменённых заголовков. + - Проверка: + - **Статус:** Подтверждено + - **Ревью функции:** Описание реализации и заявленный механизм соответствуют документации nginx. Директива `proxy_set_header` задаёт или переопределяет заголовки запроса к backend. + - **Источник:** https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_set_header + - **Результат:** Директива `proxy_set_header` задаёт или переопределяет заголовки запроса к backend. По умолчанию nginx передаёт ряд заголовков, но `Host` и `Connection` могут требовать явной настройки. `proxy_pass_request_headers` управляет передачей клиентских заголовков. + - **Пример конфигурации:** + ```nginx + location / { + proxy_pass http://backend; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + } + ``` + +- **8. Управление статическим содержимым и директориями веб-приложений** + - **8.1 Задание корневой директории сайта** + - Описание реализации: nginx обслуживает файлы из директории, заданной директивой root. + - Модуль / механизм: ngx_http_core_module; root + - Комментарий: Используется для определения разрешённой области веб-контента. + - Проверка: + - **Статус:** Подтверждено + - **Ревью функции:** Описание реализации и заявленный механизм соответствуют документации nginx. Директива `root` задаёт корневую директорию для запросов в данном server/location. + - **Источник:** https://nginx.org/en/docs/http/ngx_http_core_module.html#root + - **Результат:** Директива `root` задаёт корневую директорию для запросов в данном server/location. Путь к файлу формируется как `root` + URI. + - **Пример конфигурации:** + ```nginx + server { + root /var/www/example.com; + location / { + index index.html; + } + } + ``` + - **8.2 Задание альтернативного пути для location** + - Описание реализации: nginx позволяет сопоставлять URI с другой директорией файловой системы через alias. + - Модуль / механизм: ngx_http_core_module; alias + - Комментарий: Требует осторожной настройки, чтобы не открыть произвольные каталоги ОС. + - Проверка: + - **Статус:** Подтверждено + - **Ревью функции:** Описание реализации и заявленный механизм соответствуют документации nginx. Директива `alias` заменяет часть URI на указанный путь файловой системы. + - **Источник:** https://nginx.org/en/docs/http/ngx_http_core_module.html#alias + - **Результат:** Директива `alias` заменяет часть URI на указанный путь файловой системы. При некорректной настройке (особенно с регулярными выражениями) возможен path traversal. + - **Пример конфигурации:** + ```nginx + location /images/ { + alias /var/www/static/images/; + } + ``` + - **Примечание:** Для location с регулярным выражением `alias` должен содержать захватывающие группы; завершающий слэш обязателен. + - **8.3 Проверка существования файлов и маршрутизация** + - Описание реализации: nginx позволяет проверять наличие файлов и выполнять внутреннюю маршрутизацию через try_files. + - Модуль / механизм: ngx_http_core_module; try_files + - Комментарий: Используется для контроля, какой файл или маршрут будет обработан. + - Проверка: + - **Статус:** Подтверждено + - **Ревью функции:** Описание реализации и заявленный механизм соответствуют документации nginx. Директива `try_files` проверяет существование файлов/каталогов в указанном порядке и выполняет внутреннее перенаправление на последний параметр при отсутствии совпадений. + - **Источник:** https://nginx.org/en/docs/http/ngx_http_core_module.html#try_files + - **Результат:** Директива `try_files` проверяет существование файлов/каталогов в указанном порядке и выполняет внутреннее перенаправление на последний параметр при отсутствии совпадений. + - **Пример конфигурации:** + ```nginx + location / { + root /var/www/html; + try_files $uri $uri/ /index.html; + } + ``` + - **8.4 Ограничение доступа к произвольным каталогам ОС** + - Описание реализации: nginx должен быть настроен так, чтобы обслуживать файлы только из разрешённых директорий. + - Модуль / механизм: root, alias, location, deny all, права ФС + - Комментарий: Это не отдельный модуль nginx, а требование безопасной конфигурации. + - Проверка: + - **Статус:** Подтверждено + - **Ревью функции:** Описание реализации и заявленный механизм соответствуют документации nginx. nginx обслуживает только те пути, которые явно заданы через `root`/`alias` в `location`. + - **Источник:** https://nginx.org/en/docs/http/ngx_http_core_module.html#root , https://nginx.org/en/docs/http/ngx_http_access_module.html + - **Результат:** nginx обслуживает только те пути, которые явно заданы через `root`/`alias` в `location`. Безопасная конфигурация ограничивает `location /`, запрещает доступ к системным путям и сочетается с правами файловой системы (процесс nginx не должен иметь доступ к чувствительным каталогам). + - **Пример конфигурации:** + ```nginx + server { + root /var/www/site; + location / { + try_files $uri =404; + } + location ~ ^/(\.\.|etc|proc|sys) { + deny all; + } + } + ``` + - **Примечание:** Дополнительно на уровне ОС следует ограничить права пользователя, от которого работает nginx. См. `Минимально необходимые полномочия nginx — проверка.md` п. 3; `Контроль выполнения кода — проверка.md` п. 14. + +- **9. Минимизация поверхности атаки** + - **9.1 Исключение неиспользуемых модулей** + - Описание реализации: nginx может собираться с разным составом модулей; неиспользуемые модули могут быть исключены из сборки или не загружаться. + - Модуль / механизм: Параметры сборки; dynamic modules; load_module + - Комментарий: Это проектная мера снижения поверхности атаки. + - Проверка: + - **Статус:** Подтверждено + - **Ревью функции:** Описание реализации и заявленный механизм соответствуют документации nginx. При сборке nginx параметры `./configure` позволяют включать/отключать модули (`--without-http_autoindex_module`, `--with-http_ssl_module` и др. + - **Источник:** https://nginx.org/en/docs/configure.html , https://nginx.org/en/docs/ngx_core_module.html#load_module + - **Результат:** При сборке nginx параметры `./configure` позволяют включать/отключать модули (`--without-http_autoindex_module`, `--with-http_ssl_module` и др.). Динамические модули подключаются через `load_module` в конфигурации; неиспользуемые модули можно не загружать. + - **Пример конфигурации:** + ```nginx + # Загрузка только необходимых динамических модулей + load_module modules/ngx_http_geoip_module.so; + + # Статические модули определяются при сборке: + # ./configure --without-http_autoindex_module --with-http_ssl_module + ``` + - **Примечание:** См. `Минимизация поверхности атаки nginx — проверка.md` п. 1–2. + - **9.2 Отключение неиспользуемых возможностей конфигурацией** + - Описание реализации: Неиспользуемые возможности должны быть отключены в конфигурации: autoindex, лишние методы, лишние proxy/FastCGI-направления. + - Модуль / механизм: Конфигурация nginx + - Комментарий: Это не отдельная функция nginx, а требование безопасной эксплуатации. + - Проверка: + - **Статус:** Подтверждено + - **Ревью функции:** Описание реализации и заявленный механизм соответствуют документации nginx. Неиспользуемые возможности отключаются конфигурацией: `autoindex off`, ограничение методов через `limit_except`, удаление неиспользуемых `location` с `proxy_pass`/`fastcgi_pass`. + - **Источник:** https://nginx.org/en/docs/http/ngx_http_autoindex_module.html , https://nginx.org/en/docs/http/ngx_http_core_module.html#limit_except + - **Результат:** Неиспользуемые возможности отключаются конфигурацией: `autoindex off`, ограничение методов через `limit_except`, удаление неиспользуемых `location` с `proxy_pass`/`fastcgi_pass`. Это требование безопасной эксплуатации, а не отдельный модуль. + - **Пример конфигурации:** + ```nginx + server { + autoindex off; + + location / { + limit_except GET HEAD POST { + deny all; + } + } + + # Неиспользуемые направления не включаются в конфигурацию + # location /legacy-api/ { proxy_pass http://old-backend; } + } + ``` + - **Примечание:** См. `Минимизация поверхности атаки nginx — проверка.md` п. 4–10. + - **9.3 Контроль целостности конфигурации и разрешённых директорий** + - Описание реализации: Конфигурация nginx и разрешённые директории веб-контента должны контролироваться внешним механизмом целостности. + - Модуль / механизм: afick или иной утверждённый механизм + - Комментарий: nginx не выполняет контроль целостности сам. Это внешняя мера, требуемая для сертификационной логики. + - Проверка: + - **Статус:** Не применимо к nginx напрямую (внешняя мера) + - **Ревью функции:** Корректно отнесено к внешней мере: nginx не реализует функцию напрямую. nginx не реализует контроль целостности файлов (FIM). + - **Источник:** https://nginx.org/en/docs/ (функция FIM в nginx не описана) + - **Результат:** nginx не реализует контроль целостности файлов (FIM). Данное требование выполняется внешними средствами: afick, AIDE, OSSEC или иным утверждённым механизмом. Контролируемые объекты: `/etc/nginx/` (конфигурация), директории `root`/`alias` веб-контента. + - **Пример реализации:** + ``` + # /etc/afick.conf (фрагмент) + /etc/nginx/ R + /var/www/ R + ``` + - **Примечание:** См. `Минимизация поверхности атаки nginx — проверка.md` п. 4–10. + - **Примечание:** Для ПМИ проверяется наличие и работоспособность внешнего средства, а не конфигурация nginx. Статус отражает внешнюю меру (см. `Контроль целостности хранимого кода и конфигурации — проверка.md`; ПМИ п. 24; `Контроль выполнения кода — проверка.md` п. 15–16). diff --git a/results/Dockerfile.test-runner b/results/Dockerfile.test-runner new file mode 100644 index 0000000..76d1e06 --- /dev/null +++ b/results/Dockerfile.test-runner @@ -0,0 +1,3 @@ +FROM alpine:3.21 +RUN apk add --no-cache bash curl openssl coreutils grep findutils wget +CMD ["sleep", "infinity"] diff --git a/results/README.md b/results/README.md new file mode 100644 index 0000000..7ec2bdc --- /dev/null +++ b/results/README.md @@ -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) diff --git a/results/docker-compose.yml b/results/docker-compose.yml new file mode 100644 index 0000000..4646fe0 --- /dev/null +++ b/results/docker-compose.yml @@ -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: diff --git a/results/fim-watch/config.snippet b/results/fim-watch/config.snippet new file mode 100644 index 0000000..e957c71 --- /dev/null +++ b/results/fim-watch/config.snippet @@ -0,0 +1 @@ +# FIM watch file for integrity test (PMI p.24 stand-in) diff --git a/results/mock/auth-mock.conf b/results/mock/auth-mock.conf new file mode 100644 index 0000000..654fb3f --- /dev/null +++ b/results/mock/auth-mock.conf @@ -0,0 +1,9 @@ +server { + listen 9999; + server_name auth-mock; + + location /validate { + default_type text/plain; + return 200 "auth-ok\n"; + } +} diff --git a/results/mock/auth-server.py b/results/mock/auth-server.py new file mode 100644 index 0000000..c0850bb --- /dev/null +++ b/results/mock/auth-server.py @@ -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() diff --git a/results/mock/backend.conf b/results/mock/backend.conf new file mode 100644 index 0000000..c9bc9e6 --- /dev/null +++ b/results/mock/backend.conf @@ -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"; + } +} diff --git a/results/mock/slow-server.py b/results/mock/slow-server.py new file mode 100644 index 0000000..11035ad --- /dev/null +++ b/results/mock/slow-server.py @@ -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() diff --git a/results/mock/syslog-ng.conf b/results/mock/syslog-ng.conf new file mode 100644 index 0000000..80c5930 --- /dev/null +++ b/results/mock/syslog-ng.conf @@ -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); +}; diff --git a/results/nginx/conf.d/pmi.conf b/results/nginx/conf.d/pmi.conf new file mode 100644 index 0000000..2a16afd --- /dev/null +++ b/results/nginx/conf.d/pmi.conf @@ -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"; + } +} diff --git a/results/nginx/htpasswd b/results/nginx/htpasswd new file mode 100644 index 0000000..4a71786 --- /dev/null +++ b/results/nginx/htpasswd @@ -0,0 +1 @@ +user:$apr1$279GWHiN$DLoGAZKGBUan4Xj7kLXjF/ diff --git a/results/nginx/nginx.conf b/results/nginx/nginx.conf new file mode 100644 index 0000000..f8a9abb --- /dev/null +++ b/results/nginx/nginx.conf @@ -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; +} diff --git a/results/reports/2026-06-14_06-37-41_audit.log b/results/reports/2026-06-14_06-37-41_audit.log new file mode 100644 index 0000000..6d93207 --- /dev/null +++ b/results/reports/2026-06-14_06-37-41_audit.log @@ -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) diff --git a/results/reports/2026-06-14_06-37-41_fim.log b/results/reports/2026-06-14_06-37-41_fim.log new file mode 100644 index 0000000..0f6b793 --- /dev/null +++ b/results/reports/2026-06-14_06-37-41_fim.log @@ -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) diff --git a/results/reports/2026-06-14_06-37-41_pmi.log b/results/reports/2026-06-14_06-37-41_pmi.log new file mode 100644 index 0000000..6867eef --- /dev/null +++ b/results/reports/2026-06-14_06-37-41_pmi.log @@ -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 diff --git a/results/reports/2026-06-14_06-37-41_summary.md b/results/reports/2026-06-14_06-37-41_summary.md new file mode 100644 index 0000000..312cf77 --- /dev/null +++ b/results/reports/2026-06-14_06-37-41_summary.md @@ -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) +``` diff --git a/results/reports/nginx-file-access.log b/results/reports/nginx-file-access.log new file mode 100644 index 0000000..61f2ceb --- /dev/null +++ b/results/reports/nginx-file-access.log @@ -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 diff --git a/results/reports/nginx-file-error.log b/results/reports/nginx-file-error.log new file mode 100644 index 0000000..f580243 --- /dev/null +++ b/results/reports/nginx-file-error.log @@ -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" diff --git a/results/reports/nginx-syslog.log b/results/reports/nginx-syslog.log new file mode 100644 index 0000000..dc1207e --- /dev/null +++ b/results/reports/nginx-syslog.log @@ -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 diff --git a/results/run.bat b/results/run.bat new file mode 100644 index 0000000..66e47ee --- /dev/null +++ b/results/run.bat @@ -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 diff --git a/results/scripts/gen-certs.sh b/results/scripts/gen-certs.sh new file mode 100644 index 0000000..58d056b --- /dev/null +++ b/results/scripts/gen-certs.sh @@ -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" diff --git a/results/scripts/gen-htpasswd.sh b/results/scripts/gen-htpasswd.sh new file mode 100644 index 0000000..680cd17 --- /dev/null +++ b/results/scripts/gen-htpasswd.sh @@ -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)" diff --git a/results/scripts/generate-summary.sh b/results/scripts/generate-summary.sh new file mode 100644 index 0000000..7a58a35 --- /dev/null +++ b/results/scripts/generate-summary.sh @@ -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" diff --git a/results/scripts/run-audit-attack-surface.sh b/results/scripts/run-audit-attack-surface.sh new file mode 100644 index 0000000..a90f702 --- /dev/null +++ b/results/scripts/run-audit-attack-surface.sh @@ -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" diff --git a/results/scripts/run-audit-code-control.sh b/results/scripts/run-audit-code-control.sh new file mode 100644 index 0000000..e1be485 --- /dev/null +++ b/results/scripts/run-audit-code-control.sh @@ -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" diff --git a/results/scripts/run-audit-permissions.sh b/results/scripts/run-audit-permissions.sh new file mode 100644 index 0000000..ea47b5d --- /dev/null +++ b/results/scripts/run-audit-permissions.sh @@ -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" diff --git a/results/scripts/run-fim-checksum.sh b/results/scripts/run-fim-checksum.sh new file mode 100644 index 0000000..62e9609 --- /dev/null +++ b/results/scripts/run-fim-checksum.sh @@ -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" diff --git a/results/scripts/run-pmi-log-checks.sh b/results/scripts/run-pmi-log-checks.sh new file mode 100644 index 0000000..9e1ab23 --- /dev/null +++ b/results/scripts/run-pmi-log-checks.sh @@ -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 diff --git a/results/scripts/run-pmi-tests.sh b/results/scripts/run-pmi-tests.sh new file mode 100644 index 0000000..3ef16db --- /dev/null +++ b/results/scripts/run-pmi-tests.sh @@ -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 "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 diff --git a/results/scripts/wait-ready.sh b/results/scripts/wait-ready.sh new file mode 100644 index 0000000..5ad18e2 --- /dev/null +++ b/results/scripts/wait-ready.sh @@ -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 diff --git a/results/ssl/ca.crt b/results/ssl/ca.crt new file mode 100644 index 0000000..5d90771 --- /dev/null +++ b/results/ssl/ca.crt @@ -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----- diff --git a/results/ssl/ca.key b/results/ssl/ca.key new file mode 100644 index 0000000..eaf09ee --- /dev/null +++ b/results/ssl/ca.key @@ -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----- diff --git a/results/ssl/client.crt b/results/ssl/client.crt new file mode 100644 index 0000000..5f42386 --- /dev/null +++ b/results/ssl/client.crt @@ -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----- diff --git a/results/ssl/client.key b/results/ssl/client.key new file mode 100644 index 0000000..ff2c718 --- /dev/null +++ b/results/ssl/client.key @@ -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----- diff --git a/results/ssl/fullchain.crt b/results/ssl/fullchain.crt new file mode 100644 index 0000000..abcb8ed --- /dev/null +++ b/results/ssl/fullchain.crt @@ -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----- diff --git a/results/ssl/server.crt b/results/ssl/server.crt new file mode 100644 index 0000000..5a6fe47 --- /dev/null +++ b/results/ssl/server.crt @@ -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----- diff --git a/results/ssl/server.key b/results/ssl/server.key new file mode 100644 index 0000000..0a16f2e --- /dev/null +++ b/results/ssl/server.key @@ -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----- diff --git a/results/ssl/untrusted.crt b/results/ssl/untrusted.crt new file mode 100644 index 0000000..7ff7f2d --- /dev/null +++ b/results/ssl/untrusted.crt @@ -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----- diff --git a/results/ssl/untrusted.key b/results/ssl/untrusted.key new file mode 100644 index 0000000..dea69b4 --- /dev/null +++ b/results/ssl/untrusted.key @@ -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----- diff --git a/results/www/errors/custom_404.html b/results/www/errors/custom_404.html new file mode 100644 index 0000000..6d982e4 --- /dev/null +++ b/results/www/errors/custom_404.html @@ -0,0 +1,5 @@ +<!DOCTYPE html> +<html lang="ru"> +<head><meta charset="utf-8"><title>404 +

Custom 404 page

+ diff --git a/results/www/files/sample-file.txt b/results/www/files/sample-file.txt new file mode 100644 index 0000000..3c53a51 --- /dev/null +++ b/results/www/files/sample-file.txt @@ -0,0 +1 @@ +sample-file.txt diff --git a/results/www/protected/document.pdf b/results/www/protected/document.pdf new file mode 100644 index 0000000..7a19a35 --- /dev/null +++ b/results/www/protected/document.pdf @@ -0,0 +1 @@ +PDF test document for internal download. diff --git a/results/www/public/index.html b/results/www/public/index.html new file mode 100644 index 0000000..0012dd0 --- /dev/null +++ b/results/www/public/index.html @@ -0,0 +1,5 @@ + + +Public +

Public index

+