12个优秀平面设计素材网站,广州白云区有什么好玩的,国家官方网站,建设工程质量检测网站1. 为什么你的服务器总被“敲门”#xff1f;聊聊fail2ban的防护逻辑 不知道你有没有过这样的经历#xff1a;某天登录服务器#xff0c;用 lastb 命令一看#xff0c;好家伙#xff0c;几百上千条来自全球各地的失败登录记录#xff0c;IP地址五花八门。这就是典型的暴力…1. 为什么你的服务器总被“敲门”聊聊fail2ban的防护逻辑不知道你有没有过这样的经历某天登录服务器用lastb命令一看好家伙几百上千条来自全球各地的失败登录记录IP地址五花八门。这就是典型的暴力破解攻击攻击者用自动化脚本拿着常见的用户名密码组合一遍又一遍地“敲门”试图撞开你服务器的门。放任不管轻则系统日志被刷爆消耗资源重则万一密码设置得简单真被撞开了那服务器就成了别人的“肉鸡”数据泄露、服务被挟持后果不堪设想。手动封IP不现实。攻击IP可能来自成百上千个地址而且还在不断变化。这时候你就需要一个自动化的“保安”——fail2ban。我用了它快十年了从早期的VPS到现在管理几十台生产服务器它一直是我安全防线里最可靠的一环。简单来说fail2ban就是个“日志分析员”兼“防火墙管理员”。它24小时不间断地帮你盯着系统日志比如SSH、Nginx、FTP的日志一旦发现某个IP在短时间内有多次失败的登录尝试或者其他你定义的可疑行为它就立刻行动调用系统防火墙比如iptables或firewalld把这个IP给“拉黑”一段时间禁止它继续访问。听起来是不是很简单但它的强大之处就在于这种“监控-分析-行动”的自动化闭环。你不用再半夜爬起来看日志、加防火墙规则fail2ban帮你全干了。而且它非常灵活你可以定义什么样的行为算“攻击”、多少次算“频繁”、封禁多久。从简单的SSH防护到复杂的Web应用防护它都能胜任。接下来我就带你从零开始手把手搭建并调教好这个“智能保安”让你服务器的安全等级提升好几个档次。2. 从安装到基础配置5分钟搭建你的第一道防线2.1 安装fail2ban一条命令的事fail2ban在主流Linux发行版的软件仓库里都有安装起来毫不费力。根据你的系统选择对应的命令就行。对于像Ubuntu、Debian这样的系统打开终端执行sudo apt update sudo apt install fail2ban -y对于CentOS、Rocky Linux、AlmaLinux等CentOS 8/RHEL 8以后推荐用dnf# CentOS 7 / RHEL 7 sudo yum install epel-release sudo yum install fail2ban -y # CentOS 8 / RHEL 8 / Fedora sudo dnf install epel-release sudo dnf install fail2ban -y安装完成后系统会自动启动fail2ban服务并设置为开机自启。你可以用sudo systemctl status fail2ban命令看一下状态显示active (running)就说明它已经在后台默默守护你了。2.2 理解核心概念监狱Jail、过滤器Filter与动作Action在动手配置前花两分钟理解一下fail2ban的三个核心概念后面配置起来就不会迷糊了。过滤器Filter 定义“什么是攻击”。它本质上是一组正则表达式用来在日志文件中匹配出失败、错误或可疑的记录。比如SSH的过滤器会去匹配日志里像“Failed password for invalid user”这样的行。fail2ban自带了很多常见服务sshd, apache, nginx等的过滤器存放在/etc/fail2ban/filter.d/目录下。动作Action 定义“发现攻击后做什么”。最常见的就是调用iptables/firewalld添加一条DROP规则。动作配置文件在/etc/fail2ban/action.d/目录。除了封IP你还可以配置动作去发送邮件通知你或者调用自定义脚本。监狱Jail 把过滤器和动作组合起来并加上执行规则就形成了一个“监狱”。它告诉fail2ban监控哪个日志文件logpath使用哪个过滤器filter触发条件是什么maxretry, findtime满足条件后执行哪个动作action以及封禁多久bantime。2.3 创建你的第一个防护策略保护SSH服务fail2ban的主配置文件是/etc/fail2ban/jail.conf。但官方强烈建议不要直接修改它因为系统更新时这个文件可能会被覆盖。正确的做法是创建或修改jail.local文件这里的设置会覆盖主配置文件。我们先来做一个最基础的SSH防护配置。假设我们希望在10分钟600秒内如果同一个IP地址尝试登录SSH失败5次就封禁它1小时。# 首先复制一份本地配置文件如果已有jail.local这步可跳过 sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local然后用你喜欢的编辑器如nano或vim打开/etc/fail2ban/jail.localsudo nano /etc/fail2ban/jail.local找到文件中和[DEFAULT]以及[sshd]相关的部分。我们通常把通用设置放在[DEFAULT]区域把针对SSH的特定设置放在[sshd]区域。你可以这样设置[DEFAULT] # 默认的封禁时间秒-1代表永久封禁这里我们先设1小时 bantime 3600 # 查找失败尝试的时间窗口秒这里设10分钟 findtime 600 # 在findtime时间内允许的最大失败次数 maxretry 5 # 监听的IP地址范围一般不需要改 ignoreip 127.0.0.1/8 ::1 # 使用的防火墙后端一般自动识别无需修改 banaction iptables-multiport [sshd] # 启用这个监狱 enabled true # 监控的日志文件路径通常默认即可fail2ban知道SSH日志在哪 # logpath %(sshd_log)s # 端口默认是ssh的22端口如果你改了SSH端口这里一定要改 port 22重点解释一下这几个参数bantime 3600 违规IP会被关进“小黑屋”3600秒1小时。时间到了自动释放。如果你想给个严厉警告可以设成86400一天。极度不推荐新手一开始就设置bantime -1永久封禁万一自己输错密码或者IP变动把自己锁在外面就尴尬了。findtime 600和maxretry 5 这是一个组合条件。意思是系统会检查“最近600秒内”的日志。如果同一个IP的失败次数累计达到5次就触发封禁。这比“累计5次就封”更合理避免了长时间积累的误操作导致封禁。ignoreip 这里列出的IP或网段将不会被封禁。务必把你的办公室IP、家庭IP或可信的服务器IP加进来格式如ignoreip 127.0.0.1/8 ::1 192.168.1.0/24 203.0.113.5。配置完成后保存文件然后重启fail2ban服务让配置生效sudo systemctl restart fail2ban2.4 检查成果看看你的“保安”是否在岗重启后怎么知道它工作了呢用这几个命令查看fail2ban服务状态sudo systemctl status fail2ban确保是active (running)。查看sshd监狱的状态这是最直观的。sudo fail2ban-client status sshd你会看到类似这样的输出Status for the jail: sshd |- Filter | |- Currently failed: 0 | |- Total failed: 12 | - File list: /var/log/auth.log - Actions |- Currently banned: 1 |- Total banned: 3 - Banned IP list: 45.123.456.789Currently failed 当前处于findtime时间窗口内的失败次数。Total failed 过滤器匹配到的总失败次数。Currently banned/Banned IP list 当前正在被ban的IP数量和列表。看到这里有IP就说明已经有“倒霉蛋”撞到枪口上了验证防火墙规则 fail2ban最终是通过操作防火墙来封IP的。你可以用以下命令查看iptables规则如果用的是firewalld命令不同sudo iptables -L -n或者更精确地查看fail2ban创建的链sudo iptables -L f2b-sshd -n你应该能看到被ban的IP地址出现在REJECT或DROP规则的目标中。3. 进阶实战应对复杂场景与深度定制基础配置只能防住简单的SSH爆破。现实中攻击面更广场景也更复杂。比如你的网站后台、数据库端口、甚至通过Nginx转发的服务都可能成为目标。这就需要我们进行深度定制。3.1 场景一防护Nginx后的Web应用如WordPress登录很多人的网站用Nginx做Web服务器。攻击者会疯狂尝试wp-login.php或/admin等路径进行爆破。fail2ban可以监控Nginx的错误日志或访问日志来防御。步骤1为Nginx创建自定义过滤器在/etc/fail2ban/filter.d/目录下创建一个新文件比如nginx-wp-login.confsudo nano /etc/fail2ban/filter.d/nginx-wp-login.conf写入以下内容。这个过滤器会匹配到访问wp-login.php且返回状态码为200说明登录页面存在正在尝试登录的请求并从中提取IP。[Definition] failregex ^HOST -.*POST.*/wp-login\.php.* 200 ignoreregex 注意这是一个简化示例。更严谨的过滤器可能会结合404、200等多种状态码并排除搜索引擎爬虫的User-Agent。你可以根据实际日志格式调整正则表达式。步骤2在监狱配置中启用它编辑/etc/fail2ban/jail.local在文件末尾添加一个新的监狱配置[nginx-wp-login] enabled true port http,https filter nginx-wp-login logpath /var/log/nginx/access.log maxretry 5 findtime 300 bantime 86400 action %(action_mwl)sport http,https 封禁该IP访问80和443端口即整个网站。logpath 你的Nginx访问日志路径根据实际情况修改可能是/var/log/nginx/access.log或/www/wwwlogs/access.log。action %(action_mwl)s 这是一个组合动作表示不仅封禁IPaction_还会发送邮件m通知并记录到日志wl。你需要先配置好系统的邮件发送功能。步骤3测试过滤器在重启服务前强烈建议用fail2ban-regex工具测试一下你的过滤器是否正确sudo fail2ban-regex /var/log/nginx/access.log /etc/fail2ban/filter.d/nginx-wp-login.conf这个命令会解析日志文件并告诉你过滤器匹配到了多少行。如果匹配数符合预期说明正则写对了。步骤4重启并检查sudo systemctl restart fail2ban sudo fail2ban-client status nginx-wp-login3.2 场景二处理Nginx TCP/UDP端口转发如转发SSH这是原始文章里提到的一个非常经典且棘手的场景。很多朋友为了安全或者绕过某些限制会改用Nginx来代理转发SSH的22端口。比如外部连接服务器的2345端口Nginx收到后转发给本机127.0.0.1的22端口。这样做带来的问题是所有SSH登录尝试在系统日志/var/log/auth.log里源IP都变成了127.0.0.1fail2ban自带的sshd过滤器就完全失效了因为它无法看到真实的攻击者IP。解决方案监控Nginx的TCP/UDP代理日志。步骤1确保Nginx记录了真实IP首先你的Nginx TCP/UDP代理配置必须能记录客户端真实IP。在Nginx的stream模块配置中使用$remote_addr变量log_format tcp_proxy $remote_addr [$time_local] $protocol $status $bytes_sent $bytes_received $session_time $upstream_addr; access_log /var/log/nginx/tcp-access.log tcp_proxy;步骤2编写针对代理日志的过滤器假设你的日志格式如上并且代理的是SSH。创建过滤器文件/etc/fail2ban/filter.d/nginx-tcp-ssh.confsudo nano /etc/fail2ban/filter.d/nginx-tcp-ssh.conf内容如下正则表达式需要根据你的实际日志格式微调[Definition] failregex ^HOST \[.*\] TCP 200 .* 127\.0\.0\.1:22 .* .* .*$ ignoreregex 这个正则的意思是匹配日志中转发目标为127.0.0.1:22且状态为200成功建立连接的行并提取行首的HOST即真实客户端IP。这通常对应一次成功的TCP代理连接建立。你可以把它理解为“有人通过Nginx连接到了本机的SSH端口”。然后我们再结合SSH自身的认证失败日志但需要另一个过滤器关联或者直接认为频繁建立这种连接就是攻击行为来封禁。更精确的做法是分析后端SSH服务的认证失败日志但这需要更复杂的配置。一个更实用的简化策略是监控Nginx代理日志中对转发端口的高频连接。这虽然不是百分百准确可能误伤扫描器或某些合法客户端但对于防御暴力破解连接非常有效。步骤3配置监狱在jail.local中添加[nginx-tcp-ssh] enabled true filter nginx-tcp-ssh logpath /var/log/nginx/tcp-access.log maxretry 10 # 允许的尝试次数可以稍高因为这是连接频率 findtime 60 # 60秒内 bantime 3600 port all # 注意port all 会封禁该IP的所有端口访问慎用 # 或者指定端口 port 2345 (你的Nginx代理端口) action %(action_)s这里port all是个大杀器意味着一旦触发该IP将无法通过任何端口访问你的服务器。在内部网络或确信是攻击的情况下可以使用。生产环境建议先设为具体的代理端口进行观察。步骤4重启与测试同样重启服务后用fail2ban-client status nginx-tcp-ssh查看状态。3.3 高级技巧白名单、多动作与日志轮转精细化白名单ignoreip 除了在[DEFAULT]段设置全局白名单你还可以在每个监狱Jail里单独设置ignoreip。比如你的监控服务器需要频繁访问某个端口可以把它单独加入该监狱的白名单。使用多动作action_mwl 前面提到的action_mwl很好用。但你需要先配置好系统的邮件发送。可以安装sendmail或postfix并在jail.local的[DEFAULT]段设置destemail your-emailexample.com sender fail2ban-alertyourserver.com mta sendmail这样每次有IP被封禁你都会收到一封邮件内容包含被封IP、主机名、监狱名和相关的日志片段。处理日志轮转logrotate Linux系统通常会轮转日志如auth.log变成auth.log.1。fail2ban默认能很好地处理这种情况。但如果你自定义了日志路径确保fail2ban有读取权限。有时需要手动告诉fail2ban重新加载日志文件sudo fail2ban-client reload JAIL_NAME。封禁到Cloudflare防火墙扩展动作 如果你的网站接了Cloudflare可以封禁IP到Cloudflare的防火墙实现边缘网络层的封禁。这需要编写自定义的action文件调用Cloudflare API。社区已经有现成的脚本可以参考这能让防护效果提升一个维度。4. 运维管理监控、解封与故障排查配置好了不是就一劳永逸。日常运维中你需要知道怎么查看状态、处理误封和排查问题。4.1 常用管理命令一览表把这些命令存下来用的时候非常方便命令作用示例sudo fail2ban-client status查看所有启用的监狱状态sudo fail2ban-client status jail名查看指定监狱的详细状态sudo fail2ban-client status sshdsudo fail2ban-client ping测试fail2ban服务是否响应返回pong即正常sudo fail2ban-client set jail unbanip IP解封某个IPsudo fail2ban-client set sshd unbanip 192.168.1.100sudo fail2ban-client set jail banip IP手动封禁某个IPsudo fail2ban-client set sshd banip 123.456.789.0sudo fail2ban-client reload重载所有配置服务不需重启sudo fail2ban-client reload jail重载指定监狱配置sudo fail2ban-client reload nginx-wp-loginsudo fail2ban-client stop停止fail2ban服务临时关闭防护sudo fail2ban-client start启动fail2ban服务注意手动封禁banip是即时生效且不受bantime参数限制的默认是永久封禁。除非你手动解封否则它会一直存在。所以这个命令要慎用。4.2 如何优雅地解封与避免误伤误封是难免的尤其是当你的策略设置得比较激进时。我遇到过几次同事因为连续输错密码被锁在外面。临时解封 使用上面的unbanip命令。解封前最好先grep一下日志确认这个IP是不是真的在暴力破解。比如grep 192.168.1.100 /var/log/auth.log。永久免封白名单 确认是合法IP后最稳妥的办法是把它加到ignoreip列表里然后重启fail2ban。调整策略 如果误封频繁考虑调整maxretry调高、findtime调短或bantime调短。一个温和的策略如10分钟内失败10次封1小时比激进策略1分钟内失败2次封1天更适合大多数场景。查看详细日志 fail2ban自己的日志在/var/log/fail2ban.log。当你不确定为什么某个IP被封时可以在这里找到答案sudo tail -f /var/log/fail2ban.log关注NOTICE级别的日志你会看到类似[sshd] Ban 123.456.789.0的记录。4.3 常见问题与踩坑记录fail2ban重启后封禁列表丢失这是最常见的问题之一。默认情况下fail2ban的封禁状态是保存在内存中的。服务重启iptables规则就没了。解决方案使用iptables-persistent或firewalld的永久规则功能或者更推荐的是在jail.local的[DEFAULT]段启用数据库持久化[DEFAULT] dbfile /var/lib/fail2ban/fail2ban.sqlite3 dbpurgeage 7d这样封禁信息会存到数据库重启后可以恢复。封禁不生效按顺序检查服务状态systemctl status fail2ban监狱状态fail2ban-client status sshd看Currently banned是否有IP。防火墙规则iptables -L -n检查对应链如f2b-sshd里是否有该IP的DROP/REJECT规则。过滤器是否匹配用fail2ban-regex工具测试你的日志和过滤器。最容易被忽略的一点如果你的服务器前面有云服务商的安全组/防火墙需要在控制台放行fail2ban所使用的协议通常是TCP和端口默认是0:65535不对fail2ban操作的是本机防火墙不影响安全组。但安全组规则会优先于本机防火墙生效。如果攻击IP被云防火墙拦了根本到不了你服务器fail2ban也就看不到日志。性能影响大吗对于日志量不大的个人服务器或中小型网站fail2ban的性能消耗微乎其微。它定期默认是1秒扫描日志尾部的新增内容而不是全量扫描。对于日志量巨大的服务可以调整[DEFAULT]下的datepattern和扫描频率。说到底fail2ban是一个“基于异常检测”的被动防御工具。它不能防止零日漏洞也无法应对分布式低频攻击。它的价值在于用极低的成本和复杂度自动化地处理掉互联网上那些“噪音”级别的、自动化脚本发起的普通攻击为你省下大量精力并显著提高服务器的基线安全水平。把它作为你安全体系中的一环配合强密码、密钥登录、定期更新、最小化开放端口等好习惯你的服务器就能在充满“敲门声”的网络中安然入睡。