realip - protocol support

rcoup nginx-forum at nginx.us
Wed Nov 5 02:05:26 UTC 2014


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 :)

Posted at Nginx Forum: http://forum.nginx.org/read.php?2,254578,254578#msg-254578



More information about the nginx mailing list