Apache HTTP Server course

Configure Apache HTTP Server as a Reverse Proxy

Learn how to configure Apache on Debian or Ubuntu as a reverse proxy for a local hostname, including modules, VirtualHost settings, access control, testing, and troubleshooting.

A reverse proxy lets Apache accept requests from clients and retrieve content from another web server, called the backend or origin server. Clients connect to Apache by using the proxy hostname; they do not need direct knowledge of the backend address.

This guide configures Apache on Debian or Ubuntu to receive requests for msn.local and forward them to an HTTP backend. Use an upstream service that you own or are explicitly authorized to proxy in a real deployment.

How a Reverse Proxy Works

The client sends an HTTP request to Apache. Apache selects a matching VirtualHost, contacts the backend, receives its response, and returns that response to the client under the proxy hostname.

A VirtualHost is an Apache configuration container for a particular address, port, or hostname. ServerName identifies the hostname associated with that virtual host.

  • Client requests http://msn.local/.
  • DNS or a local hosts-file entry resolves msn.local to the Apache server.
  • Apache matches the request to the virtual host with ServerName msn.local.
  • Apache requests the corresponding resource from the backend.
  • Apache returns the backend response to the client as if it came from msn.local.

The client must be able to resolve and reach the Apache hostname. For a lab, add a suitable entry to the client's hosts file, or create an internal DNS record. The Apache host must separately be able to resolve and reach the backend.

Reverse Proxy Compared with Forward Proxy

CharacteristicReverse ProxyForward Proxy
Who configures the proxyThe service owner or administratorClients or their network administrator
Who uses the proxyClients accessing a published serviceClients reaching remote destinations
Arbitrary destinationsNormally no; routes are explicitly configuredOften yes, if permitted
Typical use caseNetwork boundaries, hostname routing, access consolidation, and traffic distributionCentralized client internet access, filtering, or privacy controls
ProxyRequestsOffOn, only when deliberately configured and secured

A reverse proxy hides backend addresses, can publish several services behind one entry point, route hostnames or paths, and distribute traffic across multiple backends. A forward proxy acts on behalf of clients that choose where to connect.

Required Apache Modules

mod_proxy is Apache's core proxy framework. Because this example uses an HTTP backend, it also requires mod_proxy_http. mod_proxy_connect is used for CONNECT tunneling and is not normally needed for a basic HTTP reverse proxy.

ItemPurposeRequired for Basic HTTP Reverse ProxyNotes
mod_proxyProvides Apache's proxy frameworkYesRequired by proxy directives
mod_proxy_httpProxies HTTP requests to HTTP backendsYesEnable for an http:// upstream
mod_proxy_connectProvides CONNECT tunnelingNoEnable only for a specific tunneling requirement
ProxyPassMaps an incoming path to an upstream URLYesDefines the reverse-proxy route
ProxyPassReverseRewrites suitable backend redirect headersStrongly recommendedHelps clients remain on the proxy hostname
ProxyRequestsControls forward-proxy request handlingMust be OffNever enable it just to configure reverse proxying
ProxyViaControls Via headersOptionalOn can make proxy hops visible in headers
sudo a2enmod proxy
sudo a2enmod proxy_http
sudo systemctl reload apache2

Apache modules are commonly represented by links in /etc/apache2/mods-enabled/, managed from the available module definitions. Module availability and service names can vary on distributions other than Debian and Ubuntu. Reload or restart Apache after changing enabled modules.

Forward-Proxy Settings That Must Stay Disabled

Set ProxyRequests Off for an ordinary reverse proxy. If it is set to On and access is broadly allowed, Apache may become an open forward proxy. That can let unrelated users use the server to reach arbitrary destinations and can cause abuse or data exposure.

<Proxy> authorization blocks control access to proxy functionality, especially forward-proxy requests. They are not a replacement for access rules on a reverse-proxy route. Use a <Location> block or virtual-host authorization rule to restrict clients accessing the published reverse-proxy URL.

ProxyVia On adds or manages a Via header that identifies proxy participation. This can be useful for transparent proxy-chain information, but it is optional for this setup.

ProxyRequests Off
ProxyVia On

Create the Reverse-Proxy Virtual Host

Create a dedicated site file at /etc/apache2/sites-available/reverse_proxy.conf:

<VirtualHost *:80>
    ServerName msn.local

    ProxyRequests Off
    ProxyPass / http://www.msn.com/
    ProxyPassReverse / http://www.msn.com/

    <Location />
        Require ip 192.168.0.0/16
    </Location>
</VirtualHost>

The example uses the private network 192.168.0.0/16. The access rule is optional; change or remove it to match the intended client network. Restricting an internal service is preferable to exposing it publicly by accident.

Understanding the Directives

  • VirtualHost *:80 makes the site listen for HTTP requests on port 80.
  • ServerName msn.local tells Apache which hostname selects this virtual host.
  • ProxyPass / http://www.msn.com/ maps every request under the incoming root path to the backend root path.
  • ProxyPassReverse / http://www.msn.com/ adjusts supported redirect response headers so redirects can point back through the proxy hostname.
  • Require ip 192.168.0.0/16 permits only clients from the specified private network.

Keep source and target slash usage consistent. With ProxyPass /app/ http://backend.example/app/, a request such as /app/file maps predictably to /app/file on the backend. Inconsistent trailing slashes can produce unexpected path joining or redirects.

Root-Path Application Example

For an application listening on an internal host and port, a root-path mapping can look like this:

