cac-litespeed: forward real client IP to logs and PHP behind HAProxy
All checks were successful
Cloud Apache Container / Build-and-Push (74) (push) Successful in 4m47s
Cloud Apache Container / Build-and-Push (80) (push) Successful in 1m18s
Cloud Apache Container / Build-and-Push (81) (push) Successful in 1m17s
Cloud Apache Container / Build-and-Push (82) (push) Successful in 2m17s
Cloud Apache Container / Build-and-Push (83) (push) Successful in 2m20s
Cloud Apache Container / Build-and-Push (84) (push) Successful in 1m16s
Cloud Apache Container / Build-and-Push (85) (push) Successful in 1m17s
Cloud Apache Container / Build-FPM-Images (74) (push) Successful in 2m6s
Cloud Apache Container / Build-FPM-Images (80) (push) Successful in 2m14s
Cloud Apache Container / Build-FPM-Images (81) (push) Successful in 2m16s
Cloud Apache Container / Build-FPM-Images (82) (push) Successful in 2m21s
Cloud Apache Container / Build-FPM-Images (83) (push) Successful in 1m18s
Cloud Apache Container / Build-FPM-Images (84) (push) Successful in 1m19s
Cloud Apache Container / Build-FPM-Images (85) (push) Successful in 2m13s
Cloud Apache Container / Build-LiteSpeed-Images (81) (push) Successful in 35s
Cloud Apache Container / Build-LiteSpeed-Images (82) (push) Successful in 45s
Cloud Apache Container / Build-LiteSpeed-Images (83) (push) Successful in 1m9s
Cloud Apache Container / Build-LiteSpeed-Images (84) (push) Successful in 30s
Cloud Apache Container / Build-LiteSpeed-Images (85) (push) Successful in 31s
Cloud Apache Container / Build-Shared-httpd (push) Successful in 26s

OLS had no equivalent of the Apache cac:phpNN mod_remoteip wiring
(configs/remote_ip.conf + RemoteIPInternalProxy), so every migrated
LiteSpeed site logged HAProxy's docker-bridge IP and handed that same
internal IP to lsphp as $_SERVER['REMOTE_ADDR']. That silently broke
traffic analytics, WP security plugins, brute-force detection, Coraza
source-IP correlation, geo, and rate-limiting.

Add server-level `useIpInProxyHeader 1` to the httpd_config append
fragment. OLS then rewrites the remote IP from X-Forwarded-For for both
logging and the LSAPI REMOTE_ADDR before PHP sees it. Value 1 mirrors the
Apache trust model (container is only reachable via HAProxy, never bound
publicly). Confirmed HAProxy customer backends are mode http with
`option forwardfor` and set X-Forwarded-For to the resolved real client IP.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-06-04 15:51:25 -07:00
parent cfdaae116a
commit 2837d40f00

View File

@@ -10,6 +10,21 @@
## envsubst. Templated vars: $user $domain $vhost_map_aliases $PHPVER
## $LSAPI_CHILDREN (computed by detect-memory-litespeed.sh)
## --- real client IP behind HAProxy ---
## OLS equivalent of the Apache cac:phpNN mod_remoteip wiring
## (configs/remote_ip.conf + RemoteIPInternalProxy in entrypoint.sh). Without
## this, OLS records HAProxy's docker-bridge IP as the peer: every site's
## access_log and lsphp $_SERVER['REMOTE_ADDR'] collapse to one internal IP,
## silently breaking traffic analytics, WP security plugins, brute-force
## detection, Coraza source-IP correlation, geo, and rate-limiting.
## 1 = trust X-Forwarded-For (the container is only reachable via HAProxy;
## it is never bound to a public address). Mirrors the Apache side, which
## trusts the whole docker subnet via RemoteIPInternalProxy $docker_network.
## When enabled, OLS rewrites the remote IP for BOTH logging and the LSAPI
## REMOTE_ADDR before PHP sees it — so the default access_log format already
## records the real visitor; no LogFormat change needed.
useIpInProxyHeader 1
## --- our listeners (replace stock Default :8088) ---
listener HTTP {
address *:80