Default splash (Josh 2026-11-08): unrouted hosts are 404 on EVERY path incl. "/" (same static page), with cache-control: no-store, x-robots-tag: noindex, nofollow, noarchive and nosniff; /robots.txt answers 200 "Disallow: /". So the server IP/hostname is never indexed as a site. Routed sites, ACME, blocked IPs, suspended hosts, rate limits, wp-* gates and WAF are unchanged. Access log: the old target 172.18.0.1:514 (host rsyslog) had no listener on the fleet. HAProxy now logs to a UNIX datagram socket in its chroot (`log /log.sock`, i.e. /var/lib/haproxy/log.sock); scripts/haproxy-log-receiver.py (started before init.py, supervised by a restart loop in start-up.sh) writes /var/log/haproxy/access.log rotated at 40 MB + 4 gzip generations (<= 200 MB). No network listener; sends are non-blocking, so a dead/stalled receiver or a full disk only drops lines (DroppedLogs). Nothing is printed to docker logs (WHP's AI monitor reads them). Same log-format (cip/host/status/Coraza fields). HAPROXY_SYSLOG_TARGET still overrides. show-tarpit-ips.sh / monitor-attacks.sh point at the new file. Tests: test-default-splash.py (19, incl. log target), new test-access-log-receiver.py (10), both in the image build; validate-rendered- config.py scenarios all accepted by haproxy -c. Lab (pre-populated volume, recreate): 404+headers on hostname/IP/unknown, robots 200, routed site 200, attack on site 403, ACME 200, suspended 503; 2000/2000 burst lines logged; receiver kill -9 -> requests 200, receiver back <3s; SIGSTOP + 2500 requests -> all 200, 1475 DroppedLogs; rotation at 64 KB cap kept 1+2 gz; logs survive recreate on the haproxy-logs volume. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0185ukXjXyosSkunDsdWz3mb
36 lines
1.7 KiB
Bash
Executable File
36 lines
1.7 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
#
|
|
# DEPRECATED SHIM — kept so existing docs/runbooks/muscle memory keep working.
|
|
#
|
|
# This script used to print a "Tarpitted IPs Report" with a "Scan Count" and a
|
|
# BLOCKED / SILENT-DROP / TARPIT status per IP, all derived from gpc0 and gpc1
|
|
# stick-table columns. Those columns DO NOT EXIST: the `web` table
|
|
# (templates/hap_listener.tpl) stores only conn_cur, conn_rate, http_req_rate
|
|
# and http_err_rate. The old parser defaulted every missing field to 0, so the
|
|
# whole report was fabricated — every IP showed "Scan Count 0 / Normal"
|
|
# regardless of what it was actually doing.
|
|
#
|
|
# The stick table also keeps NO history, so nothing in it can identify who was
|
|
# tarpitted. Real enforcement events live in the access log ON THE DOCKER HOST
|
|
# at /var/log/haproxy/access.log (inside this container since 2026.11.2):
|
|
# grep -aE ' (PT|PR)--' /var/log/haproxy/access.log | tail -20 # tarpit / deny
|
|
# grep -aE ' (429|403) ' /var/log/haproxy/access.log | tail -20 # rate-limit / block
|
|
#
|
|
# What IS knowable from the stick table — the current per-IP rates — is printed
|
|
# by show-edge-ip-rates.sh, which this shim now runs.
|
|
|
|
set -euo pipefail
|
|
|
|
cat >&2 <<'NOTE'
|
|
NOTE: show-tarpit-ips.sh is deprecated and cannot report tarpits.
|
|
The HAProxy stick table stores no history and no gpc0/gpc1 counters, so
|
|
the old "Scan Count"/"BLOCKED" columns were fabricated numbers.
|
|
Actual tarpit/deny events are in /var/log/haproxy/access.log (in this container since 2026.11.2):
|
|
grep -aE ' (PT|PR)--' /var/log/haproxy/access.log | tail -20
|
|
Running show-edge-ip-rates.sh instead (current rates, real values):
|
|
|
|
NOTE
|
|
|
|
SCRIPT_DIR="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)"
|
|
exec "$SCRIPT_DIR/show-edge-ip-rates.sh" "$@"
|