如何使用Fail2Ban保护Nginx服务器

・5 分钟阅读

我们的安全需求

  • 阻止任何试图运行脚本(.pl,.cgi, .exe等)的人,
  • 阻止任何试图将服务器用作代理的人
  • 阻止任何使用Nginx基本身份验证进行身份验证的人
  • 阻止任何人使用我们在页面中的应用程序登录进行身份验证
  • 阻止坏的机器人
  • 限制每个会话的连接数

我们可以使用ModSecurity来支持这些需求,但是,它与Nginx不兼容,我们想要一个轻巧易用的解决方案。我们可以用fail2ban和Nginx来满足所有这些需求。

配置fail2ban

Fail2Ban支持除连接限制要求之外的所有要求。要开始阻止不需要的guest虚拟机,请将它放在Fail2Ban 的jail.conf文件中(译者注: 最好把jail.conf复制一份到jail.local):


[nginx-auth]
enabled = true
filter = nginx-auth
action = iptables-multiport[name=NoAuthFailures, port="http,https"]
logpath = /var/log/nginx*/*error*.log
bantime = 600 # 10 minutes
maxretry = 6

[nginx-login]
enabled = true
filter = nginx-login
action = iptables-multiport[name=NoLoginFailures, port="http,https"]
logpath = /var/log/nginx*/*access*.log
bantime = 600 # 10 minutes
maxretry = 6
 
[nginx-badbots]
enabled = true
filter = apache-badbots
action = iptables-multiport[name=BadBots, port="http,https"]
logpath = /var/log/nginx*/*access*.log
bantime = 86400 # 1 day
maxretry = 1
 
[nginx-noscript]
enabled = true
action = iptables-multiport[name=NoScript, port="http,https"]
filter = nginx-noscript
logpath = /var/log/nginx*/*access*.log
maxretry = 6
bantime = 86400 # 1 day
 
[nginx-proxy]
enabled = true
action = iptables-multiport[name=NoProxy, port="http,https"]
filter = nginx-proxy
logpath = /var/log/nginx*/*access*.log
maxretry = 0
bantime = 86400 # 1 day

过滤配置

以下过滤器配置文件存储在/etc/fail2ban/filter.d/:


# Proxy filter /etc/fail2ban/filter.d/nginx-proxy.conf:
#
# Block IPs trying to use server as proxy.
#
# Matches e.g.
# 192.168.1.1 - - "GET http://www.something.com/
#
[Definition]
failregex = ^ -.*GET http.*
ignoreregex =
 
# Noscript filter /etc/fail2ban/filter.d/nginx-noscript.conf:
#
# Block IPs trying to execute scripts such as .php, .pl, .exe and other funny scripts.
#
# Matches e.g.
# 192.168.1.1 - - "GET /something.php
#
[Definition]
failregex = ^ -.*GET.*(.php|.asp|.exe|.pl|.cgi|scgi)
ignoreregex =
 
#
# Auth filter /etc/fail2ban/filter.d/nginx-auth.conf:
#
# Blocks IPs that fail to authenticate using basic authentication
#
[Definition]
 
failregex = no user/password was provided for basic authentication.*client: 
 user .* was not found in.*client: 
 user .* password mismatch.*client: 
 
ignoreregex =


#
# Login filter /etc/fail2ban/filter.d/nginx-login.conf:
#
# Blocks IPs that fail to authenticate using web application's log in page
#
# Scan access log for HTTP 200 + POST /sessions => failed log in
[Definition]
failregex = ^ -.*POST /sessions HTTP/1.." 200
ignoreregex =

测试fail2ban规则

你应该使用fail2ban-regex命令测试你的fail2ban规则:


# Test against a log file
# fail2ban-regex  
fail2ban-regex /var/log/nginx/access.log /etc/fail2ban/filter.d/nginx-login.conf 

# Test using strings
# fail2ban-regex  
fail2ban-regex "127.1.1.1 - - [21/Feb/2012:10:31:08 +0200] "POST /sessions HTTP/1.1" 200 1532 "https://xxx.com/sessions" "Mozilla/5.0 Safari/535.11" "-"" "^ -.*POST /sessions HTTP/1.." 200"

限制连接数量

我们将连接数限制为每秒2个,并允许突发50,使用以下nginx配置:


http {
 limit_req_zone $binary_remote_addr zone=app:10m rate=2r/s; 
 ... 
 server {
 ... 
 location / {
 limit_req zone=app burst=50;
 }

注意,你还可以使用Rack::Attack来实现许多这些需求。

引用

http://wiki.nginx.org/HttpLimitReqModulehttp://www.fail2ban.org/wiki/index.php/Main_Pagehttp://serverfault.com/questions/307575/fail2ban-doesnt-process-jail-even-though-regex-matches

讨论
Zhongy0410 profile image