fail2ban
本页面由 PageTurner AI 翻译(测试版)。未经项目官方认可。 发现错误? 报告问题 →
Fail2ban 是一款入侵防御软件框架,用于保护 计算机服务器免受暴力破解攻击。 Fail2ban 通过监控日志文件(如 /var/log/auth.log、/var/log/apache/access.log 等)中的特定条目,并根据其内容执行相应脚本。
Jellyfin 生成的日志可被 Fail2ban 监控,用于防止针对您设备的暴力破解攻击。
先决条件
-
Jellyfin 需可远程访问
-
已安装并运行 Fail2ban
-
了解 Jellyfin 日志存储位置:桌面版默认为
/var/log/jellyfin/,Docker 容器则为/config/log/ -
将 Jellyfin 日志级别设为
Info(失败的认证条目不会记录在Error级别)。该设置可在logging.json文件中找到。
第一步:创建 jail
您需要为 Fail2ban 创建 jail。若使用 Ubuntu 系统并以 nano 作为编辑器,请运行:
sudoedit /etc/fail2ban/jail.d/jellyfin.local
将以下内容添加到新文件中,并将 /path_to_logs 替换为上述日志路径(例如 /var/log/jellyfin/):
[jellyfin]
backend = auto
enabled = true
port = 80,443
protocol = tcp
filter = jellyfin
maxretry = 3
bantime = 86400
findtime = 43200
logpath = /path_to_logs/log_*.log
保存并退出 nano。
Jellyfin rotates logs daily and fail2ban cannot detect the newly created log files without service restart or config reload.
To fix this you need a daily timer that reloads above fail2ban jellyfin jail whenever the logs are rotated at roughly around midnight.
sudoedit /etc/systemd/system/fail2ban-jellyfin-reload.timer
Add this to the new file:
[Unit]
Description=Reload Fail2Ban jellyfin jail daily
[Timer]
OnCalendar=*-*-* 00:45:00
Persistent=true
[Install]
WantedBy=timers.target
保存并退出 nano。
sudoedit /etc/systemd/system/fail2ban-jellyfin-reload.service
Add this to the new file:
[Unit]
Description=Reload Fail2Ban jellyfin jail
[Service]
Type=oneshot
ExecStart=/usr/bin/fail2ban-client reload jellyfin
保存并退出 nano。
Enable and start the service:
sudo systemctl enable --now fail2ban-jellyfin-reload.timer
注意:
-
若 Jellyfin 运行在 Docker 容器中,请在
jellyfin.local文件中添加:action = iptables-allports[name=jellyfin, chain=DOCKER-USER] -
若 Jellyfin 使用非标准端口,请将端口号从
80,443改为实际端口(如8096,8920)
第二步:创建过滤器
过滤器包含一组规则,Fail2ban 将据此识别失败的认证尝试。通过以下命令创建过滤器:
sudoedit /etc/fail2ban/filter.d/jellyfin.conf
粘贴以下内容:
[Definition]
failregex = ^.*Authentication request for .* has been denied \(IP: "<ADDR>"\)\.
保存并退出,然后重新加载 Fail2ban:
sudo systemctl restart fail2ban
检查 Fail2ban 是否正常运行:
sudo systemctl status fail2ban
第三步:测试
假设至少存在一次失败的认证尝试,您可以使用 fail2ban-regex 测试新建的 jail:
sudo fail2ban-regex /path_to_logs/log_*.log /etc/fail2ban/filter.d/jellyfin.conf --print-all-matched
高级 Fail2Ban 配置:在上游代理服务器上转发和管理封禁
为增强安全性,Fail2Ban 可在上游反向代理服务器而非 Jellyfin 服务器上管理 IP 封禁。此配置允许您在网络入口点就近拦截恶意 IP,并可能惠及使用同一代理的其他服务。
本指南提供使用**动态链(Dynamic Chains)**的配置方案,使 Fail2Ban 能在上游反向代理服务器管理 IP 封禁。每个 Fail2Ban jail 会在上游服务器创建并管理独立的 iptables 链。
前提条件
-
Fail2Ban 已安装在本地服务器(运行 Jellyfin 的服务器)
-
上游服务器已配置 iptables
第一步:设置基于 SSH 密钥的认证
确保 Fail2Ban 服务器可通过 SSH 无密码登录上游服务器。这对自动化 IP 封禁/解封流程至关重要。
将 <upstream-server-ip> 替换为您上游服务器的实际 IP 地址。
-
生成 SSH 密钥(如尚未创建):
ssh-keygen -t rsa -b 4096 -f /root/.ssh/id_rsa -
将 SSH 公钥复制到上游服务器:
ssh-copy-id -i /root/.ssh/id_rsa.pub root@<upstream-server-ip> -
测试 SSH 访问:
确保 SSH 连接无需密码即可正常工作:
ssh -i /root/.ssh/id_rsa root@<upstream-server-ip>
步骤二:配置 Fail2Ban 实现动态链
-
创建 Fail2Ban 动作文件:
在 Fail2Ban 服务器上创建新动作文件:
sudo nano /etc/fail2ban/action.d/proxy-iptables-dynamic.conf添加以下配置,该配置将为每个 jail 在上游服务器动态创建、管理和删除
iptables链:请将
<upstream-server-ip>替换为您上游服务器的实际 IP 地址。[Definition]# Option: actionban# 1. Create the chain if it doesn't exist# 2. Add the banned IP to the dynamic chain based on the jail name# 3. Log the eventactionban = ssh -i /root/.ssh/id_rsa -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null root@<upstream-server-ip> \'iptables -N f2b-<name> 2>/dev/null || true; \iptables -C INPUT -j f2b-<name> 2>/dev/null || iptables -I INPUT -j f2b-<name>; \iptables -I f2b-<name> 1 -s <ip> -j DROP' && \echo "Banned <ip> from jail <name> via upstream proxy" >> /var/log/fail2ban.log# Option: actionunban# 1. Remove the banned IP from the dynamic chain# 2. Remove the chain if it becomes empty (cleanup)# 3. Log the eventactionunban = ssh -i /root/.ssh/id_rsa -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null root@<upstream-server-ip> \'iptables -D f2b-<name> -s <ip> -j DROP; \if ! iptables -L f2b-<name> | grep -q "DROP"; then \iptables -D INPUT -j f2b-<name>; \iptables -F f2b-<name>; \iptables -X f2b-<name>; \fi' && \echo "Unbanned <ip> from jail <name> via upstream proxy and cleaned up chain if empty" >> /var/log/fail2ban.log修改完成后,保存并关闭文件。
-
更新 Fail2Ban Jails 使用动态链动作:
打开 jail 配置文件(通常位于
/etc/fail2ban/jail.local):sudo nano /etc/fail2ban/jail.local对于要通过上游代理管理的每个 jail,添加或修改 action 行以使用 proxy-iptables-dynamic 动作。以下是两个 jail 的配置示例:
[jellyfin]enabled = truefilter = jellyfinlogpath = /path/to/jellyfin/logmaxretry = 3bantime = 3600action = proxy-iptables-dynamic[nginx-http-auth]enabled = truefilter = nginx-http-authlogpath = /var/log/nginx/error.logmaxretry = 5bantime = 3600action = proxy-iptables-dynamic修改完成后,保存并关闭文件。
步 骤三:向 Jellyfin 添加代理 IP
-
获取代理 IP
由于您使用代理服务器,需要让 Jellyfin 在日志中输出正确的 IP 供 fail2ban 读取。
根据您的主机配置,这些 IP 范围可能来自内部 Docker IP、haproxy 或其他服务。
Jellyfin 接受带子网掩码的 IP 地址(如
172.18.0.1/24),您需要提供这些 IP 的逗号分隔列表。 -
向 Jellyfin 添加代理
打开 Jellyfin 服务器仪表板,进入
Advanced->Networking,滚动至Known proxies选项。输入您的逗号分隔代理 IP 范围列表。根据提示重启 Jellyfin 服务器。
第四步:重启 Fail2ban 并测试设置
-
重启 Fail2ban:
完成配置更改后,重启 Fail2ban 以应用新设置:
sudo systemctl restart fail2ban -
检查监禁状 态:
验证您的监禁状态以确保其正常运行:
sudo fail2ban-client status jellyfin -
测试封禁:
通过执行无效登录尝试或手动封禁 IP 来触发封禁。例如:
sudo fail2ban-client set jellyfin banip 192.168.1.100 -
在上游服务器验证:
检查该 IP 是否在上游服务器对应的监禁链('f2b-jail-name')中被封禁:
ssh root@<upstream-server-ip> "iptables -L f2b-jellyfin" -
测试解封:
要测试解封功能,请手动解封该 IP:
sudo fail2ban-client set jellyfin unbanip 192.168.1.100 -
验证解封:
确认 IP 已从对应 jail 的链('f2b-jail-name')中移除:
ssh root@<upstream-server-ip> "iptables -L f2b-jellyfin"
第五步:监控日志
监控 Fail2ban 日志以确保操作正常执行:
tail -f /var/log/fail2ban.log
每当有 IP 被封禁或解封时,该日志将显示消息,帮助您确认配置是否按预 期工作。