4. 日志采集与传输安全

日志只有在被安全地采集和传输到后端时才有价值。我见过太多团队,花大价钱搭了分析平台,却在采集链路上开了个口子——日志被篡改、被窃听,甚至被中间人替换掉。说白了,你分析的都是假数据,那还查个什么劲?

4.1 采集链路上的核心威胁

日志从产生到入库,通常经过三个环节:日志源 → 采集代理 → 传输网络 → 接收服务。每个环节都有可能被攻击。我个人习惯把它列成一张表,方便排查时快速对照:

环节 常见攻击手法 后果
日志源 本地权限提升、日志文件删除/伪造 丢失关键证据,被注入假日志
采集代理 代理被篡改、配置泄漏、凭证盗用 日志外泄,或代理被当作跳板
传输网络 中间人攻击、嗅探、重放、丢包注入 日志机密性、完整性、可用性全毁
接收服务 伪造源地址、拒绝服务、证书伪造 存储被污染,分析结果不可信

你会问:为什么传输网络是最大短板?因为日志通常走的是可被拦截的以太网或公网,攻击者只要卡在一个交换机上就能旁路抓包。嗯,这也就是我当年在一个金融客户的日志平台上踩过的坑——他们的 Syslog 居然用明文 UDP 跑在办公网段,结果隔壁部门投诉收到大量乱码,后来发现是有人在网口注入伪造日志。从那以后,我就把传输加密放在了第一优先级。

4.2 传输加密:TLS 是底线

说白了,任何走公网或不可信网络的日志采集,必须启用 TLS。即使是内部网络,我也建议做。为什么呢?因为内部网络的“信任”往往不堪一击——一个 ARP 欺骗就能让流量拐走。

  • 双向认证:不仅客户端验证服务端证书,服务端也要求客户端出示证书。我曾在项目中用这种方式防止未授权的采集器接入。
  • 证书轮换:证书过期导致日志断流,是个非常低级的故障。建议用 ACME 或自动化脚本每 90 天轮一次。
  • 密码套件:禁用 TLS 1.0/1.1,禁用 RC4、CBC 模式。现在稳妥的做法是 TLS 1.2+ 搭配 AES-GCM。
我的一个小习惯:配置日志采集时,顺手把 tcpdump 抓 10 个包看一眼。如果看到“Client Hello”后面跟着一堆弱套件,就说明配置有问题。我曾经就这样堵住过一个测试环境的漏洞。

4.3 完整性校验:别让日志被静默替换

加密只解决机密性,不保证完整性。攻击者虽然看不懂日志内容,但可以把整段密文替换成另一段合法的密文(比如重放上一段日志)。为了防这个,我们需要在日志条目里嵌入一个 HMAC 或数字签名。

举个例子,对于基于 JSON 的日志,我会在发送前计算一个 SHA256-HMAC,密钥由采集器和接收器共享:

// 发送端
payload = {
  "timestamp": "2025-03-21T10:00:00Z",
  "event": "login_failed",
  "user": "admin",
  "hmac": hmac.new(secret_key, json.dumps(payload_raw).encode(), 'sha256').hexdigest()
}

// 接收端
received_hmac = payload.pop("hmac")
computed_hmac = hmac.new(secret_key, json.dumps(payload).encode(), 'sha256').hexdigest()
if received_hmac != computed_hmac:
    reject("日志被篡改或重放")

这么做有个附加好处:可以顺便防止日志重放。因为 HMAC 计算时带上时间戳,只要接收端检查时间戳在合理窗口内(比如 ±5 分钟),就能把重放攻击挡住。我在一个 IoT 日志采集项目中就用这个方案,挡掉过一波自动化扫描脚本的注入。

4.4 采集代理的身份与授权

代理本身就是一个可执行程序,它必须被严格管理。我曾经遇到过一个客户,他们的日志采集器用同一个 跑在几百台服务器上,结果一台服务器被攻破,key 泄漏,攻击者直接伪造海量日志把分析集群打挂了。

我建议至少要做这几件事:

  1. 每个代理独立凭证:可以用证书,也可以搭配 Vault 或 K8s ServiceAccount 。
  2. 最小权限原则:采集器只能发日志,不能收配置,更不能执行命令。
  3. 定期轮换密钥:结合自动化,密钥泄漏后 24 小时内失效。
  4. 审计代理行为:记录采集器上线、下线、发送速率突变等情况,异常时自动隔离。
警示:有些开源采集器(比如 Filebeat、Fluentd)默认使用明文 API 端点。部署在公网时,必须配反向代理加 TLS,否则等于把日志裸奔在互联网上。我曾经帮过一个 SaaS 公司,他们就是忘了在 ELK 前面加反向代理,结果搜索引擎里能直接搜到他们的日志 JSON 文件……

4.5 实战清单:构建安全日志传输基线

下面这张清单是我自己一直沿用的,每部署一套新环境就跑一遍:

  • 启用 TLS 1.2+,禁用所有弱加密套件。
  • 服务端证书由内部 CA 签发,客户端证书分发使用独立通道。
  • 每个采集代理配置唯一 client_cert + key,key 文件权限设为 600。
  • 传输协议采用 TCP 或 RELP(必要时用 WebSocket over TLS)。
  • 日志条目内嵌 HMAC 校验值,接收端验证后存储。
  • 接收端设置速率限制、白名单 IP、连接数上限。
  • 所有采集器日志(自身运行日志)单独走加密通道发到另一个审计域。

4.6 本章核心架构图

下面这张图涵盖了日志从源到存储的安全链路,以及各节点对应的防护措施。你可以把它当作排查时的对照挂图。

日志采集传输安全架构 日志采集传输安全架构图 日志源 应用/DB/系统 采集代理 Filebeat/Fluentd TLS传输通道 双向证书校验 接收服务 Logstash/RSyslog 存储与分析 ES/S3/ClickHouse 明文/本地套件 TLS加密 解密+校验HMAC 持久化 威胁点 窃听 / 篡改 / 重放 安全措施 ① 双向证书认证 ② HMAC完整性校验 ③ 独立代理凭证

4.7 一些避坑提醒

最后分享几个我亲手踩过的坑,希望能帮你省点时间:

  • 证书链不完整:客户端只发了终端证书,服务端没有中间 CA 证书,导致握手失败。检查时用 openssl s_client -connect host:port -showcerts 看全链。
  • 时间不同步:证书验证依赖系统时间,NTP 没配好,证书明明有效却被判过期。我曾经半夜被叫起来处理“全量日志中断”,最后发现是内网 NTP 服务器挂了。
  • UDP 幻觉:很多人觉得日志丢几条无所谓,所以用 UDP 发 Syslog。但一旦流量大了,UDP 丢包率可能高达 10%,而且无法溯源谁丢的。我见到的所有生产事故里,用 UDP 传日志最后都后悔了。
  • 密钥硬编码:HMAC key 写死在代码里,一泄露就要全局改。用配置中心或环境变量注入,并且定期刷新。
一句话总结:日志采集和传输的安全,本质上是信任链的建立。每一步都要问自己——我凭什么相信这个日志是真的?证书、HMAC、独立凭证,三者缺一不可。