A reverse proxy places Apache in front of one or more backend services, presenting a single public endpoint while keeping internal hosts and ports off the internet. This pattern simplifies routing (multiple apps behind one domain), centralizes logging and access control, and reduces operational churn when backend locations change.
Apache implements reverse proxying through mod_proxy plus a protocol module such as mod_proxy_http. Incoming requests are matched by URL path (or host) and forwarded upstream using ProxyPass, while ProxyPassReverse rewrites redirect headers so browsers stay on the proxy URL instead of being bounced to internal backends.
A reverse proxy must never be left as a forward proxy: keep ProxyRequests set to Off to avoid becoming the internet’s favorite anonymous relay. Path-based proxying depends on correct trailing slashes and matching ProxyPass and ProxyPassReverse prefixes, and some applications need cookie or header adjustments when served under a sub-path. Configuration changes should be syntax-tested before reloading apache2 to avoid downtime.
Related: Enable or disable Apache modules
Related: Test Apache configuration
Related: Restart Apache service
Steps to configure Apache as a reverse proxy server:
- Open a terminal with sudo privileges.
$ whoami user
- Enable the mod_proxy and mod_proxy_http modules.
$ sudo a2enmod proxy proxy_http [sudo] password for user: Enabling module proxy. Considering dependency proxy for proxy_http: Module proxy already enabled Enabling module proxy_http. To activate the new configuration, you need to run: systemctl reload apache2
- Debian and Ubuntu provide a2enmod to toggle module symlinks under /etc/apache2.
- RHEL-family systems manage module loading via packaged config under /etc/httpd/conf.modules.d instead of a2enmod.
Item Debian/Ubuntu openSUSE/SLES Fedora/CentOS/RHEL Helper to enable modules a2enmod a2enmod install/enable module packages (no a2enmod) HTTP proxy module proxy_http proxy_http mod_proxy_http (packaged) Base proxy module proxy proxy mod_proxy (packaged) - Create or edit the virtual host configuration file.
$ sudo vi /etc/apache2/sites-available/your-site.conf
- Add the reverse proxy directives to the virtual host file.
<VirtualHost *:80> ServerName proxy-server.example.com ProxyRequests Off ProxyPreserveHost On ProxyPass "/backend-service-01/" "http://backend-service-01.local/" ProxyPassReverse "/backend-service-01/" "http://backend-service-01.local/" ProxyPass "/backend-service-02/" "http://backend-service-02.local/" ProxyPassReverse "/backend-service-02/" "http://backend-service-02.local/" </VirtualHost>
Directive/Option Description ProxyRequests Off Disables forward proxy requests so the host cannot be abused as an open proxy. ProxyPreserveHost On Preserves the original Host header so upstream applications can route or generate links based on the public host name. ProxyPass Maps an incoming URL prefix to an upstream base URL, so requests to http://proxy-server.example.com/backend-service-01/ are forwarded to http://backend-service-01.local/. ProxyPassReverse Rewrites Location, Content-Location, and URI headers in upstream redirect responses so clients stay on the reverse proxy URL instead of being redirected to internal backend names. Trailing slashes should match on both sides of ProxyPass and ProxyPassReverse to keep sub-path routing predictable.
- Enable the new site configuration.
$ sudo a2ensite your-site.conf Enabling site your-site. To activate the new configuration, you need to run: systemctl reload apache2
Disabling the default site (000-default.conf) avoids accidental routing through the wrong virtual host when multiple sites listen on port 80.
- Test the Apache configuration syntax.
$ sudo apache2ctl -t Syntax OK
- Reload the apache2 service to apply the reverse proxy settings.
$ sudo systemctl reload apache2
- Test backend connectivity from the reverse proxy host.
$ curl http://backend-service-01.local/ I am backend-service-01.local
Direct backend access from an external client may fail by design when backends are private; run this check on the reverse proxy host (or any host with the same network access).
- Test the same backend through the Apache reverse proxy path.
$ curl http://proxy-server.example.com/backend-service-01/ I am backend-service-01.local
A browser check should show the same content under the proxied path without exposing the backend hostname.
- Check the apache2 service status for proxy-related errors.
$ sudo systemctl status apache2 ● apache2.service - The Apache HTTP Server Loaded: loaded (/lib/systemd/system/apache2.service; enabled; vendor preset: enabled) Active: active (running) since Mon 2025-12-08 09:14:22 UTC; 2min 3s ago Docs: https://httpd.apache.org/docs/2.4/ Main PID: 1234 (apache2) Tasks: 55 (limit: 19099) Memory: 7.3M CPU: 92ms ##### snipped #####
Mohd Shakir Zakaria is a cloud architect with deep roots in software development and open-source advocacy. Certified in AWS, Red Hat, VMware, ITIL, and Linux, he specializes in designing and managing robust cloud and on-premises infrastructures.
Comment anonymously. Login not required.
