From 5a3a51e1be9ffcfa26b90c9b6b5a07243270c384 Mon Sep 17 00:00:00 2001
From: Julian Rother <julian@cccv.de>
Date: Thu, 17 Nov 2022 19:57:28 +0100
Subject: [PATCH] Add force_forwarded_ssl_header vhost/location option

This is a workaround for running an application behind two layers of reverse
proxies with the outer one terminating ssl. In this case the inner proxy
receives requests with plain http and sets X-Forwarded-Proto, X-Forwarded-Ssl
and X-Url-Scheme to "http", although the original requests used https. This
breaks some applications.

Ideally we would use a mechanism similar to real_ip_from and just forward the
proto/ssl/scheme headers if the request came from a trusted proxy, but this
workaround is much simpler.
---
 defaults/main.yml       | 1 +
 templates/vhost.conf.j2 | 6 ++++++
 2 files changed, 7 insertions(+)

diff --git a/defaults/main.yml b/defaults/main.yml
index e9ce644..6234341 100644
--- a/defaults/main.yml
+++ b/defaults/main.yml
@@ -46,6 +46,7 @@ nginx_vhosts_defaults:
   hide_proxy_headers: {}
   backend: ~
   disallow_dotfiles: True
+  force_forwarded_ssl_header: False
 
 nginx_streams_defaults:
   listen:
diff --git a/templates/vhost.conf.j2 b/templates/vhost.conf.j2
index 255d316..9b968a8 100644
--- a/templates/vhost.conf.j2
+++ b/templates/vhost.conf.j2
@@ -53,9 +53,15 @@ server {
 		proxy_set_header Host			{{ location.host|d(vhost.host) }};
 		proxy_set_header X-Real-IP		$remote_addr;
 		proxy_set_header X-Forwarded-For	$proxy_add_x_forwarded_for;
+		{% if not location.force_forwarded_ssl_header|d(vhost.force_forwarded_ssl_header) %}
 		proxy_set_header X-Forwarded-Proto	$scheme;
 		proxy_set_header X-Forwarded-Ssl	$https;
 		proxy_set_header X-Url-Scheme		$scheme;
+		{% else %}
+		proxy_set_header X-Forwarded-Proto	https;
+		proxy_set_header X-Forwarded-Ssl	on;
+		proxy_set_header X-Url-Scheme		https;
+		{% endif %}
 
 		# add custom proxy headers
 		{% for header in vhost.add_proxy_headers if header %}
-- 
GitLab