恢复 hosts 文件的 VPN 任务会抹掉后续编辑
连接时快照 hosts 文件、断开时还原,中间做的所有编辑都会丢失。与其用快照,不如给每条映射一个所有者。
连接任务复制 Windows 的 hosts 文件并追加一个私有地址,断开任务再把保存的版本复制回去。它能正常跑上几周,然后某天下午,机器访问不了一个与 VPN 毫无关系的内网站点。还原只是照做:它把别人编辑之前的文件放了回去。问题出在模型上,不在复制命令里。
任何先快照共享文件、之后再还原的流程,都会把中间发生的每一次改动继承为一次丢失。
事后还原的备份不是当下的备份
走一遍常见顺序。任务保存文件并为隧道追加一条记录。之后管理员加了一条无关的修正,第二个配置文件也加了自己的记录。断开时,还原把最初的快照放回去,第二个配置文件的记录和管理员的修正一起消失。两者都不属于 VPN,现在都没了。
单一固定的备份文件名让情况更糟。后一次连接事件可能把已被改动的文件复制到所谓的原件上,于是恢复基线朝着最后一次事件时的文件样貌漂移。
每个事件都是通知,不是事务
由事件触发的任务是通知。重连、被中断的关机或第二个配置文件,都能在早先的任务还在写的时候重塑所需状态。没有任何东西把两者串行化,也没有任何东西回滚写到一半的改动。单凭一个事件标识符,也说不清它属于哪个配置文件——除非有提供者和它的数据。把任务当事务,正是失败的那个假设。
重复的连接事件是另一半:不做检查的追加会造出第二条一模一样的记录,于是一些解析器对同一个名字看到两个答案。
给每条映射一个所有者
hosts 文件里的每一行只把主机名映射到地址,并不说明哪个隧道正在运行。如果自动化不可避免,就为 VPN 管理的映射指定一个所有者。该所有者只更新自己的记录,保留无关的现有内容,在重复事件下避免重复,并对照真正活动的连接来对账,而不是对照一份记住的清单。
当两条活动隧道需要同一条映射时,一次断开不能在另一方仍需要它的时候把它删掉。这需要引用计数或显式的归属记录,而不是一个布尔值。
备份对经过复核的恢复仍有价值。它不该是断开时的常规动作,也不该是文件内容的唯一记录。
当条件式 DNS 才是真正的需求
如果真正的需求是一个只在隧道运行时才解析的私有命名空间,hosts 就是错误的机制。Windows NRPT 可以为命名空间选择解析器,而它本身并不创建地址记录;解析器仍然得给出答案。那是另一种设计、另一个所有者,并且彻底免除了每次切换都要改文件。
如果出于某种原因保留 hosts 只服务一个固定服务,请确保它的地址在预期路由上仍可达、主机名保持稳定,好让应用的身份校验继续有效。清 DNS 缓存修不好下一次查询又会读到的陈旧记录。
测试重复连接、两个同时存在的配置文件,以及一次无关编辑之后的断开。结果应当是:VPN 的映射跟着它的所有者走,而不把机器其余部分倒回去。