From: Rich Bowen Date: Thu, 14 May 2026 19:35:53 +0000 (+0000) Subject: rewrite guide: document %{HTTPS} behavior behind load balancers X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=58e3b90f85c57e211370c5adc106f69005ea29a2;p=thirdparty%2Fapache%2Fhttpd.git rewrite guide: document %{HTTPS} behavior behind load balancers Add note to the "Forcing HTTPS" recipe in remapping.xml explaining that %{HTTPS} queries mod_ssl directly and reports "off" when SSL is terminated upstream. Provides the X-Forwarded-Proto alternative with a security warning about trusting forwarded headers. git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1934200 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/docs/manual/rewrite/TODO.md b/docs/manual/rewrite/TODO.md index a50108c4ea..705b876746 100644 --- a/docs/manual/rewrite/TODO.md +++ b/docs/manual/rewrite/TODO.md @@ -61,7 +61,7 @@ address. Sorted by priority. in the same context confuses users every year. Belongs in avoid.xml or tech.xml. -- [ ] **%{HTTPS} behind a load balancer / SSL terminator** — %{HTTPS} +- [x] **%{HTTPS} behind a load balancer / SSL terminator** — %{HTTPS} queries mod_ssl directly; it is not an environment variable. Behind a reverse proxy, check %{HTTP:X-Forwarded-Proto} instead. Add to the HTTPS redirect recipe in remapping.xml. diff --git a/docs/manual/rewrite/remapping.xml b/docs/manual/rewrite/remapping.xml index ba32436f4f..9bd698cb22 100644 --- a/docs/manual/rewrite/remapping.xml +++ b/docs/manual/rewrite/remapping.xml @@ -131,6 +131,36 @@ RewriteRule "^(.*)" "https://%{SERVER_NAME}$1" [R=301,L]

See also the When not to use mod_rewrite document for more discussion of the Redirect approach.

+ + Behind a load balancer or SSL terminator +

The %{HTTPS} variable is not a general-purpose + environment variable — it queries mod_ssl + directly. If SSL/TLS is terminated at an upstream load balancer + or reverse proxy, mod_ssl is not handling the + connection and %{HTTPS} will always report + off, even when the original client connected over + HTTPS.

+ +

In this situation, check the header set by the upstream proxy + instead. Most load balancers set + X-Forwarded-Proto:

+
+ + +RewriteEngine On +RewriteCond "%{HTTP:X-Forwarded-Proto}" =http [NC] +RewriteRule "^(.*)" "https://%{SERVER_NAME}$1" [R=301,L] + + + +

Only trust X-Forwarded-Proto if you control the + upstream proxy and it overwrites the header on every request. An + attacker can forge this header when connecting directly to your + server. Consider restricting access so that only your load + balancer can reach the backend, or use + mod_remoteip to validate the source.

+
+