最近百家饭团队开源了一个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
-
-
- }
如果ip拦截规则只需要针对某个独立的Url配置,则可以结合location配置进行,location是server的一段,则配置位置还是在conf.d里面的具体配置里,但可以配置成这样:
- server {
- listen 80;
- server_name localhost;
-
-
- location / {
- # 看这里
- deny 1.2.3.4;
- }
- }
除了上述配置方式之外,还可以在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,例如
deny 240c:1::/32;
除了ip地址之外,其实还可以deny unix来排除unix本地读取,这个用的少,就不讲了。