如何基于X-forward-for标头拒绝对资源的访问


13

我试图基于在X-forwarded-for标头中传递的客户端IP来限制对Nginx背后资源的访问。Nginx在Google Cloud Platform的Kubernetes集群上的容器中运行,并且实际客户端ip仅在x-forward-for标头中传递

到目前为止,我已经使用以下代码为单个IP做到了这一点:

set $allow false;
if ($http_x_forwarded_for ~* 123.233.233.123) {
    set $allow true;
}
if ($http_x_forward_for ~* 10.20.30.40) {
    set $allow false;
}
if ($allow = false) {
    return 403;
}

但是我如何才能对整个IP地址范围进行操作呢?手动指定数百个IP并没有多大意义。

感谢所有帮助

Answers:


11

使用RealIP模块接受X-Forwarded-For标头的值。设置set_real_ip_from为反向代理的IP地址(的当前值$remote_addr)。

例如:

server {
    ...
    real_ip_header X-Forwarded-For;
    set_real_ip_from 10.1.2.3;
    ...
}

现在,您应该能够使用$remote_addrallow/ deny指令使用客户端的真实IP地址。有关更多信息,请参见此文档


所以我尝试了以下方法都没有用,我感到困惑吗? location / { real_ip_header X-Forwarded-For; set_real_ip_from 10.0.0.0/8; real_ip_recursive on; allow xxx.xxx.xxx.xxx;
p1hr

查看Google负载平衡文档后,我发现了以下内容:X-Forwarded-For: <unverified IP(s)>, <immediate client IP>, <global forwarding rule external IP>, <proxies running in GCP> (requests only) <即时客户端IP>条目是直接连接到负载平衡器的客户端。
p1hr

1
为此,您需要标识和的地址范围<global forwarding rule external IP><proxies running in GCP>并添加set_real_ip_from涵盖所有地址范围的语句。
理查德·史密斯

<global forwarding rule external IP>是我的服务的外部ip,在GCP中没有其他代理,在我的nginx日志上,我看到以下格式的请求,[31/Jul/2017:20:05:46 +0000] "GET / HTTP/1.1" 403 169 "-" "curl/7.54.0" "aaa.aaa.aaa.aaa, bbb.bbb.bbb.bbb, ccc.ccc.ccc.ccc"其中ccc.ccc.ccc.ccc是全局转发规则,bbb.bbb.bbb.bbb是直接客户端ip-匹配我在whatsmyip.org中看到的内容。您有机会建议如何提取该部分吗?
p1hr

1
好吧,现在我很困惑。您需要在set_real_ip_from要允许/拒绝的地址右边添加所有地址。如本real_ip_recursive节所述。
理查德·史密斯

5

理查德的答案已经包含有关如何最好地将实际IP地址获取给nginx的信息。

同时,关于指定IP范围的问题,您可以使用http://nginx.org/en/docs/http/ngx_http_geo_module.html

geo模块的工作原理与map模块相同,即,变量将根据IP地址的值获得分配的值。

一个例子:

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;
    }
}

在这里,我们分配geo映射,其默认值$allow是0。如果IP地址在subnet中192.168.168.0/24$allow则将获得值1,并且允许请求​​。

您可以在geo块中包含任意行,以定义IP范围。


谢谢!看起来真的很好,我要面对的最后一件事是X-forwarded-for的client_ip。目前,从传递的3个IP地址开始,使用最后一个。我在real_ip_recursive on;下方添加了内容,set_real_ip_from但没有任何区别
p1hr

您是说X-Forwarded-For标头具有三个单独的地址,也就是说,请求是通过多个代理发出的?您还可以使用其他仅包含客户端IP的标头吗?
Tero Kilkanen '17

链中的每个代理都将其IP地址附加到X-Forwarded-For标头。除了添加之外,real_ip_recursive on还需要为set_real_ip_from代理链中的每个受信任服务器IP地址添加指令。然后,Nginx将通过这些指令中的每一个进行操作,并返回客户端IP作为其在X-Forwarded-For标头中命中的第一个值,该标头与您指定的任何set_real_ip_from值都不匹配
miknik,

FWIW,这种组合不适用于AWS ALB。什么做的工作是使用地理块内的代理指令,用相同的IP set_real_ip - nginx.org/en/docs/http/ngx_http_geo_module.html
talonx

3

这些为我工作。

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

参考:http : //nginx.org/en/docs/http/ngx_http_geo_module.html

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.