自相矛盾的文档比写错的文档更危险:一次端口放行规则的横切审查
一个自相矛盾的文档
今天在给一个开源教学项目做文档审查时,发现了一种特别典型的文档缺陷:同一份文件里,两条相隔三百行的说明互相打架。
中文 README 第 87 行写着:
18092 / 19001:服务端内部组件 WebSocket(AgentServer / Gateway),常规部署无需对公网开放。
第 375 行给出的管理员放行命令却是:
New-NetFirewallRule -DisplayName "EduSwarm" -Direction Inbound `
-Protocol TCP -LocalPort 5173,18092,19000,19001,19200 -Action Allow
五个端口,把那两个"无需对公网开放"的内部端口一起开了。第 387 行的排障文案还补了一刀:“互动不实时 → WS 端口 19000/19001 未放行”,等于继续引导管理员去开 19001。
两条说法都是作者写的,都是善意写的,但它们不可能同时成立。
为什么这种缺陷比"写错了"更危险
写错一个数字,读者执行会失败,报错会把他推回来重新读。而自相矛盾的文档会成功执行,只是执行错了。
上面那条命令会顺利跑完,防火墙规则会加上,服务也能正常启动,测试也过。唯一的后果是:校园机房按网段放行的情况下,AgentServer 和 Gateway 的内部 WebSocket 也对同网段任意主机开放了。没有人会收到任何提示。
这是安全类文档缺陷的共性——错误的配置往往比正确的配置"更顺手"。少开一个端口可能页面打不开,多开几个端口什么都不会发生。所以靠"跑一下看看"是发现不了的。
这类矛盾的三个成因
成因一:两段话是不同时间写的。
端口约定通常是架构设计阶段写的,防火墙命令是部署踩坑之后补的。后者往往为了"一次解决所有连不上"而把所有端口一股脑放进去——它解决的是当时的故障,却没回头看前面的设计说明。
成因二:读者对象变了,文案没跟着变。
第 87 行是写给"理解架构的人"看的,讲的是端口职责;第 375 行是写给"照着做的管理员"看的,讲的是操作步骤。两段话的心智模型不同,作者写的时候没有互相校对。
成因三:排障文案的副作用。
第 387 行那句本意是好的——告诉用户"互动卡顿可能是端口没放行"。但它把 19001 和 19000 并列,读者自然会认为两个都要开。排障指引是最容易被照抄的部分,也是副作用最大的部分。
顺手查出的第二个问题
同一批文档里还有一处口径不一致,属于同一类毛病的轻症:
部署指南第 179 行的默认端口清单是五个:5173 / 18092 / 19000 / 19001 / 19200。
同一文件第 605 行的排障表格写的是四个:5173 / 18092 / 19000 / 19200。
漏了 19001。危害小得多——只是让读者在排查端口占用时少查一个——但它是同一个根因:同一份事实被写在多个地方,然后各处陆续漂移。
怎么系统地查出这类问题
一个一个读太慢,而且人会疲劳。我用的办法是按事实维度横向扫描,而不是按文件顺序纵向阅读。
具体到这次,我抓的是"端口"这一个维度:把所有文档里出现的四到五位数端口号连同上下文行一起提取出来,并列对比。
# 把所有 19000 段和 18000 段的端口出现位置连同行号抓出来
grep -n -E '\b(1[89][0-9]{3}|5173)\b' README_CN.md README.md docs/*.md
一屏就能看出哪个文件说了几个端口、哪一行漏了哪个。这比逐篇阅读快一个量级,而且不会漏。
同样的方法可以套到其他"事实维度"上:环境变量名、默认路径、依赖版本号、API 路径前缀。凡是同一个事实应该在多处一致的东西,都适合这样横切。
移植到写代码的场景也一样。我在同一个仓库里还做过一次类似扫描:提取 .env.example 里定义的所有变量名,再去 grep 代码里实际读取的变量,两边做差集。结果能直接看出"文档里有但代码不读"和"代码读但文档没写"两类问题。
修复应该长什么样
找到矛盾只是第一步,改法同样重要。我在这条 Issue 里给出的方案是分层的:
第一层,把默认命令改成最小集。 只开放浏览器真正需要的那三个:
-LocalPort 5173,19000,19200
第二层,为真实场景留出口,但加上约束。 确实要多机部署时,单独给一条命令,并要求限制来源:
-RemoteAddress 192.168.1.0/24
关键在于把"限制来源"写进命令本身,而不是写在旁边的说明文字里。写在文字里,抄命令的人会跳过。
第三层,同步修排障文案。 把"19000/19001 未放行"改成"19000 未放行"。这一步容易被忽略,但排障指引被照抄的概率最高,必须和新口径对齐。
第四层,补齐缺失的那一处清单。 部署指南第 605 行加上 19001。
一条给自己的规则
我现在给文档提 Issue 时,会先问一个问题:这个修复如果只改一处,会不会让另一处变得更矛盾?
这次的答案是会——如果只改防火墙命令而不改排障文案,读者会遇到"命令里没有 19001,但排障说 19001 要开"的新矛盾。所以四处必须一起改。
文档缺陷的特殊之处就在这里:它不是孤立的错误,而是一组事实之间的一致性被破坏了。修一处不修另一处,等于制造新的不一致。
同理,写文档时最该警惕的也不是写错字,而是同一个事实写了第二遍。每写一遍,就多一个将来会漂移的点。能用链接引用就别复制,非复制不可的话,至少把它们放在相邻的位置——相隔三百行的两句话,作者自己也不会去校对。
- 点赞
- 收藏
- 关注作者
评论(0)