在Centos上,如何使用Fail2ban保护Nginx

・23 分钟阅读

介绍

Fail2ban是一种入侵防御软件框架,它用python编写,保护计算机服务器免受暴力攻击,它可以运行在本地安装了包控制系统或防火墙接口的POSIX系统上。

Fail2ban扫描日志文件,Fail2Ban能够降低不正确的认证进行再次尝试的速率; 它不能消除弱认证所带来的风险,您可以指定希望阻止恶意源地址的时间量。你还可以在fail2ban配置中指定要忽略的源地址列表。

功能

  • 监视日志文件,
  • 入侵防护,
  • 防止字典攻击,
  • 防止DoS攻击,
  • 更新netfilter/iptables或PF防火墙规则,
  • 抵御分布式暴力攻击。

在本教程中,我们将学习如何安装Fail2ban,并且配置它以保护您CentOS-7上的Nginx服务器免受DDoS攻击,

要求

  • 运行CentOS-7的服务器,
  • 服务器有静态IP地址,
  • 服务器上具有sudo特权的非root用户帐户,

入门

先确定你的CentOS服务器是完全最新的。

你可以通过运行以下命令来更新服务器:

sudo yum update -y

安装

默认情况下,Nginx在Centos-7存储库中不可用,你将需要安装EPEL存储库来安装Nginx 。

你可以通过运行以下命令来安装EPEL库:

sudo yum install epel-release

你的服务器上已经安装了Nginx库,你可以使用下面的yum命令安装Nginx :

sudo yum install nginx

Nginx不是自启动的,要使Nginx运行,请键入:

sudo systemctl start nginx

如果运行防火墙,请运行以下命令以允许HTTP和HTTPS通信:

sudo firewall-cmd --permanent --zone=public --add-service=httpsudo firewall-cmd --permanent --zone=public --add-service=httpssudo firewall-cmd --reload

在继续之前,你可能希望在系统引导时启用Nginx ,要这样做,请输入以下命令:

sudo systemctl enable nginx

现在在浏览器中键入URL http://localhost或http://server-ip-address,检查你的计算机是否正在运行Nginx web服务器。

上面的页面用于测试nginx HTTP服务器安装后的是否正常运行。如果可以阅读此页面,则意味着该站点上安装的服务器工作正常。

#配置Nginx密码身份验证

首先,需要创建保存你的用户名和密码组合的文件,可以通过使用服务器上可用的OpenSSL实用工具来实现这一点,如果服务器上安装了OpenSSL,则可以创建没有附加包的口令文件,我们将在/etc/nginx配置目录中创建一个名为.htpasswd的隐藏文件来存储我们的用户名和密码组合。

你可以使用以下命令向文件中添加用户名,我们使用Hitesh作为用户名,但是,你也可以使用任何你想要的名称:

sudo sh -c "echo -n 'hitesh:' > /etc/nginx/.htpasswd"

接下来,键入以下命令为用户名添加加密密码条目:

sudo sh -c "openssl passwd -apr1 >> /etc/nginx/.htpasswd"

你可以重复此过程以获得其他用户名,您可以通过键入以下内容来查看用户名和加密的密码是如何存储在文件中的:

cat /etc/nginx/.htpasswd

你将看到以下输出:


 hitesh:$apr1$WE2SfA57$O6kstuLHgfZ8SJNBd0YxE0

既然你有一个Nginx可以读取的格式的用户和密码文件,你需要配置Nginx来检查这个文件,然后再提供我们的受保护内容。首先打开你希望添加限制的服务器块配置文件。

sudo nano /etc/nginx/nginx.conf

