使用Ansible在两台AWS实例间SSH时出现Port 22 Connection Refused报错
问题排查与解决步骤
错误核心为SSH连接目标服务器22端口被拒,手动连接正常说明服务器SSHD服务、安全组基础配置无问题,问题出在Ansible的执行环境或执行时机上,可按以下步骤排查:
1. 校验Ansible执行用户与手动操作用户是否一致
从错误日志可见SSH读取的配置路径为/root/.ssh/config,说明Ansible是用root身份执行的任务。如果手动SSH操作时使用的是普通用户,会出现两类差异:
- root用户的家目录
/root/.ssh/下没有存放你的my.key私钥文件 - 不同用户的
known_hosts配置不一致,首次连接新主机时root用户可能没有跳过host key校验的配置
验证方法:切换到root用户后执行Ansible任务内的完整命令,确认是否能连通:
su - root cat ~/.ssh/id_rsa.pub | ssh -vvv -p 22 -i ~/.ssh/my.key ubuntu@xx.xx.xxx.xx "cat >> ~/.ssh/authorized_keys"
如果执行失败,把普通用户下的my.key和id_rsa.pub复制到root的.ssh目录,或者配置Ansible用你手动操作的普通用户执行任务即可。
2. 检查实例创建后的等待逻辑
AWS EC2实例从创建完成到SSHD服务完全就绪通常需要30秒到2分钟的时间,如果在playbook中创建实例后立刻执行SSH连接操作,就会出现端口被拒的报错。手动操作时大概率是等了一段时间才发起连接,所以能正常连通。
解决方法:在SSH相关任务前添加端口等待任务:
- name: 等待EC2实例22端口可用 wait_for: host: xx.xx.xxx.xx # 替换为你的实例公网IP变量 port: 22 delay: 15 # 每15秒检查一次 timeout: 300 # 最长等待5分钟 state: started delegate_to: localhost
3. 替换为Ansible原生模块执行公钥复制
当前用shell拼接命令的方式很容易出现路径、权限、转义问题,建议用Ansible官方的authorized_key模块完成公钥推送,稳定性更高:
- name: 推送公钥到EC2实例 authorized_key: user: ubuntu state: present key: "{{ lookup('file', '~/.ssh/id_rsa.pub') }}" vars: ansible_host: xx.xx.xxx.xx ansible_ssh_user: ubuntu ansible_ssh_private_key_file: ~/.ssh/my.key ansible_ssh_extra_args: '-o StrictHostKeyChecking=no' # 首次连接跳过host key校验
4. 额外校验项
如果上述步骤都无效,再检查:
- 如果是在本地运行Ansible、手动连接也是本地发起,排查本机防火墙是否限制了root用户的SSH出站请求
- 检查AWS安全组入站规则的22端口是否允许Ansible执行机器的公网IP访问,如果你手动连接用的是其他网络环境,会出现手动正常、Ansible执行机器被拦截的情况
内容的提问来源于stack exchange,提问作者potta vamsi krishna
相关产品推荐
相关产品推荐

