WSL2使用scp拷贝远程服务器文件报主机密钥验证失败连接丢失错误
问题根因
报错核心来自SCP执行逻辑和WSL2网络架构的两个认知误区,和SSH服务状态、账号密码正确性无关:
- 第一,双远程地址格式的SCP执行逻辑和普遍预期不符:当执行的SCP命令中源路径、目标路径都携带
user@host:前缀时,SCP不会在当前执行命令的本地主机做流量中转,而是先登录到第一个地址(即你的remote_user@remote_server),直接在这台远程服务器上发起对第二个目标地址的SSH连接完成传输。
你把目标写为localhost时,远程服务器实际连接的是它自身的本地回环接口127.0.0.1,根本不是你本地的WSL环境,远程服务器自身的localhost要么没运行SSH服务,要么主机密钥和校验记录不匹配,自然抛出Host key verification failed错误。 - 第二,WSL2默认采用NAT虚拟网络架构:WSL2实例的IP是虚拟内网IP,和物理主机、外部远程服务器不在同一个可直接路由的网络中,外部网络默认没有到WSL2实例的路由,同时Windows物理主机防火墙默认拦截入站SSH请求。你把目标替换为物理主机IP、WSL2自身IP时,本质是让远程服务器主动跨网连接你本地NAT后的内网地址,没有提前配置端口转发、防火墙放通的情况下必然出现连接超时。
- 补充说明:你能正常从本地SSH连接远程服务器、连接本地WSL,是因为这两个连接都是从本地主机主动向外发起的出站连接,和让远程服务器主动向内连接本地WSL的入站连接网络权限完全不同,二者不存在冲突。
注:你原命令中写的StrictKeyChecking为参数拼写错误,正确参数名是StrictHostKeyChecking=no,拼写错误时该配置不会生效,但不是本次报错的核心诱因。
解决方法
按操作复杂度从低到高选择即可:
- 调整命令逻辑,直接从WSL拉取远程文件(最推荐,零额外配置)
不要使用双远程地址格式,直接打开本地WSL终端执行拉取命令,让WSL作为主动发起连接的一方,直接把远程文件存到WSL本地路径,完全避开反向连接的网络限制:
如果你不想切换到WSL终端,习惯在Windows主机终端执行命令,也可以先把文件拉到Windows本地目录,再通过WSL默认的Windows盘挂载路径转存:scp -o StrictHostKeyChecking=no remote_user@remote_server:/path/to/file.txt /path/to/wsl/directory# 先拉取文件到Windows本地目录 scp -o StrictHostKeyChecking=no remote_user@remote_server:/path/to/file.txt C:\temp\ # 进入WSL后,从/mnt挂载路径移动文件到WSL目标目录 mv /mnt/c/temp/file.txt /path/to/wsl/directory - 保留双地址写法时,加
-3参数强制本地流量中转
SCP的-3参数会强制所有传输流量经过你当前执行命令的本地主机转发,不会让远程服务器直接连接目标地址,不需要配置入站规则:
该场景下目标地址填scp -3 -v -o StrictHostKeyChecking=no remote_user@remote_server:/path/to/file.txt wsl_user@localhost:/path/to/directorylocalhost即可——WSL2默认会把本地localhost的SSH端口转发到WSL实例,地址只需要保证你的本地主机能正常访问,不需要考虑远程服务器的网络连通性。 - 非必要不选择:配置WSL2端口转发+防火墙放通
如果你确实需要让远程服务器直连WSL的SSH服务,需要在Windows管理员终端配置端口映射,将物理主机的22端口转发到WSL实例的22端口,同时在Windows高级防火墙中放通入站22端口规则,另外还要额外处理WSL2重启后虚拟IP变动的问题。该方案会把本地SSH服务暴露到公网,存在明确安全风险,不推荐普通场景使用。
踩坑提醒
- 写SCP命令时只要发现源和目标都携带
@host:格式,第一时间确认是否需要加-3参数:默认逻辑是第一台远程主机主动连接第二台远程主机,不会经过本地中转。 - WSL2的NAT网络默认仅支持本地物理主机访问WSL内的服务,外部设备访问必须手动配置端口转发,不要直接把WSL的虚拟内网IP提供给外部设备使用,该IP仅在你的本地物理机上可识别。
内容的提问来源于stack exchange,提问作者hisannonageki
相关产品推荐
相关产品推荐

