使用Ansible net_put+libssh向Cisco交换机传文件时遇文件不存在错误
net_put 结合libssh传输文件到Cisco Catalyst 2960X失败的原因 核心原因推测
结合你提供的排查信息,导致libssh模式下net_put失败的主要原因可能有以下几点:
1. libssh与Cisco IOS SCP服务的兼容性差异
Cisco Catalyst 2960X的IOS SCP实现(尤其是旧版本)可能不兼容libssh默认的SCP会话初始化逻辑。你提到失败发生在libssh.ssh_scp_init调用阶段,说明libssh向设备发送的SCP协商参数无法被设备识别或支持,直接导致会话初始化失败,抛出Socket error: No such file or directory这类错误。而手动SCP能正常工作,是因为OpenSSH客户端的协商逻辑和libssh存在差异,更适配Cisco的SCP服务。
2. WSL2环境下的libssh套接字竞态条件
你通过strace检测到套接字访问的竞态条件,WSL2的网络子系统与原生Linux环境存在差异,libssh的套接字并发处理逻辑在WSL2下可能触发了竞态,导致连接异常断开(Broken pipe)或设备无法处理IO控制请求(Inappropriate ioctl for device)。paramiko的套接字处理逻辑对WSL2的适配性更好,因此能正常工作。
3. libssh与Ansible持久连接的冲突
虽然你清理了~/.ansible/pc的持久连接,但libssh的连接复用机制可能与Ansible的网络设备持久化框架存在冲突。SCP需要独立的会话上下文,复用的连接状态可能不符合初始化要求,进而导致会话建立失败。
解决方案
临时可用方案:强制使用paramiko
你已经验证切换到paramiko可正常传输,可通过在inventory或playbook中配置参数强制使用该传输方式:ansible_connection: network_cli ansible_ssh_transport: paramiko尝试升级依赖版本
更新到最新版的libssh(建议>=0.10.0)和pylibssh,新版本通常会修复兼容性问题及套接字处理的竞态bug。调整SCP会话参数(进阶操作)
如果需要继续使用libssh,可尝试修改net_put模块的底层调用逻辑,调整ssh_scp_init的参数(比如指定二进制传输模式、禁用扩展特性),看是否能适配Cisco设备的SCP服务。
内容的提问来源于stack exchange,提问作者Appleoddity

