Implementing Apache Reverse Proxy with mod_proxy and mod_proxy_http
Learn how to configure Apache as a reverse proxy using mod_proxy and mod_proxy_http to securely route traffic to backend application servers.
02 Jan 2026, 17:23 UTC

The Problem: Exposing Backend Services Safely
Directly exposing application servers (like Node.js, Python/Flask, or Java Spring) to the public internet introduces security risks and operational rigidity. You need a way to terminate SSL/TLS, handle request filtering, and hide internal network topology while routing traffic to the correct backend service.
The solution is a Reverse Proxy. Using Apache's mod_proxy and mod_proxy_http, you can designate Apache as the single point of entry. It accepts the client request and forwards it to a backend server, then returns the backend's response to the client. The client never interacts with the backend server directly.
Core Mechanism and Configuration
To function as a reverse proxy, Apache requires two primary modules: mod_proxy (the core engine) and mod_proxy_http (the protocol handler for HTTP/HTTPS traffic). These modules intercept requests based on URL patterns and map them to internal network addresses.
Worked Example: Routing /api to a Backend Service
In this scenario, we assume a backend API is running on an internal server at 10.0.0.50:8080. We want users to access it via https://example.com/api.
Prerequisites: Ensure the modules are enabled. On Debian/Ubuntu systems, run these commands as root or with sudo:
a2enmod proxy
a2enmod proxy_http
systemctl restart apache2
Add the following configuration to your VirtualHost file (typically found in /etc/apache2/sites-available/ or httpd.conf):
<VirtualHost *:80>
ServerName example.com
# Ensure the original Host header is passed to the backend
ProxyPreserveHost On
# Map the local /api path to the remote backend server
ProxyPass /api http://10.0.0.50:8080/api
# Rewrite response headers to prevent the backend from leaking its internal IP
ProxyPassReverse /api http://10.0.0.50:8080/api
ErrorLog ${APACHE_LOG_DIR}/proxy_error.log
CustomLog ${APACHE_LOG_DIR}/proxy_access.log combined
</VirtualHost>
Key Directive Breakdown
- ProxyPass: Tells Apache that any request starting with
/apishould be forwarded to the specified URL. - ProxyPassReverse: This is critical. If the backend server sends a HTTP redirect (301 or 302), it will likely contain the internal IP (
10.0.0.50).ProxyPassReverseintercepts that header and rewrites it back to the proxy's public URL so the client doesn't try to connect to a private IP. - ProxyPreserveHost: By default, Apache sends the backend's own hostname in the
Host:header. Setting this toOnpasses the originalHost: example.comheader, which is often required by backend apps for generating correct absolute links.
Verification and Diagnostics
Before applying changes, always validate the syntax to avoid crashing the web server:
# Run as root/sudo
apachectl configtest
If the output is Syntax OK, restart the service. To verify the proxy is working, check the backend server's logs. You should see the request arriving from the Apache server's IP address. To confirm the client's original IP is being passed, check for the X-Forwarded-For header in the backend application logs.
Limitations and Common Pitfalls
The Redirect Loop
The most common mistake is omitting ProxyPassReverse. Without it, if your backend application redirects a user from /api/login to /api/dashboard, the browser may receive a location header pointing to http://10.0.0.50:8080/api/dashboard. Since the client cannot reach the internal IP, the request fails.
Timeout and Payload Mismatches
Reverse proxies introduce an additional layer of timeout management. If your backend performs heavy processing (e.g., generating a large PDF), the proxy may close the connection before the backend finishes. You may need to align the ProxyTimeout directive in Apache with the timeout settings of your backend application.
Large File Uploads
If you encounter 413 Request Entity Too Large errors, check the LimitRequestBody directive. This must be configured on both the Apache proxy and the backend server to allow the same maximum payload size.
Rollback Procedure
If the proxy configuration causes instability or routing loops, revert the changes by commenting out the ProxyPass and ProxyPassReverse lines in the VirtualHost file and restarting the service:
# Example rollback
# ProxyPass /api http://10.0.0.50:8080/api
# ProxyPassReverse /api http://10.0.0.50:8080/api
systemctl restart apache20 replies
A thoughtful contribution can make all the difference. Be the first to share one.