最近百家饭团队开源了一个Nginx日志分析工具APIcat,这周在生成报告的基础上,实现了基于Nginx的自动拦截防护,正好研究了一下Nginx配置IP拦截的配置
配置方式
nginx配置ip拦截基本是通过deny和allow两个配置关键字来实现的。可以配置单ip的拦截放行,也可以配置网段的拦截放行,比如:
allow 1.2.3.4;
deny 1.2.3.4/24;
allow 1.2.3.4/16;
deny all;
关键字后跟具体的IP或者CIDR格式的网段即可,注意加上; 否则会报格式错误。
配置和一般防火墙一样,匹配从上到下进行,匹配到的第一条就生效,比如上面这个例子,1.2.3.4会直接匹配第一条单IP的配置,而1.2.3.1会匹配第二条,1.2.4.1会匹配第三条。如果配置的顺序改变了,就会影响匹配效果,比如,如果写成这样:
deny 1.2.3.4/24;
allow 1.2.3.4;
allow 1.2.3.4/16;
deny all;
1.2.3.4会因为匹配到第一条而造成直接被deny。
配置的地点
一共有三个地方可以配置IP拦截。
配置为全局拦截
在nginx.conf里面我们可以配置全局的客户IP拦截,在配置的http段增加deny标识即可
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
sendfile on;
#tcp_nopush on;
keepalive_timeout 65;
#看这里
deny 1.2.3.4;
#gzip on;
include /etc/nginx/conf.d/*.conf;
}
配置为单服务模式
如果只是对某个server配置IP拦截,则可以在server段配置,针对debian/ubuntu等,server配置在conf.d/里面,则可以不在nginx.conf里配置,而在conf.d里面的具体配置文件里配置。例如
server {
listen 80;
server_name localhost;
# 看这里
deny 1.2.3.4
}
为某个独立Url配置
如果ip拦截规则只需要针对某个独立的Url配置,则可以结合location配置进行,location是server的一段,则配置位置还是在conf.d里面的具体配置里,但可以配置成这样:
server {
listen 80;
server_name localhost;
location / {
# 看这里
deny 1.2.3.4;
}
}
为limit_except配置
除了上述配置方式之外,还可以在limit_except里面配置,针对不同的请求方式进行排除式设置,例如
limit_except GET POST {
deny 1.2.3.4;
}
上面的配置表示除了GET和POST之外,其他的请求方式进行deny配置。
该配置段可以在http、server和location中使用。
配置方式
除了上述的直接在配置文件中配置之外,我们还可以利用include把ip配置放置在配置外面,方便独立更新,这种方式在上诉三个配置地点都可以使用,例如
server {
listen 80;
server_name localhost;
# Apicat detection include
include /etc/nginx/conf.d/iptables;
}
上述是一个server配置段,里面,我们可以通过增加一条include来include外部的一个ip规则文件。
而在外部配置文件中直接配置ip规则
deny 1.2.3.4
这样,我们就可以把ip规则独立在一个独立的文件里了,目前APIcat采用的这种方式。
是否支持IPv6
IPv6已经是一个很常见的网络访问方式了,上述配置经检查都支持IPv6,例如
deny 240c:1::/32;
除了ip地址之外,其实还可以deny unix来排除unix本地读取,这个用的少,就不讲了。