收起左侧

使用Fail2ban保护SSH、Nginx反向代理的Vaultwarden等,且设置邮箱提醒

0
回复
85
查看
[ 复制链接 ]

5

主题

3

回帖

0

牛值

江湖小虾

Fail2ban

原理介绍

Fail2ban 是一款用于防止暴力破解和恶意登录尝试的开源工具,广泛应用于 Linux 系统。它通过监控日志文件来检测失败的登录尝试或其他可疑活动,并自动更新防火墙规则以阻止恶意 IP 地址。
它通过监控日志文件(如 /var/log/auth.log)来检测失败的登录尝试,当某个 IP 地址在短时间内多次尝试失败后,Fail2ban 会自动将其添加到防火墙的黑名单中,阻止其进一步访问。

现代的Fail2ban通常可同时过滤IPv4和IPv6攻击,配置没有区别,非常方便。

我使用它来保护我NAS上的Vaultwarden(密码管理工具)、SSH、Nginx服务等。以下是我的搭建经验,目前测试均可正常保护,如有不对的地方,欢迎指正!tongue tongue tongue

实现过程

1、监控日志文件:Fail2ban 通过读取指定的日志文件来检测恶意活动。
2、检测失败尝试:它使用正则表达式来匹配日志中的失败登录尝试或其他可疑活动。
3、更新防火墙规则:当检测到恶意 IP 地址时,Fail2ban 会自动更新防火墙(如 iptables 或 nftables)规则,阻止该 IP 的进一步访问。
4、自动解封:在预设的时间后,被封锁的 IP 地址会被自动从黑名单中移除

主要配置文件

Fail2Ban的主要配置文件位于 /etc/fail2ban 目录下。关键的配置文件包括:
1、jail.confjail.local文件:这个是主要的配置文件,用于定义各种jail的设置,如SSH、Apach、Nginx等,并包含该服务的监控规则、封禁时间等参数。通常我们会修改的是jail.local文件,jail.conf文件为默认配置文件,当 jail.local jail.conf 有冲突配置时,以jail.local配置为主,当 jail.local文件中不存在某些配置时才会读取默认的 jail.conf文件;
2、action.d:该目录包含各种定义的action,这写action定义了在遇到攻击时需要采取的措施。如更新防火墙规则等。
3、filter.d:该目录包含各种过滤器的定义文件,这些过滤器用于从日志文件中提取出攻击模式,通常用户可自定义过滤规则。

安装及常用配置

1、Ubuntu/Debain安装Fail2ban

apt update && apt install fail2ban -y

Centos/RHEL安装

yum install epel-release -y
yum update && yum install fail2ban -y

2、配置示例(SSH)

避免直接修改默认配置文件 jail.conf,创建一个 jail.local文件

vim /etc/fail2ban/jail.local

添加如下配置(这里使用的是nftables防火墙,默认为iptables,如果不想改去掉banaction即可)

[DEFAULT]											# 全局模板
ignoreip = 127.0.0.1/8								# 白名单
banaction = nftables								# 默认封禁工具,仅封禁单个端口
banaction_allports = nftables[type=allports]		# 全局下全端口封禁模板
action = %(action_mwl)s								# 全局下启用组合动作(封禁 + 通知 + 日志记录)

[sshd]
enabled  = true
port    = 22
filter = sshd
maxretry= 3											# 在指定过滤时间内最大重试次数
findtime= 600										# 间隔时间,单位为 s
bantime = 43200										# 封禁时间,单位为 s
logpath = /var/log/auth.log  						# 日志路径(Ubuntu 默认为 /var/log/auth.log)

默认fail2ban使用防火墙阻止客户端访问时使用的是Reject,会提示入侵者,为了安全需要改为Drop

vim /etc/fail2ban/action.d/nftables.conf
# 找到blocktype = reject,修改为以下内容
blocktype = drop

重启fail2ban,使得配置生效

