How to Configure Apache as a Reverse Proxy with mod_proxy on Ubuntu

Apache HTTP Server provides a flexible reverse proxy framework through the mod_proxy module family. When configured appropriately, Apache can operate in front of one or several backend applications, forward requests from clients, terminate SSL/TLS connections, balance traffic between multiple servers, and provide an additional layer of security and control between users and application infrastructure.

This tutorial explains how to configure Apache as a reverse proxy on Ubuntu with the mod_proxy module family. You will install Apache, activate the required proxy modules, configure basic forwarding with ProxyPass and ProxyPassReverse, retain client information by using forwarded headers, distribute requests among multiple backend systems with mod_proxy_balancer, set up SSL termination at the proxy layer, strengthen the configuration, and troubleshoot common mod_proxy problems in production environments.

Key Takeaways

  • Apache’s mod_proxy module family enables Apache HTTP Server to work as a reverse proxy, forward requests to backend applications, terminate SSL/TLS connections, distribute traffic among several servers, and centralize request processing through one frontend layer.
  • A reverse proxy is positioned between clients and backend application servers, allowing Apache to present one public endpoint while internal services, ports, and infrastructure remain inaccessible directly from the internet.
  • Apache reverse proxy configurations are frequently used to place Node.js, Python, Java, or PHP applications behind a stable frontend server that manages HTTPS, routing, logging, and access control for the backend services.
  • The ProxyPass and ProxyPassReverse directives form the foundation of an Apache reverse proxy configuration by forwarding requests to backend services and correctly adjusting redirects and response headers returned by those applications.
  • Forwarded headers including X-Forwarded-For, X-Forwarded-Host, and X-Forwarded-Proto help backend applications retain information about the original client IP address, requested hostname, and connection protocol after traffic passes through Apache.
  • Apache separates reverse proxy functionality into modules such as mod_proxy_http, mod_proxy_balancer, mod_proxy_wstunnel, and mod_proxy_fcgi, making it possible to activate only the capabilities required for a deployment.
  • The mod_proxy_balancer module distributes requests among multiple backend servers, improving scalability and availability while supporting different balancing algorithms and sticky sessions for stateful applications.
  • Terminating SSL at the Apache proxy layer simplifies certificate administration because Apache can manage encrypted HTTPS connections from clients while forwarding requests to backend applications through HTTP or HTTPS.
  • Reverse proxies should be hardened carefully. Important measures include disabling forward proxy functionality with ProxyRequests Off, protecting administrative interfaces, minimizing server information disclosure, and choosing suitable timeout values.
  • Typical mod_proxy problems such as 502 Bad Gateway, 503 Service Unavailable, SSL verification errors, and missing module errors can usually be investigated through Apache logs, direct backend connectivity tests, and configuration validation with apache2ctl configtest.

Prerequisites

Before starting, make sure you have an Ubuntu server using a currently supported release such as Ubuntu 22.04 or Ubuntu 24.04. The system should also have a non-root account with sudo privileges and an active firewall.

If the server has not yet been prepared, configure a non-root administrative user with sudo privileges and enable an appropriate firewall. If Apache administration on Ubuntu is unfamiliar, it is also useful to understand the standard Apache installation and service-management process before proceeding.

What Is a Reverse Proxy and Why Use mod_proxy?

A reverse proxy is a server positioned between clients and one or more backend application servers. When a client requests a resource, the connection first reaches the reverse proxy. Apache evaluates the configured routing rules, generally through ProxyPass and ProxyPassReverse directives inside a VirtualHost, chooses the appropriate backend, forwards the request, and then sends the backend response to the client as though Apache had produced the response itself.

This arrangement differs from a forward proxy. A forward proxy represents clients when they access external internet resources, whereas a reverse proxy represents applications. Clients normally see only the hostname, IP address, and TLS certificate of the proxy. Backend hostnames, internal ports, and the physical server layout remain hidden. Because these layers are separated, backend services can be replaced, expanded, upgraded, or patched without requiring clients to understand how the internal infrastructure is organized.

Modern application environments commonly use this architecture because application servers such as Node.js services, Python WSGI applications, and Java servlet containers are designed to process application traffic efficiently but are not always intended to serve as the public network edge. Apache manages the public client connection, applies policies at the boundary, and delegates application processing to specialized backend services.

Why Use a Reverse Proxy?

Reverse proxies allow organizations to centralize functionality that would otherwise need to be configured repeatedly on every application instance. TLS settings, request logging, rate limits, and access restrictions can be managed at the proxy layer instead of being duplicated across individual applications. This can simplify administration, improve security consistency, and make scaling easier as traffic increases.

Separating Frontend and Backend Services

Backend applications are often bound to loopback addresses such as 127.0.0.1 or private network interfaces that cannot be accessed directly from the public internet. This is usually intentional. An application process may not be hardened sufficiently for direct exposure, or multiple services may run on one server without each requiring a separate public port.

Apache connects these layers by listening on standard ports such as 80 and 443, while backend applications listen on other ports. For example, Apache can accept public requests while a Node.js API listens locally on 127.0.0.1:3000. Path-based routing can forward requests under /api/ to that application while Apache handles static content directly. Users can therefore access one domain and certificate while application processes remain outside the public network.

This architecture can also simplify application updates. A new version of a backend can be deployed on another port, the proxy destination can be changed, or a blue-green deployment can be implemented without requiring users to change URLs or DNS records. Several applications can also share one public hostname and be routed according to paths or subdomains configured in Apache.

SSL/TLS Termination

Encrypted communication is important, but maintaining individual certificates on every backend system creates repeated administrative work and increases the possibility of expired or incorrectly configured certificates. With SSL termination, the client establishes an HTTPS connection with Apache. Apache decrypts that connection with the configured site certificate before passing the request to the backend.

Apache can forward the decrypted request to backends through HTTP when those systems are located on a trusted private network. Alternatively, it can establish another encrypted connection to an HTTPS backend with SSLProxyEngine On and the related SSLProxy* directives. Plain HTTP is frequently used when the backend runs on the same host or trusted network segment, while HTTPS can be used when internal communication must also remain encrypted.

When TLS is managed centrally at the proxy, certificate renewal, cipher configuration, and HTTP Strict Transport Security can be controlled from one location. Application frameworks can use ordinary HTTP internally without duplicating TLS configuration, which can be particularly helpful for containerized or short-lived backend processes that would otherwise require separate certificate distribution.

Load Balancing

A single backend system can eventually become a performance limitation. Apache addresses this through mod_proxy_balancer, which defines a group of backend members and distributes requests among them. Modules such as mod_lbmethod_byrequests, mod_lbmethod_bytraffic, and mod_lbmethod_bybusyness determine whether balancing is based on request count, transferred data, or current backend activity.

