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

View File

@@ -0,0 +1,3 @@
FROM alpine:3.21
RUN apk add --no-cache bash curl openssl coreutils grep findutils wget
CMD ["sleep", "infinity"]

59
results/README.md Normal file
View File

@@ -0,0 +1,59 @@
# nginx PMI test stand
Воспроизводимый стенд для практических проверок из каталога [`docs/`](../docs/).
## Требования
- Docker Desktop (Windows)
- Свободные порты **8080** (HTTP) и **8443** (HTTPS)
## Быстрый запуск
```bat
cd c:\work\astro\nginx\results
run.bat
```
Скрипт:
1. Генерирует TLS-сертификаты и `htpasswd` (user / password)
2. Поднимает Docker Compose стенд
3. Выполняет 24 мероприятия ПМИ
4. Запускает аудиты полномочий, поверхности атаки и контроля кода
5. Проверяет целостность (SHA256 baseline вместо afick)
6. Сохраняет отчёты в `reports/`
## Структура
| Путь | Назначение |
|------|------------|
| `docker-compose.yml` | nginx, mock-backend, auth, syslog, test-runner |
| `nginx/` | Конфигурация стенда |
| `scripts/` | Генерация, тесты, аудит |
| `reports/` | Результаты прогонов (`YYYY-MM-DD_HH-MM-SS_*.log`) |
| `run.bat` | Оркестратор для Windows cmd |
## Ручной запуск
```bat
docker compose up -d
docker compose exec test-runner sh /scripts/run-pmi-tests.sh
docker compose exec nginx sh /scripts/run-audit-permissions.sh
docker compose down
```
## Ограничения стенда
- **FIM (п. 24):** checksum-скрипт, не afick
- **Syslog (п. 14):** локальный syslog-ng в Compose
- **mTLS/TLS:** самоподписанные сертификаты в `ssl/`
- **П. 1 (IP):** два интерфейса test-runner (`172.28.x` / `172.29.x`) вместо двух физических хостов
## Учётные данные
- Basic Auth: `user` / `password`
- HTTPS: самоподписанный сертификат (для curl используйте `-k`)
## Документация
Методика проверок: [`docs/Проверочныеероприятия_для_ПМИ_—_проверка.md`](../docs/Проверочныеероприятия_для_ПМИ_—_проверка.md)

109
results/docker-compose.yml Normal file
View File

@@ -0,0 +1,109 @@
services:
nginx:
image: nginx:1.26-alpine
container_name: nginx-pmi
ports:
- "8080:80"
- "8443:443"
volumes:
- ./nginx/nginx.conf:/etc/nginx/nginx.conf:ro
- ./nginx/conf.d:/etc/nginx/conf.d:ro
- ./nginx/htpasswd:/etc/nginx/htpasswd:ro
- ./www:/usr/share/nginx/html:ro
- ./ssl:/etc/nginx/ssl:ro
- ./scripts:/scripts:ro
- ./fim-watch:/fim-watch
- ./reports:/reports
- nginx-cache:/var/cache/nginx
- nginx-logs:/var/log/nginx
depends_on:
- backend
- slow-backend
- auth-mock
- syslog-ng
networks:
allowed-net:
ipv4_address: 172.28.0.2
denied-net:
ipv4_address: 172.29.0.2
internal:
healthcheck:
test: ["CMD", "wget", "-q", "-O", "/dev/null", "http://127.0.0.1/public/index.html"]
interval: 5s
timeout: 3s
retries: 12
backend:
image: nginx:1.26-alpine
container_name: nginx-pmi-backend
volumes:
- ./mock/backend.conf:/etc/nginx/conf.d/default.conf:ro
networks:
- internal
slow-backend:
image: python:3.12-alpine
container_name: nginx-pmi-slow
command: ["python", "/app/slow-server.py"]
volumes:
- ./mock/slow-server.py:/app/slow-server.py:ro
networks:
- internal
auth-mock:
image: python:3.12-alpine
container_name: nginx-pmi-auth
command: ["python", "/app/auth-server.py"]
volumes:
- ./mock/auth-server.py:/app/auth-server.py:ro
- auth-mode:/auth-mode
networks:
- internal
syslog-ng:
image: balabit/syslog-ng:4.7.1
container_name: nginx-pmi-syslog
volumes:
- ./mock/syslog-ng.conf:/etc/syslog-ng/syslog-ng.conf:ro
- ./reports:/reports
networks:
- internal
test-runner:
build:
context: .
dockerfile: Dockerfile.test-runner
container_name: nginx-pmi-test-runner
volumes:
- ./scripts:/scripts:ro
- ./ssl:/ssl:ro
- ./reports:/reports
- auth-mode:/auth-mode
depends_on:
nginx:
condition: service_healthy
networks:
allowed-net:
ipv4_address: 172.28.0.20
denied-net:
ipv4_address: 172.29.0.20
internal:
networks:
allowed-net:
driver: bridge
ipam:
config:
- subnet: 172.28.0.0/16
denied-net:
driver: bridge
ipam:
config:
- subnet: 172.29.0.0/16
internal:
driver: bridge
volumes:
nginx-cache:
nginx-logs:
auth-mode:

View File

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

View File

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

View File

@@ -0,0 +1,31 @@
#!/usr/bin/env python3
"""Mock auth service for auth_request PMI test."""
from http.server import BaseHTTPRequestHandler, ThreadingHTTPServer
from pathlib import Path
MODE_FILE = Path("/auth-mode/mode")
def current_mode() -> int:
if MODE_FILE.exists():
try:
return int(MODE_FILE.read_text().strip())
except ValueError:
pass
return 200
class AuthHandler(BaseHTTPRequestHandler):
def do_GET(self):
code = current_mode()
self.send_response(code)
self.send_header("Content-Type", "text/plain")
self.end_headers()
self.wfile.write(f"auth-{code}\n".encode())
def log_message(self, fmt, *args):
pass
if __name__ == "__main__":
ThreadingHTTPServer(("0.0.0.0", 9999), AuthHandler).serve_forever()

14
results/mock/backend.conf Normal file
View File

@@ -0,0 +1,14 @@
server {
listen 80;
server_name backend;
location /status {
default_type text/plain;
return 200 "backend-ok\n";
}
location / {
default_type text/plain;
return 200 "backend-default\n";
}
}

View File

@@ -0,0 +1,20 @@
#!/usr/bin/env python3
"""HTTP backend that delays each response for limit_conn tests."""
from http.server import BaseHTTPRequestHandler, ThreadingHTTPServer
import time
class SlowHandler(BaseHTTPRequestHandler):
def do_GET(self):
time.sleep(5)
self.send_response(200)
self.send_header("Content-Type", "text/plain")
self.end_headers()
self.wfile.write(b"slow-ok\n")
def log_message(self, fmt, *args):
pass
if __name__ == "__main__":
ThreadingHTTPServer(("0.0.0.0", 8081), SlowHandler).serve_forever()

View File

@@ -0,0 +1,15 @@
@version: 4.7
@include "scl.conf"
source s_network {
network(ip(0.0.0.0) port(514) transport("udp"));
};
destination d_file {
file("/reports/nginx-syslog.log" template("$ISODATE $HOST $MSGHDR$MSG\n"));
};
log {
source(s_network);
destination(d_file);
};

View File

@@ -0,0 +1,186 @@
upstream approved_backend {
server backend:80;
}
upstream slow_upstream {
server slow-backend:8081;
}
# П.11: принудительный редирект HTTP -> HTTPS
server {
listen 80;
server_name redirect-test;
return 301 https://$host:8443$request_uri;
}
# Основной HTTP-сервер (ПМИ п. 1-2, 4-8, 12-23)
server {
listen 80 default_server;
server_name nginx-test;
root /usr/share/nginx/html/public;
index index.html;
error_page 404 /custom_404.html;
location = /custom_404.html {
root /usr/share/nginx/html/errors;
internal;
}
# П.1, П.6: ограничение по IP
location /admin/ {
allow 172.28.0.0/16;
deny all;
alias /usr/share/nginx/html/public/;
try_files /index.html =404;
}
# П.2: Basic Authentication
location /secure/ {
auth_basic "Restricted";
auth_basic_user_file /etc/nginx/htpasswd;
alias /usr/share/nginx/html/public/;
try_files /index.html =404;
}
# П.5: satisfy all (IP + пароль)
location /admin-combined/ {
satisfy all;
allow 172.28.0.0/16;
deny all;
auth_basic "Admin";
auth_basic_user_file /etc/nginx/htpasswd;
alias /usr/share/nginx/html/public/;
try_files /index.html =404;
}
# П.4: auth_request
location = /auth {
internal;
proxy_pass http://auth-mock:9999/validate;
proxy_pass_request_body off;
proxy_set_header Content-Length "";
}
location /auth-protected/ {
auth_request /auth;
proxy_pass http://approved_backend/;
}
# П.7: limit_except
location /api/ {
limit_except GET POST {
deny all;
}
proxy_pass http://approved_backend/;
}
# П.8: internal
location /protected/ {
internal;
alias /usr/share/nginx/html/protected/;
}
location /download {
rewrite ^ /protected/document.pdf last;
}
# П.13: error log через недоступный upstream
location /broken/ {
proxy_connect_timeout 2s;
proxy_read_timeout 2s;
proxy_pass http://127.0.0.1:59999/;
}
# П.12: access log
location /test-page {
default_type text/plain;
return 200 "test-page-ok\n";
}
location /another-page {
default_type text/plain;
return 200 "another-page-ok\n";
}
# П.15: limit_req
location = /rate-limit-check {
limit_req zone=pmi_uri burst=1 nodelay;
limit_req_status 503;
proxy_pass http://approved_backend/status;
}
location /rate-limit/ {
limit_req zone=pmi_uri burst=1 nodelay;
limit_req_status 503;
proxy_pass http://approved_backend/status;
}
# П.16: limit_conn
location /slow/ {
limit_conn pmi_conn 2;
proxy_pass http://slow_upstream/;
proxy_read_timeout 60s;
}
# П.17, П.18: upload
location /upload {
default_type text/plain;
return 200 "upload-ok\n";
}
# П.21: autoindex off
location /files/ {
autoindex off;
alias /usr/share/nginx/html/files/;
}
location /public/ {
alias /usr/share/nginx/html/public/;
}
location / {
try_files $uri =404;
}
}
# П.9, П.10, П.11 (HSTS): HTTPS без клиентского сертификата
server {
listen 443 ssl;
server_name nginx-test;
ssl_certificate /etc/nginx/ssl/fullchain.crt;
ssl_certificate_key /etc/nginx/ssl/server.key;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256;
ssl_prefer_server_ciphers on;
add_header Strict-Transport-Security "max-age=31536000" always;
root /usr/share/nginx/html/public;
index index.html;
location / {
try_files $uri =404;
}
}
# П.3: mTLS (клиентский сертификат)
server {
listen 443 ssl;
server_name nginx-test-mtls;
ssl_certificate /etc/nginx/ssl/fullchain.crt;
ssl_certificate_key /etc/nginx/ssl/server.key;
ssl_client_certificate /etc/nginx/ssl/ca.crt;
ssl_verify_client on;
ssl_verify_depth 2;
ssl_protocols TLSv1.2 TLSv1.3;
location / {
default_type text/plain;
return 200 "mtls-ok\n";
}
}

1
results/nginx/htpasswd Normal file
View File

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

43
results/nginx/nginx.conf Normal file
View File

