pull-filter 匹配的是文本,不是网段:把它当作前缀来读
过滤器把每个被推送选项的开头与你的文本作比较。缺少一个空格、前面一条过宽规则以及用错动作,会产生不同的故障。
本意是丢掉一条被推送的路由。改动之后,另一个路由选项不见了,或者客户端在循环重连。两种结果都来自把过滤器当成网段规则来读,而它比较的是文本。客户端只检查被推送的选项是否以你给出的字符开头,任何环节都没有地址运算参与。
过滤器实际比较的是什么
每个被推送的选项都以一行的形式到达,由名称及其参数组成。过滤器把你的字符与这一行的开头作比较,此时任何地址都还没有被解析,任何路由也还没有被安装。因此,为某个名称写下的规则会命中所有以这些字母开头的选项,而不只是你正看着的那一个。这就是为什么过滤器单独看似乎正确,却仍会删掉不相干的东西。
看起来像网段的字符串仍然只是字符。它不选择任何前缀,不对网络位做运算,也无法表达一组目的地。当这样的规则看似有效、后来又失效时,被推送的文本通常已经变了样子。
一个空格就会改变匹配集合
同一个选项名,末尾带分隔符与不带分隔符选中的是不同的行。不带分隔符时匹配保持开放,带上之后选项名必须在参数开始之前正好在那里结束。
pull-filter ignore "route"
pull-filter ignore "route "
开放形式也会命中仅仅以相同字母开头的选项,于是 不相干的路由行为就跟着你想丢掉的那条路由一起消失了。写过滤器之前,先从日志里复制被推送的那一行。把未修改的配置文件副本放在改过的副本旁边,因为从文件里撤回一条过宽的匹配比凭记忆容易。
顺序和动作会产生不同的症状
规则按顺序求值,第一个匹配决定结果,所以放在前面的过宽规则会让后面每一条具体规则都无法到达。动作也会改变故障形态:忽略匹配会把选项丢掉、会话继续,而拒绝会抛出错误并重启连接。因此,一条被反复推送的行再配上拒绝动作,就会造成重连循环。这种循环很容易被误读成网络故障,而日志中标出被匹配选项的那一行,正是区分两者的关键。
| Action | Effect on the session | How it gets reported |
|---|---|---|
| Ignore | Option dropped, session continues | Something is missing afterwards |
| Reject | Error raised, connection restarts | The VPN keeps dropping |
记下哪一行匹配了、执行的是哪个动作。被丢掉的路由和重启循环需要不同的修法,记录应当写明发生了哪一种,而不是把两者都留成可能性。
检查主机实际安装了什么
重新连接后读取已应用的路由,并同时测试你想保留的目的地和你想移除的那个。丢掉一条被推送的路由并不会提供替代,所以不想要的那条路由消失后,某个资源可能沿另一条路径变得不可达。如果某个名称现在解析到了别处,就检查被推送的解析器选项是否被同一条过宽前缀命中。改动通过了你跑的测试、却通不过你本意要跑的测试,在这里是常见结果。
把这一差别记进工单:你移除的路由、你期望保留的路由,以及表现在显示的内容。下一次改动将以这份记录为评判依据。
不要把它当作信任边界
对文本的过滤器是配置上的便利,而不是对不可信服务器的控制手段。仅仅格式上的差异就能击败它,所以手册限定了这一说法。当服务器属于你的组织时,修正推送策略比累积本地例外更清楚。
写下本地过滤器究竟为何存在,好让下一个人判断它是否仍然需要。过滤器会在理由消失很久之后继续堆积。