systemctl restart fail2ban
systemctl enable fail2ban
fail2ban-client status sshd
----------------------------------------------------------------------------------------------------------
Status for the jail: sshd
|- Filter
|  |- Currently failed: 0								 # 当前失败数
|  |- Total failed:     3				  			        # 失败总数
|  `- Journal matches: _SYSTEMD_UNIT=sshd.service + _COMM=sshd			 # 日志匹配项
`- Actions
   |- Currently banned: 1	 							 # 目前禁止
   |- Total banned:     1		 						 # 被禁总数
   `- Banned IP list:   192.168.10.1						       	 # 被禁IP列表

这里我尝试三次输入错误SSH密码,可以看到sshd的jail模块已经检测到进行阻止,并且已记录攻击者IP。需要注意的是:当封禁结束后,该IP信息将会被移除,可以通过以下查看日志的命令进行查看

cat /var/log/fail2ban.log | grep Ban              # 查看封禁IP记录
cat /var/log/fail2ban.log | grep Unban            # 查看解封禁IP记录

image.png

3、常用运维命令

fail2ban-client status	                                # 查看生效的jail数量和名称
fail2ban-client status <jail-name>                     # 查看某个jail的详细信息
fail2ban-client banned					  # 列出所有被禁的IP
fail2ban-client set <jail-name> unbanip <被禁IP>	  # 解封某个jail封禁的ip
fail2ban-client set <jail-name> unbanip 0.0.0.0/0	  # 解封某个jail封禁的所有ip

image.png

#在Centos/RHEL上默认的SSH过滤规则无法正常过滤密钥登录的尝试,需要新写一个filter规则,而Ubuntu和Debain的不需要

vim /etc/fail2ban/filter.d/sshd-public.conf
# 添加以下内容:
[Definition]
failregex = ^<F-CONTENT>.+Failed publickey for .+ from <HOST> port \d+ ssh2:.+</F-CONTENT>$
            ^<F-CONTENT>.+Connection closed by authenticating user .+ <HOST> port \d+ \[preauth\]</F-CONTENT>$
ignoreregex =
写入一个新的ssh密钥jail,原有的sshd的jail为了安全保持不变
vim /etc/fail2ban/jail.local
# 添加以下内容:
[sshd-public]
enabled = true
filter = sshd-public
port = 2003
maxretry = 3
findtime = 300
bantime = 3600
logpath = /var/log/secure

重启fail2ban,使得配置生效

systemctl restart fail2ban
systemctl enable fail2ban

image.png

4、Nginx相关配置

① 防CC、防目录扫描、防爬虫配置

先在filter.d目录下创建预定过滤规则

block_cc.conf

[Definition]
failregex = ^<HOST> -.*"(GET|POST).*HTTP.*" (200|404|503|444|403|400) .*$
ignoreregex = .*(robots.txt|favicon.ico|jpg|png|css|js)

说明:

  • 拦截返回状态码为 404503444403400 的恶意请求。
  • 忽略静态文件请求(减少误封)。

block_scan.conf

[Definition]
[Definition]
failregex = ^<HOST> -.*"(GET|POST).*(wp-admin|.git|.env|backup|admin|phpmyadmin|sql|\.bak|\.old|\.config|\.conf).* HTTP.*$
ignoreregex = .*(robots.txt)

说明:

  • 拦**问敏感路径(如 wp-admin、.git、.env 等)的请求。
  • 支持自定义添加其他敏感关键词(如 login、config)。

block_badbots.conf

[Definition]
failregex = ^<HOST> -.*"(GET|POST|HEAD).*"(?:.*(?:curl|wget|scan|bot|spider|crawler|python-requests|nikto|sqlmap|nmap|harvest|dirbuster|hydra|metasploit|nessus|acunetix|netsparker|httrack|webcopier|webreaper|libwww-perl|WinHTTP|X11|Dataprovider|Java/1\.|Go-http-client|okhttp)).*$
ignoreregex =

说明:

  • 正则表达式匹配常见恶意爬虫的 User-Agent(如 curl、sqlmap、nmap 等)。

随后在jail.local文件中加入以下内容

[DEFAULT]
ignoreip = 127.0.0.1/8
banaction = nftables
banaction_allports = nftables[type=allports]
action = %(action_mwl)s

[block_cc]
enabled = true
filter = block_cc
port = 9443
maxretry = 30
findtime = 240
bantime = 3600
logpath = /www/wwwlogs/xxxx.cn.log

[block_scan]
enabled = true
filter = block_scan
port = 9443
maxretry = 20
findtime = 300
bantime = 3600
logpath = /www/wwwlogs/xxxx.cn.log

[block_badbots]
enabled = true
filter = block_badbots
port = 9443
maxretry = 5
findtime = 300
bantime = 3600
logpath = /www/wwwlogs/xxxx.cn.log

重启Fail2ban即可

② Nginx反向代理内部的Vaultwarden防爆破

Nginx反向代理配置(主要部分)

http {
    log_format main '$remote_addr - $remote_user [$time_local] '
                    '"$request" $status $body_bytes_sent '
                    '"$http_referer" "$http_user_agent"';

    server {
        listen 80;
        server_name vault.xxx.xxx;
        access_log /var/log/nginx/vaultwarden.access.log main;  # 日志路径

        location / {
            proxy_pass https://xxx.xxxx.xx:9443;  # Vaultwarden实际端口
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
            # 重要:确保日志记录真实客户端IP(尤其在使用CDN时)
            # 若前端有CDN,需使用 $http_x_forwarded_for
        }
    }
}

自定义过滤规则

vim /etc/fail2ban/filter.d/vaultwarden.conf
[Definition]
failregex = ^<HOST> -.*POST (/identity/connect/token|/notifications/hub/negotiate).* 4[0-9]{2}.*$
ignoreregex =

说明:

  • 匹配POST请求到Vaultwarden登录端点(Bitwarden API路径)
  • 状态码 4xx(如401/400表示登录失败)
  • 自动捕获客户端IP

编辑 /etc/fail2ban/jail.local

vim /etc/fail2ban/jail.local
[DEFAULT]
ignoreip = 127.0.0.1/8
banaction = nftables
banaction_allports = nftables[type=allports]
action = %(action_mwl)s

[vaultwarden]
enabled = true
port = 9443
filter = vaultwarden
logpath = /var/log/nginx/vaultwarden.access.log	# 匹配Nginx日志路径
maxretry = 3                                    	# 3次错误后封禁
findtime = 1800                                  	# 30分钟内触发
bantime = 7200                                  	# 封禁7200秒(2小时)
action = %(action_mwl)s

重启Fail2ban

systemctl restart fail2ban

此时我尝试输入错误一次密码,使用fail2ban-client检测工具检测后输出如下内容,可以看到已经检测到了一次错误。
且经过测试,即使是输入不存在的邮箱,或是使用app或浏览器扩展通过api连接也会被封禁;

image.png

image.png

CC攻击和目录扫描测试

# 安装使用Siege(100个并发,持续30秒),-c 为并发连接数,-t 为持续时间
apt install siege -y
siege -c 100 -t 30s "http://你的域名+端口"

# Nikto 扫描(模拟专业攻击),x 为扫描常见的危险文件, 6为扫描所有目录(已知的超2000个目录)
apt install nikto -y
nikto -h http://your-domain.com -Tuning x 6

随后查看记录是否存在被封禁IP

5、对接mail在受到攻击时发送邮件进行提醒,这里使用的是qq邮箱,注意:授权码不是用户密码,需要在网页版qq邮箱的设置中进行申请!!!

# Ubuntu或Deabin
apt install bsd-mailx ssmtp -y
# Centos或RHEL
yum install mainx -y

#Centos和RHEL配置方法

vim /etc/mail.rc
#发件人邮箱
set from="Fail2ban <xxxx@qq.com>"
#发件人邮箱的SMTP地址
set smtp=smtps://smtp.qq.com:465
#发件人邮箱登陆账号
set smtp-auth-user=xxxx@qq.com
#发件人邮箱的授权码
set smtp-auth-password=xxxx
#认证方式
set smtp-auth=login
#忽略证书警告
set ssl-verify=ignore
#证书存放路径
set nss-config-dir=etc/pki/nssdb

#Ubuntu和Debain配置方法

vim /etc/ssmtp/ssmtp.conf
# 清空原有配置后加入以下配置
mailhub=smtp.qq.com:465					# qq邮箱地址
AuthUser=xxxx@qq.com					# qq邮箱用户
AuthPass=xxxx							# qq邮箱授权码
UseTLS=YES								# 使用TLS
UseSTARTTLS=NO							# 465端口的邮箱需要关闭改配置
FromLineOverride=YES
vim /etc/mail.rc
# 清空原有配置后加入以下配置
set from="Fail2ban <xxxx@qq.com>"		# 设置发件人信息

进行邮箱测试

echo 'Test Mail' | mail -v -s 'Test' xxxx@qq.com
######################################################################
Resolving host smtp.qq.com . . . done.
Connecting to 183.47.101.192:465 . . . connected.
220 newxmesmtplogicsvrszc13-0.qq.com XMail Esmtp QQ Mail Server.
>>> EHLO AliYun
250-newxmesmtplogicsvrszc13-0.qq.com
250-PIPELINING
250-SIZE 73400320
250-AUTH LOGIN PLAIN XOAUTH XOAUTH2
250-AUTH=LOGIN
250-MAILCOMPRESS
250-SMTPUTF8
250 8BITMIME
>>> AUTH LOGIN
334 VXNlcm5hbWU6
>>> MTE3OTcxMjc3MkBxcS5jb20=
334 UGFzc3dvcmQ6
>>> YmFqbWVqbGdpdHR2amhmZA==
235 Authentication successful
>>> MAIL FROM:<xxxx@qq.com>
250 OK
>>> RCPT TO:<xxxx@qq.com>
250 OK
>>> DATA
354 End data with <CR><LF>.<CR><LF>.
>>> .
250 OK: queued as.
>>> QUIT
smtp-server: "/root/dead.letter" 0/0
. . . message not sent.

Fail2ban配置

vim /etc/fail2ban/jail.local
[DEFAULT]								# 全局模板
ignoreip = 127.0.0.1/8							# 白名单
banaction = nftables							# 默认封禁工具,仅封禁单个端口
banaction_allports = nftables[type=allports]	                       # 全局下全端口封禁模板
action = %(action_mwl)s
destemail = xxx@qq.com                                               # 发件人名称
sender = xxxx@qq.com                                                 # 发件人邮件地址(写入刚才mail中配置的邮箱即可,可以收发人相同)

自定义邮件内

vim /etc/fail2ban/action.d/mail-whois-lines.conf
actionban = printf "警告!!!\n被攻击机器名:`uname -n` \n被攻击机器IP:`/bin/curl ifconfig.co` \n攻击服务:<name> \n时间范围:<findtime> 秒内 \n被攻击次数:<failures> 次 \n攻击者IP:<ip> \n攻击方式:暴力破解、尝试弱口令或洪水攻击。\n处理方式:已将<ip>加入防火墙黑名单,封禁时间为 <bantime> 秒。\n封禁时间:`date`\n日志信息摘要:\n`tail -5 <logpath>` \n\n\t                                                       ——来自fail2ban邮箱"|mail -v -s "攻城狮请注意,服务器遭到来自 <ip> 的暴力攻击!" <dest>

对于 actionstartactionstop如果觉得没必要发那么多邮件,可将其注释

重启Fail2ban

systemctl restart fail2ban

尝试登录失败三次,收到邮件

image.png

image.png

收藏
送赞
分享

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则