Sticky sessions can be used when application session information is stored locally rather than in shared storage. Apache can continue routing a particular client to the same backend for the duration of the session. If one backend stops responding or is marked as unavailable, traffic can be sent to healthy members, improving service availability without taking the complete application offline.

Proxy-based balancing also provides a straightforward approach to horizontal scaling. An additional application instance can be started, registered as another BalancerMember, and begin receiving requests without changing the public URL used by clients.

Caching and Performance Optimization

Some requests do not need to reach a backend application every time. Content that changes infrequently, including images, stylesheets, and public API responses with suitable cache lifetimes, can be cached by Apache through modules such as mod_cache and mod_cache_disk. Apache can follow HTTP caching headers and administrator-defined rules. Serving cached responses from the frontend layer reduces CPU and I/O usage on backend systems while improving response times for repeat requests.

Apache is not primarily designed as a dedicated caching proxy, but edge caching can still be useful in environments where Apache already handles TLS and static content. Response compression through mod_deflate provides another optimization. Apache can compress responses before transmitting them across the network, which reduces data transfer for clients without requiring every backend application to implement compression independently.

How mod_proxy Fits into the Apache Module Ecosystem

Apache provides reverse proxy functionality through a modular family built around mod_proxy. The core module supplies shared proxy infrastructure, including connection management, common directives, and extension hooks used by protocol-specific modules. The mod_proxy module must be enabled for reverse proxy functionality, while companion modules provide additional capabilities.

The mod_proxy_http module handles HTTP and HTTPS backend communication and is usually one of the first proxy modules activated. mod_proxy_balancer introduces load balancing through BalancerMember directives and <Proxy balancer://name> configuration blocks. mod_proxy_wstunnel handles WebSocket upgrade connections for real-time applications, while mod_proxy_fcgi forwards requests to FastCGI services such as PHP-FPM.

Other modules expand the proxy system for specialized use cases. mod_proxy_ajp communicates with Java application servers through the AJP protocol. mod_proxy_hcheck can perform backend health checks so unavailable servers are removed from rotation. mod_proxy_html can rewrite links contained in HTML responses when internal backend URLs differ from the public URL structure.

Several important directives are shared across these modules. ProxyPass connects an incoming URL path to a backend URL. ProxyPassReverse adjusts response headers so redirects refer to the public hostname instead of internal backend addresses. ProxyRequests Off disables forward-proxy functionality. Leaving forward proxying enabled unintentionally can create an open proxy and represents a serious security problem.

Because functionality is divided into modules, administrators can load only the features required by a particular system. A single Apache installation can terminate TLS, proxy REST API requests, balance traffic across a cluster, and upgrade WebSocket connections without loading unrelated protocol support. On Ubuntu and Debian systems, modules can be activated with a2enmod. Apache should then be restarted or reloaded, and the loaded proxy modules can be checked before configuring VirtualHost rules.

Understanding the mod_proxy Module Family

Apache reverse proxy support is not contained in one independent module. Instead, several related modules cooperate to handle different protocols, backend communication methods, and proxy capabilities. This modular structure makes Apache flexible enough to support many different web server architectures.

The central component is mod_proxy. It provides the underlying framework used for request forwarding, connection management, and proxy infrastructure. However, mod_proxy by itself cannot handle every type of application traffic. Protocol-specific modules perform the actual communication between the proxy and backend services.

This separation means an administrator can activate only the components needed for a deployment. A simple HTTP reverse proxy may require only mod_proxy and mod_proxy_http, whereas an environment using WebSockets, PHP-FPM, or load balancing can require several additional modules.

Each module adds a specific capability to the Apache proxy framework.

The Core mod_proxy Module

The base mod_proxy module provides Apache’s primary proxy engine. It contains the general mechanisms needed to pass requests between clients and backend servers, including proxy connection management, routing, shared directives, worker definitions, and communication flow between Apache and backend systems.

The core module also provides important directives including:

  • ProxyPass
  • ProxyPassReverse
  • ProxyRequests
  • <Proxy>
  • BalancerMember

Although mod_proxy supplies the common infrastructure, it does not handle ordinary HTTP proxy communication by itself. Additional protocol handlers are required according to the type of backend being used.

mod_proxy_http

mod_proxy_http is the proxy submodule used most frequently. It enables Apache to forward ordinary HTTP and HTTPS traffic to application servers.

In typical reverse proxy environments, it can handle communication between Apache and applications such as:

  • Node.js applications
  • Python web frameworks
  • Internal Apache or Nginx servers
  • Java application servers
  • Containerized web applications

For example, when Apache forwards requests to an application listening at:

the backend communication is performed through mod_proxy_http.

This module supports ordinary HTTP request and response processing, persistent backend connections, chunked transfer encoding, header forwarding, and HTTP protocol negotiation.

A common configuration looks like this:

ProxyPass / http://127.0.0.1:3000/
ProxyPassReverse / http://127.0.0.1:3000/

Because HTTP and HTTPS are used by most modern web applications, mod_proxy_http is normally the first protocol-specific proxy module that administrators enable.

mod_proxy_balancer

The mod_proxy_balancer module adds load-balancing functionality to Apache’s proxy framework. Rather than sending every request to one backend server, Apache can divide incoming traffic among multiple backend nodes.

This capability is especially useful in high-availability environments or horizontally scaled architectures where several application instances process requests at the same time.

Apache provides several balancing methods, including:

  • Request-count balancing with byrequests
  • Traffic-volume balancing with bytraffic
  • Pending-request balancing with bybusyness

The module also supports session persistence, often called sticky sessions. With this configuration, subsequent requests from one client can continue to be routed to the same backend server.

A basic load-balanced configuration can look like this:

<Proxy "balancer://mycluster">
    BalancerMember http://10.0.0.11:8080
    BalancerMember http://10.0.0.12:8080
</Proxy>

ProxyPass / balancer://mycluster/

Internally, mod_proxy_balancer operates together with protocol modules such as mod_proxy_http, because the balancing module itself does not implement HTTP communication.

mod_proxy_wstunnel

Many modern applications use WebSockets for persistent real-time communication. Traditional HTTP proxy behavior alone is not sufficient for every WebSocket upgrade because a WebSocket connection changes from the ordinary HTTP request-response model to a persistent bidirectional connection.

mod_proxy_wstunnel enables Apache to proxy WebSocket connections with the ws:// and wss:// protocols. Apache 2.4.47 and newer can also process WebSocket upgrades through mod_proxy_http by using upgrade parameters, although mod_proxy_wstunnel continues to be commonly used.

Typical WebSocket use cases include:

  • Real-time dashboards
  • Chat applications
  • Live notification systems
  • Multiplayer game servers
  • Streaming applications

