How to deny access to resources based on X-forwarded-for headers
Solution 1:
Use the RealIP module to honour the value of the X-Forwarded-For
header. Set set_real_ip_from
to the IP address of the reverse proxy (the current value of $remote_addr
).
For example:
server {
...
real_ip_header X-Forwarded-For;
set_real_ip_from 10.1.2.3;
...
}
You should now be able to use $remote_addr
and allow
/deny
directives using the true IP address of the client. See this document for more.
Solution 2:
Richard's answer already contained the information on how to best get the real IP address to nginx.
Meanwhile, what comes to the question of specifying IP ranges, you can use http://nginx.org/en/docs/http/ngx_http_geo_module.html.
The geo
module works like the map
module, that is, a variable gets assigned values depending on the value of IP address.
An example:
geo $allow {
default 0;
192.168.168.0/24 1;
}
server {
real_ip_header X-Forwarded-For;
set_real_ip_from 10.1.2.3;
if ($allow = 0) {
return 403;
}
}
Here we assign the geo
map, where the default value for $allow
is 0. If the IP address is in subnet 192.168.168.0/24
, then $allow
will get value 1, and the request is allowed.
You can have as many lines in the geo
block as you need to define your IP ranges.
Solution 3:
Got these working for me.
geo $remote_addr $giveaccess {
proxy 172.0.0.0/8; <-- Private IP range here
default 0;
11.22.33.44 1; <-- Allowed IP here
}
server{
##
location ^~ /secure_url_here {
if ($giveaccess = 0){
return 403;
}
try_files $uri $uri/ /index.php?$args; <-- Add this line specific for your CMS, if required.
}
Ref: http://nginx.org/en/docs/http/ngx_http_geo_module.html