> ## Content Index
> Fetch the complete content index at: https://www.ctrl.blog/llms.txt
> Use this file to discover other available public pages before exploring further.

# How to use same Host header for origin and proxy in Apache mod_proxy
- URL: https://www.ctrl.blog/entry/how-to-httpd-reverseproxy-hostheader/
- Published: 2017-04-13T01:43:00.000Z
- Updated: 2026-08-23T22:10:08.000Z
- Description: How to forward your front-end HTTP proxy server’s hostname (the HTTP Host request header) to your origin server using the Apache mod_proxy module.
- Author: Daniel Aleksandersen
- Tags: Apache HTTPD, HTTP Caching, Hypertext

An origin server should use the same hostname as any \[caching\] reverse-proxy gateways that are made available to the public web. Otherwise, you can end up leaking the hostname or IP address of the origin server, and get unexpected results in error pages and interpreted output.

The solution discussed in this article is specifically for the Apache Web Server’s `mod_proxy` module, but the concepts apply to other reverse proxy servers such as Nginx and Traffic Server as well.

The configuration discussed in this article can be applied on a `Server` or `VirtualHost` blocks in your Apache configuration file.

### A tale of two hosts responding to different names

Let us assume you’ve got a reverse proxy setup in front of your backend origin server. Both are running Apache, and the reverse proxy gateway responds to the hostnames `example.com` and `www.example.com`, and the backend origin server responds to `wphost1.example.com`. A simple configuration for this could look like:

Proxy:

```apacheconf
ServerName "www.example.com"
ServerAlias "example.com"
ProxyPass "/" "https://wphost1.example.com/"
```

Origin:

```
ServerName "wphost1.example.com"
```

In this setup, requests to the server at `www.example.com` would be transparently relayed to the server at `wphost1.example.com`. This simple setup is the starting point for a caching proxy that can work as a load balancing and geographical distribution of server load — see [mod\_proxy documentation for details](https://httpd.apache.org/docs/current/mod/mod%5Fproxy.html?ref=ctrl.blog).

Incoming requests to the proxy will arrive with the HTTP `Host` header set to either `Host: example.com` or `Host: www.example.com`. The relayed requests sent from the proxy to the origin server will be rewritten as `Host: wphost1.example.com`, and also gets a second header called `X-Forwarded-Host: www.example.com`.

The origin server is thus not aware that the preferred hostname is `www.example.com`, and the request will be processed as it was sent to `wphost1.example.com` instead. Error pages and interpreters (like PHP) will be configured to use the processed hostname and be unaware of the `X-Forwarded-Host` header.

### Same name, an alias, and name canonicalization

Let us next look at a bit more complex setup where both the proxy and origin will treat requests as they were sent to `www.example.com`:

Proxy:

```apacheconf
ServerName "www.example.com"
ServerAlias "example.com"
UseCanonicalName on
ProxyPreserveHost on
ProxyPass "/" "https://wphost1.example.com/"
```

Origin:

```
ServerName "www.example.com"
ServerAlias "wphost1.example.com"
UseCanonicalName on
```

The configuration options are named kind of self-explanatory, but I’ll go through each of them, in turn, to explain how they work together.

The reverse proxy server is made aware that the `ServerName` is the canonical name of the server and all requests, even to the server’s IP, is to be treated as if they were made to the canonical name. This behavior is managed by the `UseCanonicalName` option.

Next, the `ProxyPreserveHost` option tells Apache to not use the proxy server’s hostname in requests to the proxy, but rather to make a connection to that host and then relay the original hostname in the HTTP Host header. The `UseCanonicalName` option rewrites the incoming Host header to its canonical version before relaying, meaning that the `example.com` alias, is treated as `www.example.com` as well.

The origin server is altered similarly, setting the actual hostname as an alias and the canonical name to the public-facing hostname. The `UseCanonicalName` option is used to ensure error pages and interpreters will always use the preferred hostname.

### Alternatively, fix it on the origin

You can always fix this on the origin by rewriting all incoming requests so that they appear to have the correct `Host` header.

Origin:

```apacheconf
RequestHeader set "Host" "www.example.com"
```

This approach can cause issues for the rewrite module, caching module, GnuTLS module, as well as other modules that work with the actual hostname submitted to the server. This requires a lot of testing to verify that it doesn’t cause any problems.

### Leaking information about the origin server

A recent [blog post by Chris Knight](https://web.archive.org/web/20190504164946/https://chris-knight.net/blog/2017/02/effectively-hiding-behind-cloudflare) reminded me of the importance of hiding the hostname and IP of the origin server. He wrote about it in the context of Cloudflare, which is a commercial caching reverse-proxy service provider, but the principle also applies to non-Cloudflare proxies.

For example, if this website came under attack, I could turn off the forward-facing reverse proxies that handle incoming requests and change my DNS to hide behind a commercial proxy service.

It’s important to keep any potential attack directed at the proxy servers so that the origin server can remain relatively isolated. Chris Knight goes through other measures you can take to hide your origin server in his blog post.

Apache’s `mod_cache` will by default expose the origin server’s IP or hostname on any error page. It’s thus important to not serve any error pages from the origin server with its actual hostname exposed.

Hostname canonicalization, as discussed above, can hide the hostname on any 4xx client errors. However, 5xx server errors can possibly leak the IP address as these kinds of errors can appear when Apache isn’t correctly configured and your options thus isn’t in effect.

You can mitigate this somewhat if you use `mod_cache` with `mod_proxy` on your reverse proxies. By enabling the `CacheStaleOnError on` option, Apache will serve cached variants of requests if the origin server responds with a 5xx error code.

#### Sources

- [Effectively Hiding Behind Cloudflare](https://web.archive.org/web/20190504164946/https://chris-knight.net/blog/2017/02/effectively-hiding-behind-cloudflare), 2017-02-20, Chris Knight
- [Apache Core Features](https://httpd.apache.org/docs/2.4/mod/core.html?ref=ctrl.blog), Apache 2.4 documentation
- [Apache Module mod\_proxy](https://httpd.apache.org/docs/2.4/mod/mod%5Fproxy.html?ref=ctrl.blog), Apache 2.4 documentation
- [Apache Module mod\_cache](https://httpd.apache.org/docs/2.4/mod/mod%5Fcache.html?ref=ctrl.blog), Apache 2.4 documentation