When a client requests a WebSocket connection, Apache identifies the protocol upgrade and tunnels the persistent connection to the backend application.

A common WebSocket proxy configuration is:

ProxyPass /socket ws://127.0.0.1:3000/socket
ProxyPassReverse /socket ws://127.0.0.1:3000/socket

Without suitable WebSocket proxy support, Apache can return protocol-upgrade errors or fail to keep the WebSocket session open.

mod_proxy_fcgi

The mod_proxy_fcgi module lets Apache communicate with FastCGI backend services. This is particularly relevant for PHP installations that use PHP-FPM instead of the older embedded mod_php processing method.

PHP-FPM is widely used on modern Linux systems because it separates PHP execution from the Apache process, improving scalability, resource isolation, and operational flexibility.

Instead of forwarding HTTP requests, mod_proxy_fcgi sends FastCGI requests to FastCGI workers.

A typical PHP-FPM integration is:

<FilesMatch \.php$>
    SetHandler "proxy:unix:/run/php/php8.3-fpm.sock|fcgi://localhost/"
</FilesMatch>

This configuration instructs Apache to send PHP requests through a Unix socket to the PHP-FPM service.

Although mod_proxy_fcgi is not generally used for standard HTTP reverse proxying, it remains part of the wider mod_proxy family and is commonly used in Apache-based PHP environments.

Comparing Common mod_proxy Submodules

The following table summarizes the main Apache proxy modules and their typical purposes:

