准备工作
1、检查Firewalld是否启用
#如果您已经安装iptables建议先关闭
service iptables stop
#查看Firewalld状态
firewall-cmd --state
#启动firewalld
systemctl start firewalld
#设置开机启动
systemctl enable firewalld.service
启用Firewalld后会禁止所有端口连接,因此请务必放行常用的端口,以免被阻挡在外,以下是放行SSH端口(22)示例,供参考:
#放行22端口
firewall-cmd --zone=public --add-port=80/tcp --permanent
#重载配置
firewall-cmd --reload
#查看已放行端口
firewall-cmd --zone=public --list-ports
2、安装fail2ban
fail2ban可以监控系统日志,并且根据一定规则匹配异常IP后使用Firewalld将其屏蔽,尤其是针对一些爆破/扫描等非常有效。
#CentOS内置源并未包含fail2ban,需要先安装epel源
yum -y install epel-release
# 安装fial2ban
yum -y install fail2ban
# 如果需要支持电子邮件的话,需要安装Sendmail服务(Sendmail不需要使用Fail2Ban工具)
$ sudo yum install -y sendmail
# 启动并启用Fail2ban和Sendmail
$ sudo systemctl start fail2ban
$ sudo systemctl enable fail2ban
$ sudo systemctl start sendmail
$ sudo systemctl enable sendmail
# 如果遇到提示“没有目录/var/run/fail2ban”或者套接字文件
# “/var/run/fail2ban/fail2ban.sock”的错误,手动创建即可
$ sudo mkdir /var/run/fail2ban
3、配置
修改配置文件
安装成功后fail2ban配置文件位于/etc/fail2ban,其中jail.conf为主配置文件,它包含一组预定义的过滤器,所以尽量不要编辑该文件,除非你知道自己在干什么。而且只要有新的更新,该配置配置就会重置为默认值。而我们要做的就是,在同一目录下创建一个名为 jail.local 的新配置文件,并根据自己的意愿进行修改,即可。相关的匹配规则位于filter.d目录,其它 目录/文件
一般很少用到,如果需要详细了解可自行搜索。
虽然会优先读取jail.conf文件,但是jail.local文件会覆盖前者的配置
$ sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local
配置规则新建jail.local来覆盖fail2ban的一些默认规则:
默认 .local
会覆盖 .conf
的配置文件
#新建配置
vi /etc/fail2ban/jail.local
#默认配置
[DEFAULT]
ignoreip = 127.0.0.1/8
bantime = 86400
findtime = 600
maxretry = 5
#这里banaction必须用firewallcmd-ipset,这是fiewalll支持的关键,如果是用Iptables请不要这样填写
banaction = firewallcmd-ipset
action = %(action_mwl)s
参数说明:
ignoreip:IP白名单,白名单中的IP不会屏蔽,可填写多个以(,)分隔
bantime:屏蔽时间,单位为秒(s)
findtime:时间范围
maxretry:最大次数
banaction:屏蔽IP所使用的方法,上面使用firewalld屏蔽端口
fail2ban.conf配置文件
shell > grep -v ^# /etc/fail2ban/fail2ban.conf
[Definition]
loglevel = 3 ## 定义日志级别,默认
logtarget = /var/log/fail2ban.log ## 定义 fail2ban 日志文件
socket = /var/run/fail2ban/fail2ban.sock ## sock 文件存放位置,默认
pidfile = /var/run/fail2ban/fail2ban.pid ## pid 文件存放位置,默认
jail.conf 防护配置
shell > grep -v ^# /etc/fail2ban/jail.conf
[DEFAULT] ## 全局设置,优先级最小
ignoreip = 127.0.0.1/8 ## 不受限制的 IP ,多组用空格分割
bantime = 600 ## 非法 IP 被屏蔽时间(秒),-1 代表永远封锁
findtime = 600 ## 设置多长时间(秒)内超过 maxretry 限制次数即被封锁
maxretry = 3 ## 最大尝试次数
backend = auto ## 日志修改检测机制(gamin 、polling 、auto 三种)
usedns = warn
[ssh-iptables] ## 分类设置(基于 SSHD 服务的防护)
enabled = true ## 是否开启防护,false 为关闭
filter = sshd ## 过滤规则 filter 名称,对应 filter.d 目录下的 sshd.conf
action = iptables[name=SSH, port=ssh, protocol=tcp] ## 动作参数
logpath = /var/log/secure ## 检测系统登陆日志文件
maxretry = 5 ## 最大尝试次数
如何删除fail2ban中已被禁用的黑名单IPfail2ban-配置
格式:
fail2ban-client set 服务规则 unbanip IP地址
例子:
fail2ban-client set nginx unbanip 8.8.8.8
CentOS7下如何验证fail2ban禁止的IP已经生效
第一个命令用来查看fail2ban配置的规则是否已经生效。
firewall-cmd --direct --get-all-rules
第二个命令用来查看在fail2ban黑名单里的IP是否已经加到了firewall中。
ipset list
测试自定义规则是否生效
fail2ban-regex /var/log/secure /etc/fail2ban/filter.d/sshd.conf
进程管理
如果你使用的是 CentOS 或 Fedora 的操作系统,则需要将 jail.local 配置文件中的 backend 选项从 auto 更改为 systemd。虽然在 Debian8+ 或 Ubuntu 16.04+ 上也都是使用了 systemd 来管理服务进程的,但这并不是必需的设置。默认情况下,在 CentOS7 中默认的配置文件是没有启用任何服务的,如果我们需要启动对应服务的话,需要手动修改配置文件,例如要启用 SSH 守护程序。
# /etc/fail2ban/jail.local
# "backend" specifies the backend used to get files modification.
# Available options are "pyinotify", "gamin", "polling", "systemd" and "auto".
# This option can be overridden in each jail as well.
backend = systemd
配置服务
Fail2Ban 自带有一组预定义的过滤器,用于各种服务,如 ssh、apache、nginx 等。我们不用对配置文件进行过多的更改,只需在对应服务区域中添加 enabled = true 启用该服务。禁用服务时将 true 改为 false 即可。
# /etc/fail2ban/jail.local
# enabled: 表明服务是要打开还是关闭
# port: 使用默认端口则填写服务名称;非传统端口则需要填写端口号
# logpath: 提供服务日志的位置
# backend: 指定用于获取文件修改的后端
[sshd]
enabled = true
port = ssh
filter = sshd
logpath = %(sshd_log)s
backend = %(sshd_backend)s
maxretry = 5
服务分离
如果需要监控的服务太多的话,放到一个配置文件里面,找起来还是又不方便的地方。所以,我们可以针对不同的服务配置创建不同的配置文件,每个配置文件立里面只配置对应服务的配置即可。将对应的配置放到 /etc/fail2ban/jail.d/ 目录下面,即可。
# /etc/fail2ban/jail.d/sshd.local
[sshd]
enabled = true
filter = sshd
banaction = iptables
backend = systemd
maxretry = 5
findtime = 1d
bantime = 2w
ignoreip = 127.0.0.1/8
设置白名单
默认情况下,大多数选项都已经配置的很完美了,如果要启用忽略对某些特定 IP 的访问控制,则可以将 IP 地址添加到 ignoreip 区域即可。对于多个 IP 的情况,用空格隔开 IP 地址。配置文件中的 DEFAULT 部分包含 Fail2Ban 遵循的基本规则集,您可以根据自己的意愿调整任何参数。
# /etc/fail2ban/jail.local
# ignoreip: Fail2Ban不会禁止与列表中的地址匹配的主机;白名单
# bantime: 封禁时间秒,默认是10分钟
# findtime: 如果在最近findtime秒期间已经发生了maxretry次重试,则主机会被禁止
# maxretry: 最大重试次数,子项未设置时以此为准
# sendername: 发件人名称G
# sender: 用于发送告警邮件的邮箱地址
# destemail: 用于接收警报电子邮件的邮箱地址
[DEFAULT]
ignoreip = 127.0.0.1/8 192.168.1.100/24
bantime = 600
findtime = 600
maxretry = 3
sender = escapelife@gmail.com
destemail = escapelife@gmail.com
4、使用方式说明
工具服务启停操作
# 启动Fail2ban服务
$ sudo systemctl start fail2ban
# 停止Fail2ban服务
$ sudo systemctl stop fail2ban
# 开机自启动Fail2ban服务
$ sudo systemctl enable fail2ban
查看启用的服务监控列表
$ sudo fail2ban-client status
Status
|- Number of jail: 2
`- Jail list: apache-auth, sshd
获取 SSH 服务禁止的 IP 地址
$ sudo fail2ban-client status ssh
Status for the jail: ssh
|- filter
| |- File list: /var/log/auth.log
| |- Currently failed: 1
| `- Total failed: 3
`- action
|- Currently banned: 1
| `- IP list: 192.168.1.115
`- Total banned: 1
# 根据配置文件中的服务配置字段
$ sudo fail2ban-client status ssh-iptables
删除禁止的 IP 地址
# 根据配置文件中的服务配置字段
$ sudo fail2ban-client set ssh unbanip 192.168.1.115
$ sudo fail2ban-client set ssh-iptables unbanip 192.168.1.115
手动添加白名单
# 根据配置文件中的服务配置字段
$ sudo fail2ban-client set ssh addignoreip 192.168.1.115
$ sudo fail2ban-client set ssh-iptables addignoreip 192.168.1.115
示例演示说明
防止SSH爆破
如果您还在使用默认SSH端口(22),可能每天都会被扫描,我们可以修改端口尽量避免被扫,参考: https://www.moerats.com/archives/394/ ,或者可以使用fail2ban将恶意IP屏蔽。
继续修改jail.local这个配置文件,在后面追加如下内容:
[sshd]
enabled = true
filter = sshd
port = 22
action = %(action_mwl)s
logpath = /var/log/secure
参数说明:
[sshd]
:名称,可以随便填写
filter:规则名称,必须填写位于filter.d目录里面的规则,sshd是fail2ban内置规则,对应 filter.d/sshd.conf
port:对应的端口
action:采取的行动
logpath:需要监视的日志路径
到这一步,我们jail.local的规则看起来可能像下面这样子:
[DEFAULT]
ignoreip = 127.0.0.1/8
bantime = 86400
findtime = 600
maxretry = 5
banaction = firewallcmd-ipset
action = %(action_mwl)s
[sshd]
enabled = true
filter = sshd
port = 22
action = %(action_mwl)s
logpath = /var/log/secure
上面的配置意思是如果同一个IP,在10分钟内,如果连续超过5次错误,则使用Firewalld将他IP ban了。输入systemctl start fail2ban启动fail2ban来试试效果。
使用另一台服务器不断尝试连接SSH,并且不断的将密码输入错误,你会发现连续超过5次后直接连不上,说明IP被ban了,可以输入:fail2ban-client status sshd查看被ban的IP
使用 iptables 阻止IP访问
在不开启 firewalld 的情况下,可以使用 iptables 方式
vim jail.local
[ssh-iptables]
enabled = true
port = 5258
filter = sshd
action = iptables[name=SSH, port=5258, protocol=tcp]
logpath = /var/log/secure
maxretry = 5
自定义规则防止SSH暴力破解
查看 /var/log/secure 文件,有很多如下日志:
Jul 2 08:51:58 VM_0_8_centos sshd[22959]: Received disconnect from 119.29.191.40 port 54314:11: Bye Bye [preauth]
Jul 2 08:52:51 VM_0_8_centos sshd[23023]: Received disconnect from 104.37.189.106 port 52200:11: Bye Bye [preauth]
Jul 2 08:53:16 VM_0_8_centos sshd[23084]: Received disconnect from 119.29.191.40 port 48510:11: Bye Bye [preauth]
Jul 2 08:54:37 VM_0_8_centos sshd[23179]: Received disconnect from 119.29.191.40 port 42704:11: Bye Bye [preauth]
Jul 2 08:56:00 VM_0_8_centos sshd[23291]: Received disconnect from 119.29.191.40 port 36902:11: Bye Bye [preauth]
Jul 2 08:57:22 VM_0_8_centos sshd[23411]: Received disconnect from 119.29.191.40 port 59330:11: Bye Bye [preauth]
Jul 2 08:58:42 VM_0_8_centos sshd[23507]: Received disconnect from 119.29.191.40 port 53530:11: Bye Bye [preauth]
Jul 2 09:00:03 VM_0_8_centos sshd[23621]: Received disconnect from 119.29.191.40 port 47722:11: Bye Bye [preauth]
Jul 2 09:01:25 VM_0_8_centos sshd[23758]: Received disconnect from 119.29.191.40 port 41922:11: Bye Bye [preauth]
Jul 2 09:02:47 VM_0_8_centos sshd[23854]: Received disconnect from 119.29.191.40 port 36124:11: Bye Bye [preauth]
Jul 2 09:04:08 VM_0_8_centos sshd[23970]: Received disconnect from 119.29.191.40 port 58554:11: Bye Bye [preauth]
Jul 2 09:05:18 VM_0_8_centos sshd[24079]: Received disconnect from 104.37.189.106 port 46362:11: Bye Bye [preauth]
Jul 2 09:05:26 VM_0_8_centos sshd[24089]: Received disconnect from 119.29.191.40 port 52746:11: Bye Bye [preauth]
Jul 2 09:06:36 VM_0_8_centos sshd[24176]: Received disconnect from 62.231.7.220 port 55168:11: Bye Bye [preauth]
Jul 2 09:06:47 VM_0_8_centos sshd[24189]: Received disconnect from 119.29.191.40 port 46940:11: Bye Bye [preauth]
Jul 2 09:08:09 VM_0_8_centos sshd[24310]: Received disconnect from 119.29.191.40 port 41140:11: Bye Bye [preauth]
Jul 2 09:09:32 VM_0_8_centos sshd[24415]: Received disconnect from 119.29.191.40 port 35332:11: Bye Bye [preauth]
Jul 2 09:10:53 VM_0_8_centos sshd[24525]: Received disconnect from 119.29.191.40 port 57766:11: Bye Bye [preauth]
Jul 2 09:12:13 VM_0_8_centos sshd[24650]: Received disconnect from 119.29.191.40 port 51972:11: Bye Bye [preauth]
Jul 2 09:13:36 VM_0_8_centos sshd[24749]: Received disconnect from 119.29.191.40 port 46170:11: Bye Bye [preauth]
Jul 2 09:14:59 VM_0_8_centos sshd[24853]: Received disconnect from 119.29.191.40 port 40390:11: Bye Bye [preauth]
Jul 2 09:16:19 VM_0_8_centos sshd[24983]: Received disconnect from 119.29.191.40 port 34576:11: Bye Bye [preauth]
Jul 2 09:17:39 VM_0_8_centos sshd[25078]: Received disconnect from 119.29.191.40 port 57000:11: Bye Bye [preauth]
Jul 2 09:17:49 VM_0_8_centos sshd[25089]: Received disconnect from 104.37.189.106 port 40600:11: Bye Bye [preauth]
像这种日志,默认是不会被屏蔽的,需要手动添加规则
vim /etc/fail2ban/filter.d/sshd.conf
normal = ^%(__prefix_line_sl)s[aA]uthentication (?:failure|error|failed) for .* from <HOST>( via \S+)?\s*%(__suff)s$
^%(__prefix_line_sl)sUser not known to the underlying authentication module for .* from <HOST>\s*%(__suff)s$
...
...
# 这里是添加的自定义规则
^%(__prefix_line)sReceived disconnect from <HOST> port \d*:\d*: Bye Bye \[preauth\]\s*$
重启服务并设置开机启动
systemctl restart fail2ban
systemctl enable fail2ban
防止CC攻击
这里仅以Nginx为例,使用fail2ban来监视nginx日志,匹配短时间内频繁请求的IP,并使用firewalld将其IP屏蔽,达到CC防护的作用。
#需要先新建一个nginx日志匹配规则
vi /etc/fail2ban/filter.d/nginx-cc.conf
#填写如下内容
[Definition]
failregex = -.*- .*HTTP/1.* .* .*$
ignoreregex =
继续修改jail.local追加如下内容:
[nginx-cc]
enabled = true
port = http,https
filter = nginx-cc
action = %(action_mwl)s
maxretry = 20
findtime = 60
bantime = 3600
logpath = /usr/local/nginx/logs/access.log
上面的配置意思是如果在60s内,同一IP达到20次请求,则将其IP ban 1小时,上面只是为了测试,请根据自己的实际情况修改。logpath为nginx日志路径。
阻止恶意扫描
# 新增[nginx-dir-scan]模块
[nginx-dir-scan]
enabled = true
filter = nginx-dir-scan
action = iptables[name=nginx-dir-scan, port=443, protocol=tcp]
logpath = /path/to/nginx/access.log
maxretry = 1
bantime = 172800
findtime = 300
防止 vsftpd 攻击规则
[vsftpd-notification]
enabled = true
filter = vsftpd
action = sendmail-whois[name=VSFTPD, dest=you@example.com]
logpath = /var/log/vsftpd.log
maxretry = 5
bantime = 1800
[vsftpd-iptables]
enabled = true
filter = vsftpd
action = iptables[name=VSFTPD, port=ftp, protocol=tcp]
sendmail-whois[name=VSFTPD, dest=you@example.com]
logpath = /var/log/vsftpd.log
maxretry = 5
bantime = 1800
总结
常用命令
启动
systemctl start fail2ban
#停止
systemctl stop fail2ban
#开机启动
systemctl enable fail2ban
#查看被ban IP,其中sshd为名称,比如上面的[wordpress]
fail2ban-client status sshd
#删除被ban IP
fail2ban-client set sshd delignoreip 192.168.111.111
#查看日志
tail /var/log/fail2ban.log
备注
每个.conf文件都会被名为 .local的文件覆盖。.conf首先被读取,其次是.local。新的配置会覆盖早先的。因此,.local 文件不必包含每个相应于.conf
中的选项,只是填写你想要覆盖的设置。
修改只会出现在.local文件中,而不是.conf中。这样可以避免升级时合并的问题。这些文件也是很好很详细的文档备注信息。
通用设置
fail2ban.conf文件中包含了fail2ban-server 守护进程的通用设置,诸如日志级别和目标。你也可以指定用于client和server端的通信的socket路径。