fix(haproxy): stop the trusted-proxy volume from shadowing Cloudflare/proxy lists
/etc/haproxy is a named volume in deployed containers, so the baked-in
cloudflare_ips.list and trusted_proxies.list COPYed there in the prior
task never actually reached hosts with a pre-existing volume -- the
start-up.sh guard then found them "missing" and created them empty.
With both lists empty, the from_trusted_proxy ACL in hap_listener.tpl
matched nothing, so CF-Connecting-IP / X-Real-IP / X-Forwarded-For got
stripped from every peer, including Cloudflare's own edge. Confirmed
live: image shipped 34/13 lines, running container had 0/0.
Fix: stage both files under /haproxy/defaults (outside the volume) and
apply their ownership rule in start-up.sh instead of a blind
"create if missing":
- cloudflare_ips.list is shipped data -- always refresh it from the
baked default so Cloudflare range updates reach existing hosts.
- trusted_proxies.list is operator data -- seed it from the baked
default only when missing, and never overwrite what an operator
added on the server.
Both branches fall back to creating an empty file if the baked default
is somehow absent, since a missing "-f" target is a fatal HAProxy
config error.
Verified against a volume pre-populated to shadow the image (mimicking
a real host): cloudflare_ips.list repopulates with all 15 IPv4 + 7
IPv6 ranges even after being truncated and restarted; a distinctive
operator entry appended to trusted_proxies.list survives a restart
untouched; haproxy -c still validates cleanly.
Release-worthy fix for a defect from the just-released 2026.08.2 build.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
+8
-3
@@ -31,10 +31,15 @@ COPY haproxy_manager.py /haproxy/
|
||||
COPY scripts /haproxy/scripts
|
||||
COPY trusted_ips.list /etc/haproxy/trusted_ips.list
|
||||
COPY trusted_ips.map /etc/haproxy/trusted_ips.map
|
||||
COPY cloudflare_ips.list /etc/haproxy/cloudflare_ips.list
|
||||
COPY trusted_proxies.list /etc/haproxy/trusted_proxies.list
|
||||
# /etc/haproxy is a named volume in deployed containers, so baked-in files
|
||||
# under that path get shadowed by the volume on existing deployments.
|
||||
# under that path get shadowed by the volume on existing deployments. The
|
||||
# trusted_ips.* pair above predates that discovery and is handled by the
|
||||
# older start-up.sh guard (out of scope here). cloudflare_ips.list and
|
||||
# trusted_proxies.list are staged under /haproxy/defaults instead, so
|
||||
# start-up.sh can always read the image's baked copy regardless of what the
|
||||
# volume shadows /etc/haproxy with.
|
||||
COPY cloudflare_ips.list /haproxy/defaults/cloudflare_ips.list
|
||||
COPY trusted_proxies.list /haproxy/defaults/trusted_proxies.list
|
||||
# Place errorfiles outside the volumed path; the HAProxy config references
|
||||
# them by absolute path.
|
||||
COPY errors /haproxy/errors
|
||||
|
||||
+24
-1
@@ -21,8 +21,31 @@ set -eo pipefail
|
||||
mkdir -p /etc/haproxy
|
||||
[ -f /etc/haproxy/trusted_ips.list ] || : > /etc/haproxy/trusted_ips.list
|
||||
[ -f /etc/haproxy/trusted_ips.map ] || : > /etc/haproxy/trusted_ips.map
|
||||
|
||||
# cloudflare_ips.list is SHIPPED DATA: it must always match what this image
|
||||
# bakes in (/haproxy/defaults), so a Cloudflare range refresh actually reaches
|
||||
# existing hosts instead of being permanently shadowed by the volume.
|
||||
# Overwrite it from the baked copy on every start.
|
||||
#
|
||||
# trusted_proxies.list is OPERATOR DATA: operators add entries directly on
|
||||
# the server and those must survive restarts/recreates. Seed it from the
|
||||
# baked copy only when it's missing; never overwrite an existing one.
|
||||
#
|
||||
# Both branches fall back to an empty file if the baked default is somehow
|
||||
# absent, because "acl ... -f <missing file>" is a fatal HAProxy config
|
||||
# error -- the list files must exist unconditionally by the time HAProxy starts.
|
||||
if [ -f /haproxy/defaults/cloudflare_ips.list ]; then
|
||||
cp /haproxy/defaults/cloudflare_ips.list /etc/haproxy/cloudflare_ips.list
|
||||
else
|
||||
[ -f /etc/haproxy/cloudflare_ips.list ] || : > /etc/haproxy/cloudflare_ips.list
|
||||
[ -f /etc/haproxy/trusted_proxies.list ] || : > /etc/haproxy/trusted_proxies.list
|
||||
fi
|
||||
if [ ! -f /etc/haproxy/trusted_proxies.list ]; then
|
||||
if [ -f /haproxy/defaults/trusted_proxies.list ]; then
|
||||
cp /haproxy/defaults/trusted_proxies.list /etc/haproxy/trusted_proxies.list
|
||||
else
|
||||
: > /etc/haproxy/trusted_proxies.list
|
||||
fi
|
||||
fi
|
||||
|
||||
cron &
|
||||
|
||||
|
||||
Reference in New Issue
Block a user