feat(edge): unrouted hosts 404+noindex everywhere; access log moves into the container (2026.11.2)
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
This commit is contained in:
1 parent
8787e0d99e
commit
0075b2e0de
15 files changed
+625
-74
No files matched your search
+11
-9
@@ -138,6 +138,9 @@ CORAZA_SPOE_BACKUP_PATH = '/etc/haproxy/coraza-spoe.cfg.backup'
|
||||
# Hosts the frontend routes to a site (default splash, hap_listener.tpl). The
|
||||
# paths are hardcoded in the template's `-f` ACLs, like blocked_ips.map, and
|
||||
# written by generate_config() from the same rows as the routing ACLs.
|
||||
# HAProxy's access-log target: the receiver's socket, CHROOT-RELATIVE
|
||||
# (hap_header.tpl `chroot /var/lib/haproxy`), i.e. /var/lib/haproxy/log.sock.
|
||||
DEFAULT_LOG_TARGET = '/log.sock'
|
||||
ROUTED_HOSTS_PATH = '/etc/haproxy/routed_hosts.list'
|
||||
ROUTED_HOSTS_BACKUP_PATH = '/etc/haproxy/routed_hosts.list.backup'
|
||||
ROUTED_WILDCARDS_PATH = '/etc/haproxy/routed_wildcards.list'
|
||||
@@ -3145,15 +3148,14 @@ def generate_config():
|
||||
except Exception as e:
|
||||
logger.error(f"Failed to create {suspended_list_path}: {e}")
|
||||
|
||||
# Access-log destination for the `log` line in the global section.
|
||||
# Default 172.18.0.1:514 is the docker bridge gateway for WHP's
|
||||
# `client-net`, i.e. the host, where rsyslog's imudp listener is bound
|
||||
# by setup-haproxy-logrotate.sh. Overridable so this image stays usable
|
||||
# on standalone/home deployments with a different bridge subnet or a
|
||||
# remote log collector -- set HAPROXY_SYSLOG_TARGET to `<ip>:<port>`.
|
||||
# UDP, so an absent listener drops log lines and never affects request
|
||||
# handling.
|
||||
syslog_target = os.environ.get('HAPROXY_SYSLOG_TARGET', '172.18.0.1:514').strip()
|
||||
# Access-log destination for the `log` line in the global section:
|
||||
# the in-container receiver's UNIX socket (scripts/haproxy-log-receiver.py),
|
||||
# given relative to haproxy's chroot (/var/lib/haproxy) -- see
|
||||
# hap_header.tpl. HAPROXY_SYSLOG_TARGET overrides it (`<ip>:<port>` for
|
||||
# a remote collector). The old default, 172.18.0.1:514 (host rsyslog on
|
||||
# the docker bridge), had no listener on the fleet.
|
||||
syslog_target = (os.environ.get('HAPROXY_SYSLOG_TARGET', '').strip()
|
||||
or DEFAULT_LOG_TARGET)
|
||||
|
||||
# Default splash for unrouted hosts (server hostname, bare IP, unknown
|
||||
# names) answered by HAProxy before the WAF -- see hap_listener.tpl.
|
||||
|
||||
Reference in new issue
Block a user