1. 问题现象:当Ansible伸出友谊的小手被拒绝时
深夜两点,你盯着屏幕上的红色报错信息陷入沉思:
fatal: [web-server]: UNREACHABLE! => {"changed": false, "msg": "Failed to connect to the host via ssh: Permission denied (publickey,gssapi-keyex,gssapi-with-mic,password).", "unreachable": true}
这个报错就像一扇紧闭的大门,而Ansible手里攥着错误的钥匙。别慌!让我们化身数字侦探,揪出SSH认证失败的元凶。
2. 排雷四部曲:从入门到入土的排查指南
2.1 第一步:确认物理连接可行性
$ ping web-server
PING web-server (192.168.1.100) 56(84) bytes of data.
64 bytes from web-server (192.168.1.100): icmp_seq=1 ttl=64 time=0.423 ms
# 检查SSH端口连通性(TCP协议)
$ nc -zv web-server 22
Connection to web-server 22 port [tcp/ssh] succeeded!
如果这两个测试失败,请检查:
- 防火墙规则(特别是云主机的安全组)
- 主机是否处于运行状态
- 网络路由配置
2.2 第二步:直连测试SSH服务
# 使用与Ansible相同的用户身份手动连接
$ ssh -i ~/.ssh/ansible_key deploy@web-server
Last login: Wed Jul 12 02:34:56 2023 from 10.0.0.5
[deploy@web-server ~]$
如果手动连接成功但Ansible失败,说明问题出在Ansible配置而非SSH本身
2.3 第三步:Ansible的"坦白模式"
# 启用SSH调试模式(显示握手全过程)
$ ANSIBLE_SSH_ARGS="-vvvv" ansible all -m ping
...
debug3: send packet: type 50
debug2: we sent a publickey packet, wait for reply
debug3: receive packet: type 51
debug1: Authentications that can continue: publickey,gssapi-keyex,gssapi-with-mic,password
debug2: we did not send a packet, disable method
debug1: No more authentication methods to try.
deploy@web-server: Permission denied (publickey,gssapi-keyex,gssapi-with-mic,password).
这段输出就像SSH协议的实时字幕,注意观察:
- 密钥文件是否被正确识别
- 认证顺序是否符合预期
- 服务端支持的认证方式
3. 七大经典翻车现场与求生指南
3.1 密钥权限:Linux的洁癖有多严重
# 错误示例:密钥权限过松
$ ls -l ~/.ssh/
-rw-rw-rw- 1 user user 1675 Jul 12 03:00 ansible_key
# 正确操作(仅限所有者读写)
$ chmod 600 ~/.ssh/ansible_key
$ chmod 700 ~/.ssh/
权限过高的密钥文件会被SSH直接拒绝,这是Linux的安全机制
3.2 配置文件捉迷藏
# ansible.cfg的正确打开方式
[defaults]
inventory = hosts
private_key_file = /home/deploy/.ssh/ansible_key # 绝对路径更可靠
host_key_checking = False # 首次连接跳过确认
[ssh_connection]
ssh_args = -o ControlMaster=auto
-o ControlPersist=60s
-o ConnectTimeout=30
-o ServerAliveInterval=60
常见坑点:
- 相对路径陷阱(建议用绝对路径)
- 多配置文件的优先级问题
- 过短的超时设置导致偶发失败
3.3 用户身份的三重门禁
# playbook.yml中的用户设置陷阱
- hosts: web-server
# 错误示例:同时指定用户和密钥
remote_user: deploy
vars:
ansible_ssh_private_key_file: /wrong/path/key.pem
tasks:
- name: Test connection
ping:
正确的用户映射应该这样处理:
# 在inventory中精准配置
[web-servers]
web-server ansible_host=192.168.1.100
ansible_user=deploy
ansible_ssh_private_key_file=/home/deploy/.ssh/ansible_key
4. 高级战场:那些藏在角落的魔鬼
4.1 sudo权限的隐形锁
# 当需要提权时的正确姿势
ansible_user: deploy
become: yes
become_method: sudo
become_user: root
# 对应需要在目标机配置的sudo权限
# visudo配置示例
deploy ALL=(ALL) NOPASSWD: ALL
4.2 SSH代理转发:钥匙不在身边怎么办
# ansible.cfg启用代理转发
[ssh_connection]
ssh_args = -o ForwardAgent=yes
使用场景:
- 通过跳板机连接内网主机
- 密钥只存储在本地工作站时
5. 技术栈全景分析(Ansible+OpenSSH)
5.1 应用场景矩阵
场景 | 解决方案 | 典型配置项 |
---|---|---|
多环境密钥 | 目录分级存储 | private_key_file按环境配置 |
混合云环境 | Jump Host配置 | ProxyCommand+ssh_args |
大规模主机 | 连接池优化 | pipelining=true |
敏感数据管理 | Ansible Vault加密 | ansible-vault加密变量文件 |
5.2 技术优劣对比
优势:
- 无代理架构降低维护成本
- 基于SSH的天然安全性
- 细粒度的连接控制参数
局限:
- 大规模主机并发时性能瓶颈
- 对Windows支持需要额外配置
- 调试复杂网络拓扑较困难
6. 避坑法则:运维老司机的安全驾驶手册
密钥管理三原则:
- 生产环境禁用密码认证
- 定期轮转密钥
- 使用专用部署账户
连接优化四要素:
[ssh_connection] pipelining = True # 减少SSH会话数 control_path = %(directory)s/ansible-ssh-%%h-%%p-%%r # 复用连接 timeout = 30 # 合理超时设置
审计三板斧:
# 查看成功登录记录 $ sudo grep "Accepted publickey" /var/log/auth.log # 查看失败尝试 $ sudo grep "Failed publickey" /var/log/secure # 实时监控SSH连接 $ watch -n 5 'ss -tnop | grep :22'
7. 总结:与SSH和解的艺术
当Ansible与SSH的"爱情故事"出现裂痕时,记住这个诊断口诀:
一测网络二看权,三查配置四验连
密钥权限莫要松,sudo配置别漏空
调试参数是法宝,日志分析见真章
掌握这些技巧后,你会发现SSH认证失败就像解谜游戏——每个错误提示都是通往解决方案的线索。保持耐心,善用工具,终将成为Ansible世界的"红娘",让每个节点都顺利牵手!