拓冰建站拓冰建站
首页 / 资讯中心 / 正文

Fail2ban实战:从零构建SSH暴力破解自动化防御体系

1. 项目概述当你的服务器日志成为“攻击者名单”如果你管理过一台暴露在公网的Linux服务器并且开启了SSH服务那么打开/var/log/auth.log或/var/log/secure文件你大概率会看到一片“腥风血雨”。无数来自全球各地的IP地址正以“root”、“admin”、“test”等常见用户名搭配着字典里成千上万的密码对你的服务器发起一波又一波的登录尝试。我的其中一台测试服务器在24小时内就被扫描了超过2000次。这并非个例而是互联网的常态——你的服务器端口就像一块磁铁无时无刻不在吸引着自动化脚本的“青睐”。手动去查看日志、分析IP、再一条条添加防火墙规则封禁这无疑是低效且不现实的。我们需要的是一个自动化、智能化的“看门狗”它能够实时监控日志识别恶意行为并自动执行封禁操作。这就是Fail2ban的核心价值。它不是一个复杂的入侵检测系统而是一个轻量级、高度可配置的“日志分析-动作执行”框架。本文将从一个被扫了2000次的真实场景出发手把手带你从零部署和深度配置Fail2ban打造一个自动化的SSH暴力破解防御体系让你从此告别手动封IP的繁琐与滞后。2. 防御体系构建思路与工具选型在深入Fail2ban之前我们需要理解一个完整的SSH防御策略是分层的。Fail2ban是其中动态响应的一环但它不是全部。2.1 防御策略的“三道防线”一个稳健的SSH访问控制体系通常包含以下层次第一道防线减少暴露面与强化认证修改默认端口将SSH默认的22端口改为一个高位端口如2222、35222可以过滤掉绝大部分漫无目的的自动化扫描。这就像把家门从热闹的街边搬到了小巷深处虽然不能杜绝专业窃贼但能避开绝大多数顺手牵羊者。禁用密码登录使用密钥对这是最根本、最有效的加固方式。使用ed25519或RSA密钥进行认证从源头上杜绝了暴力破解密码的可能性。PasswordAuthentication no这个配置一旦生效攻击者连“尝试”的机会都没有。禁止root用户直接登录在/etc/ssh/sshd_config中设置PermitRootLogin no强制攻击者必须同时猜对用户名和密码增加了攻击难度。第二道防线网络层访问控制配置防火墙iptables/nftables/firewalld只允许特定的、可信的IP地址段或国家访问SSH端口。这是静态的白名单策略适用于办公网络或固定IP访问的场景。第三道防线动态行为封禁Fail2ban的舞台当第一、二道防线因各种原因如需要临时开放、IP不固定无法完美实施时Fail2ban就成为了最后的动态屏障。它不预设谁是坏人而是通过行为判定短时间内多次认证失败那你就是攻击者先关进“小黑屋”防火墙规则冷静一段时间。2.2 为什么选择Fail2ban市面上有类似的工具如DenyHosts已停止维护或自己写脚本监控日志。选择Fail2ban基于以下几点考量轻量且高效它本身不占用大量资源核心工作是监控日志文件和操作防火墙。配置灵活其基于“过滤器Filter 动作Action”的架构使得它不仅能防御SSH还能轻松扩展至防护FTP、Web服务如Nginx/PHP、数据库等多种服务的暴力破解。社区活跃拥有广泛的用户基础和丰富的现成配置案例遇到问题容易找到解决方案。与系统集成好通过systemd管理可以方便地设置开机自启、查看运行状态。注意Fail2ban是一个“补救”和“威慑”机制而非“预防”机制。它的生效前提是攻击行为已经发生并被记录在日志中。因此务必优先考虑并实施第一道防线密钥登录改端口将Fail2ban作为一道重要的补充防线。3. Fail2ban核心机制深度解析要玩转Fail2ban必须吃透它的三个核心概念过滤器Filter、监狱Jail和动作Action。你可以把它理解为一个司法系统。3.1 核心组件工作流程过滤器Filter - “法官”定义什么样的行为是犯罪。它实际上是一个正则表达式规则集用于匹配日志文件中的特定行。例如在/var/log/auth.log中匹配Failed password for invalid user或Failed password for这样的字符串每匹配一次就视为一次“犯罪证据”。监狱Jail - “法律条文”将过滤器、动作和具体的参数捆绑在一起形成一条完整的处罚规则。它定义了监控哪个日志文件logpath。使用哪个过滤器filter。触发封禁的条件在多少秒findtime内检测到多少次maxretry匹配。执行哪个动作action。封禁多长时间bantime。动作Action - “警察”定义当“犯罪”达到阈值后执行什么操作。最常用的动作是调用系统的防火墙如iptables、firewalld或nftables添加一条DROP规则。动作也可以发送邮件通知、调用Webhook等。工作流程可以简化为日志实时更新 → Fail2ban监控日志 → 过滤器匹配到失败登录条目 → 计数器1 → 在findtime内计数器超过maxretry→ 触发对应监狱的action→ 执行封禁IP操作。3.2 关键配置文件解析Fail2ban的配置文件位于/etc/fail2ban/目录下采用层级结构避免直接修改主配置是良好习惯。/etc/fail2ban/fail2ban.conf主配置文件定义全局日志级别、日志目标、socket文件等。通常无需改动。/etc/fail2ban/jail.conf核心配置文件定义了所有的监狱Jail。但绝对不要直接修改这个文件因为软件升级会被覆盖。/etc/fail2ban/jail.local这是你应该修改的配置文件。系统会先读取jail.conf然后用jail.local中的配置覆盖它。你的所有自定义监狱和参数都应放在这里。/etc/fail2ban/action.d/存放动作定义文件如iptables.conf,sendmail.conf。/etc/fail2ban/filter.d/存放过滤器定义文件如sshd.conf。4. 实战部署从安装到配置SSH防护监狱下面我们进入实战环节假设你使用的是一台Ubuntu 22.04或CentOS 8/Rocky Linux 8的服务器。4.1 安装Fail2banUbuntu/Debian:sudo apt update sudo apt install fail2ban -yCentOS/Rocky Linux/RHEL:# 需要EPEL仓库 sudo dnf install epel-release -y sudo dnf install fail2ban -y安装完成后Fail2ban服务会自动启动。你可以检查其状态sudo systemctl status fail2ban4.2 配置基础的SSH防护监狱如前所述我们创建或编辑/etc/fail2ban/jail.local文件。sudo cp /etc/fail2ban/jail.{conf,local} sudo nano /etc/fail2ban/jail.local找到[DEFAULT]区块这里设置全局参数。我们进行如下调整[DEFAULT] # 禁止访问的端口多个端口用空格分隔。这里封禁所有端口攻击性较强。 # 如果你只想封禁SSH端口可以设置为 portsshd ignorecommand /path/to/script/ignorecommand.sh # 全局的“查找时间”窗口单位秒。600秒10分钟内。 findtime 600 # 全局的最大重试次数。5次失败就触发。 maxretry 5 # 全局的封禁时间单位秒。这里设置-1代表永久封禁。建议初期设置为8640024小时观察。 bantime 86400 # 使用的防火墙后端。根据你的系统选择 # Ubuntu 通常用 ufw (如果用了UFW) 或 iptables # CentOS/Rocky 8 默认使用 firewalld但也可以切回 iptables。 # 这里使用通用的 iptables。如果你的系统是 firewalld请确保安装了 iptables-services 并禁用 firewalld或者将此处改为 banaction firewallcmd-ipset banaction iptables-multiport # 监听的协议一般tcp就够了。 banaction_allports iptables-allports # 发送邮件通知的配置需要本地邮件服务如postfix或配置外部SMTP destemail your-emailexample.com sender fail2banyour-hostname mta sendmail action %(action_)s接下来配置具体的SSH监狱。在[DEFAULT]部分之后添加或取消注释[sshd]部分[sshd] # 启用此监狱 enabled true # 监控的日志路径默认通常是正确的。如果你的SSH日志不在这个位置需要修改。 # Debian/Ubuntu: /var/log/auth.log # CentOS/RHEL: /var/log/secure logpath %(sshd_log)s # 使用的过滤器对应 /etc/fail2ban/filter.d/sshd.conf filter sshd # 端口如果你的SSH改了端口这里必须同步修改例如 port2222 port ssh # 此监狱特有的参数会覆盖DEFAULT设置。这里我们设置更严格的策略。 maxretry 3 findtime 300 bantime 604800 # 封禁一周实操心得一bantime的设置艺术不建议一开始就设置为-1永久封禁。因为可能存在误判比如自己输错密码或者一些动态IP用户。建议先设置为8640024小时或604800一周。Fail2ban会自动管理封禁列表时间到了会自动释放。观察一段时间日志确认规则有效且误封少后再考虑延长封禁时间。永久封禁更适合用于已确认的、持续攻击的恶意IP段。4.3 关键调整应对SSH端口修改与高并发扫描如果你的SSH端口不是22有两个地方必须修改监狱配置中的port如上所示在[sshd]里设置port你的端口号。过滤器规则Fail2ban的sshd过滤器默认会去日志里匹配port 22。如果你的日志里记录的是port 2222那么过滤器会匹配失败你需要修改过滤器文件。sudo nano /etc/fail2ban/filter.d/sshd.conf找到类似^%(__prefix_line)s(?:error: PAM: )?Authentication failure for .* from HOST的行可能有多处包含port 22。你需要在这些正则表达式中将port 22替换为port \d以匹配任何端口或者更精确地替换为port 你的端口号。例如 将port 22改为port \d。 保存后务必测试过滤器sudo fail2ban-regex /var/log/auth.log /etc/fail2ban/filter.d/sshd.conf如果输出中显示有匹配的条目则修改成功。应对高并发扫描有些攻击脚本会在极短时间内如1秒发起数十次尝试可能绕过基于“时间窗口内次数”的规则。我们可以启用modeaggressive。在[sshd]监狱中添加mode aggressiveaggressive模式会使用过滤器目录下的sshd-aggressive.conf规则它对某些错误类型的计数更加敏感。4.4 应用配置并验证重启Fail2ban服务sudo systemctl restart fail2ban sudo systemctl enable fail2ban # 设置开机自启检查监狱状态sudo fail2ban-client status你会看到类似输出其中sshd监狱应该是Active。Status |- Number of jail: 1 - Jail list: sshd查看指定监狱的详细状态sudo fail2ban-client status sshd这会显示当前被该监狱封禁的IP列表、失败次数、封禁时间等关键信息。Status for the jail: sshd |- Filter | |- Currently failed: 0 | |- Total failed: 1234 | - File list: /var/log/auth.log - Actions |- Currently banned: 5 |- Total banned: 87 - Banned IP list: 203.0.113.5 198.51.100.23 ...验证防火墙规则Fail2ban最终是通过操作防火墙来实现的。你可以用以下命令查看封禁规则如果使用iptables:sudo iptables -L -n -v | grep f2b-sshd # 查看f2b-sshd链的规则 sudo iptables -L f2b-sshd -n # 查看该链的详细规则如果使用firewalld且action配置为firewallcmd:sudo firewall-cmd --direct --get-all-rules5. 高级配置与实战技巧基础配置只能应对常规攻击。面对更复杂的情况我们需要一些高级技巧。5.1 封禁整个IP段慎用对于来自同一个C类地址/24的密集攻击可以考虑封禁整个网段。这需要自定义动作。在/etc/fail2ban/action.d/目录下复制一个现有的动作文件作为模板例如iptables.conf。sudo cp /etc/fail2ban/action.d/iptables.conf /etc/fail2ban/action.d/iptables-subnet.conf sudo nano /etc/fail2ban/action.d/iptables-subnet.conf找到定义actionban的部分。通常是一行iptables命令。我们需要修改它将单个IP的DROP规则改为针对一个网段。例如将-A chain -s ip -j DROP中的ip替换为ip/24的逻辑比较复杂因为Fail2ban传递的是单个IP。一个更简单粗暴的方法是修改Fail2ban的Python代码或者在动作命令中使用shell脚本来计算网段。由于操作复杂且有误封大片正常IP的风险此处不展开详细命令。新手强烈不建议使用此功能。更安全的做法是收集到恶意IP段后手动添加到防火墙规则。5.2 设置邮件报警让Fail2ban在封禁IP时发邮件通知你便于监控。确保系统有可用的邮件发送功能。可以安装postfix或sendmail并配置为仅发送本地邮件sendmail only模式然后通过外部工具如msmtp转发到你的邮箱。这是一个相对复杂的主题这里假设你已配置好本地sendmail。在/etc/fail2ban/jail.local的[DEFAULT]或[sshd]中启用邮件动作[DEFAULT] destemail adminyourdomain.com # 你的接收邮箱 sender fail2banyourserver.com # 发件人 mta sendmail [sshd] action %(action_mwl)s%(action_mwl)s是一个组合动作表示action_(封禁IP) mail-whois-lines(发送邮件邮件内容包含Whois信息和触发日志的若干行)。重启Fail2ban后下次封禁时你就会收到邮件。5.3 白名单设置避免误封自己或可信IP这是至关重要的一步否则你可能把自己锁在服务器外面。在/etc/fail2ban/jail.local的[DEFAULT]部分或具体的[sshd]监狱中添加[DEFAULT] ignoreip 127.0.0.1/8 ::1 192.168.1.0/24 203.0.113.50127.0.0.1/8和::1是本地回环地址。192.168.1.0/24是你的内网网段根据实际情况修改。203.0.113.50是你的办公室或家庭的固定公网IP如果有的話。实操心得二动态IP用户的白名单策略如果你使用家庭宽带动态IPIP可能会变。一个变通方法是先设置一个较短的bantime如36001小时。在手机或另一台电脑上通过你常用的SSH客户端连接服务器。如果因为输错密码被误封等待1小时解封或者通过云服务商的控制台VNC功能登录服务器手动解封IPsudo fail2ban-client set sshd unbanip 你的IP。更可靠的方法是优先使用SSH密钥登录并禁用密码登录这样从根本上避免了因密码错误被Fail2ban封禁的可能。5.4 保护其他服务以Nginx为例Fail2ban的威力不止于SSH。例如防止针对WordPress登录页面的暴力破解。创建Nginx登录失败过滤器sudo nano /etc/fail2ban/filter.d/nginx-http-auth.conf输入以下内容这是一个通用示例匹配Nginx的error.log中401错误[Definition] failregex ^ \[error\] \d#\d: \*\d user \S:? (password mismatch|was not found in .*), client: HOST, server: \S, request: \S \S HTTP/\d\.\d, host: \S\s*$ ignoreregex 在jail.local中启用监狱[nginx-http-auth] enabled true port http,https filter nginx-http-auth logpath /var/log/nginx/error.log maxretry 5 findtime 300 bantime 86400重启Fail2bansudo systemctl restart fail2ban6. 运维、监控与故障排查实录部署完成只是开始日常的监控和问题排查同样重要。6.1 常用管理命令解封特定IPsudo fail2ban-client set jail名 unbanip IP地址例如sudo fail2ban-client set sshd unbanip 203.0.113.5手动封禁一个IPsudo fail2ban-client set jail名 banip IP地址查看所有日志sudo tail -f /var/log/fail2ban.log实时查看更详细的日志修改/etc/fail2ban/fail2ban.local中的loglevel INFO为loglevel DEBUG然后重启服务。调试完毕后记得改回来否则日志会暴涨。6.2 常见问题与解决方案速查表问题现象可能原因排查步骤与解决方案Fail2ban服务启动失败配置文件语法错误运行sudo fail2ban-client -t或sudo fail2ban-server --test检查配置。仔细检查jail.local特别是括号、引号是否成对。服务运行但IP不被封禁1. 过滤器不匹配日志2. 端口未正确配置3. 防火墙后端不匹配1.关键步骤使用sudo fail2ban-regex /var/log/你的日志路径 /etc/fail2ban/filter.d/对应过滤器.conf测试。观察输出是否有“Matched”行。2. 确认监狱中port设置是否正确过滤器中的端口正则是否匹配。3. 运行sudo fail2ban-client status sshd看“Currently failed”计数是否增加。如果不增加就是过滤器问题。如果增加但不封禁检查maxretry和findtime。4. 确认系统使用的防火墙iptables/nftables/firewalld与banaction配置一致。自己可信IP被误封1. 白名单未设置2. 密码多次输错1. 立即通过服务器控制台VNC登录检查并添加ignoreip。2. 使用unbanip命令解封自己。3.治本改用SSH密钥登录关闭密码登录。封禁规则在防火墙中看不到1. Fail2ban动作执行失败2. 查看的防火墙命令不对1. 检查fail2ban.log是否有错误信息。2. 对于iptables使用sudo iptables -L -n -v查看所有链。Fail2ban的链名通常是f2b-jail名。3. 对于firewalld封禁可能通过--direct规则或ipset实现查询命令不同。服务器重启后封禁列表丢失Fail2ban的封禁状态默认保存在内存中这是正常现象。Fail2ban设计如此重启后从零开始。持久化封禁列表需要额外配置如使用iptables-persistent保存防火墙规则或配置Fail2ban的dbfile。对于临时服务器影响不大对于生产服务器可以考虑配置持久化但更应关注为何会频繁重启。6.3 性能监控与优化日志轮转Fail2ban监控的日志文件如果过大可能会影响性能。确保系统的logrotate正常工作。数据库后端对于被封禁IP非常多上万级别的场景默认的文本数据库可能有效率问题。可以配置使用sqlite3作为后端修改dbfile参数但普通服务器完全不需要。资源占用通常Fail2ban占用内存和CPU极少。如果发现异常检查loglevel是否误设为DEBUG并检查过滤器正则表达式是否过于复杂。7. 安全加固的延伸思考部署了Fail2ban你的服务器安全等级提升了一大步但这远不是终点。安全是一个持续的过程。定期审计日志不要完全依赖自动化工具。每周或每月抽时间看一眼/var/log/fail2ban.log和/var/log/auth.log了解攻击趋势看看有没有新的攻击模式。更新规则关注Fail2ban社区的更新特别是filter.d目录下的规则文件。新的服务漏洞出现时相应的攻击模式也会更新。纵深防御Fail2ban是服务器层面的防御。结合网络层面的安全组云服务器、WAFWeb应用防火墙、以及应用本身的强密码策略、双因素认证等构建多层次的安全体系。备份与演练在修改任何安全配置尤其是SSH配置前确保你有另外的访问途径如云控制台。修改sshd_config后务必先开一个新会话测试能否登录再断开当前连接。最后我个人最深刻的体会是安全工具再好也比不上一个良好的安全习惯。对于SSH来说这个习惯就是使用密钥登录禁用密码登录并妥善保管你的私钥。Fail2ban是你忘记关闭密码登录时的一道坚实保险但别让它成为你懈怠的理由。从我的服务器被扫2000次到如今只有零星尝试这套组合拳下来睡眠都踏实了不少。
分享:

看完干货,该让你的企业上线了

免费需求沟通 · 48 小时内出具建站方案 · 河南本地可上门