配置Google-Authenticator后Ansible SSH连接失败求助
你遇到的这个问题很典型——手动SSH能正常免验证,但Ansible执行失败,核心原因大概率是Ansible的SSH会话特性、PAM规则顺序或者认证优先级配置和手动连接不一样。下面是一步步的排查和解决方法:
1. 先确认Ansible的连接源IP是否在允许网段内
手动SSH的时候你的终端源IP肯定在<<localnetworkip>>/24里,但Ansible的连接可能走了不同的网络路径(比如用了跳转机、不同网卡)。你可以在目标服务器上实时监控认证日志:
tail -f /var/log/auth.log
然后执行一次Ansible ping命令:
ansible Host -m ping
看日志里记录的Ansible连接源IP是不是属于你配置的允许网段,如果不是,那就要调整网络或者access规则。
2. 调整PAM规则的执行顺序
这是最常见的坑:如果Google Authenticator的PAM规则在pam_access.so之前,那么即使你的IP在允许列表里,也会先触发二次验证。你需要把pam_access.so的规则放在pam_google_authenticator.so前面,确保先执行IP白名单验证:
编辑/etc/pam.d/ssh,调整后的内容应该类似:
# 先执行IP白名单验证,通过则跳过后续验证 auth [success=done default=ignore] pam_access.so accessfile=/etc/security/access-local.conf # 只有白名单验证不通过时,才触发Google Authenticator auth required pam_google_authenticator.so
这里的success=done是关键:如果pam_access验证通过,直接结束auth阶段,不会再执行后面的二次验证。
3. 强制Ansible优先使用密钥认证
Ansible默认的SSH参数可能会尝试多种认证方式,包括键盘交互,这会触发二次验证。你可以在ansible.cfg里配置SSH参数,强制优先用密钥认证,禁用密码/键盘交互:
[ssh_connection] ssh_args = -o PreferredAuthentications=publickey -o PasswordAuthentication=no -o ChallengeResponseAuthentication=no
或者在单个playbook里临时设置:
- name: 测试连接 hosts: Host vars: ansible_ssh_common_args: '-o PreferredAuthentications=publickey -o PasswordAuthentication=no -o ChallengeResponseAuthentication=no' tasks: - ping:
这样Ansible只会用密钥认证,不会触发需要交互的验证步骤。
4. 检查access-local.conf的配置格式
确保你的白名单配置没有语法错误,正确的格式应该是:
# 允许本地网段所有用户 +:ALL:<<localnetworkip>>/24 # 允许本地回环地址 +:ALL:127.0.0.1 +:ALL::1 # 最后拒绝其他所有(如果有这条的话) -:ALL:ALL
注意规则顺序:PAM access是从上到下匹配,最后匹配的规则生效,所以允许规则要放在拒绝规则前面。
5. 用verbose模式排查Ansible连接细节
执行Ansible的时候加上-vvv参数,看详细的SSH连接日志:
ansible Host -m ping -vvv
从日志里你能看到Ansible尝试的认证方式,以及是否触发了键盘交互请求,这能帮你精准定位问题。
内容的提问来源于stack exchange,提问作者didentifier

