在Debian系统上用iptables记录可疑网络包并联动日志分析,核心思路就是在iptables规则链末尾加一条LOG动作的规则,把匹配到的异常流量写入内核日志,再通过rsyslog或journalctl收集这些日志,最后用fail2ban、logwatch或者自定义脚本做自动化分析和告警。这套方案不需要额外装复杂的安全平台,原生工具就能搭起来,适合中小型服务器和运维人员快速落地。
很多人以为iptables只能做"放行"或"丢弃",其实它的LOG目标动作非常强大。你可以针对特定端口、特定源IP、特定协议甚至特定包大小设置记录规则,把所有"看起来不对劲"的流量全部捕获下来。关键在于规则顺序——LOG规则必须放在DROP或REJECT规则之前,否则包被丢弃了就没机会记录了。
一、iptables记录可疑包的具体规则写法先说最实用的几条规则。假设你的服务器对外开放了SSH(22端口)和HTTP(80端口),其他端口都应该关闭。那么第一步就是把所有未明确允许的入站流量记录并丢弃:
iptables -A INPUT -m state --state NEW -p tcp ! --dport 22 -j LOG --log-prefix "IPTABLES-DROP-NEW: " --log-level 4 iptables -A INPUT -m state --state NEW -p tcp ! --dport 80 -j DROP
上面两条规则的意思是:所有新建立的TCP连接,如果目标端口不是22也不是80,先记录一条日志(前缀是IPTABLES-DROP-NEW),然后直接丢弃。--log-level 4对应的是warning级别,在syslog里会被记录下来。
再来一个针对暴力破解的规则。如果你发现有人在疯狂尝试SSH登录,可以限制频率并记录:
iptables -A INPUT -p tcp --dport 22 -m limit --limit 5/min --limit-burst 10 -j LOG --log-prefix "SSH-BRUTE: " --log-level 4 iptables -A INPUT -p tcp --dport 22 -m limit --limit 5/min --limit-burst 10 -j ACCEPT iptables -A INPUT -p tcp --dport 22 -j DROP
这组规则的逻辑是:每分钟超过5个新连接且突发超过10个的SSH请求会被记录,正常范围内的放行,超出的直接拒绝。你可以根据实际情况调整limit参数。
还有一种常见场景是记录ICMP洪水攻击。Ping泛洪虽然老套但依然有效,加上记录规则:
iptables -A INPUT -p icmp --icmp-type echo-request -m limit --limit 10/sec -j LOG --log-prefix "ICMP-FLOOD: " --log-level 4 iptables -A INPUT -p icmp --icmp-type echo-request -m limit --limit 10/sec -j ACCEPT iptables -A INPUT -p icmp --icmp-type echo-request -j DROP
这些规则写好之后,用iptables-save保存,确保重启后依然生效:
iptables-save > /etc/iptables/rules.v4
在Debian上,你需要安装iptables-persistent来实现开机自动加载:
apt-get install iptables-persistent netfilter-persistent save二、配置rsyslog收集iptables日志
iptables的LOG动作默认把日志发到内核日志通道(kern.warning),在Debian上这些日志会被rsyslog接收。你需要确认rsyslog的配置文件/etc/rsyslog.conf或/etc/rsyslog.d/目录下的文件是否开启了kern相关的记录。
一般来说,Debian默认的rsyslog配置已经包含了kern.*这一行。如果没有,手动加上:
kern.* /var/log/kern.log
重启rsyslog服务让配置生效:
systemctl restart rsyslog
这时候你可以用tail命令实时查看iptables记录的日志:
tail -f /var/log/kern.log | grep "IPTABLES"
你会看到类似这样的输出:
Dec 15 10:23:45 server kernel: [12345.678] IPTABLES-DROP-NEW: IN=eth0 OUT= SRC=192.168.1.100 DST=10.0.0.1 PROTO=TCP DPT=445
这条日志清楚地告诉你:来自192.168.1.100的主机试图访问你服务器的445端口(SMB服务),被记录并丢弃了。这种信息对后续分析非常有价值。
三、用journalctl做快速查询和过滤Debian 10及以上版本默认使用systemd的journald来管理日志。你可以直接用journalctl按优先级或前缀过滤iptables相关日志:
journalctl -k --grep="IPTABLES" --since "1 hour ago" journalctl -k --grep="SSH-BRUTE" --since today
-k参数表示只看内核日志,--grep做文本过滤,--since限定时间范围。这比直接翻/var/log/kern.log高效得多,尤其是日志量大的时候。
如果你想统计某个时间段内被记录的可疑包数量,可以这样:
journalctl -k --grep="IPTABLES-DROP-NEW" --since "2024-12-01" --until "2024-12-15" | wc -l
这个命令会告诉你过去两周内有多少个可疑连接尝试被拦截了。数字如果突然飙升,说明你的服务器正在被扫描或攻击。
四、联动fail2ban实现自动化封禁光记录日志还不够,最好能自动把反复攻击的IP封掉。fail2ban就是干这个的。它会监控你指定的日志文件,当某个IP在设定时间内触发超过阈值的规则,就自动在iptables里加一条DROP规则。
安装fail2ban:
apt-get install fail2ban
创建自定义过滤规则/etc/fail2ban/filter.d/iptables-custom.conf:
[Definition] failregex = IPTABLES-DROP-NEW: .* SRC=<HOST> ignoreregex =
然后在/etc/fail2ban/jail.local里配置对应的jail:
[iptables-custom] enabled = true filter = iptables-custom action = iptables-multiport[name=CustomBan, port="all", protocol=tcp] logpath = /var/log/kern.log maxretry = 5 findtime = 600 bantime = 3600
这段配置的意思是:在10分钟内如果同一个IP触发了5次IPTABLES-DROP-NEW记录,就自动封禁这个IP一个小时。你可以根据自己的安全策略调整maxretry和bantime。
重启fail2ban生效:
systemctl restart fail2ban
查看当前被封禁的IP列表:
fail2ban-client status iptables-custom五、用logwatch或自定义脚本做深度分析
fail2ban解决了实时封禁的问题,但你还需要定期做趋势分析。logwatch是一个轻量级的日志分析工具,可以每天生成一份摘要报告:
apt-get install logwatch logwatch --detail high --range today --service iptables --mailto admin@example.com
它会把当天iptables相关的日志汇总,包括哪些IP被记录最多、哪些端口被扫描最频繁,然后发邮件给你。
如果你想要更定制化的分析,可以写一个简单的Shell脚本,每天定时运行,统计并生成报告:
#!/bin/bash LOGFILE="/var/log/iptables-report-$(date +%Y%m%d).txt" echo "=== iptables Suspicious Traffic Report - $(date) ===" > $LOGFILE echo "" >> $LOGFILE echo "Top 10 Source IPs:" >> $LOGFILE grep "IPTABLES-DROP-NEW" /var/log/kern.log | grep -oP 'SRC=\K[0-9.]+' | sort | uniq -c | sort -rn | head -10 >> $LOGFILE echo "" >> $LOGFILE echo "Top 10 Target Ports:" >> $LOGFILE grep "IPTABLES-DROP-NEW" /var/log/kern.log | grep -oP 'DPT=\K[0-9]+' | sort | uniq -c | sort -rn | head -10 >> $LOGFILE echo "" >> $LOGFILE echo "Total blocked connections today:" >> $LOGFILE grep -c "IPTABLES-DROP-NEW" /var/log/kern.log >> $LOGFILE cat $LOGFILE
把这个脚本放到/usr/local/bin/下,然后用cron每天凌晨执行一次,就能持续掌握服务器的安全态势。
六、注意事项和优化建议第一,LOG规则会消耗内核资源。如果你的服务器流量很大,不要对所有包都加LOG,只针对你关心的端口和协议加。每秒几千条LOG会明显影响性能。
第二,日志文件会越来越大。一定要配置logrotate来轮转/var/log/kern.log,Debian默认已经配好了,但你最好确认一下/etc/logrotate.d/rsyslog里的设置是否合理。
第三,iptables规则是有顺序的。LOG规则一定要放在DROP之前,而且要放在你希望匹配的具体规则之后。可以用iptables -L -n --line-numbers查看当前规则的顺序和编号,用iptables -I INPUT 3插入到指定位置。
第四,如果你的服务器同时跑了ufw或firewalld,要注意规则冲突。Debian上如果装了ufw,建议要么统一用ufw管理,要么把ufw关掉直接用iptables,避免两套规则互相打架。
第五,记录的日志只是第一步。真正有价值的是长期积累数据后做关联分析。比如某个IP今天扫了445端口,明天扫了3389,后天扫了23,这种跨端口的扫描模式用脚本一分析就能识别出来,比单看一条日志有用得多。
总结一下,这套方案的完整链路是:iptables LOG规则捕获可疑流量 → rsyslog/journald收集日志 → fail2ban实时封禁 + logwatch/自定义脚本定期分析。全部用Debian原生工具链实现,不依赖第三方商业软件,维护成本低,扩展性好。对于大多数Linux服务器管理员来说,这是性价比最高的安全监控方案之一。
