You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Ansible中OpenSSH连接失败但Paramiko可用的原因与排查

Ansible OpenSSH连接失效但Paramiko可用的问题排查与修复

问题描述

执行以下Ansible Playbook命令时:

ansible-playbook -u vagrant -i .vagrant/provisioners/ansible/inventory/vagrant_ansible_inventory playbook.yml -c ssh

出现连接失败错误:

fatal: [default]: UNREACHABLE! => {"changed": false, "msg": "Failed to connect to the host via ssh: ", "unreachable": true}

但添加-c paramiko参数指定Paramiko连接后,命令可正常运行:

ansible-playbook -u vagrant -i .vagrant/provisioners/ansible/inventory/vagrant_ansible_inventory playbook.yml -c paramiko

已知环境信息

  • 本地主机:Ubuntu 20.04
  • 远程主机:CentOS 7
  • Ansible版本:core 2.13.6

Verbose模式输出

启用-vvv参数执行命令:

ansible-playbook -u vagrant -i .vagrant/provisioners/ansible/inventory/vagrant_ansible_inventory playbook.yml -c ssh -vvv

输出内容:

/usr/lib/python3/dist-packages/paramiko/transport.py:236: CryptographyDeprecationWarning: Blowfish has been deprecated
  "class": algorithms.Blowfish,
ansible-playbook [core 2.13.6]
  config file = /etc/ansible/ansible.cfg
  configured module search path = ['/home/john/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /home/john/.local/lib/python3.10/site-packages/ansible
  ansible collection location = /home/john/.ansible/collections:/usr/share/ansible/collections
  executable location = /usr/bin/ansible-playbook
  python version = 3.10.6 (main, Nov  2 2022, 18:53:38) [GCC 11.3.0]
  jinja version = 3.1.2
  libyaml = True
Using /etc/ansible/ansible.cfg as config file
host_list declined parsing /home/john/test/.vagrant/provisioners/ansible/inventory/vagrant_ansible_inventory as it did not pass its verify_file() method
script declined parsing /home/john/test/.vagrant/provisioners/ansible/inventory/vagrant_ansible_inventory as it did not pass its verify_file() method
auto declined parsing /home/john/test/.vagrant/provisioners/ansible/inventory/vagrant_ansible_inventory as it did not pass its verify_file() method
Parsed /home/john/test/.vagrant/provisioners/ansible/inventory/vagrant_ansible_inventory inventory source with ini plugin
Skipping callback 'default', as we already have a stdout callback.
Skipping callback 'minimal', as we already have a stdout callback.
Skipping callback 'oneline', as we already have a stdout callback.

PLAYBOOK: playbook.yml *************************************************************************************************
1 plays in playbook.yml

PLAY [all] *************************************************************************************************************

TASK [Gathering Facts] *************************************************************************************************
task path: /home/john/test/playbook.yml:2
<127.0.0.1> ESTABLISH SSH CONNECTION FOR USER: vagrant
<127.0.0.1> SSH: EXEC ssh -C -o ControlMaster=auto -o ControlPersist=60s -o Port=2222 -o 'IdentityFile="/home/john/test/.vagrant/machines/default/virtualbox/private_key"' -o KbdInteractiveAuthentication=no -o PreferredAuthentications=gssapi-with-mic,gssapi-keyex,hostbased,publickey -o PasswordAuthentication=no -o 'User="vagrant"' -o ConnectTimeout=10 -o 'ControlPath="/home/john/.ansible/cp/055b8f4af0"' 127.0.0.1 '/bin/sh -c '"'"'echo ~vagrant && sleep 0'"'"''
<127.0.0.1> (255, b'/home/vagrant\n', b'')
fatal: [default]: UNREACHABLE! => {
    "changed": false,
    "msg": "Failed to connect to the host via ssh: ",
    "unreachable": true
}

PLAY RECAP *************************************************************************************************************
default                    : ok=0    changed=0    unreachable=1    failed=0    skipped=0    rescued=0    ignored=0

一、OpenSSH连接失效但Paramiko可用的常见原因

  • SSH版本兼容性:Ubuntu 20.04自带的OpenSSH客户端版本较新,CentOS 7的OpenSSH服务端版本偏旧,新客户端默认的加密算法、密钥交换方式不被旧服务端支持。
  • Ansible SSH插件参数冲突:从verbose输出可见,Ansible默认启用了ControlMaster=auto连接复用功能,可能因权限、路径问题导致连接失败;或者PreferredAuthentications认证顺序存在隐藏兼容性问题。
  • 密钥权限问题:OpenSSH对私钥文件权限要求严格(必须为600),Paramiko对权限的容忍度更高,若密钥权限不符合要求会导致OpenSSH连接失败。
  • 端口转发逻辑差异:Vagrant将远程22端口映射到本地2222,OpenSSH与Paramiko处理端口转发的逻辑不同,可能存在超时、连接复用的冲突。

二、调试OpenSSH连接的具体步骤

  1. 手动执行OpenSSH命令测试
    复制Ansible生成的SSH命令,去掉Control相关参数后手动执行,查看详细错误:

    ssh -C -o Port=2222 -o 'IdentityFile="/home/john/test/.vagrant/machines/default/virtualbox/private_key"' -o KbdInteractiveAuthentication=no -o PreferredAuthentications=gssapi-with-mic,gssapi-keyex,hostbased,publickey -o PasswordAuthentication=no -o 'User="vagrant"' -o ConnectTimeout=10 127.0.0.1 '/bin/sh -c "echo ~vagrant && sleep 0"'
    
  2. 检查密钥文件权限
    修正私钥权限至OpenSSH要求的600:

    chmod 600 /home/john/test/.vagrant/machines/default/virtualbox/private_key
    
  3. 关闭连接复用功能测试
    在Ansible命令中添加参数禁用ControlMaster:

    ansible-playbook -u vagrant -i .vagrant/provisioners/ansible/inventory/vagrant_ansible_inventory playbook.yml -c ssh -o ControlMaster=no
    
  4. 指定兼容的加密算法
    如果手动连接提示算法不兼容,指定CentOS 7支持的算法:

    ansible-playbook -u vagrant -i .vagrant/provisioners/ansible/inventory/vagrant_ansible_inventory playbook.yml -c ssh -o KexAlgorithms=diffie-hellman-group-exchange-sha256 -o Ciphers=aes256-ctr
    

三、修复OpenSSH连接的方案

  1. 修改Ansible全局配置
    在/etc/ansible/ansible.cfg或~/.ansible.cfg中添加以下配置,适配旧服务端:

    [ssh_connection]
    ssh_args = -o ControlMaster=no -o KexAlgorithms=diffie-hellman-group-exchange-sha256 -o Ciphers=aes256-ctr
    
  2. 升级远程主机OpenSSH服务
    在CentOS 7上升级OpenSSH服务端(注意备份配置):

    sudo yum install -y openssh-server openssh-clients
    sudo systemctl restart sshd
    
  3. 自动修正Vagrant生成的密钥权限
    在Vagrantfile中添加钩子,每次启动虚拟机后自动修正私钥权限:

    config.vm.provision "shell", inline: <<-SHELL
      chmod 600 /home/vagrant/.ssh/authorized_keys
    SHELL
    config.trigger.after :up do
      run "chmod 600 .vagrant/machines/default/virtualbox/private_key"
    end
    

内容的提问来源于stack exchange,提问作者hangindev.com

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.12 20:50:29