VPN 上的 rsync:873 守护端口与 SSH 模式之争
873 端口是隧道承载的内部服务,而不是它的替代品。分清守护进程模式与 SSH 模式,然后只打开你实际使用的那条路径。
在隧道接口上放行 TCP 873 并不会让 rsync 穿过 OpenVPN,也不会让对端接受该模块。隧道承载的是一条内部连接,其协议与目的地规则完全保持原样。因此第一个问题不是该开哪个端口,而是 rsync 建立的是哪一类连接。下文都假定隧道已经建立,存疑的只是内部服务。
判断 rsync 实际建立的是哪一类连接
命令里的远端参数通常在任何防火墙改动之前就回答了这个问题。双冒号或 URL 方案选择守护进程模式,而主机名之后的单冒号选择远端 shell。请读你真正在运行的那个参数,而不是文档示例里的那个。
显式的远端 shell 选项可能再次改变答案,因为它告诉 rsync 为传输启动哪个程序。请读整条命令行,包括继承来的包装脚本,而不只是主机部分。
| Remote argument | What it opens |
|---|---|
rsync://vault.corp.internal/archive/ | rsync daemon, normally TCP 873 |
vault.corp.internal::archive/ | rsync daemon, normally TCP 873 |
[email protected]:/srv/archive/ | Remote shell, normally SSH on its configured port |
守护进程模式:绑定地址、模块与端口
在守护进程语法里,路径段指的是配置好的模块,而不是磁盘上的目录。模块口令只有在连接被接受之后才会校验,而模块还可能被设为只读或从列表中隐藏。读错误信息时这个顺序很重要,因为连接被拒与模块被拒是两个不同阶段的失败。两条消息都不会告诉你隧道本身出了什么问题。
独立守护进程可以在配置文件里绑定到隧道地址,这样无需任何防火墙规则就能让它远离公网接口。该值必须在守护进程绑定前就存在,而由 socket 激活或由 inetd 管理的监听器可能完全忽略它。
address = 10.44.0.1
port = 873
[archive]
path = /srv/archive
read only = yes
然后用私有地址而不是公网名称去测试。公网主机名会解析成 WAN 地址并走另一条路径,即使同一台机器对两者都应答。
rsync --list-only rsync://10.44.0.1/archive/
远端 shell 模式:SSH 承载传输
使用单个冒号时,rsync 会启动远端 shell 程序并在该通道上使用其协议,因此唯一可达的服务就是服务器所监听端口上的 SSH。rsync 守护进程根本不会运行,873 端口无关紧要,访问决策变成了 SSH 账户决策。此时远端路径是真实文件系统路径,由另一侧的 shell 解释。这就是为什么针对 873 的防火墙改动对这种模式毫无作用。
这种设计需要 一个已授权的账户和主机密钥校验,并且继承 SSH 自身的认证策略。当传输必须跨越不可信网络时,这通常是更好的选择,因为加密属于为此而生的协议。带口令提示的守护进程并不是同一回事。
只打开你选择的那条路径
模式确定之后,在承载隧道的那一个接口上放行那一个内部服务。按接口、源地址池和目的地址收紧规则,以免后来的默认拒绝改动悄悄把它放宽。随后再检查规则顺序,因为链中更靠前的放行规则会让这条窄规则形同虚设。
如果守护进程运行在 VPN 网关之后的机器上而不是网关本身,网关还需要一条转发路径,目标也需要自己的许可与回程路由。只在网关上开端口,会得到一个被接受却无处可去的连接。
用你打算在生产中使用的同一模式与目的地从客户端验证。成功的列表同时证明了监听器、路由和规则;超时指向路径问题,拒绝则指向监听器。
ufw allow in on tun0 from 10.44.0.0/24 to 10.44.0.1 port 873 proto tcp
ss -ltnp | grep 873