关键在于构建可追溯、易筛选、不丢失、结构化的日志链路:一、iptables log规则须前置并启用--log-prefix、--log-tcp-options、--log-ip-options;二、调大kernel.log_buf_len至8mb,rsyslog开启$actionfileenablesync on;三、filebeat采集/var/log/iptables.log,logstash用grok解析src、dst、proto等字段供elk分析。

要在 Linux 中用 iptables -j LOG 记录足够详细、可被 ELK 有效分析的非法访问日志,关键不是“加一条规则”,而是构建一套可追溯、易筛选、不丢失、结构化程度高的日志采集链路。下面从规则配置、内核与日志系统调优、ELK 接入三方面讲清楚实操要点。
一、iptables LOG规则必须前置且带全量上下文字段
LOG 目标本身不终止匹配流程,但若放在 DROP/REJECT 后面,包已被丢弃,根本不会执行 LOG。所以规则顺序必须是:先 LOG,再阻断。
- 错误写法(LOG 不生效):
iptables -A INPUT -p tcp --dport 22 -j DROPiptables -A INPUT -p tcp --dport 22 -j LOG --log-prefix "SSH-DROP: " - 正确写法(推荐用 -I 插入链首,确保早匹配):
iptables -I INPUT -p tcp --dport 22 -m state --state NEW -j LOG \--log-prefix "SSH-ATTEMPT: " \--log-tcp-options \--log-ip-options \--log-uid - 关键参数说明:
•--log-prefix:必须设置,便于后续用 rsyslog 过滤或 Logstash 提取 tag;
•--log-tcp-options:记录 MSS、SACK、Timestamp 等,识别扫描工具或畸形握手;
•--log-ip-options:捕获 Loose Source Route 等非常规 IP 选项,常见于探测行为;
•--log-uid:仅 OUTPUT 链或本地发起连接时可用,对 INPUT 意义有限,可省略。
二、避免日志丢失:调大内核缓冲 + 强制 rsyslog 实时落盘
默认 printk 缓冲区仅 64KB,攻击流量突增时日志直接被丢弃,且无提示。rsyslog 默认批量刷盘,断电即丢数据。
- 增大内核日志缓冲(临时):
sudo sysctl -w kernel.printk_ratelimit=0sudo sysctl -w kernel.printk_ratelimit_burst=10000sudo sysctl -w kernel.log_buf_len=8388608(8MB,需重启后永久生效需写入 /etc/sysctl.conf) - 强制 rsyslog 实时写入磁盘(编辑 /etc/rsyslog.conf 或新建 /etc/rsyslog.d/iptables.conf):
$ActionFileDefaultTemplate RSYSLOG_TraditionalFileFormat$ActionFileEnableSync on:msg, contains, "SSH-ATTEMPT:" /var/log/iptables.log& stop - 重启服务:
sudo systemctl restart rsyslog
三、对接 ELK:用 Filebeat 抓取 + Logstash 做轻量解析
ELK 本身不直接读内核日志,需通过日志文件中转。建议将 iptables 日志单独输出到 /var/log/iptables.log,再由 Filebeat 收集。
- Filebeat 配置片段(/etc/filebeat/filebeat.yml):
filebeat.inputs:- type: filestreamenabled: truepaths:- /var/log/iptables.logfields:log_type: iptables - Logstash filter 示例(提取关键字段):
filter {if [fields][log_type] == "iptables" {grok { match => { "message" => "%{SYSLOGTIMESTAMP:timestamp} %{HOSTNAME:hostname} kernel: %{DATA:prefix}: IN=%{DATA:in_intf} OUT=%{DATA:out_intf} MAC=%{DATA:mac} SRC=%{IP:src_ip} DST=%{IP:dst_ip} LEN=%{NUMBER:len} TOS=%{DATA:tos} PREC=%{DATA:prec} TTL=%{NUMBER:ttl} ID=%{NUMBER:id} PROTO=%{DATA:proto} SPT=%{NUMBER:spt} DPT=%{NUMBER:dpt} WINDOW=%{NUMBER:window} RES=%{DATA:res} SYN ACK FIN RST URGP=%{NUMBER:urgp}" } }date { match => [ "timestamp", "MMM d HH:mm:ss", "MMM dd HH:mm:ss" ] }}} - Kibana 中可按
src_ip、proto、dpt、prefix等字段聚合分析,例如统计 TOP10 扫描 IP 或高频目标端口。
四、进阶建议:结合 ipset 封禁 + 日志联动告警
单纯记录不够,要形成“检测→记录→封禁→告警”闭环。
- 用 ipset 管理恶意 IP 列表,避免 iptables 规则膨胀:
ipset create badips hash:ipiptables -I INPUT -m set --match-set badips src -j DROP - 在 Logstash 或 ElastAlert 中设置规则:当
prefix包含 "SSH-ATTEMPT" 且 5 分钟内出现 ≥20 次,触发告警并自动调用脚本将src_ip加入 ipset。 - 注意:不要在 iptables 规则里直接用
-m recent替代 LOG,它无法提供 TCP/IP 头部细节,不利于深度分析。











