I'm building an application with some rather arcane TLS and caching requirements, and I'm using a stack that looks like:
HTTPS HTTP
Nginx (443) Varnish (80)
| |
Varnish (80) Nginx (8080)
\ /
AWS ALB (80)
|
ECS Pool (Docker) - Apache/80
(I have Nginx listening on 8080 in between Varnish and the ALB because Varnish doesn't handle DNS lookups with multiple/changing IP addresses as easily as Nginx).
The problem is the HTTPS request path: basically, Nginx sets X-Forwarded-Proto: https
, and then I have my Varnish VCL configured to securely pass this through to the ALB. But the ALB seems to strip the header and replace it with its own (which becomes X-Forwarded-Proto: http
), and then the backend application on the ECS servers sees http and writes all it's links/resource paths as http, causing an insecure mixed content warning in Safari, Chrome, etc.
So the only way I've been able to get this setup working is to bypass Varnish, install a backend-only TLS cert on the ALB, and set up request routing like:
HTTPS HTTP
Nginx (443) Varnish (80)
| |
AWS ALB (443) AWS ALB (80)
\ /
\ /
ECS Pool (Docker) - Apache/80
I'm mostly okay with this... but it's a shame I'm not able to use Varnish to cache static resources for HTTPS requests. The only way around that, I imagine, would be to replace the ALB entirely with Varnish and a custom vmod or some other tooling (Lambda, etc.) to account for the ever-changing ECS Docker container instance pool...
Is there any way to command AWS ALBs/ELBs to pass through a header, or any kind of control over the headers? I couldn't find anything in the docs or Console, and most other people seem to be terminating HTTPS on the ALB. If I had just one cert, or a few, or could use SNI, I would definitely do that... but I have hundreds of certs for hundreds of domains, and can't :(