使用proxy_protocol时,在nginx中阻止CIDR范围的更好方法是什么?

时间:2018-05-14 20:38:08

标签: nginx proxy-protocol real-ip

我有一小部分nginx实例,它们位于AWS的ELB后面。这个ELB面向互联网并且说PROXY协议,而不是HTTP。

以下是我main.vhost

的相关部分
server {

    # speak only PROXY protocol
    # Accept 80/443; we'll do the http -> https re-dir elsewhere in conf
    # SSL is default mode
    listen 443 default_server ssl proxy_protocol;
    listen 80 proxy_protocol;

我正在尝试使用deny中的ngx_http_access_module指令来阻止访问一系列CIDR块。

例如为: 在启动时由nginx加载的.conf文件中:

include /etc/nginx/ip_block/*.conf;

并且/etc/nginx/ip_block/目录中至少有一个文件:

$ cat /etc/nginx/ip_block/some_cidr_ranges.conf | wc -l
361
$ head /etc/nginx/ip_block/some_cidr_ranges.conf
deny 2604:a880:1::/48;
<snip>
deny 208.68.36.0/22;

但是,似乎nginx的deny指令仅适用于$remote_addr变量,并且不适用于$proxy_protocol_addr变量。这实际上意味着我不能同时使用deny指令和proxy_protocol

似乎可以使用ngx_stream_realip_module模块将$remote_addr的值调整为$proxy_protocol_addr值,但是我当前没有配置我可用的nginx版本使用--with-stream_realip_module build-flag。我目前正在运行1.10.3,但看起来with-stream_realip_module标志是在构建1.11.4https://github.com/nginx/nginx/commit/fe2774a9d689fa1bf201dd0e89449e3d9e4ad926)中引入的

选项1:使用我需要编译的功能从源代码构建nginx版本。

在查看deny指令的文档时,我发现了这个注释:

In case of a lot of rules, the use of the ngx_http_geo_module module variables is preferable.

来自:https://nginx.org/en/docs/http/ngx_http_access_module.html

这让我想知道是否有更好的方法来实现我的目标,即阻止可能与我目前拥有的nginx二进制文件有关的CIDR范围。

我可以尝试这样的事情:

geo $proxy_protocol_addr $blocked_cidr {
    default        01;
    include        conf/some_cidr_ranges_to_block.conf;
}

文件conf/some_cidr_ranges_to_block.conf的样子:

2604:a880:1::/48    02;
<snip>
208.68.36.0/22      02;

然后在我的服务器指令中,我可以做类似的事情:

if ($blocked_cidr != 01) {
 return 403;
}

选项2:尝试使用geo指令和自定义IP范围 - &gt; “国家代码”数据库阻止流量。

我的问题:

- Is *option 1* going to be a better use of time / is it worth it to build my own version of nginx with the necessary `stream_realip_module` compiled in or is it going to be more performant / effective to use the `geo` directive to map the `$proxy_protocol_addr` onto a set of ranges as shown above (*option 2*) 


- Is there some other way to block or filter traffic in nginx by cidr block when using nginx in `proxy_protocol` mode that i have not yet considered?

2 个答案:

答案 0 :(得分:0)

快速更新/回答我的问题。

感谢Tan Hong Tat的建议,我没有必要编译自己的nginx版本。这会将选项1 从表中删除并为我节省一些工作。谢谢!

我已经在nginx中加载了几百个deny规则,我正在关注性能影响。

此外,我使用geo指令从我的OP实现了类似 option 2 的东西。我同样监测影响。

到目前为止,我不清楚为什么nginx文档会发出关于使用deny和#34;批次&#34;规则:

In case of a lot of rules, the use of the ngx_http_geo_module module variables is preferable.

geo指令确实允许我更灵活一点,因为我可以选择在哪里发送用户。 deny指令是403,无法更改。

答案 1 :(得分:0)

您可以使用-

if ($proxy_protocol_addr != a.b.c.d) { return 403;
}