Realip - protocol support

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= 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 :slight_smile:

Posted at Nginx Forum:

Ugh,

  1. 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.

Of course, “set_real_scheme_from” is unnecessary, since it’ll be the
same
list of proxies as “set_real_ip_from”.

Revise as:

  1. adding a “real_scheme_header” directive to the realip module that
    manipulate the $scheme & $https variables in a similar way to
    $remote_addr.

Posted at Nginx Forum: