firewall-cmd --set-log-denied=all 是启用 firewalld 拒绝日志的关键开关,需配合 --reload 生效;日志默认输出至 /var/log/messages 或 /var/log/syslog,推荐用 journalctl 过滤或 rsyslog 分流至独立文件,并用 awk/grep 高效分析。

firewall-cmd --set-log-denied=all 是关键开关
firewalld 默认不记录任何 DROP 或 REJECT 流量,必须显式开启。只执行 firewall-cmd --set-log-denied=all 就能启用全量拒绝日志——注意这不是临时命令,它会写入永久配置(/etc/firewalld/firewalld.conf 中的 LogDenied 项),但需配合 firewall-cmd --reload 才生效。
常见错误是只运行了 --set-log-denied=all 却忘了 reload,结果日志始终为空;或者误用 --add-log-prefix(该参数仅影响用户自定义 rich rules 的日志前缀,对默认拒绝无作用)。
-
--set-log-denied=unicast更轻量,只记录单播包,适合生产环境长期开启 -
--set-log-denied=off关闭时记得 reload,否则残留日志仍可能产生 - 验证是否生效:运行
firewall-cmd --get-log-denied,输出应为all或unicast
日志默认写进 /var/log/messages,但别直接 tail 它
firewalld 拒绝日志通过 kernel 日志机制(netfilter)输出,经 rsyslog 转发,默认落盘到 /var/log/messages(RHEL/CentOS)或 /var/log/syslog(Debian/Ubuntu)。但直接 tail -f /var/log/messages 会混入大量无关系统消息,难以定位。
更可靠的方式是用 journalctl 过滤:
-
journalctl -u firewalld -f | grep "FINAL_REJECT"—— 实时看被拒绝的连接 -
journalctl -u firewalld --since "2 hours ago" | grep "_DROP"—— 查最近两小时丢弃包 - 注意:systemd-journald 默认不持久化日志,重启后旧日志丢失;如需长期保留,需启用
Storage=persistent并创建/var/log/journal
用 rsyslog 把 firewalld 日志单独切到 /var/log/firewalld.log
把所有拒绝日志塞进 /var/log/messages 会污染主日志、增大轮转压力,也妨碍审计。rsyslog 可按日志内容精准分流。
操作步骤:
- 新建
/etc/rsyslog.d/firewalld.conf,写入两行::msg, contains, "_DROP" /var/log/firewalld.log:msg, contains, "_REJECT" /var/log/firewalld.log - 每行末尾加
& stop防止重复写入其他文件(例如:& stop) - 确保
/var/log/firewalld.log存在且权限正确:touch /var/log/firewalld.log && chown root:root /var/log/firewalld.log - 重启服务:
systemctl restart rsyslog firewalld
之后所有拒绝日志只进 /var/log/firewalld.log,干净、可预测、方便 logrotate 管理。
分析日志时 awk 和 grep 组合比人工翻查快十倍
原始日志条目像这样:kernel: DROP: IN=ens3 OUT= MAC=... SRC=192.168.1.100 DST=10.0.0.5 PROTO=TCP SPT=54321 DPT=22。手动提取源 IP、协议、目的端口效率极低。
一个实用的单行分析命令(适配 IPv4):
awk '/_DROP/ && /SRC=/ && /DPT=/ {split($10,a,"="); split($17,b,"="); split($19,c,"="); if (a[2] !~ /^0\.0\.0\.0$/ && a[2] !~ /^127\.0\.0\.1$/) print a[2] " -> " b[2] "/" c[2]}' /var/log/firewalld.log | sort | uniq -c | sort -nr | head -10
要点说明:
- 过滤掉本地回环和空源地址(避免干扰)
- 用
split()提取字段比硬编码$N更健壮(字段位置可能因内核版本微调) - IPv6 地址需额外处理(
SRC=fe80::...),若需支持,加!~ /^fe80::/判断 - 高频攻击源往往集中在少数几个 IP+端口组合,这个命令能立刻暴露 top 10 攻击模式
真正难的不是记录日志,而是让日志可读、可筛选、可持续维护——尤其当 /var/log/firewalld.log 每天增长几百 MB 时,没预设好过滤逻辑和轮转策略,很快就会填满磁盘或让 awk 命令卡死。