Module Protocol Support Common Use Case Notes
mod_proxy Core proxy framework Base proxy infrastructure Required for all proxy functionality
mod_proxy_http HTTP, HTTPS Reverse proxying web applications Most frequently used proxy module
mod_proxy_balancer Load-balancing framework Distributing traffic across backend servers Works together with protocol modules
mod_proxy_wstunnel WebSocket (ws://, wss://) Proxying real-time applications Handles protocol upgrades
mod_proxy_fcgi FastCGI PHP-FPM and FastCGI services Common in PHP deployments

For many current Ubuntu reverse proxy deployments, at least the following modules are typically enabled:

mod_proxy
mod_proxy_http
mod_headers

Other modules can be activated according to application requirements and the architecture of the deployment.

Step 1: Installing Apache and Verifying mod_proxy Availability

Before Apache can be configured as a reverse proxy, install Apache HTTP Server and confirm that the required proxy modules are available. On Ubuntu, the mod_proxy module family is included with the standard Apache package, although individual modules might not be enabled automatically.

Installing Apache on Ubuntu

Ubuntu provides Apache HTTP Server through the apache2 package. Start by refreshing the package index:

Next, install Apache:

After installation, Ubuntu normally starts the Apache service automatically and enables it to launch during system boot.

Check the service status with:

sudo systemctl status apache2

If Apache started successfully, the output should resemble the following:

● apache2.service - The Apache HTTP Server
     Loaded: loaded (/usr/lib/systemd/system/apache2.service; enabled; preset: enabled)
     Active: active (running) since Tue 2026-05-19 06:59:03 UTC; 16s ago
       Docs: https://httpd.apache.org/docs/2.4/
   Main PID: 3083 (apache2)
      Tasks: 55 (limit: 2318)
     Memory: 5.1M (peak: 5.3M)
        CPU: 51ms
     CGroup: /system.slice/apache2.service
             ├─3083 /usr/sbin/apache2 -k start
             ├─3086 /usr/sbin/apache2 -k start
             └─3087 /usr/sbin/apache2 -k start

You can also confirm that Apache responds locally with curl:

If Apache is operating correctly, the command returns the default Apache HTML page.

Understanding Apache Modules on Ubuntu

Apache follows a modular design. Features are supplied through separate modules instead of being compiled directly into one large server binary. Reverse proxy functionality is implemented through the mod_proxy family, which contains separate modules for different proxy protocols and features.

On Ubuntu, Apache modules are primarily managed through two directories:

/etc/apache2/mods-available/

This directory contains the module definitions installed on the system.

Modules that are enabled are linked into:

/etc/apache2/mods-enabled/

This directory structure lets administrators enable and disable Apache functionality without manually changing the main server configuration file.

Most proxy modules are provided as dynamically loadable shared modules. They can therefore remain disabled until required, reducing unnecessary functionality in the active Apache process.

Verifying Available Proxy Modules

Before activating reverse proxy features, verify that the required proxy modules are installed.

List available proxy-related modules with:

ls /etc/apache2/mods-available/ | grep proxy

The output should contain entries similar to:

proxy.conf
proxy.load
proxy_http.load
proxy_balancer.load
proxy_wstunnel.load
proxy_fcgi.load

This confirms that the relevant module files exist and can be activated.

Each file corresponds to part of the Apache proxy framework:

  • proxy.load loads the main mod_proxy framework.
  • proxy_http.load enables HTTP and HTTPS proxy communication.
  • proxy_balancer.load provides load-balancing functionality.
  • proxy_wstunnel.load enables WebSocket proxy connections.
  • proxy_fcgi.load provides FastCGI backend support, including PHP-FPM.

Every installation does not need every module, but confirming their availability establishes that the server can support later configuration steps.

Checking Which Modules Are Currently Loaded

A module can exist on disk without being enabled in the active Apache configuration.

Display all loaded modules with:

To show only proxy modules, run:

apache2ctl -M | grep proxy

If proxy modules have already been activated, the output can resemble:

proxy_module (shared)
proxy_http_module (shared)

If no proxy modules are listed, they have not yet been enabled. The next step activates the required modules.

Verifying Apache Configuration Syntax

Before changing Apache configuration files, verify that the current configuration has valid syntax.

Run:

sudo apache2ctl configtest

If Apache detects no syntax problems, it returns:

Running configtest before and after configuration changes is useful because Apache will refuse to reload an invalid configuration. Checking syntax early reduces avoidable downtime and simplifies troubleshooting.

Step 2: Enabling mod_proxy and Required Submodules

Once the proxy modules have been confirmed as available, activate the components required for reverse proxy operation. Ubuntu normally manages Apache modules with the a2enmod utility, which creates symbolic links from mods-available to mods-enabled.

Because Apache separates proxy functionality into several modules, enabling only the core mod_proxy component is usually not enough. Protocol-specific modules must also be enabled so Apache can communicate with backend systems.

For a standard HTTP reverse proxy, the minimum modules are:

  • mod_proxy
  • mod_proxy_http

Other modules may be required according to the deployment, including modules for load balancing, WebSockets, SSL proxying, or HTTP header manipulation.

Enabling the Core Proxy Modules

Activate the basic proxy framework and HTTP proxy module:

sudo a2enmod proxy
sudo a2enmod proxy_http

The proxy module provides the main proxy infrastructure, while proxy_http lets Apache forward HTTP and HTTPS requests to application servers.

After these commands run, symbolic links for the enabled module configuration files are created under:

/etc/apache2/mods-enabled/

Confirm that the links exist:

ls /etc/apache2/mods-enabled/ | grep proxy

The directory should now contain entries similar to:

proxy.conf
proxy.load
proxy_http.load

Enabling Additional Common Proxy Modules

Many reverse proxy configurations use additional Apache modules beyond the basic HTTP proxy components.

For example, mod_headers is commonly used to pass information about the client and manipulate request headers:

If load balancing will be used, enable the balancing framework and request-based balancing method:

sudo a2enmod proxy_balancer
sudo a2enmod lbmethod_byrequests

proxy_balancer supplies the balancing framework, while lbmethod_byrequests activates Apache’s request-count balancing algorithm.

For WebSocket support, enable:

sudo a2enmod proxy_wstunnel

If Apache will terminate SSL/TLS connections or communicate with HTTPS backends, also enable the SSL module:

Activating modules that will be used later can simplify subsequent configuration, particularly in testing environments.

Understanding What a2enmod Does

The a2enmod utility does not directly rewrite Apache’s primary configuration file. Instead, it activates modules by placing symbolic links in mods-enabled that point to module files located in mods-available.

For example, activating mod_proxy creates links similar to:

/etc/apache2/mods-enabled/proxy.load
/etc/apache2/mods-enabled/proxy.conf

This modular structure makes Apache easier to administer because individual features can be enabled and disabled independently without manually maintaining one large configuration file.

A module can later be disabled with a2dismod:

sudo a2dismod proxy_wstunnel

Do not disable a module that is still referenced by active VirtualHost configurations, because Apache may be unable to start when required directives are unavailable.

Verifying Loaded Modules

After activating the necessary modules, verify that Apache loads them successfully.

Run:

apache2ctl -M | grep proxy

The output should resemble:

proxy_module (shared)
proxy_http_module (shared)
proxy_balancer_module (shared)
proxy_wstunnel_module (shared)

Check the headers module as well:

apache2ctl -M | grep headers

The expected output is:

Checking loaded modules at this stage helps prevent errors later when Apache encounters directives belonging to modules that have not been activated.

Restarting Apache After Enabling Modules

Restart Apache after activating new modules so they become available:

sudo systemctl restart apache2

Verify that Apache restarted correctly:

sudo systemctl status apache2

If Apache encounters a configuration or module-loading problem during startup, the service status usually contains a brief explanation. More detailed information is written to:

/var/log/apache2/error.log

Before continuing, validate the configuration again:

sudo apache2ctl configtest

With a valid configuration, Apache returns:

Apache is now prepared for reverse proxy configuration.

Step 3: Configuring a Basic Reverse Proxy with ProxyPass

With the required modules active, Apache can now be configured as a reverse proxy. In a basic setup, Apache receives client requests and forwards them to an application server running either locally or on another machine in the internal network.

The main directives responsible for this behavior are ProxyPass and ProxyPassReverse.

In this example, Apache accepts public requests on port 80 and sends them to a backend application at:

This configuration pattern is commonly used for applications based on Node.js, Django, Flask, Express, Spring Boot, and similar application frameworks where the application server itself should not be exposed directly to the public internet.

Understanding Reverse Proxy Request Flow

Before configuring the proxy, it helps to understand how traffic passes through the frontend layer.

In a reverse proxy setup:

  1. A client sends a request to Apache.
  2. Apache receives the request on behalf of the backend application.
  3. Apache forwards the request internally to the backend server.
  4. The backend application processes the request and generates a response.
  5. Apache returns that response to the client.

The client does not establish a direct connection to the backend application server.

This allows Apache to provide a stable public-facing layer while backend services remain isolated from direct internet exposure.

Disabling Forward Proxying

One of the most important security requirements in a reverse proxy setup is ensuring that forward proxy functionality remains disabled.

Apache can function as either:

  • A reverse proxy
  • A forward proxy

A forward proxy accepts requests from clients and retrieves arbitrary external resources for them. Unless that behavior is deliberately required, it should remain disabled because an unrestricted forward proxy can be abused by third parties.

To ensure that Apache is used only as a reverse proxy, configure:

This directive can be placed inside the relevant VirtualHost or an appropriate proxy configuration file.

Do not enable ProxyRequests unless a controlled forward proxy is intentionally being configured.

Understanding ProxyPass

The ProxyPass directive tells Apache to send requests for a particular frontend URL path to a backend server.

The general syntax is:

ProxyPass <frontend-path> <backend-url>

For example:

ProxyPass / http://127.0.0.1:3000/

This sends every request below / to the application running on port 3000.

If a client requests:

http://your-server-ip/about

Apache internally forwards that request to:

http://127.0.0.1:3000/about

The backend processes the request normally, after which Apache passes the response to the client.

Trailing slashes in ProxyPass mappings are significant because they influence how frontend and backend paths are combined. Inconsistent slash placement can lead to unexpected URL mapping behavior.

Understanding ProxyPassReverse

ProxyPassReverse modifies certain response headers returned by a backend before Apache sends them to the client.

This is necessary because backend applications can generate redirects or response headers containing internal URLs instead of the public URL exposed by the proxy.

For example, a backend might return:

Location: http://127.0.0.1:3000/login

Without ProxyPassReverse, the internal backend address could be sent directly to the client, potentially breaking routing and revealing internal infrastructure information.

Add:

ProxyPassReverse / http://127.0.0.1:3000/

Apache can then rewrite matching backend-generated response headers so clients continue using the public proxy address.

For this reason, ProxyPass and ProxyPassReverse are generally configured together.

Creating a Basic Reverse Proxy VirtualHost

Apache uses VirtualHost blocks to route incoming traffic. On Ubuntu, site configurations are normally stored in:

/etc/apache2/sites-available/

Create a new configuration file:

sudo nano /etc/apache2/sites-available/reverse-proxy.conf

Add the following configuration:

<VirtualHost *:80>
    ServerName example.com

    ProxyRequests Off

    ProxyPreserveHost On

    ProxyPass / http://127.0.0.1:3000/
    ProxyPassReverse / http://127.0.0.1:3000/

    ErrorLog ${APACHE_LOG_DIR}/reverse-proxy-error.log
    CustomLog ${APACHE_LOG_DIR}/reverse-proxy-access.log combined
</VirtualHost>

This configuration performs several functions:

  • Apache accepts HTTP requests on port 80.
  • Forward proxy functionality remains disabled.
  • Incoming traffic is passed to the backend application.
  • Backend-generated redirects are rewritten appropriately.
  • Separate access and error logs are maintained for troubleshooting.

ProxyPreserveHost On causes Apache to pass the original client Host header to the backend instead of replacing it with the backend hostname. Many applications use the original host value for routing, redirects, multi-tenant configuration, or framework behavior.

Enabling the VirtualHost Configuration

After saving the configuration, enable the site:

sudo a2ensite reverse-proxy.conf

If the standard Apache site remains active, it can optionally be disabled to avoid conflicts:

sudo a2dissite 000-default.conf

Validate the configuration before restarting Apache:

sudo apache2ctl configtest

A valid configuration returns:

Restart Apache:

sudo systemctl restart apache2

Testing the Reverse Proxy

After Apache restarts, test the configuration by visiting:

or:

If the backend application is running, its content should be delivered through Apache rather than being accessed directly from the backend port.

The proxy can also be tested with:

curl -I http://your-server-ip

The returned headers should show that Apache handled the frontend request while the backend application supplied the content.

Apache is now operating as a basic reverse proxy.

Step 4: Forwarding Client Information with Proxy Headers

In a reverse proxy architecture, backend applications do not communicate directly with clients. Requests first reach Apache and are then passed to the application server. Consequently, the backend can see the proxy server as the source of every request unless Apache forwards information about the original client through HTTP headers.

If these headers are not handled properly, backend applications can record the wrong client IP addresses, generate incorrect redirects, fail to recognize HTTPS connections, or apply security policies incorrectly.

Apache can preserve useful details from the original request, including:

  • The client’s IP address
  • The hostname requested by the client
  • The original protocol, either HTTP or HTTPS
  • Custom metadata headers

These values are normally passed through proxy headers or forwarded headers.

Why Forwarded Headers Matter

A typical reverse proxy request follows this path:

Client ---> Apache Reverse Proxy ---> Backend Application

From the backend application’s perspective, the TCP connection originates from Apache rather than directly from the user’s browser. Without forwarded information, the backend can therefore interpret:

  • Apache’s IP address as the client address
  • An internal hostname as the public hostname
  • HTTP as the connection protocol even when the original user connected through HTTPS

This can create several production issues.

For example:

  • Application logs may contain only the proxy address.
  • Rate-limiting mechanisms can fail because all requests appear to originate from a single system.
  • Authentication logic may incorrectly determine request origins.
  • Redirects can point to internal addresses.
  • Secure cookies can fail when the application cannot identify the original HTTPS connection.

Forwarded headers preserve the original request context and allow backend applications to behave correctly behind the proxy.

Preserving the Original Host Header

During proxying, Apache can replace the incoming Host header with the backend hostname. Some applications depend on the public Host value for domain routing, multi-tenant logic, configuration, or URL generation.

To retain the hostname originally requested by the client, use:

For example, when a client requests:

Apache can preserve that host value instead of passing the internal backend address:

This is particularly useful for:

  • Applications using virtual-host routing
  • Frameworks generating absolute URLs
  • Multi-domain deployments
  • OAuth and authentication callbacks
  • Applications operating behind an HTTPS proxy

For many modern reverse proxy deployments, ProxyPreserveHost On is appropriate unless the backend application specifically expects a different host value.

Forwarding the Original Client IP Address

X-Forwarded-For is one of the most commonly used proxy headers.

It provides the original client IP address so backend applications can distinguish the actual request source from the proxy server.

Apache can automatically add forwarding headers with:

This setting is already enabled by default in many Apache configurations, but declaring it explicitly makes the intended behavior clearer.

Apache can then add headers similar to:

X-Forwarded-For: 203.0.113.25
X-Forwarded-Host: app.example.com
X-Forwarded-Server: proxy-server

The backend can inspect X-Forwarded-For to determine the original client address.

When traffic passes through several proxies or content-delivery layers, this header can contain a comma-separated chain of addresses representing each proxy hop.

Forwarding HTTPS and Protocol Information

Backend applications frequently need to determine whether the user originally connected through HTTP or HTTPS.

This affects behavior such as:

  • Secure cookies
  • Redirect generation
  • Authentication
  • CSRF protection
  • URL generation

If Apache terminates HTTPS and then communicates with a backend through HTTP, the backend only sees the internal HTTP connection unless the original protocol is forwarded separately.

A common solution is to send X-Forwarded-Proto:

RequestHeader set X-Forwarded-Proto "https"

This tells the application that the public client connection used HTTPS even when the internal proxy connection uses HTTP.

The value can also be selected dynamically:

RequestHeader set X-Forwarded-Proto expr=%{REQUEST_SCHEME}

This forwards either http or https according to the protocol used by the incoming request.

Because RequestHeader belongs to mod_headers, make sure that module is enabled:

Setting Custom Proxy Headers

Apache also supports custom headers that can be passed to backend services.

For example:

RequestHeader set X-Proxy-Server "Apache-Reverse-Proxy"

Custom request headers can be useful for:

  • Identifying internal services
  • Debugging and tracing requests
  • Application-specific routing
  • API gateway integration
  • Security metadata

Headers can also be removed:

RequestHeader unset X-Unwanted-Header

This provides detailed control over the request information sent to backend applications.

Complete VirtualHost Example with Forwarded Headers

The following example combines several common reverse proxy header settings:

<VirtualHost *:80>
    ServerName example.com

    ProxyRequests Off
    ProxyPreserveHost On
    ProxyAddHeaders On

    ProxyPass / http://127.0.0.1:3000/
    ProxyPassReverse / http://127.0.0.1:3000/

    RequestHeader set X-Forwarded-Proto expr=%{REQUEST_SCHEME}

    ErrorLog ${APACHE_LOG_DIR}/reverse-proxy-error.log
    CustomLog ${APACHE_LOG_DIR}/reverse-proxy-access.log combined
</VirtualHost>

This allows the backend application to receive:

  • The hostname originally requested by the client
  • The original client IP address
  • The original request protocol
  • Correctly rewritten redirect information

Together, these settings allow applications to retain the necessary client context while operating behind Apache.

Applying the Configuration Changes

After changing the VirtualHost, validate the Apache configuration:

sudo apache2ctl configtest

If the syntax is valid, reload Apache:

sudo systemctl reload apache2

A reload applies the updated configuration without performing a complete web server restart.

Verifying Forwarded Headers

Forwarded headers can be verified through the backend application or by inspecting the headers received by a diagnostic endpoint.

Many application frameworks provide access to incoming request headers. A temporary backend that echoes request headers can also be used to verify that Apache passes the expected information.

A properly forwarded request can contain:

X-Forwarded-For: 203.0.113.25
X-Forwarded-Host: example.com
X-Forwarded-Proto: https

The reverse proxy now preserves the original request context for the backend application.

Step 5: Configuring Load Balancing with mod_proxy_balancer

Apache can distribute incoming traffic among several backend servers with mod_proxy_balancer. This can improve scalability and availability while preventing one application server from handling every request.

In a load-balanced architecture, Apache is positioned in front of multiple backend application instances and selects a destination according to a configured balancing algorithm.

Enabling the Load Balancing Modules

Activate the required modules before creating a balancer:

sudo a2enmod proxy_balancer
sudo a2enmod lbmethod_byrequests

proxy_balancer provides the core balancing framework, while lbmethod_byrequests supplies request-based distribution.

Reload Apache:

sudo systemctl reload apache2

Defining Backend Servers with BalancerMember

Apache organizes backend systems into a logical pool by using a <Proxy> block. Individual servers are registered through BalancerMember.

For example:

<Proxy "balancer://mycluster">
    BalancerMember http://127.0.0.1:3001
    BalancerMember http://127.0.0.1:3002
</Proxy>

Here, balancer://mycluster identifies the backend pool, while every BalancerMember entry represents one application server.

Apache can then distribute requests among those members automatically.

Configuring the Load Balancing Method

Apache provides several balancing algorithms. Common options are:

Method Description
byrequests Distributes traffic according to request count
bytraffic Balances based on the amount of data transferred
bybusyness Sends requests toward the least busy backend

For many environments, byrequests provides a straightforward balancing strategy.

The method can be configured with ProxySet:

ProxySet lbmethod=byrequests

Configuring Sticky Sessions

Some applications keep session information locally on an individual backend server. In that situation, repeated requests from one client need to continue reaching the same node. This behavior is known as session persistence or sticky sessions.

Apache supports this with the stickysession setting.

For example:

<Proxy "balancer://mycluster">
    BalancerMember http://127.0.0.1:3001 route=node1
    BalancerMember http://127.0.0.1:3002 route=node2

    ProxySet lbmethod=byrequests stickysession=ROUTEID
</Proxy>

Each backend receives a route identifier. The application must then create a cookie containing the corresponding route value so Apache can continue directing that client’s requests to the appropriate server.

Sticky sessions are particularly relevant when session data is not stored in a shared system accessible to every backend node.

Complete Load Balancer Configuration Example

The following configuration uses Apache as a reverse proxy load balancer for two backend applications:

<VirtualHost *:80>
    ServerName example.com

    ProxyRequests Off
    ProxyPreserveHost On

    <Proxy "balancer://mycluster">
        BalancerMember http://127.0.0.1:3001
        BalancerMember http://127.0.0.1:3002

        ProxySet lbmethod=byrequests
    </Proxy>

    ProxyPass / balancer://mycluster/
    ProxyPassReverse / balancer://mycluster/

    ErrorLog ${APACHE_LOG_DIR}/balancer-error.log
    CustomLog ${APACHE_LOG_DIR}/balancer-access.log combined
</VirtualHost>

Apache accepts requests on port 80 and distributes them between the two application servers.

Testing the Load Balancer

After saving the configuration, validate Apache syntax:

sudo apache2ctl configtest

If the configuration is valid, reload Apache:

sudo systemctl reload apache2

Send several requests to the proxy:

curl http://your-server-ip

If the backend applications return distinguishable responses, repeated requests should demonstrate that Apache is distributing traffic between the servers.

Apache can now balance incoming requests across multiple backends with mod_proxy_balancer.

Step 6: Enabling SSL Termination at the Proxy Layer

In many production environments, Apache handles HTTPS at the reverse proxy rather than requiring every backend application server to maintain separate SSL/TLS configuration. This design is commonly described as SSL termination or TLS offloading.

The client establishes an encrypted HTTPS connection with Apache. Apache decrypts the incoming traffic and then forwards requests internally through either HTTP or HTTPS.

Centralizing TLS at the proxy reduces duplicated configuration, simplifies certificate management, and allows HTTPS policies to be enforced consistently.

Enabling the SSL Module

Before creating an HTTPS VirtualHost, enable Apache’s SSL module:

Reload Apache:

sudo systemctl reload apache2

Obtaining an SSL Certificate

HTTPS requires a valid SSL certificate and its associated private key. A self-signed certificate can be used for local development or testing.

Production environments normally use a certificate issued by Let’s Encrypt or another trusted certificate authority.

Ubuntu installations commonly store certificates in directories such as:

Private keys are commonly stored under:

When Let’s Encrypt and Certbot are used, certificate files are typically located below /etc/letsencrypt/live/your-domain/.

Configuring HTTPS Reverse Proxying

Create or edit the HTTPS site configuration:

sudo nano /etc/apache2/sites-available/reverse-proxy-ssl.conf

Add a configuration similar to:

<VirtualHost *:443>
    ServerName example.com

    SSLEngine On
    SSLCertificateFile /etc/ssl/certs/example.com.crt
    SSLCertificateKeyFile /etc/ssl/private/example.com.key

    ProxyRequests Off
    ProxyPreserveHost On
    ProxyAddHeaders On

    ProxyPass / http://127.0.0.1:3000/
    ProxyPassReverse / http://127.0.0.1:3000/

    RequestHeader set X-Forwarded-Proto "https"

    ErrorLog ${APACHE_LOG_DIR}/ssl-proxy-error.log
    CustomLog ${APACHE_LOG_DIR}/ssl-proxy-access.log combined
</VirtualHost>

With this configuration, Apache accepts HTTPS connections on port 443, decrypts them, and passes requests to the application listening on port 3000.

X-Forwarded-Proto informs the backend application that the original client request used HTTPS.

Proxying to HTTPS Backends

Some backend application servers also use HTTPS. Apache must establish a separate encrypted connection when forwarding requests to such servers.

Enable HTTPS backend proxying with:

Requests can then be sent to an HTTPS backend:

ProxyPass / https://127.0.0.1:8443/
ProxyPassReverse / https://127.0.0.1:8443/

Without SSLProxyEngine On, Apache will not establish HTTPS proxy connections to backend servers.

Configuring Backend Certificate Verification

When communicating with HTTPS backends, Apache can verify their certificates to prevent connections to untrusted systems.

Certificate verification is controlled through settings such as:

SSLProxyVerify require
SSLProxyCheckPeerName On
SSLProxyCheckPeerExpire On

These directives tell Apache to:

  • Require a trusted backend certificate.
  • Verify the backend hostname.
  • Check that the certificate has not expired.

In internal testing environments that use self-signed certificates, verification is sometimes disabled temporarily:

SSLProxyVerify none
SSLProxyCheckPeerName Off

Disabling certificate verification reduces connection security and should generally be avoided in production.

Redirecting HTTP Traffic to HTTPS

Production reverse proxies commonly redirect ordinary HTTP traffic to HTTPS.

A separate HTTP VirtualHost can perform the redirect:

<VirtualHost *:80>
    ServerName example.com

    Redirect permanent / https://example.com/
</VirtualHost>

This ensures clients use encrypted HTTPS connections.

Enabling the HTTPS Site

Enable the HTTPS configuration:

sudo a2ensite reverse-proxy-ssl.conf

Check the configuration:

sudo apache2ctl configtest

If the syntax is valid, reload Apache:

sudo systemctl reload apache2

Testing HTTPS Proxying

Test the HTTPS reverse proxy by visiting:

The SSL connection can also be checked with:

curl -I https://your-domain.com

If the configuration is correct, Apache terminates the HTTPS client connection and forwards the request successfully to the backend.

Apache is now handling encrypted client connections at the reverse proxy layer.

Step 7: Security Hardening for the Proxy Configuration

After configuring Apache as a reverse proxy, the proxy layer should be secured carefully. An incorrectly configured reverse proxy can reveal internal systems, permit unintended proxy behavior, or unnecessarily increase the attack surface.

Ensure Forward Proxying Is Disabled

Disabling forward proxy operation is one of the most important security requirements.

Always make sure the following directive is configured:

If forward proxying is unintentionally enabled, outside users may be able to relay arbitrary traffic through the server. Open proxies are commonly abused for spam, malicious routing, and anonymity.

For ordinary reverse proxy installations, ProxyRequests Off should be defined globally or within every proxy-enabled VirtualHost.

Restrict Proxy Access with <Proxy> Blocks

Apache supports access-control rules for proxied resources through <Proxy> and <ProxyMatch> containers.

For example:

<Proxy "*">
    Require all denied
</Proxy>

This blocks access to forward proxy destinations unless they are specifically allowed.

Access to selected backend paths or internal services can also be restricted:

<Proxy "http://127.0.0.1:3000/admin">
    Require ip 192.168.1.0/24
</Proxy>

Such restrictions are especially important when a reverse proxy exposes internal application functionality.

Hide Backend and Server Information

Apache and backend applications can expose unnecessary technology information through headers such as:

Server: Apache/2.4.58
X-Powered-By: Express

These headers can disclose software versions or backend technologies that can be useful during reconnaissance.

Server information can be reduced by configuring:

ServerTokens Prod
ServerSignature Off

Backend-specific headers can also be removed with mod_headers:

Header unset X-Powered-By

ServerTokens Prod
ServerSignature Off

Headers generated directly by a backend may require additional configuration within that application.

Reducing these details limits the amount of infrastructure information exposed publicly.

Configure Timeouts Carefully

Unsuitable timeout values can leave Apache resources occupied by stalled backend connections or contribute to resource-exhaustion problems.

Relevant settings include:

ProxyTimeout 30
Timeout 60

ProxyTimeout controls how long Apache waits for backend responses, while Timeout affects general request processing.

Reasonable values prevent unresponsive backend connections from consuming worker resources indefinitely.

Apply Rate Limiting When Necessary

Internet-facing reverse proxies can benefit from rate limiting to reduce abusive traffic and denial-of-service attempts.

Apache has several traffic-control modules, including:

  • mod_ratelimit
  • mod_evasive
  • mod_qos

For example, mod_ratelimit can restrict response bandwidth for selected locations or content types.

Advanced rate-limiting configuration is a separate topic, but some form of request throttling can be useful for publicly exposed services.

Restrict Access to Administrative Interfaces

Administrative endpoints such as Balancer Manager should not be exposed publicly without restrictions.

For example:

<Location "/balancer-manager">
    SetHandler balancer-manager
    Require local
</Location>

If remote administrative access is needed, limit it through IP-based rules or authentication.

An unrestricted management interface can reveal backend infrastructure details and provide access to balancing controls.

Test for Open Proxy Behavior

After configuring the reverse proxy, verify that Apache is not operating as an unintended forward proxy.

A simple test can be performed with:

curl -x http://your-server-ip:80 http://example.com

If Apache rejects the request, it is not functioning as an open proxy.

If the request unexpectedly succeeds, immediately check that:

  • ProxyRequests Off is configured.
  • No overly permissive <Proxy> rules exist.
  • No unintended forward proxy configuration is active.

Keep Apache and Modules Updated

Because a reverse proxy is normally located at the network edge, keeping Apache and its modules current is important.

Regularly update installed packages with:

sudo apt update
sudo apt upgrade

Security updates can address problems involving:

  • HTTP request parsing
  • TLS weaknesses
  • Request smuggling
  • Denial-of-service vulnerabilities
  • Module-specific security flaws

Applying security updates promptly reduces exposure to publicly documented vulnerabilities.

Validate Configuration Changes

After making security-related modifications, check Apache syntax:

sudo apache2ctl configtest

If the syntax is valid, reload Apache:

sudo systemctl reload apache2

The reverse proxy configuration is now better protected and more suitable for production use.

Troubleshooting Common mod_proxy Errors

Small configuration mistakes can prevent Apache from communicating properly with backend applications. Incorrect backend addresses, unavailable modules, SSL verification problems, and header errors can all lead to proxy failures.

When diagnosing Apache reverse proxy issues, first examine the error log:

/var/log/apache2/error.log

Monitor the file continuously with:

sudo tail -f /var/log/apache2/error.log

Configuration validation is also important before reloading Apache:

sudo apache2ctl configtest

If Apache returns:

the configuration is syntactically valid.

The following sections describe several common mod_proxy problems.

502 Bad Gateway

A 502 Bad Gateway response usually means Apache could not communicate successfully with the configured backend application server.

Common causes include:

  • The backend application is stopped.
  • The backend is listening on a different port.
  • A firewall is blocking the connection.
  • The ProxyPass destination is incorrect.
  • The backend crashes or exceeds a timeout.

For example, if Apache forwards requests to:

ProxyPass / http://127.0.0.1:3000/

but no service is listening on port 3000, Apache returns a 502 response.

Check whether a service is listening:

sudo ss -tulpn | grep 3000

Test the backend directly:

curl http://127.0.0.1:3000

If the backend does not respond locally, the problem is with the application or its configuration rather than the Apache proxy.

The Apache log can contain an entry such as:

AH01114: HTTP: failed to make connection to backend

This normally indicates a connection failure between Apache and the backend service.

503 Service Unavailable

A 503 Service Unavailable error frequently appears in environments using mod_proxy_balancer.

It generally means Apache considers all configured workers unavailable.

Possible causes include:

  • All backend servers are offline.
  • Health checks are failing.
  • BalancerMember definitions are incorrect.
  • Backend requests are timing out.
  • DNS resolution is failing.

For example:

<Proxy "balancer://mycluster">
    BalancerMember http://127.0.0.1:3001
    BalancerMember http://127.0.0.1:3002
</Proxy>

Test each backend directly:

curl http://127.0.0.1:3001
curl http://127.0.0.1:3002

When a backend is unavailable, Apache can temporarily mark it as unusable until it recovers.

The error log can include:

AH01170: balancer://mycluster: All workers are in error state

This indicates that Apache could not find a usable backend server for the request.

SSL Handshake Failures to HTTPS Backends

When Apache proxies requests to HTTPS backends, the TLS negotiation can fail.

Common causes include:

  • Invalid or expired backend certificates
  • Self-signed certificates
  • Hostname mismatches
  • Missing SSLProxyEngine On
  • Certificate verification failures

For example:

SSLProxyEngine On

ProxyPass / https://127.0.0.1:8443/

When certificate verification fails, Apache may log an error such as:

AH02039: Certificate Verification: Error

For temporary internal testing with self-signed certificates, verification is sometimes disabled:

SSLProxyVerify none
SSLProxyCheckPeerName Off

Certificate verification should remain enabled in production whenever possible.

Test the HTTPS backend directly with:

curl -k https://127.0.0.1:8443

Header Forwarding Not Working Correctly

Backend applications can fail to recognize the original client address, hostname, or HTTPS status when forwarding headers are missing or configured incorrectly.

Typical symptoms include:

  • The application records the proxy address instead of the client address.
  • Redirect URLs are incorrect.
  • Secure cookies do not work as expected.
  • The application fails to detect HTTPS.

Verify that the appropriate directives are configured:

ProxyPreserveHost On
ProxyAddHeaders On
RequestHeader set X-Forwarded-Proto expr=%{REQUEST_SCHEME}

Also ensure mod_headers is enabled:

Forwarded values can be inspected from the backend application or through a diagnostic endpoint that displays request headers.

Module Not Found or Unknown Directive Errors

Apache reports directive-related errors when the module that provides a configuration directive has not been enabled.

A common example is:

Invalid command 'ProxyPass'

or:

Invalid command 'RequestHeader'

These messages usually indicate that the corresponding proxy or headers module is disabled.

Enable the necessary modules:

sudo a2enmod proxy
sudo a2enmod proxy_http
sudo a2enmod headers

Reload Apache:

sudo systemctl reload apache2

Loaded modules can be checked with:

Diagnosing Backend Connectivity Problems

If Apache cannot connect to a backend, verify:

  • The backend service is running.
  • The configured IP address and port are correct.
  • No firewall rule blocks the required connection.
  • The backend is listening on the expected network interface.

Useful diagnostic commands include:

ss -tulpn
curl http://127.0.0.1:3000

Testing the backend without the proxy helps determine whether the problem belongs to Apache or to the backend application itself.

Reload Apache After Configuration Changes

After correcting configuration problems, validate and reload Apache:

sudo apache2ctl configtest
sudo systemctl reload apache2

Using reload instead of a full restart applies configuration updates without completely interrupting active connections.

At this stage, Apache has been configured as a reverse proxy through the mod_proxy module family with forwarded headers, load balancing, SSL termination, WebSocket proxy support, and basic security hardening.

Frequently Asked Questions

1. What Is the Difference Between ProxyPass and ProxyPassReverse?

ProxyPass maps incoming frontend request URLs to a backend URL. ProxyPassReverse adjusts response headers such as Location, Content-Location, and URI so redirects generated by the backend refer to the public frontend URL instead of exposing the internal backend address.

2. Do I Need ProxyRequests On to Use Apache as a Reverse Proxy?

No. ProxyRequests On enables forward proxy functionality, allowing clients to route arbitrary external requests through Apache. A reverse proxy should normally use ProxyRequests Off and define explicit backend mappings through ProxyPass. Enabling ProxyRequests On without appropriate restrictions can create an open proxy.

3. Which mod_proxy Submodule Is Required for HTTP and HTTPS Backend Connections?

mod_proxy_http is required for proxying HTTP and HTTPS application traffic. The core mod_proxy module alone is not sufficient. When Apache connects to an HTTPS backend, mod_ssl and SSLProxyEngine On are also required.

4. How Do I Enable mod_proxy on Ubuntu or Debian?

Run sudo a2enmod proxy proxy_http and then restart Apache with sudo systemctl restart apache2. For load balancing, also activate proxy_balancer and a balancing module such as lbmethod_byrequests.

5. How Does Apache mod_proxy Compare with Nginx as a Reverse Proxy?

Apache mod_proxy integrates directly with existing Apache configurations and benefits from Apache’s extensive module system. Nginx uses an event-driven, non-blocking architecture and is often selected for reverse proxy environments requiring very high concurrency. On systems that already use Apache, mod_proxy provides reverse proxy functionality without requiring an additional web server process.

6. Can Apache mod_proxy Handle WebSocket Connections?

Yes. The mod_proxy_wstunnel module supports WebSocket proxying. ProxyPass directives can use the ws:// or wss:// schemes to send WebSocket traffic to backend applications. The required proxy modules must be enabled for this configuration.

7. What Causes a 502 Bad Gateway Error When Using mod_proxy?

A 502 response normally indicates that Apache could not communicate successfully with the backend application or received an invalid backend response. Common causes include a stopped backend process, an incorrect backend port in ProxyPass, firewall restrictions between Apache and the backend, or a timeout. Examine Apache’s error.log and test the backend directly with tools such as curl or nc.

8. How Do I Pass the Original Client IP Address to the Backend?

Enable ProxyAddHeaders On and ProxyPreserveHost On in the relevant VirtualHost. Apache can then add headers such as X-Forwarded-For and X-Forwarded-Host. When TLS is terminated by Apache, also provide X-Forwarded-Proto through RequestHeader so the backend can identify the original HTTPS connection.

Conclusion

This tutorial demonstrated how to configure Apache as a reverse proxy on Ubuntu with the mod_proxy module family. Apache was installed and the required proxy modules were enabled. Request forwarding was configured through ProxyPass and ProxyPassReverse, original client information was preserved with forwarded headers, traffic was distributed among several application servers with mod_proxy_balancer, and SSL termination was configured at the frontend proxy. Security-hardening measures and common approaches for diagnosing mod_proxy errors were also covered.

This foundation can be extended with more advanced configurations, including path-based routing across multiple applications, WebSocket proxying with mod_proxy_wstunnel, and backend health checks through mod_proxy_hcheck. Additional technical details are available in the Apache mod_proxy documentation.

Source: digitalocean.com

Create a Free Account

Register now and get access to our Cloud Services.

Posts you might be interested in: