不依赖 SSH 的同步通道:配置文件里那几个默认宽松的开关

一、换掉的不是命令写法,而是三件事的承担方
有一类增量同步工具,常规用法是走远程登录通道执行,靠既有的账号体系和密钥完成认证。另有一种用法是把同步服务以守护进程模式常驻跑起来:它监听一个固定端口(默认 873)、走自有协议,不依赖远程登录通道,配置分成全局段与模块段,密码文件的权限要求收到仅属主可读写,运行身份建议用不带家目录、登录 shell 设为不可登录的专用系统用户;排障时要先把防火墙与强制访问控制这两层干扰排除掉。
这条路的动机通常很实在:两侧没法互授系统账号、跨机房只想开一个端口、批量分发不想为每台机器配密钥。但它换掉的东西比看上去多。原来由账号体系承担的认证、由远程登录通道自带的加密、由登录审计留下的痕迹,在守护进程模式下全部换了承担方:认证变成配置文件里的一个模块开关加一份共享密码文件,加密变成”要么依赖外部隧道要么就是明文传输”,审计变成模块访问日志,而日志里能留下什么,取决于你有没有把格式写全。
默认值是宽松的。这是这类配置文件最容易出问题的地方:能跑起来的最小配置,通常正好是一个不需要凭据也能读、来源不限、日志什么都不记的服务。我们治理它的口径是:把这个端口当成一定会被扫到的暴露面来配置,而不是等真出事再收紧。端口号本身不是秘密,但把它写进方案时,要按这种暴露面假设来治理,不要假设没人注意。
二、两种模式的责任对照
| 责任项 | 走远程登录通道的同步 | 守护进程模式的同步服务 | 需要额外补的东西 |
|---|---|---|---|
| 认证主体 | 系统账号与密钥,能对应到人或者到具体部署身份 | 共享密码加来源地址限制 | 按来源与用途拆分密码,并建立分发台账 |
| 传输加密 | 通道自带,默认为加密链路 | 默认不加密,需要外部隧道或者只在可信网络内使用 | 明确网络边界与隧道方案,写明”跨不可信网络不得裸跑” |
| 审计入口 | 登录审计与命令记录 | 模块访问日志,字段由配置决定 | 日志格式包含来源、用户标识、动作、路径、结果 |
| 凭据管理 | 密钥轮换与分发有既有流程 | 密码文件本身成为关键资产 | 文件权限收紧、变更需审批、每次分发留记录 |
| 运行身份 | 由发起方的账号决定 | 由配置里指定的用户与组决定 | 专用系统用户加目录属主关系的核对 |
| 失败暴露 | 认证失败发生在登录层,容易发现 | 配置写错往往静默生效 | 用只读试探和日志核对做变更验收 |
这张表在我们内部的作用是限定评审问题。方案评审时不需要争论”这种模式安不安全”,只需要逐项问右列补了没有。凡是”传输加密”一格写”内网所以没事”的,我们会追问内网边界怎么定义、谁能在这一段接入。
三、模块段必须显式声明的八类开关
我们的规则是这八类不允许依赖默认值,每一项都要在模块配置里写出来,评审只查有没有写,不查”应该生效了”。
| 开关类别 | 要显式声明的内容 | 我们采用的安全默认 |
|---|---|---|
| 允许来源 | 可访问的客户端地址范围 | 按网段或者主机白名单收口,不写下不限来源的形式 |
| 读写属性 | 模块只读还是可写 | 默认只读,可写单独立模块并说明理由 |
| 是否可列出 | 客户端能否列出模块清单 | 关闭,模块清单本身是探测信息 |
| 路径根目录约束 | 是否把访问限制在目录根内 | 启用,避免路径解释差异带来的越界读写 |
| 运行身份 | 以哪个用户与组提供文件服务 | 专用低权限身份,且与目录属主关系明确 |
| 并发上限 | 允许的最大连接数 | 按容量给上限,防止遍历任务把主机拖满 |
| 带宽上限 | 单连接与总体速率 | 显式限速,避免抢占生产链路带宽 |
| 日志格式 | 记录哪些字段、日志落在哪里 | 记全来源、标识、动作、路径与结果,日志与主日志系统汇聚 |
这里有两个开关值得单独说。路径根目录约束不是装饰:不启用时,模块路径与实际访问路径之间的解释差异会随版本和用法变化,一旦和上面的”可写”叠加,风险就不是读多个文件而是改错文件。日志格式则常被留到”以后再加”,而事后补日志的代价是所有历史留证都为空,出事时只剩一句”当时没记”。
另外三条属于文件层面的纪律:密码文件的权限要收到仅属主可读写,并且这条要写进部署脚本而不是靠人工执行;文件本身要纳入备份与变更审批;任何把密码明文抄到工单、聊天或者运维笔记里的做法,都按凭据外泄处理。
四、共享密码让归因失效,专用用户决定能不能改文件
多人共用一个密码,后果不是”不够安全”这种抽象评价,是一个很具体的能力丧失:无法回答”谁在什么时候同步走了哪些路径”。日志里只有同一个标识,来源地址也可能被同一批机器共用,事后追责和变更核查都指不到具体动作。改法是按来源与用途拆分密码,一台机器、一条链路、一个用途一份,同时建一份分发台账,记密码对应的用途、接收方、生效与作废时间、轮换责任人。台账里的”作废”要有验证动作,删掉一行不代表客户端那侧已经不能访问。
运行身份这一格要看得比配置更细。专用系统用户的三点要求来自来源实践的表述:不建家目录、shell 设为不可登录、与所服务目录的属主关系决定它能不能改文件。第三点最容易被误解成”权限越大越省事”,实际相反:如果这个身份对目标目录只有读权限,可写模块就会以失败告终,于是有人直接把它加成目录属主,顺带给可写模块开了口子。正确做法是把只读和可写拆成两个模块,各自指向不同的目录归属,需要写的用途单独走审批。
五、危险参数组合、排障顺序与和生产线共存
最容易造成实际损失的组合是递归删除语义加上排除规则。同步任务的删除选项会清理目标侧源端不存在的内容,而排除规则让一部分文件在源端”不可见”,两者叠加的结果是目标侧那些被排除的内容被当成多余项删掉。这个失效是静默的,第一次发现往往是在恢复数据时。我们的硬规则有两条:任何带删除语义的任务,先用只读方式核对差异清单;生产任务之外先在一套演练副本上跑一遍,把核对结果留档,两份留档都过了才允许进生产。
排障顺序同样值得写成流程。这类服务出问题,第一层查端口与来源限制(防火墙规则、监听地址、来源白名单),第二层查强制访问控制(安全上下文与相关布尔值是否阻止了对目标目录的访问),最后一层才怀疑应用自身配置。顺序反过来的典型后果是改一堆配置去解决一个网络问题。这里有一条纪律要说明白:把强制访问控制临时切成宽容模式不是排障手段,它是一次新的暴露面变更;确认是不是这一层的问题,应该用日志和上下文标签比对,而不是先把防护关掉。
和生产线共存要靠限额而不是靠错峰自觉。除上面表格里的并发与带宽上限外,还要处理两件事:大目录遍历会冲击系统的元数据缓存,代价由同机上的业务进程承担,因此遍历型任务要避开业务高峰并有限速;同步窗口和备份窗口要设排他关系,两者叠在同一存储上时,先执行哪个、后到的那个要不要等,都要在计划任务里写清,而不是靠两边都不改。
六、日志要回答的三个问题、替代方案与上线前自查
模块访问日志的价值只有一句话:出事时能回答问题。我们要求它至少能回答三个。谁在什么时候从哪台机器取走了哪些路径,这是归因,靠的是标识、来源地址和路径字段。有没有失败与重试,这是数据完整性,靠的是结果字段,光有请求没有结果等于什么都没记。有没有非授权来源被拒绝,这是暴露面证据,需要在拒绝时也留记录,而不是直接丢包。
替代方案要放在同一张桌面上比。带远程登录通道的同步适合两侧能互授账号、审计要求跟着账号体系走的场景;对象存储适合同步方向单一、需要版本与生命周期管理、还要多消费方的场景;内网分发服务适合一对多的批量部署包分发。守护进程模式确实更合适的,是跨机房大量小文件的增量同步加上两侧无法互授系统账号这一类需求。选它的理由应当是这两条,而不是”配起来更快”。
上线前的暴露面自查清单,我们固定按下面这几条走:
- 端口是否只监听必要的地址,来源是否已收口,能否被外部网段直连;
- 匿名访问是否被彻底关闭,模块清单是否不可列出;
- 可写模块是否单独存在并有审批来源;
- 密码文件权限是否为仅属主可读写,是否有分发台账与作废验证;
- 运行身份是否无家目录、shell 不可登录,与目录属主关系是否逐项核对;
- 路径根目录约束是否启用;
- 并发与带宽上限是否已写;
- 日志是否覆盖请求与结果两类事件,是否汇入统一日志平台;
- 配置变更是否有只读试探的验收步骤,能否一键回退。
洹拓把这份清单当作这类同步服务的常备基线:新增模块时重跑一遍,而不是每次现编问题。配置文件里的宽松默认值不会因为服务跑了一段时间就自动收紧,能把它们管住的只有”必须显式声明”这条纪律,加上上线前那一次可复核的自查。