半夜收到SSH爆破告警,登上去敲fail2ban-client status sshd,返回的currently banned是0,可日志里密码失败的行数已经排了几百行。服务在跑,一条都没封,这两件事可以同时成立。先看客户端列出来的jail名字,名字不在列表里,说明这条规则根本没启用。
这几项都不用改配置就能核实,只有收阈值那一项要动文件。核一遍的代价是几分钟,改错一次要重启服务、再从头排查一轮,所以先把不动手的部分做完,再动配置。
第一处看jail有没有真启用。jail.conf是发行版自带的模板,改它当下能生效,包管理升级时会整份覆盖,改动会丢,官方给的做法是另建jail.local写自己的段。真正让这条jail不进列表的是enabled,段里没显式写true,或者写成false,重启后客户端列出jail时看不见它。
第二处看logpath指错没有。日志文件按发行版分,Debian/Ubuntu系是auth.log,RHEL/CentOS系是secure。系统并不在写这个文件的时候,把这一项改成backend = systemd,让jail去读journal。日志文件全都不存在,默认配置下启动会直接报Have not found any log file,这条jail起不来。所以启动之后先翻一眼它自己的日志。
第三处是过滤规则的正则和日志格式对不上。把sshd的日志级别调到不记录认证失败、或者系统把时间戳换成了带T的ISO格式,原来的datepattern就认不出行首,失败次数一条都数不到。换过SSH端口的,jail里的port得跟着改,否则封的还是22。装fail2ban时一起装上的fail2ban-regex,把日志文件和过滤器名传进去。输出里matched为0,说明问题在正则不在阈值;没匹配的行也会统计,行数一多只给一句too many to print,要看具体的行得加--print-all-missed。
第四处是maxretry、findtime、bantime三个值配得太松。以默认值为例,十分钟内失败满五次就封,对方五分钟才试一次,十分钟里最多三次,够不到那条线。这三个数是默认值,按你的实际攻击频率定,别照抄。动手之前先在DEFAULT段写一行ignoreip,把127.0.0.1/8和自己的运维IP列进去,保存重启后确认这条白名单已经生效。没有它,把maxretry调小,先被封住的可能是你自己的运维IP。
改完重启服务。重启前先用fail2ban-client -d把合并后的配置打出来,确认这条jail最终的backend和logpath跟你写的一致;-t在部分老版本里没有,能用就用,不能用就用-d核对。重启后立刻用fail2ban-client status sshd确认jail回来了,currently banned和total banned都在正常打印,服务没起来就把上一次的jail.local退回去。total banned在涨而currently banned一直是0,说明封完又解开了,bantime设得太短。还有一处容易忽略,云厂商的安全组在上游就把连接拦掉了,fail2ban看到的失败记录本来就少。
正则通了之后再收阈值。记录数一条都数不出来时,maxretry调到多低都不会触发,封不封与阈值无关。命中数先弄正常,再去动findtime和bantime,两处改动都写进jail.local,别改模板文件。
A5创业网 版权所有