使用fail2ban防止ssh穷举爆破
ssh被爆破
ssh:notty
:意思是没有使用tty,而 ssh 表示端口 22,它们合在一起意味着诸如 scp
或 rsync
之类的东西。
# 查看错误的登录
lastb
0.安装fail2ban
官网: https://www.fail2ban.org
项目地址:https://github.com/fail2ban/fail2ban
参考:https://blog.51cto.com/waringid/5811979
fail2ban
是一个更加强大和灵活的工具,它可以监控多种日志文件
,并根据用户自定义的规则
进行拉黑
。例如,可以监控 SSH
、FTP
、Apache
等服务的日志文件,根据设定的规则
来判断恶意访问
行为,如登录失败
、多次访问不存在的 URL
、频繁访问
等,然后自动拉黑恶意 IP 地址
。
fail2ban
的优点是功能强大
,可以对多种恶意行为
进行处理;
缺点
是配置比较繁琐
,需要用户自定义规则,并且可能会误判
合法访问。
yum安装epel_release源
# 安装epel_release源
yum install -y epel-release
# 建立缓存
yum makecache
# 安装fail2ban
yum install -y fail2ban fail2ban-firewalld fail2ban-systemd
# Centos7支持tcpd,需要安装fail2ban-hostsdeny
yum install -y fail2ban-hostsdeny
# 现在启动并开机自启
systemctl enable --now fail2ban
源码安装fail2ban
版本 1.0/0.11/0.10(和旧的 0.9)
将仍然基于 python2.7
版本1.01及以后
以后使用python3
# 安装sqlite3
yum install -y sqlite
# 安装依赖
yum install -y python2 python3
# 下载Fail2ban源码
wget -c https://github.com/fail2ban/fail2ban/archive/refs/tags/1.0.2.tar.gz
# 解压Fail2ban
tar xvf 1.0.2.tar.gz
# 进入解压后的Fail2ban目录
cd fail2ban-1.0.2
# 安装Fail2ban
python3 setup.py install --record fail2ban_install.log
# 如果是1.0以下低版本,请使用python2安装
python2 setup.py install --record fail2ban_install.log
# 卸载Fail2ban
cat fail2ban_install.log | xargs rm -rf
Fail2ban目录结构如下:
https://blog.51cto.com/waringid/5811979
yum
安装的/etc/fail2ban``目录结构
:
/etc/fail2ban/action.d
-----iptables
、mail
等动作文件目录/etc/fail2ban/fail2ban.conf
----- 定义日志级别
、日志
、sock
文件位置等/etc/fail2ban/filter.d
----- 条件匹配(过滤器
)文件目录,过滤日志关键内容/etc/fail2ban/jail.conf
-----主配置文件
,主要设置启用ban动作
的服务及动作阀值
,不建议修改
/etc/fail2ban/jail.d/
----- fail2ban模块化子配置文件
配置文件
https://www.cnblogs.com/RidingWind/p/13853762.html
1.配置sshd防护
# 先备份一下配置
cp /etc/fail2ban/jail.conf{,.bak}
全局配置
白名单IP–非必须
vim /etc/fail2ban/filter.d/jail.local
# 全局配置部分
[DEFAULT]
# 要忽略的 IP 地址。这些 IP 地址不会被封禁。
# 可以指定多个 IP 地址,使用 CIDR 表示法表示一个 IP 段。
# 在这个例子中,忽略的 IP 范围是 10.0.0.0 到 10.0.0.255
ignoreip = 10.0.0.0/24
# 封禁 IP 的时间长度(秒为单位)。
# 如果设置为负数(如 -1),则表示永久封禁。
# 当前设置为 864000 秒(即 10 天)
bantime = 864000
# 发现同一 IP 进行多次失败尝试的时间窗口(秒为单位)。
# 例如,如果 findtime 设置为 1200(20 分钟),
# 则在 20 分钟内如果检测到多次失败尝试将触发封禁。
findtime = 1200
# 最大失败尝试次数。
# 如果某个 IP 在 findtime 时间窗口内超过这个次数,IP 将被封禁。
# 当前设置为 2 次
maxretry = 2
# 采取的封禁动作。可以指定不同的动作来处理封禁 IP。
# 默认封禁动作是 `iptables-multiport`,即使用 iptables 管理多个端口的规则。
# 在这个配置文件中,这行被注释掉了,使用系统默认的封禁动作。
# banaction = iptables-multiport
# 后端日志分析引擎。
# `systemd` 表示使用 systemd 作为日志分析后台。
# 可选值包括:`polling`(基于文件系统的轮询),`gamin`(基于 gamin 的监视),`systemd`(使用 systemd 日志)。
backend = systemd
子配置
启用sshd保护策略
/etc/fail2ban/jail.d/
fail2ban模块化策略子配置文件
# 编辑自定义配置
vim /etc/fail2ban/jail.d/sshd_jail.local
粘贴以下内容:
[sshd]
# 启用防护
enabled = true
# 选择过滤器
filter = sshd
# 启用抗攻击防护模式--防护策略敏感度最高
# 正常(默认)、ddos、额外或 aggressive (攻击性 全部组合)。
## normal (default), ddos, extra or aggressive (combines all).
# 有关使用示例和详细信息,请参阅“tests/files/logs/sshd”或“filter.d/sshd.conf”。
mode = aggressive
# 禁止 IP 的持续时间(以秒为单位)。负数-1为“永久”禁止。
## 864000秒为10天
bantime = 864000
## 如果在“findtime”秒内未找到匹配,则计数器设置为零。默认 600s
findtime = 1200
# ssh登录失败阈值默认为 3
maxretry = 1
# 指定封禁的端口,默认为0:65535,也就是所有端口,但可以在jail中设定
port = ssh
# 使用哪个工具方法阻止IP
## firewall防火墙: firewallcmd-ipset
## iptables防火墙: iptables 或 iptables-multiport
## 拉黑到/etc/hosts.deny: hostsdeny
banaction = iptables-multiport
hostsdeny
# 日志路径
logpath = %(sshd_log)s
# 指定用于修改日志文件的后端
#backend = %(sshd_backend)s
backend = systemd
应用配置
保存
好配置后重启服务
# 重新加载配置或重启服务
systemctl reload-or-restart fail2ban.service
# 查看服务是否正常运行
systemctl status fail2ban.service -l
sshd防护常用命令
# 查看哪些IP被ban
fail2ban-client status sshd
# 将IP从黑名单中移除
fail2ban-client set sshd unbanip 8.8.8.8
# 将IP添加到黑名单中
fail2ban-client set sshd banip 8.8.8.8
# 清空黑名单
fail2ban-client unban --all
# 查看日志详情
tail -f /var/log/fail2ban.log
典型子配置示例
以上每行内容的大致意义如下:
# 定义jail名称
[ssh-示例]
# 是否启用该jail,默认的所有规则都没有该项,需要手动添加
enabled = true
# 指定封禁的端口,默认为0:65535,也就是所有端口,但可以在jail中设定
port = 22
# 指定过滤器名称
filter = 过滤器名称
## logpath与action可以有多行,如action中的设定:调用iptables-multiport封禁目标IP访问的多个端口,调用sendmail发送告警邮件
# 日志路径
logpath = %(sshd_log)s
# 达到阈值后的动作
action =
# 阈值默认为 3
maxretry = 3
# 时间间隔
## findtime不是检查日志的时间间隔,日志的检查是实时的。因为fail2ban自带数据库,所以可以在设定的时间内统计匹配次数
## 如果在“findtime”秒内未找到匹配,则计数器设置为零。默认 600s
findtime = 180
# 禁止 IP 的持续时间(以秒为单位)。负数为“永久”禁止。
bantime = -1
# 指定不禁止的 IP 地址或主机名列表。
## ignoreip添加后端服务器的IP或CDN的IP
ignoreip =
# 禁止方式,如何拉黑IP
banaction =
# 指定用于修改日志文件的后端
backend = systemd
0.综合示例
https://blog.51cto.com/u_15499155/6149769
配置文件:/etc/fail2ban/jail.d/ssh_web.local
# 默认配置
[DEFAULT]
# 忽略 IP 的列表,多个 IP 用空格分隔
ignoreip = 127.0.0.1/8 ::1
# 忽略的用户列表,多个用户用空格分隔
# ignoreuser = root
# 日志文件路径
logtarget = /var/log/fail2ban.log
# 日志级别
loglevel = INFO
# 封禁时间(以秒为单位)
bantime = 3600
# 最大重试次数
maxretry = 5
# 启用邮件通知
# mail-destemail = admin@example.com
# mail-sendername = Fail2Ban
# mail-subject = Fail2Ban notification
# Fail2ban 配置文件
# SSH 配置
[sshd]
# 启动此策略
enabled = true
# SSH 服务端口
port = ssh
# 使用 sshd 过滤器
filter = sshd
# SSH 日志文件路径
# logpath = /var/log/auth.log
logpath = /var/log/secure
# 封禁时间为 1 小时
bantime = 3600
# 最大重试次数为 5
maxretry = 5
# Apache 配置
[apache]
# 启用 Apache 防护
enabled = true
# Apache 服务端口
port = http,https
# 使用 apache-auth 过滤器
filter = apache-auth
# Apache 访问日志文件路径
logpath = /var/log/apache2/access.log
# 封禁时间为 1 小时
bantime = 3600
# 最大重试次数为 5
maxretry = 5
# Nginx 配置
[nginx-http-auth]
# 启用 Nginx 防护
enabled = true
# Nginx 服务端口
port = http,https
# 使用 nginx-http-auth 过滤器
filter = nginx-http-auth
# Nginx 访问日志文件路径
logpath = /var/log/nginx/access.log
# 封禁时间为 1 小时
bantime = 3600
# 最大重试次数为 5
maxretry = 5
1.防止 SSH 密码爆破示例–iptables
[ssh-iptables]
模块的配置修改如下。其中,port
应按照实际情况填写。
# 定义了一个 jail 名称为 ssh-iptables
[ssh-iptables]
# 启用此策略
enabled = true
# 使用名为 sshd 的过滤器来过滤日志
filter = sshd
# 在防火墙上创建名为 SSH 的规则以阻止来自 IP 地址的 SSH 登录尝试
action = iptables[name=SSH, port=22, protocol=tcp]
# 指定日志文件的路径
logpath = /var/log/secure
# 允许的最大失败登录尝试次数
maxretry = 7
# 时间段(以秒为单位),在此时间段内,如果尝试次数超过 maxretry,则会触发 action 所定义的操作
findtime = 300
2.阻止恶意web扫描
新增 [nginx-dir-scan]
模块,配置信息如下。
此处,port
和 logpath
应按照实际情况填写。
# 定义了一个 jail 名称为 nginx-dir-scan
[nginx-dir-scan]
# 启用了此策略
enabled = true
# 使用名为 nginx-dir-scan 的过滤器来过滤日志
filter = nginx-dir-scan
# 在防火墙上创建名为 nginx-dir-scan 的规则以阻止来自 IP 地址的目录扫描尝试
action = iptables[name=nginx-dir-scan, port=443, protocol=tcp]
# 指定日志文件的路径
logpath = /path/to/nginx/access.log
# 允许的最大失败登录尝试次数
maxretry = 1
# 封禁时间(以秒为单位),在此时间段内,被禁止的 IP 将无法访问服务器
bantime = 172800
# 时间段(以秒为单位),在此时间段内,如果尝试次数超过 maxretry,则会触发 action 所定义的操作
findtime = 300
配置正则规则匹配
然后在/etc/fail2ban/filter.d/
目录下新建nginx-dir-scan.conf
。
# 复制一份nginx-dir-scan.conf配置文件
cp /etc/fail2ban/filter.d/nginx-http-auth.conf /etc/fail2ban/filter.d/nginx-dir-scan.conf
# 编辑nginx-dir-scan.conf配置文件
vim /etc/fail2ban/filter.d/nginx-dir-scan.conf
对 nginx-dir-scan.conf
进行修改,具体配置信息如下:
[Definition]
# 匹配失败登录的正则表达式
failregex = <HOST> -.*- .*Mozilla/4.0* .* .*$
# 忽略的正则表达式
ignoreregex =
此处的正则匹配规则
是根据 nginx 的访问日志进行撰写,不同的恶意扫描有不同的日志特征。
本文采用此规则是因为在特殊的应用场景下有绝大的把握可以肯定 Mozilla/4.0
是一些老旧的数据采集软件
使用的UA
,所以就针对其做了屏蔽。不可否认 Mozilla/4.0 这样的客户端虽然是少数,但仍旧存在。因此,此规则并不适用于任何情况。
测试正则规则的有效性
使用如下命令,可以测试正则规则的有效性。
# 测试正则规则的有效性
fail2ban-regex /path/to/nginx/access.log /etc/fail2ban/filter.d/nginx-dir-scan.conf
Fail2ban 已经内置很多匹配规则,位于 filter.d 目录下,包含了常见的 SSH/FTP/Nginx/Apache 等日志匹配,如果都还无法满足需求,也可以自行新建规则来匹配异常IP。
总之,使用 Fail2ban
+iptables
来阻止恶意 IP 是行之有效的办法,可极大提高服务器安全。
3.变更 iptables 封禁策略
Fail2ban 的默认 iptables 封禁策略为 REJECT –reject-with icmp-port-unreachable
,需要变更 iptables 封禁策略
为 DROP
。
在 /etc/fail2ban/action.d/
目录下新建文件 iptables-blocktype.local
。
cd /etc/fail2ban/action.d/
# 新建文件 iptables-blocktype.local
cp iptables-blocktype.conf iptables-blocktype.local
# 编辑配置文件iptables-blocktype.local
vim iptables-blocktype.local
修改内容如下:
[INCLUDES]
# 在 iptables-blocktype.local 之后加载
after = iptables-blocktype.local
[Init]
# 阻止所有进入的数据包
blocktype = DROP
最后,别忘记重启 fail2ban 使其生效。
# 重启 fail2ban
systemctl restart fail2ban
启用ocserv保护规则
github上的issue为ocserv增加过滤器
https://github.com/fail2ban/fail2ban/issues/3563
监视日志backend = systemd
必须在jail
中指定(它与过滤器无关
);
不需要创建过滤器文件,直接编辑jail
vim /etc/fail2ban/jail.d/ocserv.local
[ocserv]
enabled = true
# 根据您的 ocserv 配置修改端口号
port = 443
filter =
failregex = ^\s*\S+\s+ocserv\[\d+\]: worker: <ADDR> warning: Received record packet of unknown type
backend = systemd
journalmatch = _SYSTEMD_UNIT=ocserv.service
# 忽略的规则
ignoreregex =
# 根据您的需求设置最大尝试次数
maxretry = 2
# 根据您的需求设置封禁时间(以秒为单位)
bantime = 3600
命中规则如下:
防护效果
Fail2ban 常用命令
# 检查fail2ban的启动问题
fail2ban-client -x start
# 查看fail2ban状态
fail2ban-client status
# 查看被 ban IP,其中 ssh-iptables 为名称,比如上面的 [ssh-iptables] 和 [nginx-dir-scan]
fail2ban-client status ssh-iptables
# 添加白名单
fail2ban-client set ssh-iptables addignoreip IP地址
# 删除白名单
fail2ban-client set ssh-iptables delignoreip IP地址
# 查看日志
tail /var/log/fail2ban.log
# 查看被禁止的 IP 地址
iptables -L -n
排错
# 以debug方式启动,打印详细日志
fail2ban-client -d