在内部,删除注释后,文件应类似于以下内容:

 server {

listen 80 default_server;

listen [::]:80 default_server;

server_name _;

root /usr/share/nginx/html;

# Load configuration files for the default server block.

include /etc/nginx/default.d/*.conf;

location / {

}

error_page 404 /404.html;

location = /40x.html {

}

error_page 500 502 503 504 /50x.html;

location = /50x.html {

}

}

要设置身份验证,你需要决定要限制的上下文,除了其他选择,Nginx允许你在服务器级别或特定位置设置限制,在我们的示例中,我们将将整个文档root限制为一个位置块,但是,你可以修改这个列表,在此位置块中,使用auth_basic指令启用身份验证,并选择要在提示时显示给用户的领域名,我们将使用auth_basic_user_file指令将Nginx指向我们创建的密码文件:

sudo nano /etc/nginx/nginx.conf

添加/编辑以下行:

 server {

listen 80 default_server;

listen [::]:80 default_server;

server_name _;

root /usr/share/nginx/html;

# Load configuration files for the default server block.

include /etc/nginx/default.d/*.conf;

location / {

} error_page 404 /404.html;

location = /40x.html {

}

auth_basic "Restricted Content";

auth_basic_user_file /etc/nginx/.htpasswd;

error_page 500 502 503 504 /50x.html;

location = /50x.html {

}

}

完成后保存并关闭文件,重新启动Nginx以实现你的密码策略:

sudo systemctl restart nginx

你指定的目录现在应该是密码保护的。

要确认内容是否受保护,请尝试通过键入URL http://server-ip-address.在web浏览器中访问受限内容,

如果输入正确的凭证,你将被允许访问内容,如果输入错误的凭据或按"取消",你将看到"需要授权"错误页:

你现在应该拥有为你的站点设置基本身份验证所需的一切,记住密码保护应该与SSL加密结合使用,以便你的凭据不会以纯文本形式发送到服务器。

安装Fail2Ban

一旦Nginx服务器运行,并且启用密码验证,就可以继续安装Fail2ban ,Fail2ban是一种入侵防御框架,它与服务器上安装的包控制系统或防火墙一起工作,它通常用于在多次失败尝试后阻止连接尝试,它通过监视特定类型的日志文件来操作日志文件,并根据它结果运行预定的操作,使用下面的命令安装程序。

sudo yum install fail2ban fail2ban-systemd

默认情况下,fail2ban被配置为只禁止失败的SSH登录尝试,你需要启用一些规则来配置它来检查我们的Nginx日志,以检查恶意活动的模式。 安装后,复制默认的jail.conf文件以使用此命令进行本地配置,

sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local

然后打开新的 local配置文件,用你喜欢的文本编辑器进行编辑,例如,

sudo nano /etc/fail2ban/jail.local

添加/编辑文件,如下所示:

 [DEFAULT]

# MISCELLANEOUS OPTIONS # "ignoreip" can be an IP address, a CIDR mask or a DNS host. Fail2ban will not # ban a host which matches an address in this list. Several addresses can be # defined using space separator.

ignoreip = 127.0.0.1/8 server-ip-address

# External command that will take an tagged arguments to ignore, e.g. , # and return true if the IP is to be ignored. False otherwise. # ignorecommand = /path/to/command

ignorecommand =

# "bantime" is the number of seconds that a host is banned.

bantime = 600

# A host is banned if it has generated "maxretry" during the last "findtime" seconds.

findtime = 600

# "maxretry" is the number of failures before a host get banned.

maxretry = 5

保存并关闭文件。

  • Ignoreip用于设置不被禁止的IPs列表,IP地址列表应使用空格分隔符,此参数用于设置你的个人IP地址(如果你从固定ip访问服务器),
  • Bantime参数用于设置主机需要被禁用的秒的持续时间,
  • Findtime是用于检查主机是否必须被禁止的参数。当主机在它上次findtime内生成maxrety时,它将被禁止。
  • Maxretry是用于设置重试主机数量限制的参数,超过此限制后,主机被禁用,

执行以下命令以在服务器上运行保护Fail2Ban软件。

sudo systemctl enable fail2bansudo systemctl start fail2ban

配置Fail2Ban以监视Nginx日志

现在你已经有了一些常规的Fail2ban设置,你可以专注于添加一些可以监视web服务器日志的datacontext ,配置文件中的每个jail都由包含jail (除了[DEFAULT]部分,每个部分都表示一个特定的配置)中的jail名称的标题标记。

sudo nano /etc/fail2ban/jail.local

添加以下内容:

 #To enable log monitoring for Nginx login attempts.

[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

#This is the only Nginx-specific jail included with CentOS 7 fail2ban package. However, you can create our own jails to add additional functionality. #You can create an [nginx-noscript] jail to ban clients that are searching for scripts on the website to execute and exploit. If you do not use PHP #or any other language in conjunction with your web server, you can add this jail to ban those who request these types of resources: #to ban clients that are searching for scripts on the website to execute and exploit.

[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

#You can add a section called [nginx-badbots] to stop some known malicious bot request patterns: # to stop some known malicious bot request patterns

[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

#If you do not use Nginx to provide access to web content within users' home directories, you can ban users who request these resources by adding an #[nginx-nohome] jail: #to provide access to web content within users' home directories

[nginx-nohome] enabled = true port = http,https filter = nginx-nohome logpath = /var/log/nginx/access.log maxretry = 2

#We should ban clients attempting to use our Nginx server as an open proxy. We can add an [nginx-noproxy] jail to match these requests: #ban clients attempting to use our Nginx server as an open proxy

[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

完成修改所需的修改后,保存并关闭文件,你现在必须为我们创建的jail添加过滤器。

添加额外Nginx jail的过滤器

你需要更新/etc/fail2ban/jail.local文件,使用一些额外的监狱规范来匹配和禁止更大的行为范围,你需要为我们创建的jail创建过滤器文件,这些过滤器文件将通过更改过滤器目录指定在Nginx logs.Begin中查找的模式:

cd /etc/fail2ban/filter.d

实际上,我们希望通过调整预先提供的Nginx身份验证过滤器来匹配其他失败登录日志模式,你可以通过创建nginx-auth.conf file:来实现

sudo nano nginx-auth.conf

添加以下内容:


 # 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 =

完成后保存并关闭文件。

接下来,创建另一个file:

sudo nano nginx-proxy.conf

添加以下内容:


 # 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 =

完成后保存并关闭文件。

接下来,为[nginx-noscript] jail创建过滤器:

sudo nano nginx-noscript.conf

添加以下内容:


 # 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 =

完成后保存并关闭文件。

接下来,为[nginx-noscript] jail创建过滤器:

sudo nano nginx-login.conf

添加以下内容:


 # 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服务,你可以通过键入以下命令来执行该操作:

sudo service fail2ban restart

服务应该重新启动,实现你所配置的不同的禁止策略。

你可以使用fail2ban-client命令查看所有启用的jail :

sudo fail2ban-client status

你应该会看到你所启用的所有jail的列表:


 Status
 |- Number of jail: 5
 `- Jail list: nginx-badbots, nginx-login, nginx-proxy, nginx-auth, nginx-noscript, nginx-nohome

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

sudo fail2ban-regex /var/log/nginx/access.log /etc/fail2ban/filter.d/nginx-auth.conf

你将看到以下输出:


 Running tests
 =============

Use regex file : /etc/fail2ban/filter.d/nginx-auth.conf Use log file : /var/log/nginx/access.log

Results =======

Failregex: 0 total

Ignoreregex: 0 total

Summary =======

Sorry, no match

Look at the above section 'Running tests' which could contain important information.

你可以查看iptables,看看fail2ban已经修改了防火墙规则来创建用于禁止客户端的框架,即使没有以前的防火墙规则,你也可以启用框架,允许fail2ban通过将客户端添加到目的构建链来选择性地禁止客户机:

sudo iptables –S

你将看到以下输出:


 -P INPUT ACCEPT
 -P FORWARD ACCEPT
 -P OUTPUT ACCEPT
 -N FORWARD_IN_ZONES
 -N FORWARD_IN_ZONES_SOURCE
 -N FORWARD_OUT_ZONES
 -N FORWARD_OUT_ZONES_SOURCE
 -N FORWARD_direct
 -N FWDI_public
 -N FWDI_public_allow
 -N FWDI_public_deny
 -N FWDI_public_log
 -N FWDO_public
 -N FWDO_public_allow
 -N FWDO_public_deny
 -N FWDO_public_log
 -N INPUT_ZONES
 -N INPUT_ZONES_SOURCE
 -N INPUT_direct
 -N IN_public
 -N IN_public_allow
 -N IN_public_deny
 -N IN_public_log
 -N OUTPUT_direct
 -N fail2ban-BadBots
 -N fail2ban-NoAuthFailures
 -N fail2ban-NoLoginFailures
 -N fail2ban-NoProxy
 -N fail2ban-NoScript
 -A INPUT -p tcp -m multiport --dports 80,443 -j fail2ban-NoProxy
 -A INPUT -p tcp -m multiport --dports 80,443 -j fail2ban-NoScript
 -A INPUT -p tcp -m multiport --dports 80,443 -j fail2ban-BadBots
 -A INPUT -p tcp -m multiport --dports 80,443 -j fail2ban-NoLoginFailures
 -A INPUT -p tcp -m multiport --dports 80,443 -j fail2ban-NoAuthFailures
 -A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
 -A INPUT -i lo -j ACCEPT
 -A INPUT -j INPUT_direct
 -A INPUT -j INPUT_ZONES_SOURCE
 -A INPUT -j INPUT_ZONES
 -A INPUT -p icmp -j ACCEPT
 -A INPUT -j REJECT --reject-with icmp-host-prohibited
 -A FORWARD -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
 -A FORWARD -i lo -j ACCEPT
 -A FORWARD -j FORWARD_direct
 -A FORWARD -j FORWARD_IN_ZONES_SOURCE
 -A FORWARD -j FORWARD_IN_ZONES
 -A FORWARD -j FORWARD_OUT_ZONES_SOURCE
 -A FORWARD -j FORWARD_OUT_ZONES
 -A FORWARD -p icmp -j ACCEPT
 -A FORWARD -j REJECT --reject-with icmp-host-prohibited
 -A OUTPUT -j OUTPUT_direct
 -A FORWARD_IN_ZONES -i eth0 -g FWDI_public
 -A FORWARD_IN_ZONES -g FWDI_public
 -A FORWARD_OUT_ZONES -o eth0 -g FWDO_public
 -A FORWARD_OUT_ZONES -g FWDO_public
 -A FWDI_public -j FWDI_public_log
 -A FWDI_public -j FWDI_public_deny
 -A FWDI_public -j FWDI_public_allow
 -A FWDO_public -j FWDO_public_log
 -A FWDO_public -j FWDO_public_deny
 -A FWDO_public -j FWDO_public_allow
 -A INPUT_ZONES -i eth0 -g IN_public
 -A INPUT_ZONES -g IN_public
 -A IN_public -j IN_public_log
 -A IN_public -j IN_public_deny
 -A IN_public -j IN_public_allow
 -A IN_public_allow -p tcp -m tcp --dport 80 -m conntrack --ctstate NEW -j ACCEPT
 -A IN_public_allow -p tcp -m tcp --dport 22 -m conntrack --ctstate NEW -j ACCEPT
 -A IN_public_allow -p tcp -m tcp --dport 8080 -m conntrack --ctstate NEW -j ACCEPT
 -A fail2ban-BadBots -j RETURN
 -A fail2ban-NoAuthFailures -j RETURN
 -A fail2ban-NoLoginFailures -j RETURN
 -A fail2ban-NoProxy -j RETURN
 -A fail2ban-NoScript -j RETURN

测试Fail2Ban策略

测试Fail2ban策略以确保按预期阻止流量是很重要的,例如,从客户端机器打开web浏览器,并且在Nginx身份验证提示时键入URL http://server-ip-address,给出不正确的凭证次数,超过限制后,你将被禁止,无法访问网站。

在服务器计算机上,如果使用fail2ban-client命令查看状态,则会看到从站点禁止的IP地址:

sudo fail2ban-client status nginx-auth

输出:


 Status for the jail: nginx-auth
 |- filter
 | |- File list: /var/log/nginx/error.log
 | |- Currently failed: 5
 | `- Total failed: 0
 `- action
 |- Currently banned: 1
 | `- IP list: 
 `- Total banned: 1
 `- Banned IP list: 192.168.0.13

当你满意你的规则时,你可以使用fail2ban-client命令手动取消禁用你的IP地址:

sudo fail2ban-client set nginx-auth unbanip 192.168.0.13

你现在应该能够再次尝试验证。

结束语

在本教程中,你学习了如何在CentOS-7中安装Nginx和fail2ban ,Fail2ban为构建符合特定安全需求的策略提供了很大的灵活性,您可以查看/etc/fail2ban/jail.local文件中的变量和模式,以及/etc/fail2ban/filter.d和/etc/fail2ban/action.d目录中依赖的文件,您可以为您的网站提供更安全的环境。使用fail2ban,可以让web服务器上的攻击停止,并以自动方式阻止这种类型的攻击。

Zhongy0410 profile image