@@ -0,0 +1,43 @@
user nginx;
worker_processes auto;
error_log /reports/nginx-file-error.log warn;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
server_tokens off;
autoindex off;
ssi off;
sendfile on;
keepalive_timeout 30s;
log_format pmi '$remote_addr - [$time_local] "$request" $status $body_bytes_sent';
limit_req_zone $binary_remote_addr zone=pmi_req:10m rate=2r/s;
limit_req_zone $request_uri zone=pmi_uri:10m rate=1r/m;
limit_conn_zone $binary_remote_addr zone=pmi_conn:10m;
client_body_temp_path /var/cache/nginx/client_temp;
proxy_temp_path /var/cache/nginx/proxy_temp;
fastcgi_temp_path /var/cache/nginx/fastcgi_temp;
client_body_timeout 5s;
client_header_timeout 5s;
send_timeout 10s;
client_max_body_size 1m;
access_log /reports/nginx-file-access.log pmi;
error_log /reports/nginx-file-error.log warn;
access_log syslog:server=syslog-ng:514,facility=local7,tag=nginx,severity=info pmi;
error_log syslog:server=syslog-ng:514,facility=local7,tag=nginx,severity=error;
include /etc/nginx/conf.d/*.conf;
}

View File

@@ -0,0 +1,140 @@
Permissions audit 2026-06-14T06:37:59+00:00
=== Worker user ===
user nginx;
1 root 0:00 nginx: master process nginx -g daemon off;
20 nginx 0:00 nginx: worker process
21 nginx 0:00 nginx: worker process
22 nginx 0:00 nginx: worker process
23 nginx 0:00 nginx: worker process
24 nginx 0:00 nginx: worker process
25 nginx 0:00 nginx: worker process
26 nginx 0:00 nginx: worker process
27 nginx 0:00 nginx: worker process
28 nginx 0:00 nginx: worker process
29 nginx 0:00 nginx: worker process
30 nginx 0:00 nginx: worker process
31 nginx 0:00 nginx: worker process
32 nginx 0:00 nginx: worker process
33 nginx 0:00 nginx: worker process
34 nginx 0:00 nginx: worker process
35 nginx 0:00 nginx: worker process
36 nginx 0:00 nginx: worker process
37 nginx 0:00 nginx: worker process
38 nginx 0:00 nginx: worker process
39 nginx 0:00 nginx: worker process
=== Config permissions ===
total 40
drwxr-xr-x 1 root root 4096 Jun 14 05:28 .
drwxr-xr-x 1 root root 4096 Jun 14 05:28 ..
drwxrwxrwx 1 root root 4096 Jun 14 04:56 conf.d
-rw-r--r-- 1 root root 1077 Feb 5 2025 fastcgi.conf
-rw-r--r-- 1 root root 1007 Feb 5 2025 fastcgi_params
-rw-r--r-- 1 root root 43 Jun 14 06:37 htpasswd
-rw-r--r-- 1 root root 5349 Feb 5 2025 mime.types
lrwxrwxrwx 1 root root 22 Apr 16 2025 modules -> /usr/lib/nginx/modules
-rwxrwxrwx 1 root root 1233 Jun 14 06:27 nginx.conf
-rw-r--r-- 1 root root 636 Feb 5 2025 scgi_params
drwxrwxrwx 1 root root 4096 Jun 14 06:37 ssl
-rw-r--r-- 1 root root 664 Feb 5 2025 uwsgi_params
-rwxrwxrwx 1 root root 1233 Jun 14 06:27 /etc/nginx/nginx.conf
FAIL: nginx can write nginx.conf
=== Web root permissions ===
total 0
drwxrwxrwx 1 root root 4096 Jun 14 04:56 .
drwxrwxrwx 1 root root 4096 Jun 14 04:55 ..
-rwxrwxrwx 1 root root 138 Jun 14 04:56 index.html
FAIL: nginx can write web root
=== TLS certificates and keys ===
total 40
drwxrwxrwx 1 root root 4096 Jun 14 06:37 .
drwxr-xr-x 1 root root 4096 Jun 14 05:28 ..
-rw-r--r-- 1 root root 1814 Jun 14 06:37 ca.crt
-rw------- 1 root root 3272 Jun 14 06:37 ca.key
-rw-r--r-- 1 root root 1448 Jun 14 06:37 client.crt
-rw------- 1 root root 1704 Jun 14 06:37 client.key
-rw-r--r-- 1 root root 3254 Jun 14 06:37 fullchain.crt
-rw-r--r-- 1 root root 1440 Jun 14 06:37 server.crt
-rw------- 1 root root 1704 Jun 14 06:37 server.key
-rw-r--r-- 1 root root 1131 Jun 14 06:37 untrusted.crt
-rw------- 1 root root 1704 Jun 14 06:37 untrusted.key
OK: nginx cannot read private key
=== htpasswd ===
-rw-r--r-- 1 root root 43 Jun 14 06:37 /etc/nginx/htpasswd
OK: nginx cannot write htpasswd
=== Logs ===
total 8
drwxr-xr-x 2 root root 4096 Jun 14 05:18 .
drwxr-xr-x 1 root root 4096 Apr 16 2025 ..
lrwxrwxrwx 1 root root 11 Apr 16 2025 access.log -> /dev/stdout
lrwxrwxrwx 1 root root 11 Apr 16 2025 error.log -> /dev/stderr
=== Temp/cache paths ===
total 28
drwxr-xr-x 7 root root 4096 Jun 14 05:18 .
drwxr-xr-x 1 root root 4096 Apr 16 2025 ..
drwx------ 2 nginx root 4096 Jun 14 05:18 client_temp
drwx------ 2 nginx root 4096 Jun 14 05:18 fastcgi_temp
drwx------ 2 nginx root 4096 Jun 14 05:18 proxy_temp
drwx------ 2 nginx root 4096 Jun 14 05:18 scgi_temp
drwx------ 2 nginx root 4096 Jun 14 05:18 uwsgi_temp
client_body_temp_path /var/cache/nginx/client_temp;
proxy_temp_path /var/cache/nginx/proxy_temp;
=== Attack surface audit 2026-06-14T06:38:00+00:00 ===
--- nginx -V ---
nginx version: nginx/1.26.3
built by gcc 13.2.1 20240309 (Alpine 13.2.1_git20240309)
built with OpenSSL 3.3.0 9 Apr 2024 (running with OpenSSL 3.3.3 11 Feb 2025)
TLS SNI support enabled
configure arguments: --prefix=/etc/nginx --sbin-path=/usr/sbin/nginx --modules-path=/usr/lib/nginx/modules --conf-path=/etc/nginx/nginx.conf --error-log-path=/var/log/nginx/error.log --http-log-path=/var/log/nginx/access.log --pid-path=/var/run/nginx.pid --lock-path=/var/run/nginx.lock --http-client-body-temp-path=/var/cache/nginx/client_temp --http-proxy-temp-path=/var/cache/nginx/proxy_temp --http-fastcgi-temp-path=/var/cache/nginx/fastcgi_temp --http-uwsgi-temp-path=/var/cache/nginx/uwsgi_temp --http-scgi-temp-path=/var/cache/nginx/scgi_temp --with-perl_modules_path=/usr/lib/perl5/vendor_perl --user=nginx --group=nginx --with-compat --with-file-aio --with-threads --with-http_addition_module --with-http_auth_request_module --with-http_dav_module --with-http_flv_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_mp4_module --with-http_random_index_module --with-http_realip_module --with-http_secure_link_module --with-http_slice_module --with-http_ssl_module --with-http_stub_status_module --with-http_sub_module --with-http_v2_module --with-http_v3_module --with-mail --with-mail_ssl_module --with-stream --with-stream_realip_module --with-stream_ssl_module --with-stream_ssl_preread_module --with-cc-opt='-Os -fstack-clash-protection -Wformat -Werror=format-security -fno-plt -g' --with-ld-opt='-Wl,--as-needed,-O1,--sort-common -Wl,-z,pack-relative-relocs'
--- load_module ---
(none)
--- optional modules in config ---
application/x-perl pl pm;
# П.4: auth_request
auth_request /auth;
--- autoindex ---
autoindex off;
# П.21: autoindex off
autoindex off;
--- limit_except / request_method ---
# П.7: limit_except
limit_except GET POST {
--- proxy_pass / upstream ---
upstream approved_backend {
upstream slow_upstream {
proxy_pass http://auth-mock:9999/validate;
proxy_pass_request_body off;
proxy_pass http://approved_backend/;
proxy_pass http://approved_backend/;
# П.13: error log через недоступный upstream
proxy_pass http://127.0.0.1:59999/;
proxy_pass http://approved_backend/status;
proxy_pass http://approved_backend/status;
proxy_pass http://slow_upstream/;
--- ssi ---
(ssi off)
=== Code execution control audit 2026-06-14T06:38:01+00:00 ===
application/x-perl pl pm;
root /usr/share/nginx/html/public;
root /usr/share/nginx/html/errors;
internal;
alias /usr/share/nginx/html/public/;
alias /usr/share/nginx/html/public/;
alias /usr/share/nginx/html/public/;
internal;
# П.8: internal
internal;
alias /usr/share/nginx/html/protected/;
alias /usr/share/nginx/html/files/;
alias /usr/share/nginx/html/public/;
root /usr/share/nginx/html/public;
--- SCRIPT_FILENAME ---
(no fastcgi)

View File

@@ -0,0 +1,7 @@
FIM checksum audit 2026-06-14T06:38:01+00:00
NOTE: SHA256 baseline substitute for afick on test stand only.
Baseline created (22 files)
PASS baseline check (no changes)
PASS tamper detected after file change (/fim-watch/config.snippet)
PASS baseline restored after revert
PASS #24 integrity control (checksum substitute for afick)

View File

@@ -0,0 +1,27 @@
=== PMI tests 2026-06-14T06:37:49+00:00 ===
PASS #1 IP allow/deny (allowed=200 denied=403)
PASS #2 Basic auth (401/401/200)
PASS #3 Client TLS certificate (400/200/400)
PASS #4 auth_request (200/401/403)
PASS #5 satisfy all matrix (200/401/403/403)
PASS #6 URL access rules (/public/ vs /admin/)
PASS #7 limit_except GET POST (PUT/DELETE=403)
PASS #8 internal location (direct=404 rewrite=200)
PASS #9 HTTPS TLS handshake
PASS #10 TLSv1.2 ok, TLSv1.1 rejected
PASS #11 HTTP redirect 301 + HSTS header
PASS #14 syslog receives nginx events
PASS #15 limit_req returns 503 (3) and 200 (2) in: 200 200 503 503 503
PASS #16 limit_conn returns 503 (200200503503503)
PASS #17 client_max_body_size (small=200 large=413)
PASS #18 client_body_timeout (curl exit 1)
PASS #19 server_tokens off
PASS #20 custom error_page 404
PASS #21 autoindex off (403, no listing)
PASS #22 proxy_pass to backend (200)
PASS #23 web root restriction (200/404)
=== Summary: PASS=21 FAIL=0 SKIP=0 ===
PASS #12 access_log contains test-page and another-page
PASS #13 error_log contains upstream error

View File

@@ -0,0 +1,69 @@
# Сводный отчёт nginx PMI stand
**Дата прогона:** 2026-06-14_06-37-41
**Стенд:** Docker Compose (`results/docker-compose.yml`)
## Результаты ПМИ
| Метрика | Значение |
|---------|----------|
| PASS | 23 |
| FAIL | 0 |
## Целостность (FIM stand-in)
| Метрика | Значение |
|---------|----------|
| PASS | 4 |
| FAIL | 0 |
> FIM выполнен через SHA256 baseline (`run-fim-checksum.sh`), не afick.
> Syslog проверялся локальным syslog-ng, не корпоративным SIEM.
## Файлы отчётов
- [`2026-06-14_06-37-41_pmi.log`](2026-06-14_06-37-41_pmi.log)
- [`2026-06-14_06-37-41_audit.log`](2026-06-14_06-37-41_audit.log)
- [`2026-06-14_06-37-41_fim.log`](2026-06-14_06-37-41_fim.log)
## PMI log excerpt
```
=== PMI tests 2026-06-14T06:37:49+00:00 ===
PASS #1 IP allow/deny (allowed=200 denied=403)
PASS #2 Basic auth (401/401/200)
PASS #3 Client TLS certificate (400/200/400)
PASS #4 auth_request (200/401/403)
PASS #5 satisfy all matrix (200/401/403/403)
PASS #6 URL access rules (/public/ vs /admin/)
PASS #7 limit_except GET POST (PUT/DELETE=403)
PASS #8 internal location (direct=404 rewrite=200)
PASS #9 HTTPS TLS handshake
PASS #10 TLSv1.2 ok, TLSv1.1 rejected
PASS #11 HTTP redirect 301 + HSTS header
PASS #14 syslog receives nginx events
PASS #15 limit_req returns 503 (3) and 200 (2) in: 200 200 503 503 503
PASS #16 limit_conn returns 503 (200200503503503)
PASS #17 client_max_body_size (small=200 large=413)
PASS #18 client_body_timeout (curl exit 1)
PASS #19 server_tokens off
PASS #20 custom error_page 404
PASS #21 autoindex off (403, no listing)
PASS #22 proxy_pass to backend (200)
PASS #23 web root restriction (200/404)
=== Summary: PASS=21 FAIL=0 SKIP=0 ===
PASS #12 access_log contains test-page and another-page
PASS #13 error_log contains upstream error
```
## FIM log excerpt
```
FIM checksum audit 2026-06-14T06:38:01+00:00
NOTE: SHA256 baseline substitute for afick on test stand only.
Baseline created (22 files)
PASS baseline check (no changes)
PASS tamper detected after file change (/fim-watch/config.snippet)
PASS baseline restored after revert
PASS #24 integrity control (checksum substitute for afick)
```

View File

@@ -0,0 +1,57 @@
127.0.0.1 - [14/Jun/2026:06:37:58 +0000] "GET /test-page HTTP/1.1" 200 13
127.0.0.1 - [14/Jun/2026:06:37:58 +0000] "GET /another-page HTTP/1.1" 200 16
127.0.0.1 - [14/Jun/2026:06:37:58 +0000] "GET /broken/ HTTP/1.1" 502 150
127.0.0.1 - [14/Jun/2026:06:37:59 +0000] "GET /public/index.html HTTP/1.1" 200 138
127.0.0.1 - [14/Jun/2026:06:38:04 +0000] "GET /public/index.html HTTP/1.1" 200 138
127.0.0.1 - [14/Jun/2026:06:38:09 +0000] "GET /public/index.html HTTP/1.1" 200 138
127.0.0.1 - [14/Jun/2026:06:38:14 +0000] "GET /public/index.html HTTP/1.1" 200 138
127.0.0.1 - [14/Jun/2026:06:38:19 +0000] "GET /public/index.html HTTP/1.1" 200 138
127.0.0.1 - [14/Jun/2026:06:38:24 +0000] "GET /public/index.html HTTP/1.1" 200 138
127.0.0.1 - [14/Jun/2026:06:38:29 +0000] "GET /public/index.html HTTP/1.1" 200 138
127.0.0.1 - [14/Jun/2026:06:38:34 +0000] "GET /public/index.html HTTP/1.1" 200 138
127.0.0.1 - [14/Jun/2026:06:38:39 +0000] "GET /public/index.html HTTP/1.1" 200 138
127.0.0.1 - [14/Jun/2026:06:38:44 +0000] "GET /public/index.html HTTP/1.1" 200 138
127.0.0.1 - [14/Jun/2026:06:38:49 +0000] "GET /public/index.html HTTP/1.1" 200 138
127.0.0.1 - [14/Jun/2026:06:38:54 +0000] "GET /public/index.html HTTP/1.1" 200 138
127.0.0.1 - [14/Jun/2026:06:39:00 +0000] "GET /public/index.html HTTP/1.1" 200 138
127.0.0.1 - [14/Jun/2026:06:39:05 +0000] "GET /public/index.html HTTP/1.1" 200 138
127.0.0.1 - [14/Jun/2026:06:39:10 +0000] "GET /public/index.html HTTP/1.1" 200 138
127.0.0.1 - [14/Jun/2026:06:39:15 +0000] "GET /public/index.html HTTP/1.1" 200 138
127.0.0.1 - [14/Jun/2026:06:39:20 +0000] "GET /public/index.html HTTP/1.1" 200 138
127.0.0.1 - [14/Jun/2026:06:39:25 +0000] "GET /public/index.html HTTP/1.1" 200 138
127.0.0.1 - [14/Jun/2026:06:39:30 +0000] "GET /public/index.html HTTP/1.1" 200 138
127.0.0.1 - [14/Jun/2026:06:39:35 +0000] "GET /public/index.html HTTP/1.1" 200 138
127.0.0.1 - [14/Jun/2026:06:39:40 +0000] "GET /public/index.html HTTP/1.1" 200 138
127.0.0.1 - [14/Jun/2026:06:39:45 +0000] "GET /public/index.html HTTP/1.1" 200 138
127.0.0.1 - [14/Jun/2026:06:39:50 +0000] "GET /public/index.html HTTP/1.1" 200 138
127.0.0.1 - [14/Jun/2026:06:39:55 +0000] "GET /public/index.html HTTP/1.1" 200 138
127.0.0.1 - [14/Jun/2026:06:40:00 +0000] "GET /public/index.html HTTP/1.1" 200 138
127.0.0.1 - [14/Jun/2026:06:40:05 +0000] "GET /public/index.html HTTP/1.1" 200 138
127.0.0.1 - [14/Jun/2026:06:40:10 +0000] "GET /public/index.html HTTP/1.1" 200 138
127.0.0.1 - [14/Jun/2026:06:40:15 +0000] "GET /public/index.html HTTP/1.1" 200 138
127.0.0.1 - [14/Jun/2026:06:40:21 +0000] "GET /public/index.html HTTP/1.1" 200 138
127.0.0.1 - [14/Jun/2026:06:40:26 +0000] "GET /public/index.html HTTP/1.1" 200 138
127.0.0.1 - [14/Jun/2026:06:40:31 +0000] "GET /public/index.html HTTP/1.1" 200 138
127.0.0.1 - [14/Jun/2026:06:40:36 +0000] "GET /public/index.html HTTP/1.1" 200 138
127.0.0.1 - [14/Jun/2026:06:40:41 +0000] "GET /public/index.html HTTP/1.1" 200 138
127.0.0.1 - [14/Jun/2026:06:40:46 +0000] "GET /public/index.html HTTP/1.1" 200 138
127.0.0.1 - [14/Jun/2026:06:40:51 +0000] "GET /public/index.html HTTP/1.1" 200 138
127.0.0.1 - [14/Jun/2026:06:40:56 +0000] "GET /public/index.html HTTP/1.1" 200 138
127.0.0.1 - [14/Jun/2026:06:41:01 +0000] "GET /public/index.html HTTP/1.1" 200 138
127.0.0.1 - [14/Jun/2026:06:41:06 +0000] "GET /public/index.html HTTP/1.1" 200 138
127.0.0.1 - [14/Jun/2026:06:41:11 +0000] "GET /public/index.html HTTP/1.1" 200 138
127.0.0.1 - [14/Jun/2026:06:41:16 +0000] "GET /public/index.html HTTP/1.1" 200 138
127.0.0.1 - [14/Jun/2026:06:41:21 +0000] "GET /public/index.html HTTP/1.1" 200 138
127.0.0.1 - [14/Jun/2026:06:41:26 +0000] "GET /public/index.html HTTP/1.1" 200 138
127.0.0.1 - [14/Jun/2026:06:41:31 +0000] "GET /public/index.html HTTP/1.1" 200 138
127.0.0.1 - [14/Jun/2026:06:41:36 +0000] "GET /public/index.html HTTP/1.1" 200 138
127.0.0.1 - [14/Jun/2026:06:41:42 +0000] "GET /public/index.html HTTP/1.1" 200 138
127.0.0.1 - [14/Jun/2026:06:41:47 +0000] "GET /public/index.html HTTP/1.1" 200 138
127.0.0.1 - [14/Jun/2026:06:41:52 +0000] "GET /public/index.html HTTP/1.1" 200 138
127.0.0.1 - [14/Jun/2026:06:41:57 +0000] "GET /public/index.html HTTP/1.1" 200 138
127.0.0.1 - [14/Jun/2026:06:42:02 +0000] "GET /public/index.html HTTP/1.1" 200 138
127.0.0.1 - [14/Jun/2026:06:42:07 +0000] "GET /public/index.html HTTP/1.1" 200 138
127.0.0.1 - [14/Jun/2026:06:42:12 +0000] "GET /public/index.html HTTP/1.1" 200 138
127.0.0.1 - [14/Jun/2026:06:42:17 +0000] "GET /public/index.html HTTP/1.1" 200 138
127.0.0.1 - [14/Jun/2026:06:42:22 +0000] "GET /public/index.html HTTP/1.1" 200 138
127.0.0.1 - [14/Jun/2026:06:42:27 +0000] "GET /public/index.html HTTP/1.1" 200 138

View File

@@ -0,0 +1 @@
2026/06/14 06:37:58 [error] 20#20: *70 connect() failed (111: Connection refused) while connecting to upstream, client: 127.0.0.1, server: nginx-test, request: "GET /broken/ HTTP/1.1", upstream: "http://127.0.0.1:59999/", host: "127.0.0.1"

View File

@@ -0,0 +1,130 @@
2026-06-14T06:37:49+00:00 nginx-pmi nginx: 172.28.0.20 - [14/Jun/2026:06:37:49 +0000] "GET /public/index.html HTTP/1.1" 200 138
2026-06-14T06:37:49+00:00 nginx-pmi nginx: 172.28.0.20 - [14/Jun/2026:06:37:49 +0000] "GET /admin/ HTTP/1.1" 200 138
2026-06-14T06:37:49+00:00 nginx-pmi nginx: 2026/06/14 06:37:49 [error] 22#22: *3 access forbidden by rule, client: 172.29.0.20, server: nginx-test, request: "GET /admin/ HTTP/1.1", host: "172.29.0.2"
2026-06-14T06:37:49+00:00 nginx-pmi nginx: 172.29.0.20 - [14/Jun/2026:06:37:49 +0000] "GET /admin/ HTTP/1.1" 403 146
2026-06-14T06:37:49+00:00 nginx-pmi nginx: 172.28.0.20 - [14/Jun/2026:06:37:49 +0000] "GET /secure/ HTTP/1.1" 401 172
2026-06-14T06:37:49+00:00 nginx-pmi nginx: 2026/06/14 06:37:49 [error] 25#25: *5 user "wrong" was not found in "/etc/nginx/htpasswd", client: 172.28.0.20, server: nginx-test, request: "GET /secure/ HTTP/1.1", host: "172.28.0.2"
2026-06-14T06:37:49+00:00 nginx-pmi nginx: 172.28.0.20 - [14/Jun/2026:06:37:49 +0000] "GET /secure/ HTTP/1.1" 401 172
2026-06-14T06:37:49+00:00 nginx-pmi nginx: 172.28.0.20 - [14/Jun/2026:06:37:49 +0000] "GET /secure/ HTTP/1.1" 200 138
2026-06-14T06:37:49+00:00 nginx-pmi nginx: 172.28.0.20 - [14/Jun/2026:06:37:49 +0000] "GET / HTTP/1.1" 400 230
2026-06-14T06:37:49+00:00 nginx-pmi nginx: 172.28.0.20 - [14/Jun/2026:06:37:49 +0000] "GET / HTTP/1.1" 200 8
2026-06-14T06:37:49+00:00 nginx-pmi nginx: 172.28.0.20 - [14/Jun/2026:06:37:49 +0000] "GET / HTTP/1.1" 400 208
2026-06-14T06:37:50+00:00 nginx-pmi nginx: 172.28.0.20 - [14/Jun/2026:06:37:50 +0000] "GET /auth-protected/status HTTP/1.1" 200 11
2026-06-14T06:37:50+00:00 nginx-pmi nginx: 172.28.0.20 - [14/Jun/2026:06:37:50 +0000] "GET /auth-protected/status HTTP/1.1" 401 172
2026-06-14T06:37:51+00:00 nginx-pmi nginx: 172.28.0.20 - [14/Jun/2026:06:37:51 +0000] "GET /auth-protected/status HTTP/1.1" 403 146
2026-06-14T06:37:51+00:00 nginx-pmi nginx: 172.28.0.20 - [14/Jun/2026:06:37:51 +0000] "GET /admin-combined/ HTTP/1.1" 200 138
2026-06-14T06:37:51+00:00 nginx-pmi nginx: 172.28.0.20 - [14/Jun/2026:06:37:51 +0000] "GET /admin-combined/ HTTP/1.1" 401 172
2026-06-14T06:37:51+00:00 nginx-pmi nginx: 2026/06/14 06:37:51 [error] 31#31: *19 access forbidden by rule, client: 172.29.0.20, server: nginx-test, request: "GET /admin-combined/ HTTP/1.1", host: "172.29.0.2"
2026-06-14T06:37:51+00:00 nginx-pmi nginx: 172.29.0.20 - [14/Jun/2026:06:37:51 +0000] "GET /admin-combined/ HTTP/1.1" 403 146
2026-06-14T06:37:51+00:00 nginx-pmi nginx: 2026/06/14 06:37:51 [error] 32#32: *20 access forbidden by rule, client: 172.29.0.20, server: nginx-test, request: "GET /admin-combined/ HTTP/1.1", host: "172.29.0.2"
2026-06-14T06:37:51+00:00 nginx-pmi nginx: 172.29.0.20 - [14/Jun/2026:06:37:51 +0000] "GET /admin-combined/ HTTP/1.1" 403 146
2026-06-14T06:37:51+00:00 nginx-pmi nginx: 172.28.0.20 - [14/Jun/2026:06:37:51 +0000] "GET /public/index.html HTTP/1.1" 200 138
2026-06-14T06:37:51+00:00 nginx-pmi nginx: 2026/06/14 06:37:51 [error] 34#34: *22 access forbidden by rule, client: 172.29.0.20, server: nginx-test, request: "GET /admin/ HTTP/1.1", host: "172.29.0.2"
2026-06-14T06:37:51+00:00 nginx-pmi nginx: 172.29.0.20 - [14/Jun/2026:06:37:51 +0000] "GET /admin/ HTTP/1.1" 403 146
2026-06-14T06:37:51+00:00 nginx-pmi nginx: 172.28.0.20 - [14/Jun/2026:06:37:51 +0000] "GET /api/status HTTP/1.1" 200 11
2026-06-14T06:37:51+00:00 nginx-pmi nginx: 172.28.0.20 - [14/Jun/2026:06:37:51 +0000] "POST /api/status HTTP/1.1" 200 11
2026-06-14T06:37:51+00:00 nginx-pmi nginx: 2026/06/14 06:37:51 [error] 37#37: *27 access forbidden by rule, client: 172.28.0.20, server: nginx-test, request: "PUT /api/status HTTP/1.1", host: "172.28.0.2"
2026-06-14T06:37:51+00:00 nginx-pmi nginx: 172.28.0.20 - [14/Jun/2026:06:37:51 +0000] "PUT /api/status HTTP/1.1" 403 146
2026-06-14T06:37:51+00:00 nginx-pmi nginx: 2026/06/14 06:37:51 [error] 38#38: *28 access forbidden by rule, client: 172.28.0.20, server: nginx-test, request: "DELETE /api/status HTTP/1.1", host: "172.28.0.2"
2026-06-14T06:37:51+00:00 nginx-pmi nginx: 172.28.0.20 - [14/Jun/2026:06:37:51 +0000] "DELETE /api/status HTTP/1.1" 403 146
2026-06-14T06:37:51+00:00 nginx-pmi nginx: 172.28.0.20 - [14/Jun/2026:06:37:51 +0000] "GET /protected/document.pdf HTTP/1.1" 404 138
2026-06-14T06:37:51+00:00 nginx-pmi nginx: 172.28.0.20 - [14/Jun/2026:06:37:51 +0000] "GET /download HTTP/1.1" 200 41
2026-06-14T06:37:51+00:00 nginx-pmi nginx: 172.28.0.20 - [14/Jun/2026:06:37:51 +0000] "" 400 0
2026-06-14T06:37:51+00:00 nginx-pmi nginx: 172.28.0.20 - [14/Jun/2026:06:37:51 +0000] "" 400 0
2026-06-14T06:37:52+00:00 nginx-pmi nginx: 172.28.0.20 - [14/Jun/2026:06:37:52 +0000] "\x15\x03\x03\x00\x02\x02F" 400 150
2026-06-14T06:37:52+00:00 nginx-pmi nginx: 172.28.0.20 - [14/Jun/2026:06:37:52 +0000] "HEAD / HTTP/1.1" 301 0
2026-06-14T06:37:52+00:00 nginx-pmi nginx: 172.28.0.20 - [14/Jun/2026:06:37:52 +0000] "HEAD / HTTP/1.1" 404 0
2026-06-14T06:37:52+00:00 nginx-pmi nginx: 172.28.0.20 - [14/Jun/2026:06:37:52 +0000] "GET /test-page HTTP/1.1" 200 13
2026-06-14T06:37:52+00:00 nginx-pmi nginx: 172.28.0.20 - [14/Jun/2026:06:37:52 +0000] "GET /another-page HTTP/1.1" 200 16
2026-06-14T06:37:52+00:00 nginx-pmi nginx: 2026/06/14 06:37:52 [error] 21#21: *38 connect() failed (111: Connection refused) while connecting to upstream, client: 172.28.0.20, server: nginx-test, request: "GET /broken/ HTTP/1.1", upstream: "http://127.0.0.1:59999/", host: "172.28.0.2"
2026-06-14T06:37:52+00:00 nginx-pmi nginx: 172.28.0.20 - [14/Jun/2026:06:37:52 +0000] "GET /broken/ HTTP/1.1" 502 150
2026-06-14T06:37:52+00:00 nginx-pmi nginx: 172.28.0.20 - [14/Jun/2026:06:37:52 +0000] "GET /syslog-probe-1781419072 HTTP/1.1" 404 138
2026-06-14T06:37:53+00:00 nginx-pmi nginx: 172.28.0.20 - [14/Jun/2026:06:37:53 +0000] "GET /rate-limit-check HTTP/1.1" 200 11
2026-06-14T06:37:53+00:00 nginx-pmi nginx: 172.28.0.20 - [14/Jun/2026:06:37:53 +0000] "GET /rate-limit-check HTTP/1.1" 200 11
2026-06-14T06:37:53+00:00 nginx-pmi nginx: 2026/06/14 06:37:53 [error] 21#21: *45 limiting requests, excess: 2.000 by zone "pmi_uri", client: 172.28.0.20, server: nginx-test, request: "GET /rate-limit-check HTTP/1.1", host: "172.28.0.2"
2026-06-14T06:37:53+00:00 nginx-pmi nginx: 172.28.0.20 - [14/Jun/2026:06:37:53 +0000] "GET /rate-limit-check HTTP/1.1" 503 190
2026-06-14T06:37:53+00:00 nginx-pmi nginx: 2026/06/14 06:37:53 [error] 21#21: *46 limiting requests, excess: 2.000 by zone "pmi_uri", client: 172.28.0.20, server: nginx-test, request: "GET /rate-limit-check HTTP/1.1", host: "172.28.0.2"
2026-06-14T06:37:53+00:00 nginx-pmi nginx: 172.28.0.20 - [14/Jun/2026:06:37:53 +0000] "GET /rate-limit-check HTTP/1.1" 503 190
2026-06-14T06:37:53+00:00 nginx-pmi nginx: 2026/06/14 06:37:53 [error] 21#21: *47 limiting requests, excess: 2.000 by zone "pmi_uri", client: 172.28.0.20, server: nginx-test, request: "GET /rate-limit-check HTTP/1.1", host: "172.28.0.2"
2026-06-14T06:37:53+00:00 nginx-pmi nginx: 172.28.0.20 - [14/Jun/2026:06:37:53 +0000] "GET /rate-limit-check HTTP/1.1" 503 190
2026-06-14T06:37:53+00:00 nginx-pmi nginx: 2026/06/14 06:37:53 [error] 21#21: *49 limiting connections by zone "pmi_conn", client: 172.28.0.20, server: nginx-test, request: "GET /slow/ HTTP/1.1", host: "172.28.0.2"
2026-06-14T06:37:53+00:00 nginx-pmi nginx: 2026/06/14 06:37:53 [error] 20#20: *53 limiting connections by zone "pmi_conn", client: 172.28.0.20, server: nginx-test, request: "GET /slow/ HTTP/1.1", host: "172.28.0.2"
2026-06-14T06:37:53+00:00 nginx-pmi nginx: 172.28.0.20 - [14/Jun/2026:06:37:53 +0000] "GET /slow/ HTTP/1.1" 503 190
2026-06-14T06:37:53+00:00 nginx-pmi nginx: 2026/06/14 06:37:53 [error] 22#22: *54 limiting connections by zone "pmi_conn", client: 172.28.0.20, server: nginx-test, request: "GET /slow/ HTTP/1.1", host: "172.28.0.2"
2026-06-14T06:37:53+00:00 nginx-pmi nginx: 172.28.0.20 - [14/Jun/2026:06:37:53 +0000] "GET /slow/ HTTP/1.1" 503 190
2026-06-14T06:37:53+00:00 nginx-pmi nginx: 172.28.0.20 - [14/Jun/2026:06:37:53 +0000] "GET /slow/ HTTP/1.1" 503 190
2026-06-14T06:37:54+00:00 nginx-pmi nginx: 127.0.0.1 - [14/Jun/2026:06:37:54 +0000] "GET /public/index.html HTTP/1.1" 200 138
2026-06-14T06:37:58+00:00 nginx-pmi nginx: 172.28.0.20 - [14/Jun/2026:06:37:58 +0000] "GET /slow/ HTTP/1.1" 200 18
2026-06-14T06:37:58+00:00 nginx-pmi nginx: 172.28.0.20 - [14/Jun/2026:06:37:58 +0000] "GET /slow/ HTTP/1.1" 200 18
2026-06-14T06:37:58+00:00 nginx-pmi nginx: 172.28.0.20 - [14/Jun/2026:06:37:58 +0000] "POST /upload HTTP/1.1" 200 10
2026-06-14T06:37:58+00:00 nginx-pmi nginx: 2026/06/14 06:37:58 [error] 21#21: *57 client intended to send too large body: 2097152 bytes, client: 172.28.0.20, server: nginx-test, request: "POST /upload HTTP/1.1", host: "172.28.0.2"
2026-06-14T06:37:58+00:00 nginx-pmi nginx: 172.28.0.20 - [14/Jun/2026:06:37:58 +0000] "POST /upload HTTP/1.1" 413 176
2026-06-14T06:37:58+00:00 nginx-pmi nginx: 172.28.0.20 - [14/Jun/2026:06:37:58 +0000] "POST /upload HTTP/1.1" 200 10
2026-06-14T06:37:58+00:00 nginx-pmi nginx: 172.28.0.20 - [14/Jun/2026:06:37:58 +0000] "HEAD /public/index.html HTTP/1.1" 200 0
2026-06-14T06:37:58+00:00 nginx-pmi nginx: 172.28.0.20 - [14/Jun/2026:06:37:58 +0000] "GET /nonexistent-page-19 HTTP/1.1" 404 138
2026-06-14T06:37:58+00:00 nginx-pmi nginx: 172.28.0.20 - [14/Jun/2026:06:37:58 +0000] "GET /nonexistent-page-20 HTTP/1.1" 404 138
2026-06-14T06:37:58+00:00 nginx-pmi nginx: 2026/06/14 06:37:58 [error] 20#20: *62 directory index of "/usr/share/nginx/html/files/" is forbidden, client: 172.28.0.20, server: nginx-test, request: "GET /files/ HTTP/1.1", host: "172.28.0.2"
2026-06-14T06:37:58+00:00 nginx-pmi nginx: 172.28.0.20 - [14/Jun/2026:06:37:58 +0000] "GET /files/ HTTP/1.1" 403 146
2026-06-14T06:37:58+00:00 nginx-pmi nginx: 2026/06/14 06:37:58 [error] 20#20: *63 directory index of "/usr/share/nginx/html/files/" is forbidden, client: 172.28.0.20, server: nginx-test, request: "GET /files/ HTTP/1.1", host: "172.28.0.2"
2026-06-14T06:37:58+00:00 nginx-pmi nginx: 172.28.0.20 - [14/Jun/2026:06:37:58 +0000] "GET /files/ HTTP/1.1" 403 146
2026-06-14T06:37:58+00:00 nginx-pmi nginx: 172.28.0.20 - [14/Jun/2026:06:37:58 +0000] "GET /api/status HTTP/1.1" 200 11
2026-06-14T06:37:58+00:00 nginx-pmi nginx: 172.28.0.20 - [14/Jun/2026:06:37:58 +0000] "GET /index.html HTTP/1.1" 200 138
2026-06-14T06:37:58+00:00 nginx-pmi nginx: 172.28.0.20 - [14/Jun/2026:06:37:58 +0000] "GET /etc/passwd HTTP/1.1" 404 138
2026-06-14T06:37:58+00:00 nginx-pmi nginx: 127.0.0.1 - [14/Jun/2026:06:37:58 +0000] "GET /test-page HTTP/1.1" 200 13
2026-06-14T06:37:58+00:00 nginx-pmi nginx: 127.0.0.1 - [14/Jun/2026:06:37:58 +0000] "GET /another-page HTTP/1.1" 200 16
2026-06-14T06:37:58+00:00 nginx-pmi nginx: 2026/06/14 06:37:58 [error] 20#20: *70 connect() failed (111: Connection refused) while connecting to upstream, client: 127.0.0.1, server: nginx-test, request: "GET /broken/ HTTP/1.1", upstream: "http://127.0.0.1:59999/", host: "127.0.0.1"
2026-06-14T06:37:58+00:00 nginx-pmi nginx: 127.0.0.1 - [14/Jun/2026:06:37:58 +0000] "GET /broken/ HTTP/1.1" 502 150
2026-06-14T06:37:59+00:00 nginx-pmi nginx: 127.0.0.1 - [14/Jun/2026:06:37:59 +0000] "GET /public/index.html HTTP/1.1" 200 138
2026-06-14T06:38:04+00:00 nginx-pmi nginx: 127.0.0.1 - [14/Jun/2026:06:38:04 +0000] "GET /public/index.html HTTP/1.1" 200 138
2026-06-14T06:38:09+00:00 nginx-pmi nginx: 127.0.0.1 - [14/Jun/2026:06:38:09 +0000] "GET /public/index.html HTTP/1.1" 200 138
2026-06-14T06:38:14+00:00 nginx-pmi nginx: 127.0.0.1 - [14/Jun/2026:06:38:14 +0000] "GET /public/index.html HTTP/1.1" 200 138
2026-06-14T06:38:19+00:00 nginx-pmi nginx: 127.0.0.1 - [14/Jun/2026:06:38:19 +0000] "GET /public/index.html HTTP/1.1" 200 138
2026-06-14T06:38:24+00:00 nginx-pmi nginx: 127.0.0.1 - [14/Jun/2026:06:38:24 +0000] "GET /public/index.html HTTP/1.1" 200 138
2026-06-14T06:38:29+00:00 nginx-pmi nginx: 127.0.0.1 - [14/Jun/2026:06:38:29 +0000] "GET /public/index.html HTTP/1.1" 200 138
2026-06-14T06:38:34+00:00 nginx-pmi nginx: 127.0.0.1 - [14/Jun/2026:06:38:34 +0000] "GET /public/index.html HTTP/1.1" 200 138
2026-06-14T06:38:39+00:00 nginx-pmi nginx: 127.0.0.1 - [14/Jun/2026:06:38:39 +0000] "GET /public/index.html HTTP/1.1" 200 138
2026-06-14T06:38:44+00:00 nginx-pmi nginx: 127.0.0.1 - [14/Jun/2026:06:38:44 +0000] "GET /public/index.html HTTP/1.1" 200 138
2026-06-14T06:38:49+00:00 nginx-pmi nginx: 127.0.0.1 - [14/Jun/2026:06:38:49 +0000] "GET /public/index.html HTTP/1.1" 200 138
2026-06-14T06:38:54+00:00 nginx-pmi nginx: 127.0.0.1 - [14/Jun/2026:06:38:54 +0000] "GET /public/index.html HTTP/1.1" 200 138
2026-06-14T06:39:00+00:00 nginx-pmi nginx: 127.0.0.1 - [14/Jun/2026:06:39:00 +0000] "GET /public/index.html HTTP/1.1" 200 138
2026-06-14T06:39:05+00:00 nginx-pmi nginx: 127.0.0.1 - [14/Jun/2026:06:39:05 +0000] "GET /public/index.html HTTP/1.1" 200 138
2026-06-14T06:39:10+00:00 nginx-pmi nginx: 127.0.0.1 - [14/Jun/2026:06:39:10 +0000] "GET /public/index.html HTTP/1.1" 200 138
2026-06-14T06:39:15+00:00 nginx-pmi nginx: 127.0.0.1 - [14/Jun/2026:06:39:15 +0000] "GET /public/index.html HTTP/1.1" 200 138
2026-06-14T06:39:20+00:00 nginx-pmi nginx: 127.0.0.1 - [14/Jun/2026:06:39:20 +0000] "GET /public/index.html HTTP/1.1" 200 138
2026-06-14T06:39:25+00:00 nginx-pmi nginx: 127.0.0.1 - [14/Jun/2026:06:39:25 +0000] "GET /public/index.html HTTP/1.1" 200 138
2026-06-14T06:39:30+00:00 nginx-pmi nginx: 127.0.0.1 - [14/Jun/2026:06:39:30 +0000] "GET /public/index.html HTTP/1.1" 200 138
2026-06-14T06:39:35+00:00 nginx-pmi nginx: 127.0.0.1 - [14/Jun/2026:06:39:35 +0000] "GET /public/index.html HTTP/1.1" 200 138
2026-06-14T06:39:40+00:00 nginx-pmi nginx: 127.0.0.1 - [14/Jun/2026:06:39:40 +0000] "GET /public/index.html HTTP/1.1" 200 138
2026-06-14T06:39:45+00:00 nginx-pmi nginx: 127.0.0.1 - [14/Jun/2026:06:39:45 +0000] "GET /public/index.html HTTP/1.1" 200 138
2026-06-14T06:39:50+00:00 nginx-pmi nginx: 127.0.0.1 - [14/Jun/2026:06:39:50 +0000] "GET /public/index.html HTTP/1.1" 200 138
2026-06-14T06:39:55+00:00 nginx-pmi nginx: 127.0.0.1 - [14/Jun/2026:06:39:55 +0000] "GET /public/index.html HTTP/1.1" 200 138
2026-06-14T06:40:00+00:00 nginx-pmi nginx: 127.0.0.1 - [14/Jun/2026:06:40:00 +0000] "GET /public/index.html HTTP/1.1" 200 138
2026-06-14T06:40:05+00:00 nginx-pmi nginx: 127.0.0.1 - [14/Jun/2026:06:40:05 +0000] "GET /public/index.html HTTP/1.1" 200 138
2026-06-14T06:40:10+00:00 nginx-pmi nginx: 127.0.0.1 - [14/Jun/2026:06:40:10 +0000] "GET /public/index.html HTTP/1.1" 200 138
2026-06-14T06:40:15+00:00 nginx-pmi nginx: 127.0.0.1 - [14/Jun/2026:06:40:15 +0000] "GET /public/index.html HTTP/1.1" 200 138
2026-06-14T06:40:21+00:00 nginx-pmi nginx: 127.0.0.1 - [14/Jun/2026:06:40:21 +0000] "GET /public/index.html HTTP/1.1" 200 138
2026-06-14T06:40:26+00:00 nginx-pmi nginx: 127.0.0.1 - [14/Jun/2026:06:40:26 +0000] "GET /public/index.html HTTP/1.1" 200 138
2026-06-14T06:40:31+00:00 nginx-pmi nginx: 127.0.0.1 - [14/Jun/2026:06:40:31 +0000] "GET /public/index.html HTTP/1.1" 200 138
2026-06-14T06:40:36+00:00 nginx-pmi nginx: 127.0.0.1 - [14/Jun/2026:06:40:36 +0000] "GET /public/index.html HTTP/1.1" 200 138
2026-06-14T06:40:41+00:00 nginx-pmi nginx: 127.0.0.1 - [14/Jun/2026:06:40:41 +0000] "GET /public/index.html HTTP/1.1" 200 138
2026-06-14T06:40:46+00:00 nginx-pmi nginx: 127.0.0.1 - [14/Jun/2026:06:40:46 +0000] "GET /public/index.html HTTP/1.1" 200 138
2026-06-14T06:40:51+00:00 nginx-pmi nginx: 127.0.0.1 - [14/Jun/2026:06:40:51 +0000] "GET /public/index.html HTTP/1.1" 200 138
2026-06-14T06:40:56+00:00 nginx-pmi nginx: 127.0.0.1 - [14/Jun/2026:06:40:56 +0000] "GET /public/index.html HTTP/1.1" 200 138
2026-06-14T06:41:01+00:00 nginx-pmi nginx: 127.0.0.1 - [14/Jun/2026:06:41:01 +0000] "GET /public/index.html HTTP/1.1" 200 138
2026-06-14T06:41:06+00:00 nginx-pmi nginx: 127.0.0.1 - [14/Jun/2026:06:41:06 +0000] "GET /public/index.html HTTP/1.1" 200 138
2026-06-14T06:41:11+00:00 nginx-pmi nginx: 127.0.0.1 - [14/Jun/2026:06:41:11 +0000] "GET /public/index.html HTTP/1.1" 200 138
2026-06-14T06:41:16+00:00 nginx-pmi nginx: 127.0.0.1 - [14/Jun/2026:06:41:16 +0000] "GET /public/index.html HTTP/1.1" 200 138
2026-06-14T06:41:21+00:00 nginx-pmi nginx: 127.0.0.1 - [14/Jun/2026:06:41:21 +0000] "GET /public/index.html HTTP/1.1" 200 138
2026-06-14T06:41:26+00:00 nginx-pmi nginx: 127.0.0.1 - [14/Jun/2026:06:41:26 +0000] "GET /public/index.html HTTP/1.1" 200 138
2026-06-14T06:41:31+00:00 nginx-pmi nginx: 127.0.0.1 - [14/Jun/2026:06:41:31 +0000] "GET /public/index.html HTTP/1.1" 200 138
2026-06-14T06:41:36+00:00 nginx-pmi nginx: 127.0.0.1 - [14/Jun/2026:06:41:36 +0000] "GET /public/index.html HTTP/1.1" 200 138
2026-06-14T06:41:42+00:00 nginx-pmi nginx: 127.0.0.1 - [14/Jun/2026:06:41:42 +0000] "GET /public/index.html HTTP/1.1" 200 138
2026-06-14T06:41:47+00:00 nginx-pmi nginx: 127.0.0.1 - [14/Jun/2026:06:41:47 +0000] "GET /public/index.html HTTP/1.1" 200 138
2026-06-14T06:41:52+00:00 nginx-pmi nginx: 127.0.0.1 - [14/Jun/2026:06:41:52 +0000] "GET /public/index.html HTTP/1.1" 200 138
2026-06-14T06:41:57+00:00 nginx-pmi nginx: 127.0.0.1 - [14/Jun/2026:06:41:57 +0000] "GET /public/index.html HTTP/1.1" 200 138
2026-06-14T06:42:02+00:00 nginx-pmi nginx: 127.0.0.1 - [14/Jun/2026:06:42:02 +0000] "GET /public/index.html HTTP/1.1" 200 138
2026-06-14T06:42:07+00:00 nginx-pmi nginx: 127.0.0.1 - [14/Jun/2026:06:42:07 +0000] "GET /public/index.html HTTP/1.1" 200 138
2026-06-14T06:42:12+00:00 nginx-pmi nginx: 127.0.0.1 - [14/Jun/2026:06:42:12 +0000] "GET /public/index.html HTTP/1.1" 200 138
2026-06-14T06:42:17+00:00 nginx-pmi nginx: 127.0.0.1 - [14/Jun/2026:06:42:17 +0000] "GET /public/index.html HTTP/1.1" 200 138
2026-06-14T06:42:22+00:00 nginx-pmi nginx: 127.0.0.1 - [14/Jun/2026:06:42:22 +0000] "GET /public/index.html HTTP/1.1" 200 138
2026-06-14T06:42:27+00:00 nginx-pmi nginx: 127.0.0.1 - [14/Jun/2026:06:42:27 +0000] "GET /public/index.html HTTP/1.1" 200 138

84
results/run.bat Normal file
View File

@@ -0,0 +1,84 @@
@echo off
setlocal EnableExtensions
cd /d "%~dp0"
echo [%date% %time%] nginx PMI stand - start
for /f %%i in ('docker run --rm alpine date +%%Y-%%m-%%d_%%H-%%M-%%S') do set TS=%%i
set REPORTS=%CD%\reports
set PMI_LOG=%TS%_pmi.log
set AUDIT_LOG=%TS%_audit.log
set FIM_LOG=%TS%_fim.log
echo Timestamp: %TS%
echo.
echo [1/8] Generate TLS certificates...
if not exist ssl mkdir ssl
docker run --rm --entrypoint sh -v "%CD%/ssl:/ssl" -v "%CD%/scripts/gen-certs.sh:/gen-certs.sh:ro" alpine/openssl /gen-certs.sh
if errorlevel 1 goto :fail
echo.
echo [2/8] Generate htpasswd...
docker run --rm --entrypoint sh -v "%CD%/nginx:/out" -v "%CD%/scripts/gen-htpasswd.sh:/gen-htpasswd.sh:ro" alpine/openssl /gen-htpasswd.sh
if errorlevel 1 goto :fail
echo.
echo [3/8] Build and start containers...
docker compose build
if errorlevel 1 goto :fail
docker compose up -d
if errorlevel 1 goto :fail
docker compose restart nginx syslog-ng
if errorlevel 1 goto :fail
echo.
echo [4/8] Wait for nginx...
docker compose exec -T test-runner sh /scripts/wait-ready.sh
if errorlevel 1 goto :fail
echo.
echo [5/8] Run PMI tests...
docker compose exec -T -e REPORT=/reports/%PMI_LOG% test-runner sh /scripts/run-pmi-tests.sh
set PMI_RC=%ERRORLEVEL%
docker compose exec -T -e REPORT=/reports/%PMI_LOG% nginx sh /scripts/run-pmi-log-checks.sh
if errorlevel 1 set PMI_RC=1
echo.
echo [6/8] Run audits...
docker compose exec -T -e REPORT=/reports/%AUDIT_LOG% nginx sh /scripts/run-audit-permissions.sh
docker compose exec -T -e REPORT=/reports/%AUDIT_LOG% nginx sh /scripts/run-audit-attack-surface.sh
docker compose exec -T -e REPORT=/reports/%AUDIT_LOG% nginx sh /scripts/run-audit-code-control.sh
echo.
echo [7/8] Run FIM checksum (afick stand-in)...
docker compose exec -T -e REPORT=/reports/%FIM_LOG% nginx sh /scripts/run-fim-checksum.sh
set FIM_RC=%ERRORLEVEL%
echo.
echo [8/8] Generate summary...
docker compose exec -T -e REPORTS_DIR=/reports test-runner sh /scripts/generate-summary.sh %TS%
echo.
echo Done. Reports in: %REPORTS%
echo %PMI_LOG%
echo %AUDIT_LOG%
echo %FIM_LOG%
echo %TS%_summary.md
if not "%PMI_RC%"=="0" (
echo PMI tests: FAILED
exit /b 1
)
if not "%FIM_RC%"=="0" (
echo FIM check: FAILED
exit /b 1
)
echo All checks completed successfully.
exit /b 0
:fail
echo ERROR: step failed.
exit /b 1

View File

@@ -0,0 +1,31 @@
#!/bin/sh
set -eu
SSL_DIR="${SSL_DIR:-/ssl}"
cd "$SSL_DIR"
openssl genrsa -out ca.key 4096
openssl req -x509 -new -nodes -key ca.key -sha256 -days 3650 \
-subj "/CN=PMI Test CA" -out ca.crt
openssl genrsa -out server.key 2048
openssl req -new -key server.key -subj "/CN=nginx-test" -out server.csr
openssl x509 -req -in server.csr -CA ca.crt -CAkey ca.key -CAcreateserial \
-out server.crt -days 825 -sha256
openssl genrsa -out client.key 2048
openssl req -new -key client.key -subj "/CN=trusted-client" -out client.csr
openssl x509 -req -in client.csr -CA ca.crt -CAkey ca.key -CAcreateserial \
-out client.crt -days 825 -sha256
openssl genrsa -out untrusted.key 2048
openssl req -x509 -new -nodes -key untrusted.key -sha256 -days 365 \
-subj "/CN=untrusted-client" -out untrusted.crt
chmod 600 ca.key server.key client.key untrusted.key
chmod 644 ca.crt server.crt client.crt untrusted.crt
cat server.crt ca.crt > fullchain.crt
chmod 644 fullchain.crt
rm -f server.csr client.csr ca.srl
echo "Certificates generated in $SSL_DIR"

View File

@@ -0,0 +1,7 @@
#!/bin/sh
set -eu
OUT="${OUT:-/out/htpasswd}"
hash=$(openssl passwd -apr1 'password')
echo "user:$hash" > "$OUT"
echo "Created $OUT (user:password)"

View File

@@ -0,0 +1,69 @@
#!/bin/bash
# Build summary markdown from report logs.
set -euo pipefail
TS="${1:-unknown}"
REPORTS="${REPORTS_DIR:-/reports}"
OUT="$REPORTS/${TS}_summary.md"
pmi="$REPORTS/${TS}_pmi.log"
audit="$REPORTS/${TS}_audit.log"
fim="$REPORTS/${TS}_fim.log"
count_status() {
local file="$1" status="$2"
local n=0
if [ -f "$file" ]; then
n=$(grep -c "^${status} " "$file" 2>/dev/null) || n=0
fi
echo "$n"
}
pass_pmi=$(count_status "$pmi" PASS)
fail_pmi=$(count_status "$pmi" FAIL)
pass_fim=$(count_status "$fim" PASS)
fail_fim=$(count_status "$fim" FAIL)
{
echo "# Сводный отчёт nginx PMI stand"
echo ""
echo "**Дата прогона:** $TS"
echo "**Стенд:** Docker Compose (\`results/docker-compose.yml\`)"
echo ""
echo "## Результаты ПМИ"
echo ""
echo "| Метрика | Значение |"
echo "|---------|----------|"
echo "| PASS | $pass_pmi |"
echo "| FAIL | $fail_pmi |"
echo ""
echo "## Целостность (FIM stand-in)"
echo ""
echo "| Метрика | Значение |"
echo "|---------|----------|"
echo "| PASS | $pass_fim |"
echo "| FAIL | $fail_fim |"
echo ""
echo "> FIM выполнен через SHA256 baseline (\`run-fim-checksum.sh\`), не afick."
echo "> Syslog проверялся локальным syslog-ng, не корпоративным SIEM."
echo ""
echo "## Файлы отчётов"
echo ""
echo "- [\`${TS}_pmi.log\`](${TS}_pmi.log)"
echo "- [\`${TS}_audit.log\`](${TS}_audit.log)"
echo "- [\`${TS}_fim.log\`](${TS}_fim.log)"
echo ""
echo "## PMI log excerpt"
echo ""
echo '```'
[ -f "$pmi" ] && grep -E '^(PASS|FAIL|SKIP|===)' "$pmi" || echo "(no pmi log)"
echo '```'
echo ""
echo "## FIM log excerpt"
echo ""
echo '```'
[ -f "$fim" ] && cat "$fim" || echo "(no fim log)"
echo '```'
} > "$OUT"
echo "Summary written: $OUT"

View File

@@ -0,0 +1,26 @@
#!/bin/sh
# Audit: attack surface minimization (docs/Минимизация_поверхности_атаки_nginx)
set -eu
REPORT="${REPORT:-/reports/audit.log}"
{
echo ""
echo "=== Attack surface audit $(date -Iseconds) ==="
echo "--- nginx -V ---"
nginx -V 2>&1
echo "--- load_module ---"
nginx -T 2>/dev/null | grep load_module || echo "(none)"
echo "--- optional modules in config ---"
nginx -T 2>/dev/null | grep -E 'dav_methods|perl|js_import|js_content|xslt_stylesheet|auth_request' || echo "(none found)"
echo "--- autoindex ---"
nginx -T 2>/dev/null | grep autoindex || echo "(default off)"
echo "--- limit_except / request_method ---"
nginx -T 2>/dev/null | grep -E 'limit_except|request_method' || true
echo "--- proxy_pass / upstream ---"
nginx -T 2>/dev/null | grep -E 'proxy_pass|upstream' || true
echo "--- ssi ---"
nginx -T 2>/dev/null | grep -i 'ssi on' || echo "(ssi off)"
} >> "$REPORT"
echo "Attack surface audit appended -> $REPORT"

View File

@@ -0,0 +1,15 @@
#!/bin/sh
# Audit: code execution control (docs/Контроль_выполнения_кода)
set -eu
REPORT="${REPORT:-/reports/audit.log}"
{
echo ""
echo "=== Code execution control audit $(date -Iseconds) ==="
nginx -T 2>/dev/null | grep -E 'fastcgi_pass|uwsgi_pass|scgi_pass|grpc_pass|perl|js_import|internal|^\s*root\s|alias' || true
echo "--- SCRIPT_FILENAME ---"
nginx -T 2>/dev/null | grep SCRIPT_FILENAME || echo "(no fastcgi)"
} >> "$REPORT"
echo "Code control audit appended -> $REPORT"

View File

@@ -0,0 +1,56 @@
#!/bin/sh
# Audit: minimal permissions (docs/Минимальноеобходимые_полномочия_nginx)
set -eu
REPORT="${REPORT:-/reports/audit.log}"
section() { echo "" >> "$REPORT"; echo "=== $1 ===" >> "$REPORT"; echo "=== $1 ==="; }
: > "$REPORT"
echo "Permissions audit $(date -Iseconds)" >> "$REPORT"
section "Worker user"
nginx -T 2>/dev/null | grep '^user ' >> "$REPORT" || true
ps aux | grep 'nginx:' >> "$REPORT" || true
section "Config permissions"
ls -la /etc/nginx/ >> "$REPORT"
namei -l /etc/nginx/nginx.conf >> "$REPORT" 2>/dev/null || ls -l /etc/nginx/nginx.conf >> "$REPORT"
if su -s /bin/sh nginx -c 'test -w /etc/nginx/nginx.conf' 2>/dev/null; then
echo "FAIL: nginx can write nginx.conf" >> "$REPORT"
else
echo "OK: nginx cannot write nginx.conf" >> "$REPORT"
fi
section "Web root permissions"
ls -la /usr/share/nginx/html/public/ >> "$REPORT"
if su -s /bin/sh nginx -c 'test -w /usr/share/nginx/html/public/index.html' 2>/dev/null; then
echo "FAIL: nginx can write web root" >> "$REPORT"
else
echo "OK: nginx cannot write web root" >> "$REPORT"
fi
section "TLS certificates and keys"
ls -la /etc/nginx/ssl/ >> "$REPORT"
if su -s /bin/sh nginx -c 'cat /etc/nginx/ssl/server.key' 2>/dev/null; then
echo "FAIL: nginx can read private key" >> "$REPORT"
else
echo "OK: nginx cannot read private key" >> "$REPORT"
fi
section "htpasswd"
ls -la /etc/nginx/htpasswd >> "$REPORT" 2>/dev/null || true
if su -s /bin/sh nginx -c 'test -w /etc/nginx/htpasswd' 2>/dev/null; then
echo "FAIL: nginx can write htpasswd" >> "$REPORT"
else
echo "OK: nginx cannot write htpasswd" >> "$REPORT"
fi
section "Logs"
ls -la /var/log/nginx/ >> "$REPORT"
section "Temp/cache paths"
ls -la /var/cache/nginx/ >> "$REPORT" 2>/dev/null || echo "cache dir not yet created" >> "$REPORT"
nginx -T 2>/dev/null | grep -E 'client_body_temp_path|proxy_temp_path' >> "$REPORT" || true
echo "Audit permissions complete -> $REPORT"

View File

@@ -0,0 +1,45 @@
#!/bin/sh
# FIM substitute: SHA256 baseline (docs/Контроль_целостности; PMI p.24)
# Note: stand-in for afick, not a certification tool.
set -eu
REPORT="${REPORT:-/reports/fim.log}"
BASELINE="${BASELINE:-/tmp/fim-baseline.sha256}"
PATHS="/etc/nginx /usr/share/nginx/html /fim-watch"
WATCH_FILE="/fim-watch/config.snippet"
checksum() {
find $PATHS -type f 2>/dev/null | sort | xargs sha256sum 2>/dev/null
}
: > "$REPORT"
echo "FIM checksum audit $(date -Iseconds)" >> "$REPORT"
echo "NOTE: SHA256 baseline substitute for afick on test stand only." >> "$REPORT"
checksum > "$BASELINE"
echo "Baseline created ($(wc -l < "$BASELINE") files)" >> "$REPORT"
if checksum | diff -q "$BASELINE" - > /dev/null 2>&1; then
echo "PASS baseline check (no changes)" >> "$REPORT"
else
echo "FAIL unexpected baseline diff before tamper test" >> "$REPORT"
exit 1
fi
echo "# tamper $(date +%s)" >> "$WATCH_FILE"
if checksum | diff -q "$BASELINE" - > /dev/null 2>&1; then
echo "FAIL tamper not detected" >> "$REPORT"
exit 1
else
echo "PASS tamper detected after file change ($WATCH_FILE)" >> "$REPORT"
fi
printf '# FIM watch file for integrity test (PMI p.24 stand-in)\n' > "$WATCH_FILE"
if checksum | diff -q "$BASELINE" - > /dev/null 2>&1; then
echo "PASS baseline restored after revert" >> "$REPORT"
else
echo "WARN baseline differs after revert (review manually)" >> "$REPORT"
fi
echo "PASS #24 integrity control (checksum substitute for afick)" >> "$REPORT"
echo "FIM checksum complete -> $REPORT"

View File

@@ -0,0 +1,33 @@
#!/bin/sh
# Log checks for PMI items 12 and 13 (runs inside nginx container).
set -eu
REPORT="${REPORT:-/reports/pmi.log}"
ACCESS_LOG="/reports/nginx-file-access.log"
ERROR_LOG="/reports/nginx-file-error.log"
: > "$ACCESS_LOG"
: > "$ERROR_LOG"
curl -s --max-time 5 http://127.0.0.1/test-page > /dev/null
curl -s --max-time 5 http://127.0.0.1/another-page > /dev/null
curl -s --max-time 5 http://127.0.0.1/broken/ > /dev/null || true
sleep 1
if grep -q '/test-page' "$ACCESS_LOG" && grep -q '/another-page' "$ACCESS_LOG"; then
echo "PASS #12 access_log contains test-page and another-page" >> "$REPORT"
echo "PASS #12 access_log contains test-page and another-page"
else
echo "FAIL #12 access_log missing expected entries" >> "$REPORT"
echo "FAIL #12 access_log missing expected entries"
exit 1
fi
if grep -qE 'connect\(\) failed|Connection refused|upstream' "$ERROR_LOG"; then
echo "PASS #13 error_log contains upstream error" >> "$REPORT"
echo "PASS #13 error_log contains upstream error"
else
echo "FAIL #13 error_log missing upstream error" >> "$REPORT"
echo "FAIL #13 error_log missing upstream error"
exit 1
fi

View File

@@ -0,0 +1,291 @@
#!/bin/bash
set -uo pipefail
NGINX_A="http://172.28.0.2"
NGINX_D="http://172.29.0.2"
HTTPS="https://172.28.0.2"
TLS_HOST="172.28.0.2:443"
ALLOWED_IF="172.28.0.20"
DENIED_IF="172.29.0.20"
SSL="/ssl"
REPORT="${REPORT:-/reports/pmi.log}"
AUTH_MODE="/auth-mode/mode"
PASS=0
FAIL=0
SKIP=0
log() { echo "$@" | tee -a "$REPORT"; }
pass() { log "PASS #$1 $2"; PASS=$((PASS + 1)); }
fail() { log "FAIL #$1 $2"; FAIL=$((FAIL + 1)); }
skip() { log "SKIP #$1 $2"; SKIP=$((SKIP + 1)); }
http_code() {
local iface="$1" url="$2"
shift 2
curl -s -o /dev/null -w '%{http_code}' --interface "$iface" --connect-timeout 10 "$url" "$@"
}
set_auth_mode() {
echo "$1" > "$AUTH_MODE"
sleep 0.5
}
: > "$REPORT"
log "=== PMI tests $(date -Iseconds) ==="
log ""
# --- 1. IP allow/deny ---
c1=$(http_code "$ALLOWED_IF" "$NGINX_A/admin/")
c2=$(http_code "$DENIED_IF" "$NGINX_D/admin/")
if [ "$c1" = "200" ] && [ "$c2" = "403" ]; then
pass 1 "IP allow/deny (allowed=$c1 denied=$c2)"
else
fail 1 "IP allow/deny (allowed=$c1 denied=$c2, expected 200/403)"
fi
# --- 2. Basic auth ---
c_no=$(http_code "$ALLOWED_IF" "$NGINX_A/secure/")
c_wrong=$(http_code "$ALLOWED_IF" "$NGINX_A/secure/" -u 'wrong:wrong')
c_ok=$(http_code "$ALLOWED_IF" "$NGINX_A/secure/" -u 'user:password')
if [ "$c_no" = "401" ] && [ "$c_wrong" = "401" ] && [ "$c_ok" = "200" ]; then
pass 2 "Basic auth (401/401/200)"
else
fail 2 "Basic auth ($c_no/$c_wrong/$c_ok expected 401/401/200)"
fi
# --- 3. mTLS ---
c3_no=$(curl -sk -o /dev/null -w '%{http_code}' --interface "$ALLOWED_IF" \
--resolve nginx-test-mtls:443:172.28.0.2 https://nginx-test-mtls/)
c3_ok=$(curl -sk -o /dev/null -w '%{http_code}' --interface "$ALLOWED_IF" \
--resolve nginx-test-mtls:443:172.28.0.2 --cert "$SSL/client.crt" --key "$SSL/client.key" --cacert "$SSL/ca.crt" \
https://nginx-test-mtls/)
c3_bad=$(curl -sk -o /dev/null -w '%{http_code}' --interface "$ALLOWED_IF" \
--resolve nginx-test-mtls:443:172.28.0.2 --cert "$SSL/untrusted.crt" --key "$SSL/untrusted.key" --cacert "$SSL/ca.crt" \
https://nginx-test-mtls/)
if [ "$c3_no" = "400" ] && [ "$c3_ok" = "200" ] && [ "$c3_bad" = "400" ]; then
pass 3 "Client TLS certificate (400/200/400)"
else
fail 3 "Client TLS certificate ($c3_no/$c3_ok/$c3_bad expected 400/200/400)"
fi
# --- 4. auth_request ---
set_auth_mode 200
c4a=$(http_code "$ALLOWED_IF" "$NGINX_A/auth-protected/status")
set_auth_mode 401
c4b=$(http_code "$ALLOWED_IF" "$NGINX_A/auth-protected/status")
set_auth_mode 403
c4c=$(http_code "$ALLOWED_IF" "$NGINX_A/auth-protected/status")
set_auth_mode 200
if [ "$c4a" = "200" ] && [ "$c4b" = "401" ] && [ "$c4c" = "403" ]; then
pass 4 "auth_request (200/401/403)"
else
fail 4 "auth_request ($c4a/$c4b/$c4c expected 200/401/403)"
fi
# --- 5. satisfy all ---
c5a=$(http_code "$ALLOWED_IF" "$NGINX_A/admin-combined/" -u 'user:password')
c5b=$(http_code "$ALLOWED_IF" "$NGINX_A/admin-combined/")
c5c=$(http_code "$DENIED_IF" "$NGINX_D/admin-combined/" -u 'user:password')
c5d=$(http_code "$DENIED_IF" "$NGINX_D/admin-combined/")
if [ "$c5a" = "200" ] && [ "$c5b" = "401" ] && [ "$c5c" = "403" ] && [ "$c5d" = "403" ]; then
pass 5 "satisfy all matrix (200/401/403/403)"
else
fail 5 "satisfy all ($c5a/$c5b/$c5c/$c5d expected 200/401/403/403)"
fi
# --- 6. URL separation ---
c6a=$(http_code "$ALLOWED_IF" "$NGINX_A/public/index.html")
c6b=$(http_code "$DENIED_IF" "$NGINX_D/admin/")
if [ "$c6a" = "200" ] && [ "$c6b" = "403" ]; then
pass 6 "URL access rules (/public/ vs /admin/)"
else
fail 6 "URL access ($c6a/$c6b expected 200/403)"
fi
# --- 7. limit_except ---
c7g=$(http_code "$ALLOWED_IF" "$NGINX_A/api/status" -X GET)
c7p=$(http_code "$ALLOWED_IF" "$NGINX_A/api/status" -X POST)
c7u=$(http_code "$ALLOWED_IF" "$NGINX_A/api/status" -X PUT)
c7d=$(http_code "$ALLOWED_IF" "$NGINX_A/api/status" -X DELETE)
if [ "$c7g" = "200" ] && [ "$c7p" = "200" ] && [ "$c7u" = "403" ] && [ "$c7d" = "403" ]; then
pass 7 "limit_except GET POST (PUT/DELETE=403)"
else
fail 7 "limit_except ($c7g/$c7p/$c7u/$c7d expected 200/200/403/403)"
fi
# --- 8. internal ---
c8a=$(http_code "$ALLOWED_IF" "$NGINX_A/protected/document.pdf")
c8b=$(http_code "$ALLOWED_IF" "$NGINX_A/download")
if [ "$c8a" = "404" ] && [ "$c8b" = "200" ]; then
pass 8 "internal location (direct=404 rewrite=200)"
else
fail 8 "internal ($c8a/$c8b expected 404/200)"
fi
# --- 9. TLS connection ---
s9=$(echo | openssl s_client -connect "$TLS_HOST" -servername nginx-test 2>&1 || true)
if echo "$s9" | grep -qE "Verify return code: (0|18|19|21)|SSL-Session:"; then
pass 9 "HTTPS TLS handshake"
else
fail 9 "HTTPS TLS handshake failed"
fi
# --- 10. TLS versions ---
s10ok=$(echo | openssl s_client -connect "$TLS_HOST" -servername nginx-test -tls1_2 2>&1 || true)
s10bad=$(echo | openssl s_client -connect "$TLS_HOST" -servername nginx-test -tls1_1 2>&1 || true)
if echo "$s10ok" | grep -q "Protocol : TLSv1.2" && echo "$s10bad" | grep -qi "alert protocol version\|no protocols available\|wrong version"; then
pass 10 "TLSv1.2 ok, TLSv1.1 rejected"
else
fail 10 "TLS version policy"
fi
# --- 11. HTTPS redirect + HSTS ---
h11=$(curl -sI --interface "$ALLOWED_IF" -H "Host: redirect-test" "$NGINX_A/" | tr -d '\r')
hsts=$(curl -skI --interface "$ALLOWED_IF" "$HTTPS/" -H "Host: nginx-test" | tr -d '\r')
ok11=0
echo "$h11" | grep -q "301" && ok11=$((ok11 + 1))
echo "$h11" | grep -qi "location: https://" && ok11=$((ok11 + 1))
echo "$hsts" | grep -qi "strict-transport-security:" && ok11=$((ok11 + 1))
if [ "$ok11" -eq 3 ]; then
pass 11 "HTTP redirect 301 + HSTS header"
else
fail 11 "Redirect/HSTS (checks $ok11/3)"
fi
# --- 12-13. access/error logs (detailed check in run-pmi-log-checks.sh) ---
curl -s --interface "$ALLOWED_IF" "$NGINX_A/test-page" > /dev/null
curl -s --interface "$ALLOWED_IF" "$NGINX_A/another-page" > /dev/null
curl -s --max-time 5 --interface "$ALLOWED_IF" "$NGINX_A/broken/" > /dev/null || true
# --- 14. syslog ---
curl -s --interface "$ALLOWED_IF" "$NGINX_A/syslog-probe-$(date +%s)" > /dev/null || true
ok14=0
for _ in 1 2 3 4 5; do
sleep 1
if [ -f /reports/nginx-syslog.log ] && grep -q "nginx" /reports/nginx-syslog.log 2>/dev/null; then
ok14=1
break
fi
done
if [ "$ok14" -eq 1 ]; then
pass 14 "syslog receives nginx events"
else
fail 14 "syslog log missing or empty (/reports/nginx-syslog.log)"
fi
# --- 15. limit_req ---
count503=0
count200=0
codes15=""
for i in $(seq 1 5); do
c=$(http_code "$ALLOWED_IF" "$NGINX_A/rate-limit-check")
codes15="$codes15 $c"
[ "$c" = "503" ] && count503=$((count503 + 1))
[ "$c" = "200" ] && count200=$((count200 + 1))
done
if [ "$count503" -gt 0 ] && [ "$count200" -gt 0 ]; then
pass 15 "limit_req returns 503 ($count503) and 200 ($count200) in:$codes15"
elif [ "$count503" -gt 0 ]; then
pass 15 "limit_req returns 503 ($count503 of 5 in:$codes15)"
else
fail 15 "limit_req no 503 in:$codes15"
fi
# --- 16. limit_conn ---
pids=""
for i in 1 2 3 4 5; do
curl -s -o /tmp/s16_$i -w '%{http_code}' --interface "$ALLOWED_IF" --max-time 25 "$NGINX_A/slow/" > /tmp/c16_$i &
pids="$pids $!"
done
for p in $pids; do wait "$p" 2>/dev/null || true; done
codes16=$(cat /tmp/c16_* 2>/dev/null | tr '\n' ' ')
if echo "$codes16" | grep -q "503"; then
pass 16 "limit_conn returns 503 ($codes16)"
else
fail 16 "limit_conn no 503 in: $codes16"
fi
rm -f /tmp/c16_* /tmp/s16_* 2>/dev/null || true
# --- 17. client_max_body_size ---
dd if=/dev/zero of=/tmp/pmi-small bs=1024 count=100 status=none 2>/dev/null
dd if=/dev/zero of=/tmp/pmi-large bs=1M count=2 status=none 2>/dev/null
c17s=$(curl -s -o /dev/null -w '%{http_code}' --interface "$ALLOWED_IF" -X POST -T /tmp/pmi-small "$NGINX_A/upload")
c17l=$(curl -s -o /dev/null -w '%{http_code}' --interface "$ALLOWED_IF" -X POST -T /tmp/pmi-large "$NGINX_A/upload")
if [ "$c17s" = "200" ] && [ "$c17l" = "413" ]; then
pass 17 "client_max_body_size (small=$c17s large=$c17l)"
else
fail 17 "client_max_body_size ($c17s/$c17l expected 200/413)"
fi
# --- 18. client_body_timeout ---
if dd if=/dev/zero bs=1K count=800 2>/dev/null | curl -s -o /dev/null -w '%{http_code}' \
--interface "$ALLOWED_IF" --limit-rate 1K -m 30 -X POST -d @- "$NGINX_A/upload" | grep -qv 200; then
pass 18 "client_body_timeout (slow upload rejected/timed out)"
else
# curl may return 000 on timeout
ec=$?
if [ "$ec" -ne 0 ]; then
pass 18 "client_body_timeout (curl exit $ec)"
else
fail 18 "client_body_timeout (upload unexpectedly succeeded quickly)"
fi
fi
# --- 19. server_tokens off ---
hdr=$(curl -sI --interface "$ALLOWED_IF" "$NGINX_A/public/index.html" | tr -d '\r')
body=$(curl -s --interface "$ALLOWED_IF" "$NGINX_A/nonexistent-page-19")
if echo "$hdr" | grep -i "^server: nginx$" && ! echo "$hdr" | grep -q "nginx/"; then
if ! echo "$body" | grep -q "nginx/"; then
pass 19 "server_tokens off"
else
fail 19 "server_tokens off (version in error body)"
fi
else
fail 19 "server_tokens off (Server header: $(echo "$hdr" | grep -i ^server:))"
fi
# --- 20. error_page ---
b20=$(curl -s --interface "$ALLOWED_IF" "$NGINX_A/nonexistent-page-20")
if echo "$b20" | grep -q "Custom 404"; then
pass 20 "custom error_page 404"
else
fail 20 "custom error_page (body missing Custom 404)"
fi
# --- 21. autoindex off ---
c21=$(http_code "$ALLOWED_IF" "$NGINX_A/files/")
body21=$(curl -s --interface "$ALLOWED_IF" "$NGINX_A/files/")
if [ "$c21" = "403" ] && ! echo "$body21" | grep -qi "<title>Index of"; then
pass 21 "autoindex off (403, no listing)"
else
fail 21 "autoindex ($c21, listing=$(echo "$body21" | head -1))"
fi
# --- 22. proxy_pass ---
c22=$(http_code "$ALLOWED_IF" "$NGINX_A/api/status")
if [ "$c22" = "200" ]; then
pass 22 "proxy_pass to backend ($c22)"
else
fail 22 "proxy_pass ($c22 expected 200)"
fi
# --- 23. path traversal ---
c23a=$(http_code "$ALLOWED_IF" "$NGINX_A/index.html")
c23b=$(http_code "$ALLOWED_IF" "$NGINX_A/../../../etc/passwd")
if [ "$c23a" = "200" ] && [ "$c23b" = "404" ]; then
pass 23 "web root restriction ($c23a/$c23b)"
else
fail 23 "web root ($c23a/$c23b expected 200/404)"
fi
# --- 24. FIM (run-fim-checksum.sh) ---
log ""
log "=== Summary: PASS=$PASS FAIL=$FAIL SKIP=$SKIP ==="
if [ "$FAIL" -gt 0 ]; then
exit 1
fi
exit 0

View File

@@ -0,0 +1,14 @@
#!/bin/sh
set -eu
echo "Waiting for nginx..."
for i in $(seq 1 30); do
if wget -q -O /dev/null http://nginx/public/index.html 2>/dev/null; then
echo "nginx is ready"
exit 0
fi
sleep 2
done
echo "nginx not ready after 60s" >&2
exit 1

30
results/ssl/ca.crt Normal file
View File

@@ -0,0 +1,30 @@
-----BEGIN CERTIFICATE-----
MIIFDTCCAvWgAwIBAgIUZZIrRtH2O6qauuDjnP2jwFNtdfQwDQYJKoZIhvcNAQEL
BQAwFjEUMBIGA1UEAwwLUE1JIFRlc3QgQ0EwHhcNMjYwNjE0MDYzNzQzWhcNMzYw
NjExMDYzNzQzWjAWMRQwEgYDVQQDDAtQTUkgVGVzdCBDQTCCAiIwDQYJKoZIhvcN
AQEBBQADggIPADCCAgoCggIBAJ+Uha/JdxrEvoogtY2gGdpmWWoSDZuh3F5uKLjw
k4F39PQ1hAeO3YBpcmPkY6CpwZMYvkoZU1Fd8B404FTDSg2zpV/gulgr0fncMjPg
xpqzRnuOaB7jEuWV1f6IHlRn+NDv/HEZEobhrDdL9/EIrx5SFQFgWuB+EMxwJI8I
oNYhMF6d9GRvyXNos49a9BDfkNH6TDktIK/w/z2ASQYxoAj5bQK7B+jcKf84FA6x
FrWYmW+v0d0Gp3ghtjVnvRSF11YK4OkAFJtNCh8v3scFqSBDqC4Lo9g8hKnDQCio
5IgjQy7zV48BJ/ZEqoL66qDcVZyi202A+MKaj2naCmKhqMWFiuJdY6Y0QxXn02jD
gRiyWq0bElnyDUhqJEC/A4NoMAxjYBBZMRXU2/3rbKodUlLMYH5hWGbWkQzWoiWb
jzvks7gXRcTFFr2nJG4RbfTRRlUI7t5utvcmyX6Czw1QEyE67vJ/KkW0hvDuLznc
OgX9dc9mWBlU16kWlCn19g4o4qzw4155HEc2Ro7jr7gATRilKVb70yXq877LUlN7
/jrTb+lMFr9e9dzsY0YS3xpjx2dn8TsXuaVjY+VWMRXrHmgs661Ur10SVe6K1AN/
jaLo6vRXF8XqPVxIjg/uiInIwsxJNjOpOK/aqjmmH02pmPlUTgtURoZ0GXvJNNAd
kD53AgMBAAGjUzBRMB0GA1UdDgQWBBSqDA68B/rOcM63XMAFkyJKxaNzjjAfBgNV
HSMEGDAWgBSqDA68B/rOcM63XMAFkyJKxaNzjjAPBgNVHRMBAf8EBTADAQH/MA0G
CSqGSIb3DQEBCwUAA4ICAQCRnXhE1VX2++3RT8fTtsH+WYNOo5zcHTqKlqQd922+
i3LX0QHoy/8v8ZHVfPvD2swFGB9gkq5YimS5qPtSm8p0WkGscIeMqOaxGsUBcEzK
XTjDYBoPorBx3+JpVp4jERz0umKo1H3QRwDKGADp3y+I+JcsxO64LOv15tkSYhmZ
sqhs6fr9hnqbYFyARiFMvMZX5zLKDbqtHSOOZUVeo3QKXKu5+mwYBTOO5NTcsiR7
FoWVpIlAvT0ST/YtfLyl8YIRfhJn2RXjNXDSXWkNlDwz6WEAaKtr/SyD0OCMQGqk
BmjSTPAgbh4VpLTA1HFf47fQp7tMXmNpRR+MMqmT5Q41jLr8/jZDns+yjCaXHulK
1N1axdHdDBAfZiwgfSmeCm4dhZfWEmgLwm2zNdbqR7hxDmpmf0YRuzthABeRs9+q
NfnY1z6vLYV+guei239l5AuopwyMjkXbZvl4+CxZ4iIA5abPoax5Ij3T1blQSS/t
eTOd/7YIacg7RmixFp6D7IJUehRADGEVFT//Kiao3K9Csa0fbSKUIcS5b6aIJv8R
s6ho7anoyE8ZmNU1yS/nOKzg59TVG6dMx49eWIwzCdRnihMhYadJ8GsxLluuH5dh
BqTFPmA4ejtrtORFO+b457EUM3Ay2wlaYQj+e4Qp7znQP5IugsX4nXQfPr7FrJ2J
8Q==
-----END CERTIFICATE-----

52
results/ssl/ca.key Normal file
View File

@@ -0,0 +1,52 @@
-----BEGIN PRIVATE KEY-----
MIIJQgIBADANBgkqhkiG9w0BAQEFAASCCSwwggkoAgEAAoICAQCflIWvyXcaxL6K
ILWNoBnaZllqEg2bodxebii48JOBd/T0NYQHjt2AaXJj5GOgqcGTGL5KGVNRXfAe
NOBUw0oNs6Vf4LpYK9H53DIz4Maas0Z7jmge4xLlldX+iB5UZ/jQ7/xxGRKG4aw3
S/fxCK8eUhUBYFrgfhDMcCSPCKDWITBenfRkb8lzaLOPWvQQ35DR+kw5LSCv8P89
gEkGMaAI+W0Cuwfo3Cn/OBQOsRa1mJlvr9HdBqd4IbY1Z70UhddWCuDpABSbTQof
L97HBakgQ6guC6PYPISpw0AoqOSII0Mu81ePASf2RKqC+uqg3FWcottNgPjCmo9p
2gpioajFhYriXWOmNEMV59Now4EYslqtGxJZ8g1IaiRAvwODaDAMY2AQWTEV1Nv9
62yqHVJSzGB+YVhm1pEM1qIlm4875LO4F0XExRa9pyRuEW300UZVCO7ebrb3Jsl+
gs8NUBMhOu7yfypFtIbw7i853DoF/XXPZlgZVNepFpQp9fYOKOKs8ONeeRxHNkaO
46+4AE0YpSlW+9Ml6vO+y1JTe/4602/pTBa/XvXc7GNGEt8aY8dnZ/E7F7mlY2Pl
VjEV6x5oLOutVK9dElXuitQDf42i6Or0VxfF6j1cSI4P7oiJyMLMSTYzqTiv2qo5
ph9NqZj5VE4LVEaGdBl7yTTQHZA+dwIDAQABAoICADC2IHzBTacRKWx2gZTiqyGc
nmyfaCH6rY7xp2KUpSIfINmuwEeiV4DML0vIupSfXORu6B8sTd+HgjVmRJf7KM63
6KI0sg0aCzVu/rARS+6LDNfIZ4YOIIWOUE0q9b8kIbJ9nxxS3/HmTzBt8xhTY0kp
GxpZdEQUl0IgdThoFNhoNyCarLA/40lkS3NV+yxvYgCGm9/UI6cxNGhskV3fpg83
PAxaVRbCpdsvHghCDEGQfD24eKI0Vsh32evBZ9ks5cdw+KiHCsNBJ/bPIPy1gKPF
oz+y8+ecyY4ceKgwrdnUkbxyMWcInk8xNK9Ysmg5+bQfjjvBQ637ig1wrjzfRenR
QiSM57HXZ/5AIYQaT9B73x5nQWJINeI9rk0bv50Q7J7k/eu3XYCe9gLaEA2raAv+
dkGnT3aPAo/59IYmEO7YUDXGwcmbeWtuzSdM9QVGNkvyBlknc64QYrXOLMEtiVk8
cbkBI2c0wMh0Z3KBV4e6/qwBZ7NzHlVyWrcaEG7dsGierfLBgoqvGQKiNmBDwy1X
Zmh6n7qXeA1XJgp/OqF3TsIzL9STQ48g0MQl9eXJLhXXCZ1oeXh0UPob/TOneM4G
reKGa5aum3TEpt8QPHZB3jXJf4ZUvmlzcGamaOSohwYSuCXp1oGtCxhQ8LXobZP8
O3tGHWIfH120JsNaCCsBAoIBAQDgTrTsQ8txjK0hKlB8TyH08mkh+UitiM/UOLOG
XToa++HceR/rudbgWU0BaKCwZp2rNWro6WGUKb9D/3KPxS8tbPnKhDuEAgRjoUHO
QbuLr6OHWabtoGKu99KsQ/KIj5iDDpdPJaCE+eZXphjiGProqlSUBFzAQOsQBpW7
rO2KJSgT/UrNglXSSb4VL9O1Bu9HF4NO2MrEuhgMI5j5+TniRFEvFyQc9NaktAcS
umn9g5eQdZtyBNA4cxWm3z+XtXQ0+yCZ7UUMF1E0ZnZlfsy9a0M+NaiVG8Ls1wdo
B35o+TAYX8vGVuYRmxcsXY5M538OkbBGfNydcOpGWZWIC3D3AoIBAQC2IJpUSkQx
MH7CY66XbqLV1COXo+Sf8s/kFr5Y+lNGtP5r3WWAeqMipc7Rvc+4BBfWa0AjBr24
HqffibS3AmhtbOBt58FqgPxeCFxWq8Q3bZaKCa2fDDH1GkPaTGiXzPPEIuGK/4jw
8vpfQTZCxqvdxrgn2hROB7FCJUrDme1klo/Dvum9/I13CHoa/6ytaDZprfZQ9Bh8
/fgyJORwhlG6o+c5SrN+Zzb611N94lP+Jto7LU0u/fRbNGYFp9yjiaR39cFia5/i
sXyW1r6ZM0NFbpL2510LXGkhB96bAqmQFjQ+4rVOnOV/CFXAf0hp/ufhIlb2y9lB
yXvnTiaFc76BAoIBACZlEo8Go8JSBCiTJ6e/m95jyB8qnoglzP1Un1Y2iwWna+fj
S9V7wA4y+v1svWS0i/SMdjpcCHnmE3k+NovpgsPRzYgezlkwRzQOnEcD9WhZrjIy
5GH0fC/a99LI5rD9c2uribbgh/N7GzSRl9zLzdcZoNSdUosOEa5ykhrH5Pkqlwuk
5bL7xljyinjx8Nkh0L9ohO9wKHU4LXmWdk8DnCbg7sySt3nFZyBWOIe6JP5iEgWG
PA9uR34CJQilWitLwhJ3kgMHHDSPoTTI/ScuZzldLOtvH+Y2FE2aGQhzj+3ECbmC
XE0c/tCwrWzIrtz3G0aRJY1LPjAs7c0Q9ImO+80CggEBAI1rqYq0FFmBx5wYHTUX
Qrf5Px37tIaC2+zHwEyFLG7mEf0d8DggglZgG8V/tzCzdPMZWrcX/+9dVotceYf2
BbKabXbKE8UonU5C/biLLhTAMrnDJB8xMAWbvH5hAIKHMe3mC+6L2AEJG2Ml1wVp
EYFnUg4X59ZjYL/1ByX1e4G067NaplPRLOP2ICKgz6vjFQVggLiBohZEexoszXmW
wxXDOcOh/tizOtzyoLFKMmBSOPjkh19q8Ph1KpdPriMKuTwxB1XuLjuwCAd0fpGl
XaInZ1TzeKteuX9dhfwlyBbLNwxxq8l8STQn+7Y637b2qYWGzbJbvbq4wk5sv7q2
koECggEAGevA2ceMhM5DyLjZUaMNkVWd3GefO9kmpNA6yu0ashfIR0Elnt/go6Mh
pVwTPA+tUllidjY4IHR2sWv2OCNGETek2Ke+xbDHOQJ9kz6NehLAuJoXZusTB3pX
xxCe+YxgiFX9nkIdrx+F/nmHm7CQtVy6dBuNBEHgOUmEuXBM2GxVGx1HmcELVCwx
a9uL7EDFhbnPArFvrICA6R7BGe944XkBEw8Oi4RLvTasytFVijNkav5AQ3vUSKIN
/e+Il56iV+HVcTfrOIDbJy5MiiWpWIYxgB/97y9I9tN5tTWEJxWRhrqwHqkeaP9G
VX8MV5cZIQylsYzuupzaYcIqOTLowg==
-----END PRIVATE KEY-----

24
results/ssl/client.crt Normal file
View File

@@ -0,0 +1,24 @@
-----BEGIN CERTIFICATE-----
MIID/zCCAeegAwIBAgIUHLNAeqUKFk+dccHcoEJuHnC/AGQwDQYJKoZIhvcNAQEL
BQAwFjEUMBIGA1UEAwwLUE1JIFRlc3QgQ0EwHhcNMjYwNjE0MDYzNzQzWhcNMjgw
OTE2MDYzNzQzWjAZMRcwFQYDVQQDDA50cnVzdGVkLWNsaWVudDCCASIwDQYJKoZI
hvcNAQEBBQADggEPADCCAQoCggEBAPUDSiryiTv+BJlk2OEYheL0HvJDDT973aJu
QVEQHrebTjpsNrfqw+B8J0kx8y7sRKKQMsW1oxi6ltzZZES7WHcZKTiReevlgWWA
Z1We2OK3e2z/xFgtTKnnfZ2lJSSjhYcsADLPUQmt+9kKvfzvvR3VFcO3mEs8UWVx
beacnsbiIFVJOP0DS2R63J1blpVGH2u5dICdNWlVmo2mAGXtAwRkxm4mQUademic
rgrEOmOftJcwQYXgr9Si8H4P21U4VRZdLhS3vU73npLSqC6P2GoAiAQjdDDQMEfK
j6EYud9pt5rapnBSFPyfMAAZt+V7eXIgQfqumSNiEiB8ckgVK3sCAwEAAaNCMEAw
HQYDVR0OBBYEFC8RXtw9o19b0W3uc0Dg35rQLQufMB8GA1UdIwQYMBaAFKoMDrwH
+s5wzrdcwAWTIkrFo3OOMA0GCSqGSIb3DQEBCwUAA4ICAQB1PK/Bcw5lIyRIbfql
ZumaC3cla3IcoCJipSSnUeqOknFkPgSLqxM0b99k+FL7Hc7o7JQJeUwdGGf5StQ9
vAMdj1TaEkEK2TR4nWdbX3yLH2jnoouhCfxPOk6ci9D9hfd85v0UDtjvzxStrRlq
Fy+mmTEe7yTlr8CzWzC/MAm2VuozZI2yhTJiIXL7bB2R3FvlnpH5pxXccbYyYPZy
7AIEQj0psMnA6egyNATM8D8sGpAv1nC3QXdYmXg1SmkZkmivbjrYqnyJmQnJTMOQ
p8EzKmzMCtlfxT4nvzsSuLalepcpeRz5ap6zyU9vjVW3f3FRVi3axYvs+BhX4Bu7
2KC054npZp3S9mTRgvB+6GJrxfZ3xqmqWjhxWEo77A6bF50xAoEextuxKDTYZdeF
Gm8sKjxzdjArS3QB5yp+inl2OqmqQ/EuP24NGWZplO22W+qwkDd23Hj+CQuqgbYA
DDbDvGltXFO0Kh9qtc6JabOIOetP8qhzfgxSyU3PNmcyd9hoCNZEjfNyYGcAJhk6
afJ21r7DZzSckIGaYCe5nrTIdDTLvG8u1+IGMFdVPInd8S0uyE2j2tZ0oCL0p31f
88+RJSbicgIMK+mTg3G0OLjDFzlDe4/P5dW4Xr5xz2/1o8qlTu/piNF6bIggEPP2
/8VHHblhHtH6lA8SuB6lm8y/BA==
-----END CERTIFICATE-----

28
results/ssl/client.key Normal file
View File

@@ -0,0 +1,28 @@
-----BEGIN PRIVATE KEY-----
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQD1A0oq8ok7/gSZ
ZNjhGIXi9B7yQw0/e92ibkFREB63m046bDa36sPgfCdJMfMu7ESikDLFtaMYupbc
2WREu1h3GSk4kXnr5YFlgGdVntjit3ts/8RYLUyp532dpSUko4WHLAAyz1EJrfvZ
Cr38770d1RXDt5hLPFFlcW3mnJ7G4iBVSTj9A0tketydW5aVRh9ruXSAnTVpVZqN
pgBl7QMEZMZuJkFGnXponK4KxDpjn7SXMEGF4K/UovB+D9tVOFUWXS4Ut71O956S
0qguj9hqAIgEI3Qw0DBHyo+hGLnfabea2qZwUhT8nzAAGbfle3lyIEH6rpkjYhIg
fHJIFSt7AgMBAAECggEAPnehQEPn81C3UXihxvoeoJeHEFNCHG5zOoeLxaQrgLpq
/oA6jzeeyyw8Q/AlRVBdy2iiWUAPHi3satBOPSvayTq0BMUqZZd1HzDWp8DBIUSQ
hmDLaYPbKPJpV3kUeDvsvmLchhfPXH1sWZDgkY16FRIP4396p6vwQMHjuEk0PhZH
WOjeK0g96k5HaflYqIyC9GiTi8O2PUjMm3Ftr9nl7XaGyIfukLVjjaM4isVwD2/R
ypSf4RWcFw1T9ieLJmNLM/0WbEgPuTWouF1G5JOPKQ7gAUDtzo7gT8qs927U+OKW
NYWH/wUolJB5TTHkU4W/uw54wU6SMzVSR+5CQeJx8QKBgQD+eqF4ft/vD1fNVUNl
Zgq7Ld5qGKPbaHuYqk2nelRPKp063GiHJFbrKfnt6qWpSjtOKkgtGBLhAoZz9OyK
NvqvsJJQEs1CDNx0i6BGY3xRXWZU6Erws7X82Z3hOsHd16HGoMWah75tYygemTSA
OyEktEaINC6AJ7vCpvcDKAyvWQKBgQD2eizUZHv9eKnfzDY+DkoACv8vDIiqOX44
bWsNaejtWF7iEj5Qws+GqhnuMjLW084//nc/j+6L328oqSLOfdpXUSpy++sAl+3Q
mTzH9N2Caa1pTCd2VfJOidg4RcUOzw3F+/h+0tGHAB2UXyPTpJ8iVpVR5t5r9yMj
nzPsS9NK8wKBgALGvbo90B2gkjmoQ3r4uQc/wdxwdmEva6HHwd8g44iVk2+P9gf7
aoNYSuTAmZwWNj1tEqqDR7lyuJrNQkNjxCpkh8Qd4GVnFISk/VOnRDTzCunEOwUT
QNoIWcOaS4ErGBW9rUo5TueMnGRxEXSQsJTg7qAPya4WQOMnxSwgpLrJAoGAeUE3
prFcciEXaRr8oGDFNOo0CgBfh2bLWpUxsiKlTYZI/2y8LVz5XSV3pkAZ1KfUcpUM
Mz/qufMMq3MxxWYSsRwkBvc58EvN2e5ZAYHMK2kzv3aQf13e25ZiwaRJQnTIMNs5
r6KlI4YCB0kaxfbZtrnjsawjRfgJ2G9sytWut9MCgYEAmaLhWDhS50JXO27uybQP
M/g0E8OuNeXLPrRwPNOYhzKYHR5mmz8iGrjWIMKl6pP3so3AgezRiAAoPbsDg1WD
Nfy61bnPyauNZOHozuYCyzWHt2TrXSiZw8C3oTPLdDzg0fVMtUHDpeNb3HiB1gz9
ApYXJxXwLAjx9b+OzYZssxQ=
-----END PRIVATE KEY-----

54
results/ssl/fullchain.crt Normal file
View File

@@ -0,0 +1,54 @@
-----BEGIN CERTIFICATE-----
MIID+zCCAeOgAwIBAgIUHLNAeqUKFk+dccHcoEJuHnC/AGMwDQYJKoZIhvcNAQEL
BQAwFjEUMBIGA1UEAwwLUE1JIFRlc3QgQ0EwHhcNMjYwNjE0MDYzNzQzWhcNMjgw
OTE2MDYzNzQzWjAVMRMwEQYDVQQDDApuZ2lueC10ZXN0MIIBIjANBgkqhkiG9w0B
AQEFAAOCAQ8AMIIBCgKCAQEAkyZzCULOJgtzNHMf8Mfmks0UYRlsEBF6cC6uokIP
VUOkN1TYENKWAoc5LBJgJbPlXoOAd488jIybX6097iV9Rh0bW2g/LDEZZxWhOiEK
t0yfkgv++kgSW3E0CRNskn3IfSRy33KNRHIBVANgCfYAzbvPgu1hd57g/4lEuOCi
ZmP0dECATohqXPtFmcOTI1XVWLg135E+78EJJabn9UAaVBg+D2vlNhIXXahSva5Z
zPOvKrokGYu2xq2bITif1TNW0oCKV8nyUOMI/SOs0Aqoh0s6LynzWLXVTS15km5n
kst5WYSbqSPLnvdNC+F6vcBHQzpPTgA/HadGWnsmypLIqQIDAQABo0IwQDAdBgNV
HQ4EFgQUKvi6Yan9WEZMPrlKGVpPzu3LZmkwHwYDVR0jBBgwFoAUqgwOvAf6znDO
t1zABZMiSsWjc44wDQYJKoZIhvcNAQELBQADggIBAIj0SXcXLMKylfCEkF2IHZ7a
MtiVcOjrMKRrfwvufgSd5dEL813axbDas5Eq9asbM/epd7x/t+oWTnRlZAOet6nO
92etE/+EolWThOMFlRxr+c6i88O0nqqsdUypS7mE/egw3CAktEFJhjzyTmS2EMaq
44n4rdwVc3yNeLKzZIKs0haSzbKyeqhJNt+x9CgBSpS5hGtCBPSILcMu2XvtugqA
l0PhMA5T5WE8uUVqzAhETRcZWh/X9wcbpRUJ3EPFbqGoleLUmgRH36k04mp/P11d
HXmbZkXFMRS4+ovj6nW6SqcHXa53frlcYinarhX5TWLViwD49iEgoBfv4V9aRDzB
auOoRculc6F+euI6dCbJiHUt2PAa/SRCA3i37VOqmrjlQ4L6fe+cNc/+PY6n4EyK
sOPX/OPs1XLAXOpZQ5/JDgBdBNIxZFtT6KDKFGoHLRt7KNN78VRowX4DRwwhN/CR
f7tgKk3m57IxtHNmq++wPiofmPyY+d1vCe0S+0aKf6lblxdG2Cuo+n0D1DnXL0Vv
2EFDpGyW+5V9G5Toxc5Dmvy5MpHFF/7Wtq8dMty9c91G6PCgHB7Yw/MOfWa6thbm
dSWOA0Wxdinneaq6NI2e7p4zEKkibnnHr/YY2wgI5MC5pNJUYVDqnkzrNLcDi6yA
QADElgz27j8zOConcqRz
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIFDTCCAvWgAwIBAgIUZZIrRtH2O6qauuDjnP2jwFNtdfQwDQYJKoZIhvcNAQEL
BQAwFjEUMBIGA1UEAwwLUE1JIFRlc3QgQ0EwHhcNMjYwNjE0MDYzNzQzWhcNMzYw
NjExMDYzNzQzWjAWMRQwEgYDVQQDDAtQTUkgVGVzdCBDQTCCAiIwDQYJKoZIhvcN
AQEBBQADggIPADCCAgoCggIBAJ+Uha/JdxrEvoogtY2gGdpmWWoSDZuh3F5uKLjw
k4F39PQ1hAeO3YBpcmPkY6CpwZMYvkoZU1Fd8B404FTDSg2zpV/gulgr0fncMjPg
xpqzRnuOaB7jEuWV1f6IHlRn+NDv/HEZEobhrDdL9/EIrx5SFQFgWuB+EMxwJI8I
oNYhMF6d9GRvyXNos49a9BDfkNH6TDktIK/w/z2ASQYxoAj5bQK7B+jcKf84FA6x
FrWYmW+v0d0Gp3ghtjVnvRSF11YK4OkAFJtNCh8v3scFqSBDqC4Lo9g8hKnDQCio
5IgjQy7zV48BJ/ZEqoL66qDcVZyi202A+MKaj2naCmKhqMWFiuJdY6Y0QxXn02jD
gRiyWq0bElnyDUhqJEC/A4NoMAxjYBBZMRXU2/3rbKodUlLMYH5hWGbWkQzWoiWb
jzvks7gXRcTFFr2nJG4RbfTRRlUI7t5utvcmyX6Czw1QEyE67vJ/KkW0hvDuLznc
OgX9dc9mWBlU16kWlCn19g4o4qzw4155HEc2Ro7jr7gATRilKVb70yXq877LUlN7
/jrTb+lMFr9e9dzsY0YS3xpjx2dn8TsXuaVjY+VWMRXrHmgs661Ur10SVe6K1AN/
jaLo6vRXF8XqPVxIjg/uiInIwsxJNjOpOK/aqjmmH02pmPlUTgtURoZ0GXvJNNAd
kD53AgMBAAGjUzBRMB0GA1UdDgQWBBSqDA68B/rOcM63XMAFkyJKxaNzjjAfBgNV
HSMEGDAWgBSqDA68B/rOcM63XMAFkyJKxaNzjjAPBgNVHRMBAf8EBTADAQH/MA0G
CSqGSIb3DQEBCwUAA4ICAQCRnXhE1VX2++3RT8fTtsH+WYNOo5zcHTqKlqQd922+
i3LX0QHoy/8v8ZHVfPvD2swFGB9gkq5YimS5qPtSm8p0WkGscIeMqOaxGsUBcEzK
XTjDYBoPorBx3+JpVp4jERz0umKo1H3QRwDKGADp3y+I+JcsxO64LOv15tkSYhmZ
sqhs6fr9hnqbYFyARiFMvMZX5zLKDbqtHSOOZUVeo3QKXKu5+mwYBTOO5NTcsiR7
FoWVpIlAvT0ST/YtfLyl8YIRfhJn2RXjNXDSXWkNlDwz6WEAaKtr/SyD0OCMQGqk
BmjSTPAgbh4VpLTA1HFf47fQp7tMXmNpRR+MMqmT5Q41jLr8/jZDns+yjCaXHulK
1N1axdHdDBAfZiwgfSmeCm4dhZfWEmgLwm2zNdbqR7hxDmpmf0YRuzthABeRs9+q
NfnY1z6vLYV+guei239l5AuopwyMjkXbZvl4+CxZ4iIA5abPoax5Ij3T1blQSS/t
eTOd/7YIacg7RmixFp6D7IJUehRADGEVFT//Kiao3K9Csa0fbSKUIcS5b6aIJv8R
s6ho7anoyE8ZmNU1yS/nOKzg59TVG6dMx49eWIwzCdRnihMhYadJ8GsxLluuH5dh
BqTFPmA4ejtrtORFO+b457EUM3Ay2wlaYQj+e4Qp7znQP5IugsX4nXQfPr7FrJ2J
8Q==
-----END CERTIFICATE-----

24
results/ssl/server.crt Normal file
View File

@@ -0,0 +1,24 @@
-----BEGIN CERTIFICATE-----
MIID+zCCAeOgAwIBAgIUHLNAeqUKFk+dccHcoEJuHnC/AGMwDQYJKoZIhvcNAQEL
BQAwFjEUMBIGA1UEAwwLUE1JIFRlc3QgQ0EwHhcNMjYwNjE0MDYzNzQzWhcNMjgw
OTE2MDYzNzQzWjAVMRMwEQYDVQQDDApuZ2lueC10ZXN0MIIBIjANBgkqhkiG9w0B
AQEFAAOCAQ8AMIIBCgKCAQEAkyZzCULOJgtzNHMf8Mfmks0UYRlsEBF6cC6uokIP
VUOkN1TYENKWAoc5LBJgJbPlXoOAd488jIybX6097iV9Rh0bW2g/LDEZZxWhOiEK
t0yfkgv++kgSW3E0CRNskn3IfSRy33KNRHIBVANgCfYAzbvPgu1hd57g/4lEuOCi
ZmP0dECATohqXPtFmcOTI1XVWLg135E+78EJJabn9UAaVBg+D2vlNhIXXahSva5Z
zPOvKrokGYu2xq2bITif1TNW0oCKV8nyUOMI/SOs0Aqoh0s6LynzWLXVTS15km5n
kst5WYSbqSPLnvdNC+F6vcBHQzpPTgA/HadGWnsmypLIqQIDAQABo0IwQDAdBgNV
HQ4EFgQUKvi6Yan9WEZMPrlKGVpPzu3LZmkwHwYDVR0jBBgwFoAUqgwOvAf6znDO
t1zABZMiSsWjc44wDQYJKoZIhvcNAQELBQADggIBAIj0SXcXLMKylfCEkF2IHZ7a
MtiVcOjrMKRrfwvufgSd5dEL813axbDas5Eq9asbM/epd7x/t+oWTnRlZAOet6nO
92etE/+EolWThOMFlRxr+c6i88O0nqqsdUypS7mE/egw3CAktEFJhjzyTmS2EMaq
44n4rdwVc3yNeLKzZIKs0haSzbKyeqhJNt+x9CgBSpS5hGtCBPSILcMu2XvtugqA
l0PhMA5T5WE8uUVqzAhETRcZWh/X9wcbpRUJ3EPFbqGoleLUmgRH36k04mp/P11d
HXmbZkXFMRS4+ovj6nW6SqcHXa53frlcYinarhX5TWLViwD49iEgoBfv4V9aRDzB
auOoRculc6F+euI6dCbJiHUt2PAa/SRCA3i37VOqmrjlQ4L6fe+cNc/+PY6n4EyK
sOPX/OPs1XLAXOpZQ5/JDgBdBNIxZFtT6KDKFGoHLRt7KNN78VRowX4DRwwhN/CR
f7tgKk3m57IxtHNmq++wPiofmPyY+d1vCe0S+0aKf6lblxdG2Cuo+n0D1DnXL0Vv
2EFDpGyW+5V9G5Toxc5Dmvy5MpHFF/7Wtq8dMty9c91G6PCgHB7Yw/MOfWa6thbm
dSWOA0Wxdinneaq6NI2e7p4zEKkibnnHr/YY2wgI5MC5pNJUYVDqnkzrNLcDi6yA
QADElgz27j8zOConcqRz
-----END CERTIFICATE-----

28
results/ssl/server.key Normal file
View File

@@ -0,0 +1,28 @@
-----BEGIN PRIVATE KEY-----
MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQCTJnMJQs4mC3M0
cx/wx+aSzRRhGWwQEXpwLq6iQg9VQ6Q3VNgQ0pYChzksEmAls+Veg4B3jzyMjJtf
rT3uJX1GHRtbaD8sMRlnFaE6IQq3TJ+SC/76SBJbcTQJE2ySfch9JHLfco1EcgFU
A2AJ9gDNu8+C7WF3nuD/iUS44KJmY/R0QIBOiGpc+0WZw5MjVdVYuDXfkT7vwQkl
puf1QBpUGD4Pa+U2EhddqFK9rlnM868quiQZi7bGrZshOJ/VM1bSgIpXyfJQ4wj9
I6zQCqiHSzovKfNYtdVNLXmSbmeSy3lZhJupI8ue900L4Xq9wEdDOk9OAD8dp0Za
eybKksipAgMBAAECggEACLHaKhcsMqkftMmY/s4fr0IWZ5lhXlQGDyMMVxKTsNxR
vkzmr8cdrYcQx1b2SZaxts4K39BTHyk/aghvcxxRz2bbYwvhGwrzVGO9tn9Vey4N
dLX9lODVfYPjc6YrQWmqGHji9RXh8oQmVMZBR71lNULZGK75liBJbQKkUKSXUU4/
h6M8iv0v9m7Itrrg8v1LEkDCwmlvviII0wODEKNtOcUt9TEhkrVLT6wqJgAkOVEm
J8f6tIkREUCslHQ+Ls/wcGjAtr1Z8c3Dx/onIKosbRl04/ahcfX9fGaYqWiONH7w
m6/29tsac8nkGbsJ3oHXdPt6Zy8QVm3TeX110T1aPQKBgQDOIkqwW1NuZitk+bT4
D0L7aBVTKhtJEq9Oe9g6qnhdmd0VNyhH69oYpvlUUXJ4pqfSSeUFfUDjfNTIVi0M
5HmsU8HdipP0CceX8YERSOn7uNnjoBfdKpxyBT+FzDLQhLBoFM9yEc7/3ttjPN93
0RmDVK42rBK4E11V8qJNaaB+jQKBgQC2v1dfArjE9v/idt2DiTO4RWjbooNjAn71
u9Dz1L/YomIX7Il8FLqoRfhTWxvwkRCJpYpsW9cpXN7KLfX8abZh7GPHUTFBG9pT
E6ZTIQOXnfnyWVskhmytWKkZ/YSrzeYyHEWdwXtk2qJrJy6YVnucHlkZ3IH74zlv
UZmvIKqpjQKBgCiAimZee2UsxAgCHHHFJecaC16c3mGcPz/Pi6vzRNU3Xz5E6TBA
gkjnvgO4QSK9tCnYhRxwAOjx5Sk77XwkBFg82NG74dhId6Q+Opr31am1J3LXSPkW
30h0CYgzmCRqffLla+FA6IhT9I1qL4puVnH8mIJ7iu4KOAOkOgm14GgdAoGAFba4
f+6H28dpchQjj9x+i7eblPVDXUFPqo0Nb9tojCoHM8aEM30XDKV7sxPRRw1FhMVp
pCRpdV22jxlU8A/zfsEive0UyCKyF0rvaVMz5RD9QOGDJdzfDt3JAfCQkgVeA7g+
QVda/QnJYKgALlOgTlWAysTboP1HtsVgWGGuRYUCgYBIrhX5D1vXLxheLFz+w7LI
Y0aZQ3dvgRj7gOYQYp5tFcziqFUMly3XzMQO9YibSGJmilrtdhjteGGcBc7vmnSy
BiL79mBRz6SsmZRoEvF302TKae+pnJ+h3z1mtptYOm3zq1v9pHSKVXDwXvKSpM+5
9GVIWzBHS9ljJ0rN4ICZWw==
-----END PRIVATE KEY-----

19
results/ssl/untrusted.crt Normal file
View File

@@ -0,0 +1,19 @@
-----BEGIN CERTIFICATE-----
MIIDFzCCAf+gAwIBAgIUKtZLCLBMCJ4MQ4lG8yfujsMKbEcwDQYJKoZIhvcNAQEL
BQAwGzEZMBcGA1UEAwwQdW50cnVzdGVkLWNsaWVudDAeFw0yNjA2MTQwNjM3NDNa
Fw0yNzA2MTQwNjM3NDNaMBsxGTAXBgNVBAMMEHVudHJ1c3RlZC1jbGllbnQwggEi
MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC7w8FTPXsENWLUSSmfA9J9uVY3
+pUEuzcaL3GYNFN7KBxdURdE7D9PE9qmZRLKIvQA/oeSMqOovWeDad0zj/x2+Rcw
9q9SMPF5k5WVXTZtFA7QGPh4ZlnxNsVTD5jUUjlL7RBaNudQq7xiiCn906MG7+e3
6EIf7fRWetwHktTwT4IL6jttHT1HlpTTTW5jUV/htUbXAny/UE78j2jnfyWlU5RP
GJNMhYnC2bjKlbDitio/FWcwM9cbgCnqBFsSYU0SXmAdc8LeCta4D/U3ZZks3I19
oV7x0yOz9EApGE/vRII5AhtI9thmbLKKdiQsjX3euV3Ob0uM7nLcD9L214KrAgMB
AAGjUzBRMB0GA1UdDgQWBBSpDQPnd0AN3OINmHVw4dUD1IkVHzAfBgNVHSMEGDAW
gBSpDQPnd0AN3OINmHVw4dUD1IkVHzAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3
DQEBCwUAA4IBAQAJqyA96YOZAVp0C6ef7WqFgulTXWBbDw16j80SWZFfZqXEmmYR
4lgLy/Rf7IMZYbxOhLZnG7aHYhh+DVGdC1pDja80dthHRrLBjK1W7PlBktsS4f7H
GuDeBYpnV9LojemuFt0q63KYHmNm8Bs/zzyi5DfpVUr4EqoJns9Sy5jBP42tqzMX
AaFUoQ0lWB7XVK9RCdHWvWg4etJE+APvOp3OHHC0JpGF/1DfytOg9lnlwxH+rGOH
lwaIPRwtZl1o0zxwxs2ZxSzmNNq82xVKV8dfS4T+vS+YFTm8uB5zohK/uE1rsfz2
KnBW3RHFfSpBZd0RF2Z9nS7P1lRcG0xjgAAV
-----END CERTIFICATE-----

28
results/ssl/untrusted.key Normal file
View File

@@ -0,0 +1,28 @@
-----BEGIN PRIVATE KEY-----
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQC7w8FTPXsENWLU
SSmfA9J9uVY3+pUEuzcaL3GYNFN7KBxdURdE7D9PE9qmZRLKIvQA/oeSMqOovWeD
ad0zj/x2+Rcw9q9SMPF5k5WVXTZtFA7QGPh4ZlnxNsVTD5jUUjlL7RBaNudQq7xi
iCn906MG7+e36EIf7fRWetwHktTwT4IL6jttHT1HlpTTTW5jUV/htUbXAny/UE78
j2jnfyWlU5RPGJNMhYnC2bjKlbDitio/FWcwM9cbgCnqBFsSYU0SXmAdc8LeCta4
D/U3ZZks3I19oV7x0yOz9EApGE/vRII5AhtI9thmbLKKdiQsjX3euV3Ob0uM7nLc
D9L214KrAgMBAAECggEAU35oXNIFfmkY8eo4wleqRbLhJpJcqpZvmcrIGhUGnEjJ
WCuji8f8HPdorr5aPR2O4FROx9GR2gqjWZn9PZ0E+IiqaeEANC3EazoX9avV9GpL
bfj0oGFvFGa1F0rjvGJ1zQ/1ShCJCuPbKPuApLj0ETUkFrEGmnkvQjdu2UVPQC5v
1Shry2UisYKnUSgYGY58mpio0TzccQ/X7EhwZWTbT2ueiztqJ/STniL6mMMl8PVk
wWHtFID0bD1UYIvQgQX1Bo/abqRvjZoIP3UnBRKZB9u5SStpYkUPYOOEXUlOOQH4
mjDc2uE2qjPGRivNT283AwltVJYgjw2cKEdfMS1xmQKBgQDekt9ofQFSxNKSAFXv
7C6mdjD8vU377vKXmaL/Jo/esCGSUOMQ0hNV9NPzz1Msnng4OsTzsc2guTniJoo/
xXkm7JhPI3mVCqHrJauw6OqcIslqQ3Nwsm6X10BVjCKF5yGpOUzcPKOVLuYTVffR
8Ml4Zjv1mFhL4xJ23inryjIF+QKBgQDX9prFM2F5h1f8csGU7iIPRhfCOVBzkVS5
wvFcjnhos2IRUrhMKlWjoOsHEsco3j0dBeBU3hMRi3Hk2iJ8aeMRGZPdB6Ng4Eu8
O5E8BngWsvP5PjkQfxouNjwKwc4MYvTguAykX9MwkFz+I4aR6N8NL4FKfBSArKEa
21lCoyomwwKBgGx63VSKCMkUkSUD8N69GIedd4bXpVizP53QDfeaDekVo2cy8VjT
awUsDNn6JKnMmv+c9T1pXbWGUcX9zsgCMWhdTGbV/X487moztBjHjQGImu6l7W/y
J6DuErcfU/w7iNZ3zRRSodAmSZEHB4BVgXyjJ3ouRGrIQ8mXworfw73RAoGBAI1Z
HGdhf7TY/p9+RHFDgwtYJwi6FovtXPTQQMUBgpGUhuUrrPA87RxRoEJa6fs3qewr
Am7JgtWC3SKaGuQvMazpfru12hr38tnaau5MlaDVs5U4QoUni20fliC8RC4bPocu
LygOh91LP3Iesl8heYvZwdeMaqblVfSMCFnzDQ2dAoGAGZSkN8AGM3krNLEXNvSL
5j53GGBIf12jkfbV4mbMUGsfE7317HTqiM0/nKUYW/0BkdVltNs8fdrSBDnmUfGf
QEUT6g0PWOkoKdraAtQouTEpDZczL31fDIvc/omxzeTTT3GMbZIyPRqnJDDd0MyP
AeTHeMvO931CDI8/iSgsDpM=
-----END PRIVATE KEY-----

View File

@@ -0,0 +1,5 @@
<!DOCTYPE html>
<html lang="ru">
<head><meta charset="utf-8"><title>404</title></head>
<body><h1>Custom 404 page</h1></body>
</html>

View File

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

View File

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

View File

@@ -0,0 +1,5 @@
<!DOCTYPE html>
<html lang="ru">
<head><meta charset="utf-8"><title>Public</title></head>
<body><h1>Public index</h1></body>
</html>