Skip to content

📝 日志记录与分析

为什么要记录日志?

防火墙默默丢弃了数据包,但你想知道到底丢了什么。没有日志的防火墙就像没有监控的工厂——出了问题只能猜。

iptables 的 LOG 目标可以在丢弃前记录数据包信息到 /var/log/kern.log/var/log/messages

LOG 目标详解

bash
# 基本日志记录
iptables -A INPUT -j LOG --log-prefix "IPT-INPUT-DROP: " --log-level 4

# 常用日志级别
# 0 = emerg    1 = alert   2 = crit    3 = err
# 4 = warning  5 = notice  6 = info    7 = debug

# 只记录特定端口的流量(别什么都记,日志会爆炸)
iptables -A INPUT -p tcp --dport 22 -m conntrack --ctstate NEW \
  -j LOG --log-prefix "SSH-NEW: " --log-level 4

# 限制日志速率(防止日志风暴拖垮系统!)
iptables -A INPUT -m limit --limit 5/min --limit-burst 10 \
  -j LOG --log-prefix "IPT-DROP: " --log-level 4

# 记录无效包
iptables -A INPUT -m conntrack --ctstate INVALID \
  -j LOG --log-prefix "INVALID: " --log-level 4

# 分别记录不同服务的拒绝(方便排查)
iptables -A INPUT -p tcp --dport 3306 -j LOG --log-prefix "MYSQL-BLOCKED: "
iptables -A INPUT -p tcp --dport 6379 -j LOG --log-prefix "REDIS-BLOCKED: "
iptables -A INPUT -p tcp --dport 27017 -j LOG --log-prefix "MONGO-BLOCKED: "

⚠️ 注意: ⚠️ 重要:LOG 后面不要跟 DROP/REJECT!LOG 只是"记录",不会终止规则链的处理。正确用法是在 LOG 前面匹配,LOG 之后的规则会继续匹配(通常后面跟一条 DROP)。

查看和分析日志

bash
# 实时查看防火墙日志
tail -f /var/log/kern.log | grep IPT

# 查看最近 100 条被拒绝的连接
journalctl -k --since "1 hour ago" | grep "IPT-DROP" | tail -100

# 统计被拒绝最多的 IP(Top 10 攻击者)
journalctl -k | grep "IPT-DROP" | \
  grep -oP 'SRC=\K[0-9.]+' | sort | uniq -c | sort -rn | head -10
  15234 185.220.101.34
   8921 45.155.205.12
   3201 192.168.1.200
   ...

# 分析哪些端口被扫描最多
journalctl -k | grep "IPT-DROP" | \
  grep -oP 'DPT=\K[0-9]+' | sort | uniq -c | sort -rn | head -10
  23001 445
  18923 3389
   5421 22
   2100 3306
   ...

# 查看特定 IP 的所有日志
journalctl -k | grep "185.220.101.34" | tail -20

# 一键导出分析报告
echo "=== iptables 日志分析报告 ===" > /tmp/ipt-report.txt
echo "时间: $(date)" >> /tmp/ipt-report.txt
echo "" >> /tmp/ipt-report.txt
echo "--- Top 10 被拒 IP ---" >> /tmp/ipt-report.txt
journalctl -k --since "24 hours ago" | grep "IPT-DROP" | \
  grep -oP 'SRC=\K[0-9.]+' | sort | uniq -c | sort -rn | head -10 >> /tmp/ipt-report.txt
echo "" >> /tmp/ipt-report.txt
echo "--- Top 10 被扫端口 ---" >> /tmp/ipt-report.txt
journalctl -k --since "24 hours ago" | grep "IPT-DROP" | \
  grep -oP 'DPT=\K[0-9]+' | sort | uniq -c | sort -rn | head -10 >> /tmp/ipt-report.txt
cat /tmp/ipt-report.txt

用 rsyslog 分类存储

iptables 日志混在系统日志里不好找?用 rsyslog 把它单独存一个文件:

bash
# 创建 rsyslog 规则
cat > /etc/rsyslog.d/iptables.conf << 'EOF'
:msg, contains, "IPT-" /var/log/iptables.log
& stop
EOF

# 重启 rsyslog
systemctl restart rsyslog

# 配置 logrotate 防止日志撑爆磁盘
cat > /etc/logrotate.d/iptables << 'EOF'
/var/log/iptables.log {
    daily
    rotate 7
    compress
    missingok
    notifempty
    postrotate
        systemctl restart rsyslog
    endscript
}
EOF