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.

Steps to configure Apache as a reverse proxy server:

  1. Open a terminal with sudo privileges.
    $ whoami
    user
  2. 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)
  3. Create or edit the virtual host configuration file.
    $ sudo vi /etc/apache2/sites-available/your-site.conf
  4. 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.

  5. 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.

  6. Test the Apache configuration syntax.
    $ sudo apache2ctl -t
    Syntax OK
  7. Reload the apache2 service to apply the reverse proxy settings.
    $ sudo systemctl reload apache2
  8. 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).

  9. 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.

  10. 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 #####
Discuss the article:

Comment anonymously. Login not required.