Hi all,
I'm successfully using the realip module to validate proxies and set $remote_addr to the external IP for a request, but I'm trying to do the same for HTTP vs HTTPS where the proxy (Amazon ELB, CDN, etc) is terminating SSL and adding an X-Forwarded-Proto header ("https" or "http"). Note that not all requests are proxied through to nginx, some are coming direct.
Initial idea:
# Set $reqScheme to the original client scheme
# Amazon ELB sets X-Forwarded-Proto
map $http_x_forwarded_proto $reqScheme {
default $scheme;
https https;
}
# Amazon ELBs will be in the VPC public subnets
set_real_ip_from 10.99.0.0/16;
Which works, except that an end-user can forge the "X-Forwarded-Proto" header for requests that hit nginx directly.
Attempt two was using:
# Set $reqScheme to the original client scheme
# Amazon ELB sets X-Forwarded-Proto
map "$remote_addr:$http_x_forwarded_proto" $reqScheme {
default $scheme;
~"10\.99\..*:https" https; # ELB subnets only
}
# Amazon ELBs will be in the VPC public subnets
set_real_ip_from 10.99.0.0/16;
But of course, $remote_addr is changed from the proxy address by realip really early in processing the request, so it's set to the actual client IP by the time the map is evaluated. From a look at the realip module code, it doesn't appear to save the original remote address to another variable which I could use in place of $remote_addr in the above, and there doesn't appear to be another way to find if realip-proxying happened.
Does anyone have any other ideas for making this work?
If not, would any of the following be a suitable approach to resolve this?
1. setting a $remote_addr_original=<ip> variable in the realip module, set to the original $remote_addr if realip changes it
2. setting a $remote_addr_proxied=<true/false> variable in the realip module, set to true if realip changes $remote_addr
3. adding "set_real_scheme_from" and "real_scheme_header" directives to the realip module that manipulate the $scheme & $https variables in a similar way to $remote_addr.
Seems unnecessary to create an entirely new module for this purpose, though that's an option too.
Thanks,
Rob :)