Nginx Map how to check value if empty

c0nw0nk nginx-forum at forum.nginx.org
Mon Mar 6 19:12:40 UTC 2017


So I figured out the problem is a bit of a dynamic one.

My Nginx accepts some connections via cloudflare's proxy and other's via
their DNS only and other connections go through a load balancing ip that
sets a x-forwarded-for header containing the real IP, While others can avoid
all of that and connect to a specific origin servers IP (remote_addr is the
real IP for these connections).

So to explain how to get the origin IP for each method someone could be
using here is the list :

Cloudflares proxied traffic :
sets the header $http_cf_connecting_ip so use this header to get the
Client's real IP

Traffic from cloudflare via the DNS only connections :
These would not have the $http_cf_connecting_ip header present.
But those connections hit a load balancing ip what sets the header
$http_x_forwarded_for header so that is the way to get the Clients real ip
via those connections.

And then some connections don't hit my load balancing IP and go directly to
a specific origin server these connections can use $remote_addr.



My Solution / conclusion :

How to come up with a fix that allows me to obtain the real IP in a dynamic
situation like this ?

I have solved my issue with the following.

map $http_x_forwarded_for $client_ip_x_forwarded_for {
"" $remote_addr; #if this header missing set remote_addr as real ip
default $http_x_forwarded_for;
}
map $http_cf_connecting_ip $client_ip_from_cf {
"" $client_ip_x_forwarded_for; #if this header missing set x-forwarded-for
as real ip
default $http_cf_connecting_ip;
}

So if the cf_connecting_ip header from cloudflares proxied traffic is
missing we fall back to the x_forwarded_for header to get the clients real
ip.

And if that x_forwarded_for header was also missing then we fall back to
setting their IP as $remote_addr.


Thank's for explaining my log output to me helped me realise what the root
of the issue was :) and thanks to Francis for telling me that my map just
needed "" as a if empty check.





B.R. via nginx Wrote:
-------------------------------------------------------
> Again, it is not empty, nor containing an hyphen...
> Look slowly to the log line and compare it to the log format. You use
> hyphens as separators, which, again, might not be a good idea at this
> precise location.
> 
> ​The IP address you get is a private one though, so not 'client' but
> rather
> 'downstream'.​
> ​It seems you are hiding behind CloudFlare, you should read their doc
> to
> see how to get the real client IP address. The HTTP header you tried
> to use
> seems to be empty (ie 'dash'.
> 
> As for using hyphens rather than real emptiness, I guess that helps
> validating there is no real value, ​differentating this case from a
> bogus
> 'empty' which would be a sign of a bug.
> ---
> *B. R.*
> 
> On Sun, Mar 5, 2017 at 10:50 PM, c0nw0nk <nginx-forum at forum.nginx.org>
> wrote:
> 
> > Thank's for the info :)
> >
> > But why is $remote_addr outputting a hyphen instead of the users
> IP...
> >
> > I still expect to see the client's IP address.
> >
> > B.R. via nginx Wrote:
> > -------------------------------------------------------
> > > That is because it is not: your eyes deceived you having a too
> quick
> > > look
> > > at the log line.
> > >
> > > Your 'empty' variables are actually showing the value '-' in this
> log
> > > line.
> > > It probably does not help debugging to have static '-' mixed in
> the
> > > format
> > > of your log lines where you put them.
> > > ---
> > > *B. R.*
> > >
> > > On Sun, Mar 5, 2017 at 10:00 PM, c0nw0nk
> <nginx-forum at forum.nginx.org>
> > > wrote:
> > >
> > > > Francis Daly Wrote:
> > > > -------------------------------------------------------
> > > > > On Fri, Mar 03, 2017 at 10:47:26AM -0500, c0nw0nk wrote:
> > > > >
> > > > > Hi there,
> > > > >
> > > > > > map $http_cf_connecting_ip $client_ip_from_cf {
> > > > > > default $http_cf_connecting_ip;
> > > > > > }
> > > > > >
> > > > > > How can I make it so if the client did not send that $http_
> > > header
> > > > > it makes
> > > > > > $client_ip_from_cf variable value = $binary_remote_addr
> > > > > >
> > > > > > Not sure how to check in a map if that http header is
> present.
> > > > >
> > > > > If the http header is absent, the matching variable is empty.
> So
> > > it
> > > > > will
> > > > > have the value "".
> > > > >
> > > > > Use that as the first half of your "map" pair.
> > > > >
> > > > >       f
> > > > > --
> > > > > Francis Daly        francis at daoine.org
> > > > > _______________________________________________
> > > > > nginx mailing list
> > > > > nginx at nginx.org
> > > > > http://mailman.nginx.org/mailman/listinfo/nginx
> > > >
> > > >
> > > > Hey Francis,
> > > >
> > > >
> > > > HTTP BLOCK
> > > > log_format cf_custom 'CFIP:$http_cf_connecting_ip - $remote_addr
> -
> > > > $remote_user [$time_local]  '
> > > > '"$request" Status:$status $body_bytes_sent '
> > > > '"$http_referer" "$http_user_agent"'
> > > > '$http_cf_ray';
> > > > map $status $loggable {
> > > > ~^[23]  0;
> > > > default 1;
> > > > }
> > > > access_log logs/access.log cf_custom if=$loggable;
> > > >
> > > > map $remote_addr $client_ip_from_cf {
> > > > default $remote_addr;
> > > > }
> > > >
> > > >
> > > > Access.log output
> > > > CFIP:- - 10.108.22.40 - - [05/Mar/2017:21:27:50 +0100]  "GET
> > > >
> > > >
> > > > Any idea why the remote_addr is empty surely it should display
> to me
> > > the
> > > > clients IP address i am not proxying traffic or anything like
> that.
> > > I
> > > > expected to see an IP there instead it seems the value is empty.
> > > >
> > > > Posted at Nginx Forum: https://forum.nginx.org/read.p
> > > > hp?2,272744,272766#msg-272766
> > > >
> > > > _______________________________________________
> > > > nginx mailing list
> > > > nginx at nginx.org
> > > > http://mailman.nginx.org/mailman/listinfo/nginx
> > > >
> > > _______________________________________________
> > > nginx mailing list
> > > nginx at nginx.org
> > > http://mailman.nginx.org/mailman/listinfo/nginx
> >
> > Posted at Nginx Forum: https://forum.nginx.org/read.
> > php?2,272744,272768#msg-272768
> >
> > _______________________________________________
> > nginx mailing list
> > nginx at nginx.org
> > http://mailman.nginx.org/mailman/listinfo/nginx
> >
> _______________________________________________
> nginx mailing list
> nginx at nginx.org
> http://mailman.nginx.org/mailman/listinfo/nginx

Posted at Nginx Forum: https://forum.nginx.org/read.php?2,272744,272779#msg-272779



More information about the nginx mailing list