I'm trying to set up Apache as a reverse proxy. Here is the essential part of its configuration:


  ServerName proxy.lan:9443

  SSLEngine on

  TraceEnable off

  SSLProxyEngine on
  ProxyPreserveHost On
  ProxyRequests Off
  ProxyVia full
  ProxyPass / http://localhost/
  ProxyPassReverse / http://localhost/

Note, that the proxy is listening on a non standard port 9443. When I use a dummy page showing phpinfo as a backend everything works as expected. However the site I need to put behind the proxy is either too strictly or too poorly written, so the behaivior changes like this:

client -> https://proxy.lan:443 -> http://localhost = success
client -> https://proxy.lan:<ANY_OTHER_PORT> -> http://localhost = wrong redirect

The client gets redirected from https://proxy.lan:9443/ to https://proxy.lan/auth/login and obviously proxy can't serve the request cause it doesn't listen on port 443:

# wget --no-check-certificate -vS https://proxy.lan:9443
--2019-05-12 02:51:37--  https://proxy.lan:9443/
Resolving proxy.lan (proxy.lan)...
Connecting to proxy.lan (proxy.lan)||:9443... connected.
WARNING: cannot verify proxy.lan's certificate, issued by '...':
  Self-signed certificate encountered.
    WARNING: certificate common name 'backend.lan' doesn't match requested host name 'proxy.lan'.
HTTP request sent, awaiting response... 
  HTTP/1.1 302 Found
  Date: Sat, 11 May 2019 23:51:37 GMT
  Server: Apache
  Expires: Thu, 19 Nov 1981 08:52:00 GMT
  Cache-Control: no-cache, no-store, must-revalidate
  Pragma: no-cache
  Location: https://proxy.lan/auth/login
  X-Frame-Options: DENY
  X-XSS-Protection: 1; mode=block
  X-Content-Type-Options: nosniff
  Strict-Transport-Security: max-age=31536000; includeSubDomains; preload
  Content-Security-Policy: default-src *; style-src 'self' 'unsafe-inline'; script-src 'self' 'unsafe-inline' 'unsafe-eval'
  X-Permitted-Cross-Domain-Policies: none
  Content-Length: 0
  Content-Type: text/html; charset=UTF-8
  Set-Cookie: PHPSESSID=...; path=/; secure; HttpOnly
  Via: 1.1 proxy.lan:9443 (Apache/2.2.31)
  Connection: close
Location: https://proxy.lan/auth/login [following]
--2019-05-12 02:51:37--  https://proxy.lan/auth/login
Connecting to proxy.lan (proxy.lan)||:443... failed: Connection refused.
Resolving proxy.lan (proxy.lan)...
Connecting to proxy.lan (proxy.lan)||:443... failed: Connection refused.

I can manually add the port to the resulting URL and https://proxy.lan:9443/auth/login works except for all links on the page pointing to https://proxy.lan/...

Apache environment looks like this:

HTTP_HOST   proxy.lan:9443
HTTP_VIA    1.1 proxy.lan:9443 (Apache/2.2.31)
HTTP_X_FORWARDED_HOST   proxy.lan:9443
SERVER_SIGNATURE    <address>Apache Server at proxy.lan Port 9443</address>
SERVER_NAME     proxy.lan
SERVER_PORT     9443

Any ideas what can be done on the proxy side? Some rewrite rules maybe?


The ProxyPreserveHost on is causing this. If you are not sure-sure that you need it, always leave it at default off and you are good.

For the rare cases when you do need ProxyPreserveHost on, adjust your ProxyPassReverse wisely - this is the only directive that handles the redirects.

ProxyPassReverse / http://localhost/ looks wrong in your scenario, because your backend (the 80 app) doesn't seem to say "I redirect you to http://localhost/foo/bar" anywhere. If you put ProxyPassReverse / https://proxy.lan/ there is a chance it will work better - check the official docs.

  • Thanks a lot @kubanczyk. Your version of ProxyPassReverse helped me to set the port right, although I can't say I understand clearly why it works. As for ProxyPreserveHost directive, it still set to on. In case it's off I get redirect to localhost/auth/login. I also installed mod_proxy_html to remap paths in resulting page ProxyHTMLEnable On; ProxyHTMLURLMap https://proxy.lan/ https://proxy.lan:9443/ and that concludes my setup. – Fmy Oen May 13 at 13:54
  • I think if you use curl -v http://localhost and pay attention to the Host: header and the Location: header, you'll understand what the ProxyPassReverse does. It's a simple textual replacement. @FmyOen – kubanczyk May 13 at 19:54
  • Can you also explain the idea behind ProxyPreserveHost Off? Currently it looks for me like a total no-go, at least without applying some rewrite rules. – Fmy Oen May 14 at 8:53
  • The idea is to behave as a normal http client, i.e. use header Host: localhost when talking to url http://localhost/ – kubanczyk May 14 at 12:16

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.