之前网站受到过CC攻击和DDoS攻击,因此研究了服务器防CC设置,并针对WordPress做特别防CC处理。采用上述设置后,基本上消除了CC攻击影响,网站能正常运行。

最近发现 WordPress防CC攻击 结合 使用fail2ban防止恶意扫描和CC攻击 会带来一个很麻烦的问题:后台编辑文章时经常导致IP被封禁。查看Nginx错误日志,原因是并发连接数多次超过限制,最终被fail2ban封禁。

查找原因

根据Nginx设置:

limit_conn limit_conn 20;

单ip超过20个并发连接才会被限制。难道WordPress后台编辑文章需要同时打开这么多连接?

解封IP后,通过中转机登录服务器,运行 watch -n 1 'ss -ntp | grep IP地址' 实时监控连接。然后打开WordPress后台新建一篇文章,监控到浏览器和Nginx只建立了两个连接:

ESTAB 0 0 154.17.10.239:443 xxxx:1824 users:(("nginx",pid=xxx,fd=xx))
ESTAB 0 0 154.17.10.239:443 xxxx:1826 users:(("nginx",pid=xxx,fd=xx))

但很快,IP还是被封禁了。

这说明Nginx理解的并发连接和我们认为的TCP连接不是一回事。

还是得以官方说明为准。于是翻看Nginx的limit_conn文档,看到了这么一个备注:

In HTTP/2 and SPDY, each concurrent request is considered a separate connection.

翻译过来就是:使用HTTP/2和SPDY协议时,每一个并发请求都被当成一个独立连接。

有了这句话,问题就真相大白了:后台编辑文章时浏览器使用HTTP2协议请求数据,每一个请求都被Nginx当作一个连接。短时间内发起两百多个请求,超过了Nginx设定的并发连接数限制,最终导致IP被fail2ban拉黑。

WordPress后台请求
WordPress后台请求

解决办法

找到了原因,问题就比较容易解决了。主要的解决办法有:

1. 禁用HTTP2。这个方法不会导致IP被拉黑,但非常不推荐,因为HTTP2比HTTP1.1有10%-50%的性能提升

2. 将Nginx中的并发连接数调大。根据WordPress后台数据,这个值要设置得比较大,但会减弱CC攻击防护效果;

3. WordPress后台使用单独入口,并对这个入口取消防护设置。

本人使用的第三种方式,配置方便又不影响现有安全防护设置。

参考

  1. HTTP/2简介
  2. Module ngx_http_limit_conn_module