
Образовательная среда для LTAT.04.022 Домашнее задание 4.
Учебная среда для LTAT.04.022 Домашнее задание 4.
Четыре контейнера позволяют сканировать и сравнивать уязвимые и исправленные конфигурации.
| Контейнер | Порт | Программное обеспечение | Статус |
|---|---|---|---|
| nginx-vuln | 8441 | nginx 1.24 | Уязвимый |
| nginx-secure | 8442 | nginx latest | Исправленный |
| apache-vuln | 8443 | Apache 2.4.57 | Уязвимый |
| apache-secure | 8444 | Apache latest | Исправленный |
# Создание самоподписанных TLS-сертификатов (требуется для всех контейнеров)
bash gen-certs.sh
# Запуск всех 4 контейнеров
docker compose up -d
# Проверка, что все запущены
docker compose ps
# Проверка, что каждый контейнер отвечает (игнорировать предупреждения сертификата с -k)
curl -k --http2 -I https://localhost:8441 # nginx уязвимый
curl -k --http2 -I https://localhost:8442 # nginx защищённый
curl -k --http2 -I https://localhost:8443 # apache уязвимый
curl -k --http2 -I https://localhost:8444 # apache защищённый
Ожидается: HTTP/2 200 от всех четырёх.
curl -k --http2 -v https://localhost:8441 2>&1 | grep -E "ALPN|HTTP/"
Ищите:
* ALPN: server accepted h2
< HTTP/2 200
# Скопируйте сканер сюда (или измените путь)
cp ../scanner.py .
python3 scanner.py localhost 8441 # nginx уязвимый
python3 scanner.py localhost 8442 # nginx защищённый
python3 scanner.py localhost 8443 # apache уязвимый
python3 scanner.py localhost 8444 # apache защищённый
Ожидаемые результаты:
| Цель | HTTP/2 |
|---|
Используйте nghttp, чтобы просмотреть кадр SETTINGS, отправляемый каждым сервером.
Это показывает значение SETTINGS_MAX_CONCURRENT_STREAMS напрямую.
# Установка клиента nghttp2
sudo apt install nghttp2-client # Ubuntu/Debian
brew install nghttp2 # macOS
# Просмотр кадра SETTINGS
for port in 8441 8442 8443 8444; do
streams=$(nghttp -nvy https://localhost:$port 2>&1 | grep "MAX_CONCURRENT" | tail -1 | awk -F: '{print $2}' | tr -d ']')
echo "port $port → MAX_CONCURRENT_STREAMS: $streams"
done
# (Результаты)
port 8441 → MAX_CONCURRENT_STREAMS: 128
port 8442 → MAX_CONCURRENT_STREAMS: 32
port 8443 → MAX_CONCURRENT_STREAMS: 1000
port 8444 → MAX_CONCURRENT_STREAMS: 32
Уязвимый сервер: высокий лимит потоков (128+)
Защищённый сервер: ограничен до 32
Это отправляет 50 запросов быстро по одному соединению — не реальная атака, но показывает поведение сервера при обработке RST в логах.
# h2load является частью nghttp2-client
h2load -n 1000 -c 1 -m 50 https://localhost:8441 # уязвимый
h2load -n 1000 -c 1 -m 50 https://localhost:8442 # защищённый
Ожидаемые логи для примеров:
$ h2load -n 1000 -c 1 -m 1000 https://localhost:8441
starting benchmark...
spawning thread #0: 1 total client(s). 1000 total requests
TLS Protocol: TLSv1.3
Cipher: TLS_AES_256_GCM_SHA384
Server Temp Key: X25519 253 bits
Application protocol: h2
progress: 10% done
progress: 20% done
progress: 30% done
progress: 40% done
progress: 50% done
progress: 60% done
progress: 70% done
progress: 80% done
progress: 90% done
progress: 100% done
finished in 22.51ms, 44428.65 req/s, 5.38MB/s
requests: 1000 total, 1000 started, 1000 done, 1000 succeeded, 0 failed, 0 errored, 0 timeout
status codes: 1000 2xx, 0 3xx, 0 4xx, 0 5xx
traffic: 124.07KB (127049) total, 83.01KB (85000) headers (space savings 38.85%), 23.44KB (24000) data
min max mean sd +/- sd
time for request: 260us 2.98ms 2.25ms 384us 87.70%
time for connect: 2.51ms 2.51ms 2.51ms 0us 100.00%
time to 1st byte: 3.24ms 3.24ms 3.24ms 0us 100.00%
req/s : 45059.11 45059.11 45059.11 0.00 100.00%
$ h2load -n 1000 -c 1 -m 1000 https://localhost:8442
starting benchmark...
spawning thread #0: 1 total client(s). 1000 total requests
TLS Protocol: TLSv1.3
Cipher: TLS_AES_256_GCM_SHA384
Server Temp Key: X25519 253 bits
Application protocol: h2
progress: 10% done
finished in 5.38ms, 18583.91 req/s, 2.33MB/s
requests: 1000 total, 1000 started, 167 done, 100 succeeded, 900 failed, 900 errored, 0 timeout
status codes: 100 2xx, 0 3xx, 0 4xx, 0 5xx
traffic: 12.83KB (13134) total, 8.30KB (8500) headers (space savings 38.85%), 2.25KB (2300) data
min max mean sd +/- sd
time for request: 83us 1.04ms 533us 256us 63.00%
time for connect: 2.96ms 2.96ms 2.96ms 0us 100.00%
time to 1st byte: 3.55ms 3.55ms 3.55ms 0us 100.00%
req/s : 19316.22 19316.22 19316.22 0.00 100.00%
Защищённый контейнер покажет сбросы соединений или отказы при достижении лимита потоков; уязвимый примет все 50 без нареканий.
# Уязвимые серверы раскрывают информацию о версии
curl -k -I https://localhost:8441 2>/dev/null | grep -i server
curl -k -I https://localhost:8443 2>/dev/null | grep -i server
# Защищённые серверы скрывают или минимизируют информацию о версии
curl -k -I https://localhost:8442 2>/dev/null | grep -i server
curl -k -I https://localhost:8444 2>/dev/null | grep -i server
docker compose down
| Параметр | Уязвимый (2.4.57) | Защищённый (2.4.58+) |
|---|---|---|
H2MaxSessionStreams | 1000 | 32 |
ServerTokens | Full |
| Вердикт |
|---|
| 8441 | ДА | ВЕРОЯТНО УЯЗВИМ |
| 8442 | ДА | ВЕРОЯТНО ИСПРАВЛЕН |
| 8443 | ДА | ВЕРОЯТНО УЯЗВИМ |
| 8444 | ДА | НЕИЗВЕСТНО |
| Параметр | Уязвимый (1.24) | Защищённый (1.25.3+) |
|---|
http2_max_concurrent_streams | 128 (по умолчанию) | 32 |
keepalive_requests | 10000 | 100 |
keepalive_timeout | 300s | 65s |
| Защита от RST_STREAM | Нет | Встроена в патч |
| Prod |
| Защита от сброса | Отсутствует | Применена |