Fail2ban是一款入侵防御软件,可以保护服务器免受暴力攻击。Fail2ban 基于 auth 日志文件工作,默认情况下它会扫描所有 auth 日志文件,如/var/log/auth.log等,并禁止带有恶意标志的 IP,如密码尝试次数过多等。
Fail2ban 由 Python 编写而成,主要配合 iptables 来进行工作,为各种服务提供了过滤器,如 SSH、Apache、Nginx、Squid、Named、Mysql、Nagios 等。Fail2ban 能够降低风险,但不能消除风险,这只是服务器防止暴力攻击的安全手段之一,本文以CentOS为例。
安装Fail2ban Fail2ban不在官方软件包仓库中,它在EPEL中(Extra Packages for Enterprise Linux)。 安装epel-release:
1 sudo yum install epel-release
由于 Fail2ban 依赖于 Python,需要确保 Python 版本 ≥ 2.6:
安装Fail2ban:
1 sudo yum install fail2ban
安装完成之后,启用Fail2ban:
1 sudo systemctl enable fail2ban
文件目录结构 1 2 3 4 5 /etc/fail2ban ## fail2ban 服务配置目录 /etc/fail2ban/action.d ## iptables 、mail 等动作文件目录 /etc/fail2ban/filter.d ## 条件匹配文件目录,过滤日志关键内容 /etc/fail2ban/jail.conf ## fail2ban 防护配置文件 /etc/fail2ban/fail2ban.conf ## fail2ban 配置文件,定义日志级别、日志、sock 文件位置等
配置Fail2ban Fail2ban服务的配置文件在/etc/fail2ban目录。在其中可以找到jail.conf配置文件,官方的文档写到:在配置时,我们应该避免修改由fail2ban安装创建的文件,我们应该去编写具有.local扩展名的新文件,因为在升级软件包时,会覆盖这个文件,使配置失效。当我们的配置发生改变了我们可以使用 fail2ban-client reload ,来加载新的配置。我们应该创建一个新文件jail.local,在jail.local定义的值会覆盖jail.conf中的值。 我们来创建一个jail.local文件:
1 vim /etc/fail2ban/jail.local
或者:
1 vim /etc/fail2ban/jail.d/jail.local
写入如下代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 # defalut这里是设定全局设置,如果下面的监控没有设置就以全局设置的值设置。 [DEFAULT] # 用于指定哪些地址ip可以忽略 fail2ban 防御,以空格间隔。 ignoreip = 127.0.0.1/8 # 客户端主机被禁止的时长(默认单位为秒) bantime = 3600 # 过滤的时长(秒) findtime = 600 # 匹配到的阈值(次数) maxretry = 3 [ssh-iptables] # 是否开启 enabled = true # 过滤规则 filter = sshd # 动作 action = iptables[name=SSH, port=ssh, protocol=tcp] # 日志文件的路径 logpath = /var/log/secure # 匹配到的阈值(次数) maxretry = 3
在上面配置好了之后,我们需要让配置生效:
配置完成之后,重启fail2ban:
1 sudo systemctl restart fail2ban
或者:
1 sudo service fail2ban restart
查看登录失败的记录:
查询fail2ban服务状态:
1 sudo fail2ban-client status
查询某个jail的详细信息:
1 fail2ban-client status ssh-iptables
实用命令 最近一次启动,fail2ban日志:
1 journalctl -b -u fail2ban
实时跟踪显示fail2ban日志(按Ctrl-C退出):
1 tail -F /var/log/fail2ban.log
显示防火墙规则:
显示防火墙规则对应的命令:
fail2ban从黑名单(ban list)中移除IP的方法:
1 fail2ban-client set ssh-iptables unbanip 1.1.1.1
此时再查看banlist会发现IP已移除。
1 fail2ban-client status ssh-iptables
跟踪失败的登录条目: 以下命令用于检查是否通过ssh端口尝试登录服务器失败。
1 cat /var/log/secure | grep 'Failed password'
执行上述命令将得到来自不同IP地址的根密码尝试失败的列表。 结果的格式与下面所示的相似:
1 2 3 4 Fer 8 12:41:12 htf sshd[5487]: Failed password for root from 1.1.1.1 port 23021 ssh2 Fer 8 12:41:15 htf sshd[1254]: Failed password for root from 1.1.1.1 port 15486 ssh2 Fer 8 12:41:16 htf sshd[1254]: Failed password for root from 1.1.1.1 port 24457 ssh2 Fer 8 12:41:18 htf sshd[1254]: Failed password for root from 1.1.1.1 port 24457 ssh2
通过Fail2Ban检查被禁止的IP:
查看当前被禁止登陆的ip:
1 2 3 4 5 6 7 8 9 10 [root@121]# fail2ban-client status ssh-iptables Status for the jail: ssh-iptables |- filter | |- File list: /var/log/secure #日志文件路径 | |- Currently failed: 0 #当前失败次数 | `- Total failed: 3 #总失败次数 `- action |- Currently banned: 1 #当前禁止的ip数量 | `- IP list: 192.168.1.112 #当前禁止的ip `- Total banned: 1 #禁止的ip总数
启动暂停查看状态:
1 systemctl start/restart/stop/status fail2ban
fail2ban-regex测试筛选规则设否匹配当前的日志格式:
1 fail2ban-regex /var/log/secure /etc/fail2ban/filter.d/sshd.conf
fail2ban.conf配置文件 1 2 3 4 5 6 7 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 防护配置 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 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 ## 最大尝试次数
其他配置 修改端口问题:sshd更改端口号后使用fail2ban需要注意在填写配置的时候也需要更改端口号。否则会出现就算会将ip添加到防火墙,但由于变更了SSH端口号,是起不到禁止作用的。 解决方法:配置文件中 action = iptables[name=SSH, port=ssh, protocol=tcp] ,port位置修改为新的端口。