scp 在两台不同 SSH 端口的远程主机之间复制时连错端口
远端到远端复制需要分别表达两端的 SSH 端口。使用独立 Host 配置和本地 -3 中转,核对有效端口,并区分连接、认证与 SFTP 子系统故障。
两台远程主机分别使用 SSH 端口 2222 和 2200,从本机执行远端到远端的 scp,却出现 port 22: Connection refused,或者把一端的端口用到了另一端。把两个 -P 分别塞在源地址和目标地址旁边,也不能可靠地表达“两端各用一个端口”。
-P 是 scp 的命令选项,不是给紧挨着它的一个路径附加端口。两端使用不同连接参数时,应分别描述两个目标,而不是把整条命令当成两段独立调用。
下面采用本地中转的方式,针对 OpenSSH 9.0 及之后默认使用 SFTP 的 scp,两端都需要提供可用的 SFTP 服务。本机必须能访问两端的 SSH 端口并完成各自认证。旧 SCP 协议和让源主机直接连接目标的模式,认证位置与限制不同,不与这里混用。
为两端分别设置地址、账号和端口
先保存已有 ~/.ssh/config,加入两个不与现有配置重名的专用别名。示例不是整个配置文件,不要覆盖原有身份文件、跳板机或其他必要设置:
Host copy-source
HostName source.example.com
User source_user
Port 2222
Host copy-target
HostName target.example.com
User target_user
Port 2200
主机名、账号和端口均为占位值,必须换成两端实际提供的信息。具体 Host 块通常应放在通用默认块之前,避免先匹配的端口设置抢先生效。不要在本次 scp 命令里再附加全局 -P 或 -o Port=...,它们会干扰已经分开的端口配置。
本机可以分别查看解析结果:
ssh -G copy-source
ssh -G copy-target
核对各自的 hostname、user 和 port,应分别对应源端与目标端。此步骤检查配置,不证明网络可达或认证已成功。只对可信配置使用它;配置中的 Match exec 可能在解析时执行本地命令。
如果本来就有两端可用的 Host 别名,优先使用那些别名,并核对有效配置,不必再建一套。端口错误也不应通过清空 known_hosts 来解决;主机身份变化需要独立核实。
显式从本机中转这次复制
在目标目录已经存在、源文件可读、目标账户可写的前提下,使用新的目标文件名做一次受控复制:
scp -3 -v \
copy-source:/srv/export/report.txt \
copy-target:/srv/import/report.txt.incoming
这些路径需要替换成实际路径,目标文件必须不存在或已明确允许覆盖。命令没有删除源文件,也没有递归复制目录。-3 明确让数据经过发起命令的本机;详细日志中的连接地址和端口应与前面的两个 Host 块一致。
这种模式会占用本机与两端之间的网络带宽。大文件不会因此变成两台服务器之间的直传,本机也不能在传输途中断网后仍期待任务继续完成。它的好处是两端都由本机建立连接和认证,不需要为了这次复制把本机私钥放到源服务器上。
不要为了“加速”随手改成 -R。该选项改为连接源端并在那里执行 scp,要求源端能连接并认证到目标端;本机的目标别名及凭据也不会自然变成源端的相同配置。是否采用直传应作为另一项明确的网络与认证安排。
分清端口修好之后的下一层错误
如果详细日志显示的端口仍不对,回头核对实际执行的命令、Host 名称和命令行覆盖值。若端口已正确,但连接仍被拒绝,应确认这个目标的监听和访问路径,不要继续随机交换两端端口。
端口可达后出现 Permission denied,说明需要处理对应那一端的认证;出现 SFTP 子系统拒绝,则要确认服务是否支持本文采用的传输方式。添加旧协议 -O 不能修复 TCP 连接错误,也会改变两端中转时的认证限制,不应作为遇到任何错误时的通用补丁。
复制结束后,核对目标文件与源文件的大小及可信校验结果,再按既定流程让它生效。不要仅因为连接日志里端口正确,就认定文件已完整传输。
若中途失败,目标可能留下不完整的 .incoming 文件;确认它是本次任务创建的文件后再处理,保留源文件和已有正式目标。回退配置时仅撤销本次新增块或恢复备份,不需要重启远端 SSH 服务。


