在不抓取内容的情况下定位被丢弃的 VPN 数据包
规则计数器与范围很窄的元数据日志可以在不归档用户所发内容的情况下定位被丢弃的 VPN 流。针对一次新请求比较一个计数器的差值。
当数据包匹配某条规则时,防火墙计数器就会增加,而且它并不保留该数据包。这足以回答大多数丢包排查中的第一个问题:这个流究竟有没有到达这条规则。抓取载荷回答的是另一个问题,而且它在运行期间会收集穿过该接口的其他所有内容。先从计数器开始,只有计数器含糊时再转向元数据日志。
计数器回答第一个问题
每条可能匹配的规则都有计数器,在测试前后读取它就能知道流量是否到达。这是两个数字的比较,而不是存档,在存储和暴露方面都没有任何代价。
用拥有这些规则的工具读取计数器:
iptables -L FORWARD -v -n --line-numbers
nft list ruleset差值就是证据。计数器不动的那条规则从未见过这个流,这指向更早的一处边界:错误的接口、错误的表,或者一条从未把数据包送到那里去的路由。计数器动了却仍然丢弃的规则,说明策略正在按写入的方式执行。
计数器无法告诉你的事
计数器给你一个数字,而不是原因。它无法区分按地址匹配的数据包和按端口匹配的数据包,也无法告诉你在两条相似规则中是哪一条抓住了该流。除非你读取拥有该计数器的那条规则,它也无法判断数据包是被丢弃、被拒绝,还是被接受后又在后面丢失。
这正是元数据日志的用武之地,而范围就是全部要点。为某个具体的测试流记录接口、方向、地址、协议和判定。这些字段能在不记录用户正在做什么的情况下定位失败的边界。
载荷日志回答的是另一个问题,而且它回答的是接口上所有人的情况。
范围很窄的元数据日志
写一条只匹配你的测试流的规则,给它一个醒目的前缀,并在平台自身的控制下限制速率,使普通的重试无法淹没存储。正是前缀让你能在设备记录的其他所有内容中找到自己的条目。
不要仅仅因为功能存在就启用载荷日志或不限量的数据包日志。截断的抓包也并不自动不含载荷,因为头部大小和数据包布局各不相同,所以看起来很小的抓取长度仍可能携带应用字节。
如果必须抓包,就只抓一个流,限定时间,并使用能回答你问题的最小抓取长度。
匹配一次新请求
生成沿着真实客户端路径的无害流量,然后比较前后相关的计数器。网关本地的测试可能完全漏掉一条转发规则,因为数据包从不走转发路径。已建立的会话也可能与新建连接走不同的状态处理,所以长生命周期的流不能替代一次新流。
给窗口设定时间范围并写下来。在指定的两分钟之间,从这个客户端地址,到这个协议上的这个目的地,才是诊断。今天早上某个时候,那只是搜寻。
一个流、一个窗口、一处边界,就是这里的进度单位。
清理干净,只保留摘录
调查结束后,通过所属配置删除临时诊断规则。一条狭窄的日志规则若留在原处,就会变成一套并非本意的记录系统,六个月后没人记得它为何存在。
策略要求时,私下保存原始记录,并分享经审阅的最小摘录,而不是整份抓包。即使没有载荷,地址、账户标识符和内部拓扑也是敏感的。把摘录当作有归属的文档。凡是诊断不需要的内容都要隐去。
目标是针对特定请求的特定失败边界。任何生成所有 VPN 使用者完整存档的做法,都已经超出了诊断,开始了另一个项目。在添加任何内容之前,先查看平台日志文档了解它默认记录什么。