最近百家饭团队开源了一个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本地读取,这个用的少,就不讲了。