How to Configure Apache Reverse Proxy with Custom Host Header for Identical Backend Services


2 views

When setting up reverse proxies for development environments, we often encounter situations where multiple backend servers run identical copies of an application but require different host headers. The classic case is when you need to proxy:

app-dev.proxy.domain -> app.internal.domain (10.0.1.2)
app.proxy.domain -> app.internal.domain (10.0.1.1)

Both backends expect requests with app.internal.domain as the Host header, but we need to route them to different IPs.

The key is to combine ProxyPreserveHost with explicit IP routing in your VirtualHost configuration:

<VirtualHost *:80>
    ServerName app-dev.proxy.domain
    
    ProxyPreserveHost On
    ProxyPass / http://10.0.1.2/
    ProxyPassReverse / http://10.0.1.2/
    
    # Force the Host header
    RequestHeader set Host "app.internal.domain"
</VirtualHost>

<VirtualHost *:80>
    ServerName app.proxy.domain
    
    ProxyPreserveHost On
    ProxyPass / http://10.0.1.1/
    ProxyPassReverse / http://10.0.1.1/
    
    # Force the Host header
    RequestHeader set Host "app.internal.domain"
</VirtualHost>

For more complex scenarios, you might want to use mod_proxy with explicit host headers:

<Location />
    ProxyPass http://10.0.1.2/ connectiontimeout=5 timeout=30
    ProxySet enablereuse=on
    RequestHeader set Host "app.internal.domain"
</Location>
  • Always enable ProxyPreserveHost when overriding host headers
  • Use ProxyPassReverse to handle redirects properly
  • Consider adding timeout parameters for production environments

After implementing these changes, verify with:

curl -v -H "Host: app-dev.proxy.domain" http://your-proxy-server/

Check that the request reaches the correct backend while maintaining the required host header.


When setting up reverse proxies with Apache mod_proxy, a common challenge emerges when backend applications require specific host headers but need to be accessed through multiple proxy endpoints. Here's a deep dive into solving this with minimal configuration changes.


# Standard proxy configuration that WON'T work in this case
<VirtualHost *:80>
    ServerName app-dev.proxy.domain
    ProxyPass / http://10.0.1.2/
    ProxyPassReverse / http://10.0.1.2/
</VirtualHost>

The above would route traffic correctly but sends the wrong Host header (10.0.1.2 instead of app.internal.domain).

Apache's ProxyPreserveHost combined with ProxyPass solves this elegantly:


<VirtualHost *:80>
    ServerName app-dev.proxy.domain
    ProxyPreserveHost On
    ProxyPass / http://10.0.1.2/
    ProxyPassReverse / http://10.0.1.2/
    RequestHeader set Host "app.internal.domain"
</VirtualHost>

For production and development environments coexisting:


# Production config
<VirtualHost *:80>
    ServerName app.proxy.domain
    ProxyPass / http://app.internal.domain/
    ProxyPassReverse / http://app.internal.domain/
</VirtualHost>

# Dev config with IP override
<VirtualHost *:80>
    ServerName app-dev.proxy.domain
    ProxyPreserveHost On
    ProxyPass / http://10.0.1.2/
    ProxyPassReverse / http://10.0.1.2/
    RequestHeader set Host "app.internal.domain"
</VirtualHost>

For more complex routing scenarios:


RewriteEngine On
RewriteCond %{HTTP_HOST} ^app-dev\.proxy\.domain$
RewriteRule ^(.*)$ http://10.0.1.2/$1 [P,L]
ProxyPreserveHost On
RequestHeader set Host "app.internal.domain"

Verify your configuration works with:


curl -v -H "Host: app-dev.proxy.domain" http://your-proxy-server/

Check Apache logs for header modifications and routing decisions.