4. 来源IP的获取:日志采集、NetFlow/sFlow、PCAP解析、API接口
说到来源IP,我们都知道它是异常检测的基石。但问题来了——IP从哪里来?
我早期做安全运营时,接手过一个告警:说某内网IP在疯狂扫端口。当时监控平台挂了,日志也丢了。我愣是翻了三天的防火墙连接表,才把这个IP揪出来。
那次之后,我养成了一个习惯:搞清数据怎么来,比怎么分析更重要。因为你再牛的分析算法,碰到坏数据也是白搭。
4.1 日志采集——最原始但也最可靠的方式
说白了,日志就是每个设备自己写的“流水账”。谁在什么时间干了什么,通常都记在里面。
我最常用的是各类服务器的访问日志。比如Nginx的access.log,每行都有客户端IP、请求时间、请求URL、状态码。
4.1.1 典型的日志结构
拿Web服务器举例,一行日志长这样:
192.168.1.100 - - [10/Oct/2024:13:55:36 +0800] "GET /admin/login.php HTTP/1.1" 403 2345 "-" "Mozilla/5.0"
你看,第一个字段就是来源IP。但这里有个坑——如果经过反向代理或CDN,这个IP可能不是真正的客户端IP。遇到这种情况,我建议去查X-Forwarded-For字段。
| 类型 | 常见格式 | 关键字段 |
|---|---|---|
| Apache/Nginx访问日志 | combined格式 | 客户端IP、时间、请求行、状态码 |
| syslog | RFC 5424 | Facility、Severity、App-Name、Msg |
| Windows Event Log | EVTX | EventID、Source、User、IP Address |
4.1.2 采集实践
我个人习惯用Filebeat + Logstash做采集管道。Filebeat负责读文件、发数据,Logstash负责解析。
# Filebeat配置示例
filebeat.inputs:
- type: log
paths:
- /var/log/nginx/access.log
output.logstash:
hosts: ["192.168.1.10:5044"]
日志采集最怕的是 时间不同步。我曾经排查一个攻击链,发现A日志和B日志的时间差了3分钟。最后发现是服务器时区没对齐。所以,建议统一使用UTC+0或统一NTP服务器。
4.2 NetFlow/sFlow——网络设备自己的日记本
你想想看,交换机、路由器每天都在转包。它能不能告诉你流量去了哪?能。这就是NetFlow。
NetFlow说白了就是网络设备自己记的“日志”。记录谁找谁、用了啥端口、传了多少数据包。sFlow呢?它是采样式的,更适合超大规模网络。
4.2.1 关键字段对比
| 字段 | NetFlow v5/v9 | sFlow v5 |
|---|---|---|
| 来源IP | ✓ | ✓ |
| 目的IP | ✓ | ✓ |
| 源端口 | ✓ | ✓ |
| 协议号 | ✓ | ✓ |
| 包数量/字节数 | ✓ | ✓ |
| 采样率 | 1:1(设备全量) | 1:N(典型值1:4096) |
4.2.2 我在项目中踩过的坑
有一次客户说流量监控看不到某个IP的攻击流量。我排查了很久,发现是NetFlow的采样率设置太高,导致短连接被漏掉了。
后来我在采集器加了校验:如果流量异常但NetFlow无记录,就触发一次临时PCAP抓包。这就是多源校验的思路,回头我们讲到异常检测时还会用上。
流日志虽然轻量,但无法还原应用层内容。遇到HTTP攻击、SQL注入等,流日志只能告诉你“谁找谁”,说不出具体干了什么。这时候还是得靠PCAP。
4.3 PCAP解析——最全的数据,但也是最笨的数据
PCAP就是直接抓包。你把数据包原封不动抓下来,然后解析每个包的IP头。
用Python做PCAP解析,我最推荐scapy和dpkt。scapy胜在灵活,dpkt胜在轻量快速。
4.3.1 基础解析代码
from scapy.all import rdpcap, IP
def extract_src_ips(pcap_file):
packets = rdpcap(pcap_file)
src_ips = set()
for pkt in packets:
if IP in pkt:
src_ips.add(pkt[IP].src)
return src_ips
# 使用示例
ips = extract_src_ips("capture.pcap")
print(f"发现 {len(ips)} 个不同的来源IP")
4.3.2 性能问题与优化
我解析过一个200GB的PCAP文件。直接用scapy的rdpcap,跑了3小时,内存爆了。后来改用PcapReader按包流式读取,15分钟搞定。
from scapy.all import PcapReader, IP
def extract_src_ips_chunked(pcap_file):
src_ips = set()
with PcapReader(pcap_file) as reader:
for i, pkt in enumerate(reader):
if IP in pkt:
src_ips.add(pkt[IP].src)
if i % 1000000 == 0:
print(f"已处理 {i} 个包...")
return src_ips
- 日志采集:适合非实时、准静态的异常检测,如暴力破解分析
- NetFlow/sFlow:适合流量基线监控、DDoS检测
- PCAP解析:最全面,适合取证和深度分析
4.4 API接口——新一代的数据获取方式
这几年云原生起来了,很多流量走容器、走服务网格。你没法在Kubernetes节点上装tcpdump?可以用API啊。
比如云平台的安全组日志API、CDN厂商的边缘日志API、SIEM平台的查询API,都可以直接获取来源IP。
4.4.1 一个REST API示例
import requests, json
def fetch_src_ips_from_api(api_url, , start_time, end_time):
headers = {"Authorization": f"Bearer {}"}
payload = {
"filter": {
"time_range": {"start": start_time, "end": end_time}
}
}
resp = requests.post(api_url, headers=headers, json=payload)
data = resp.json()
# 假设返回格式中有 source_ips 字段
return data.get("source_ips", [])
4.4.2 注意认证和限流
API接口通常有频率限制。我踩过这个坑:写了一个脚本批量拉24小时数据,跑了1000次请求就被封了IP。
后面我加了个自适应退避算法:发现429错误后,指数退避重试。并且按批次拆分请求,每次不超过API要求的最小间隔。
4.5 我推荐的数据源选择策略
怎么选?其实没有标准答案。我的策略是——三层混合:
- 第一层:实时告警。用NetFlow/sFlow做基线,超过阈值立刻报。
- 第二层:深度分析。收到告警后,回查日志(API或日志采集),确认IP详情。
- 第三层:取证。如果确认是攻击,去翻PCAP做完整还原。
数据源之间可以互补,但不能完全替代。
日志告诉你“谁访问了哪个页面”,但不知道路径之外的扫描;
流日志告诉你“谁找了哪个端口”,但不知道那是什么协议的内容;
PCAP最全,但存储成本高、性能开销大。
建议根据检测场景选择主要数据源,再辅以其他源做验证。