<VirtualHost *:80>
    ServerName app.internal.example
    ProxyRequests Off
    ProxyPass / http://10.0.0.20:8080/
    ProxyPassReverse / http://10.0.0.20:8080/
</VirtualHost>

The backend application should know its public URL when it generates absolute links, cookies, redirects, or security headers. Apache cannot automatically correct every application-generated reference.

Enable and Apply the Site

On Debian-family systems, enable the site, validate the complete Apache configuration, and then reload the service:

sudo a2ensite reverse_proxy.conf
sudo apache2ctl configtest
sudo systemctl reload apache2

Proceed only when the syntax check reports Syntax OK. A restart can be used when a full process restart is required:

sudo systemctl restart apache2

Confirm that the site is loaded and that Apache selected the expected virtual host:

sudo apachectl -S

The enabled site normally appears through the Debian-family site-management layout under /etc/apache2/sites-enabled/. The available configuration remains under /etc/apache2/sites-available/.

Verify the Configuration

Check Name Resolution and Connectivity

From an internal client, verify that the proxy hostname resolves to the Apache server, not directly to the backend. Then check that port 80 is reachable:

getent hosts msn.local
curl -I http://msn.local/

If the name is for a test environment, the client hosts file must contain an entry equivalent to APACHE_IP msn.local. Replace APACHE_IP with the Apache server's address.

Request the Proxy

Use verbose output to inspect the request, response status, redirects, and connection behavior:

curl -v http://msn.local/

A successful test shows that the client reached Apache, Apache connected to the backend, and the expected backend content or response was returned. A response status alone is not always sufficient: inspect redirects and application content as well.

Use Logs to Locate Failures

Apache's access log records requests received from clients. The error log records configuration problems, connection failures, timeouts, and other proxy errors. On many Debian and Ubuntu installations, these logs are under /var/log/apache2/.

sudo tail -f /var/log/apache2/access.log
sudo tail -f /var/log/apache2/error.log
  • No access-log entry usually points to client DNS, client routing, a firewall, or a request reaching a different server.
  • An access entry with proxy errors in the error log usually points to Apache-to-backend connectivity, an incorrect upstream URL, or backend behavior.
  • A successful Apache request with unexpected application content may indicate backend hostname, redirect, cookie, or application configuration problems.

Troubleshooting

Unknown ProxyPass Directive or Apache Will Not Start

Usually mod_proxy is not enabled, or HTTP proxy support is missing. Enable both required modules and validate before reloading:

sudo a2enmod proxy
sudo a2enmod proxy_http
sudo apache2ctl configtest

502 Bad Gateway or 503 Service Unavailable

Apache may not be able to connect to the backend. Test the backend URL directly from the Apache server:

curl -v http://BACKEND_HOST:BACKEND_PORT/

Check the upstream hostname, port, scheme, routing, firewall policy, DNS, backend service status, and Apache error log. A backend that listens only on a different interface can also be unreachable from Apache.

The Proxy Hostname Does Not Open

  • Check DNS or the client hosts-file mapping.
  • Confirm that the site is enabled and Apache was reloaded.
  • Confirm that ServerName exactly matches the requested hostname.
  • Use sudo apachectl -S to inspect loaded virtual hosts.
  • Verify that client traffic to port 80 is allowed by host and network firewalls.

Redirects Expose the Backend Hostname

Ensure that ProxyPassReverse matches the ProxyPass mapping. Inspect redirect headers with:

curl -I http://msn.local/

ProxyPassReverse handles supported backend redirect headers, but an application may also generate absolute URLs in HTML, JavaScript, or API responses. Configure the application's external base URL or trusted-proxy settings when available.

Apache Acts as an Open Proxy

Set ProxyRequests Off, remove unnecessary forward-proxy configuration, and restrict the reverse-proxy virtual host or route with appropriate Require rules. Do not use ProxyRequests On for reverse proxying.

Broken Links, Scripts, Cookies, or Security Headers

A third-party site or backend that assumes its original hostname may not work reliably behind a reverse proxy. Absolute URLs, cookies, redirects, content security policies, origin checks, and application routing can all depend on the backend hostname. Prefer an application designed to operate behind a proxy and configure its public URL and trusted proxy behavior.

Operational and Security Considerations

  • Limit access with Require ip or other appropriate authorization when the service is intended only for an internal network.
  • Keep ProxyRequests Off and review forward-proxy authorization so Apache cannot be used as an unintended open proxy.
  • Permit the Apache host to reach the backend through DNS, routing, firewall policy, and network security controls.
  • Production deployments commonly use HTTPS between clients and Apache. Some environments also use HTTPS between Apache and the backend.
  • When proxying to an HTTPS backend, additional TLS configuration such as SSLProxyEngine may be required.
  • Remote third-party websites are often poor proxy backends because of redirects, required host headers, content security policies, cookies, or application-specific behavior.
  • For multiple backends, investigate load-balancing features such as mod_proxy_balancer rather than duplicating ad hoc routes.

Configuration Reference

Path or CommandRoleWhen Used
/etc/apache2/mods-enabled/Contains enabled module configuration linksCheck whether proxy modules are enabled
/etc/apache2/sites-available/reverse_proxy.confStores the dedicated virtual-host configurationCreate and edit the reverse-proxy site
a2enmodEnables an Apache moduleEnable proxy and proxy_http
a2ensiteEnables an Apache siteActivate the virtual-host file
apache2ctl configtestChecks Apache syntaxRun before reload or restart
systemctl reload apache2Applies configuration without a full stopUse after a successful syntax check

Related Apache Topics