我有一个小型的nginx实例池,它们位于AWS中的ELB后面。这个ELB是面向互联网的,使用代理协议,而不是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;
我正在尝试使用ngx_http_access_module
的deny
指令来阻止访问一系列 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
构建标志。 我目前正在运行1.10.3
但看起来with-stream_realip_module
标志是在构建1.11.4
中引入的 (https://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 范围 ->"国家/地区代码"数据库来阻止流量。
我的问题:
- 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?
快速更新/回答我的问题。
感谢Tan Hong Tat的建议,我没有必要编译自己的nginx版本。 这消除了选项 1的桌面,并为我节省了一些工作。谢谢!
我已经将几百条deny
规则加载到nginx中,并且我正在关注性能影响。
此外,我还使用geo
指令实现了类似于 OP 中的选项 2的东西。 我同样在监测影响。
到目前为止,我不清楚为什么nginx文档会发出有关使用带有"大量"规则deny
的建议:
In case of a lot of rules, the use of the ngx_http_geo_module module variables is preferable.
geo
指令确实允许我更灵活,因为我可以选择将用户发送到何处。deny
指令是 403,无法更改。
你可以使用 -
if ($proxy_protocol_addr != a.b.c.d) {
return 403;
}