Skip to content

Conversation

@cuppett
Copy link
Contributor

@cuppett cuppett commented Dec 28, 2025

Summary

Adds opt-in Apache mod_remoteip support via the HTTPD_ENABLE_REMOTEIP=1 environment variable to properly handle X-Forwarded-For headers when running behind reverse proxies, load balancers, or in Kubernetes/OpenShift environments.

Why Enable This?

When PHP containers run behind reverse proxies (Nginx, HAProxy, Kubernetes Ingress, OpenShift Routes, cloud load balancers), Apache sees the proxy's IP address instead of the actual client's IP address. This causes issues with:

  • Access logs: Show proxy IP (e.g., 10.0.0.5) instead of real client IP
  • PHP $_SERVER['REMOTE_ADDR']: Returns proxy IP instead of client IP
  • Security: IP-based access controls, rate limiting, and geo-blocking don't work correctly
  • Analytics: User tracking and analytics receive incorrect IP addresses
  • Compliance: Audit logs don't capture actual client IPs

What This Changes

With mod_remoteip Enabled

Apache will:

  1. Read the X-Forwarded-For header from trusted proxy IPs
  2. Replace REMOTE_ADDR with the real client IP from the header
  3. Log the actual client IP in access logs instead of the proxy IP
  4. Pass correct IP to PHP via $_SERVER['REMOTE_ADDR']

Example Impact on Logs

Before (proxy IP logged):

10.0.0.5 - - [28/Dec/2025:16:00:00] "GET /index.php HTTP/1.1" 200

After (real client IP logged):

203.0.113.45 - - [28/Dec/2025:16:00:00] "GET /index.php HTTP/1.1" 200

Security Considerations

This feature only trusts X-Forwarded-For headers from private IP ranges:

  • 10.0.0.0/8 - Private networks
  • 172.16.0.0/12 - Private networks
  • 192.168.0.0/16 - Private networks
  • 169.254.0.0/16 - Link-local
  • 127.0.0.0/8 - Loopback

This prevents external clients from spoofing their IP address via forged headers.

Implementation

This implementation follows the approach used in docker-library/wordpress but adapted for RHEL-based httpd (vs Debian's apache2).

Changes

  • Pre-start scripts: Created 40-remoteip.sh for PHP versions 7.4, 8.0, 8.1, 8.2, 8.3 that conditionally enable mod_remoteip
  • Documentation: Updated README files for all versions to document the HTTPD_ENABLE_REMOTEIP environment variable
  • Tests: Added comprehensive test coverage with 3 test methods
    • Verifies config file creation with correct directives
    • Ensures container starts successfully with feature enabled
    • Validates default disabled behavior
  • Test runner: Added Python 3.14 support to test/run-pytest

Configuration Applied

When HTTPD_ENABLE_REMOTEIP=1 is set:

LoadModule remoteip_module modules/mod_remoteip.so
RemoteIPHeader X-Forwarded-For
RemoteIPTrustedProxy 10.0.0.0/8
RemoteIPTrustedProxy 172.16.0.0/12
RemoteIPTrustedProxy 192.168.0.0/16
RemoteIPTrustedProxy 169.254.0.0/16
RemoteIPTrustedProxy 127.0.0.0/8

Usage

Docker:

docker run -e HTTPD_ENABLE_REMOTEIP=1 php-83:latest

Kubernetes/OpenShift:

env:
  - name: HTTPD_ENABLE_REMOTEIP
    value: "1"

Test Results

All new tests passing:

  • ✅ Config file creation with correct directives
  • ✅ Container startup with feature enabled
  • ✅ Default disabled behavior verified

🤖 Generated with Claude Code

Adds HTTPD_ENABLE_REMOTEIP environment variable that enables Apache mod_remoteip
to properly handle X-Forwarded-For headers when running behind reverse proxies,
load balancers, or in Kubernetes/OpenShift environments. When enabled, configures
Apache to trust private IP ranges commonly used in Docker/container networks.

Changes:
- Added pre-start scripts (40-remoteip.sh) for PHP versions 7.4, 8.0, 8.1, 8.2, 8.3
- Updated README documentation for all versions
- Added comprehensive test coverage (3 test methods)
- Fixed test/run-pytest to support Python 3.14

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 (1M context) <noreply@anthropic.com>
@github-actions
Copy link

Pull Request validation

Failed

🔴 Review - Missing review from a member (1 required)

Success

🟢 CI - All checks have passed

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant