Ansible 失败并显示 "Permission denied (keyboard-interactive)"
Ansible fails with "Permission denied (keyboard-interactive)"
我有两台不同的机器,我可以使用企业 VPN 和代理在 SSH 中连接。
为此,我的 ~/.ssh/config
有两个这样定义的主机:
Host foobar
User alice
HostName XXX.XXX.XXX.XXX
ProxyCommand nc -x proxy-socks.foobar.com:4242 %h %p
两个主机的 ProxyCommand
相同,只有 HostName
和 User
不同。每个主机都有我的 public 密钥,我只需输入 ssh foobar
即可连接到每个主机,不需要密码。
现在,我尝试在这些机器上使用ansible。我有一个类似 inventory.cfg
的列表,其中列出了我的 ~/.ssh/config
:
中定义的两台机器的名称
[vpn]
foobar
barfoo
我尝试了这个简单的命令:
ansible -i inventory.cfg vpn -m ping
这适用于其中一台机器,但不适用于另一台机器。这是编辑后的输出:
foobar | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/libexec/platform-python"
},
"changed": false,
"ping": "pong"
}
barfoo | UNREACHABLE! => {
"changed": false,
"msg": "Failed to connect to the host via ssh: Welcome on barfoo [...] Permission denied (keyboard-interactive).",
"unreachable": true
}
由于我在输出中收到了来自主机的“欢迎”消息,这意味着我确实到达了主机(因此代理配置应该没问题)。
但我无法理解错误“权限被拒绝(键盘交互)”。我可以通过 SSH 连接到这台机器而无需密码(事实上,管理员甚至禁用了密码验证,我不得不通过电子邮件将我的 public 密钥发送给他们)。
我试图通过添加 --private-key $HOME/.ssh/id_rsa
来明确指定我的 SSH 密钥,但错误消息完全相同。
出于好奇,我尝试使用 Python 的包 fabric
,但这对两台机器都很好:
import fabric
fabric.Connection('barfoo').run('hostname')
所以在 ansible 和这台机器配置之间似乎发生了一些奇怪的事情。有什么线索吗?
编辑
根据@GeralexGR 的建议,我在 ansible 命令中添加了 -vvvv
以获得更多输出。
在输出中,我可以看到 ansible 正在调用 SSH :
ssh -vvv -C -o ControlMaster=auto -o ControlPersist=60s -o KbdInteractiveAuthentication=no -o PreferredAuthentications=gssapi-with-mic,gssapi-keyex,hostbased,publickey -o PasswordAuthentication=no -o ConnectTimeout=10 -o 'ControlPath="/home/alice/.ansible/cp/dbd7338475"' barfoo '/bin/sh -c '"'"'echo ~ && sleep 0'"'"''
通过反复试验,我可以将这个命令简化为这个命令:
ssh -vvv -o PreferredAuthentications=publickey barfoo 'hostname'
此命令在一台机器上失败,但在另一台机器上失败。但是,如果我删除 PreferredAuthentications
选项,它在两台机器上都能正常工作。
当它失败时,它输出类似的东西:
debug1: Next authentication method: publickey
debug1: Offering public key: [...]
[...]
debug1: Server accepts key: [...]
[...]
Authenticated with partial success.
debug1: Authentications that can continue: keyboard-interactive
debug3: start over, passed a different list keyboard-interactive
debug3: preferred publickey
debug1: No more authentication methods to try.
如果我删除此选项并执行简单的 ssh -vvvv
,我将在输出中得到以下内容:
debug1: Next authentication method: publickey
debug1: Offering public key: [...]
[...]
debug1: Server accepts key: [...]
[...]
Authenticated with partial success.
debug1: Authentications that can continue: keyboard-interactive
[...]
debug1: Next authentication method: keyboard-interactive
debug2: userauth_kbdint
[...]
debug1: Authentication succeeded (keyboard-interactive).
所以,我的猜测是这台机器需要 keyboard-interactive
。事实上,如果我把 publickey
和 keyboard-interactive
都放在选项中,这有效:
ssh -vvv -o preferredauthentications=publickey,keyboard-interactive barfoo 'hostname'
所以,回到ansible,我试过这个:
ansible -vvvv --ssh-extra-args='-o preferredauthentications=publickey,keyboard-interactive' -i inventory.cfg -m ping vpn
但还是失败了,我猜这个认证机制在ansible中是不可能的?我不确定这里是否需要 why/how keyboard-interactive,因为我从来没有被提示输入密码。我去问机器的管理员
解决方案由@Zeitounator 在评论中友情提供。
我在 inventory.cfg
文件中添加了这两行(使用虚拟密码):
[vpn:vars]
ansible_ssh_pass=foo
现在初始 ansible 命令运行良好。
或者,在命令行中使用 --ask-pass
选项也可以:
ansible --ask-pass -i inventory.cfg -m ping vpn
对于上下文,我向机器的管理员询问了更多信息。这台机器不要求我输入密码或任何东西,但是,它要求一些外部用户(不是我)接受一些条款和条件。这就是为什么需要 keyboard-interactive
机制。
我有两台不同的机器,我可以使用企业 VPN 和代理在 SSH 中连接。
为此,我的 ~/.ssh/config
有两个这样定义的主机:
Host foobar
User alice
HostName XXX.XXX.XXX.XXX
ProxyCommand nc -x proxy-socks.foobar.com:4242 %h %p
两个主机的 ProxyCommand
相同,只有 HostName
和 User
不同。每个主机都有我的 public 密钥,我只需输入 ssh foobar
即可连接到每个主机,不需要密码。
现在,我尝试在这些机器上使用ansible。我有一个类似 inventory.cfg
的列表,其中列出了我的 ~/.ssh/config
:
[vpn]
foobar
barfoo
我尝试了这个简单的命令:
ansible -i inventory.cfg vpn -m ping
这适用于其中一台机器,但不适用于另一台机器。这是编辑后的输出:
foobar | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/libexec/platform-python"
},
"changed": false,
"ping": "pong"
}
barfoo | UNREACHABLE! => {
"changed": false,
"msg": "Failed to connect to the host via ssh: Welcome on barfoo [...] Permission denied (keyboard-interactive).",
"unreachable": true
}
由于我在输出中收到了来自主机的“欢迎”消息,这意味着我确实到达了主机(因此代理配置应该没问题)。 但我无法理解错误“权限被拒绝(键盘交互)”。我可以通过 SSH 连接到这台机器而无需密码(事实上,管理员甚至禁用了密码验证,我不得不通过电子邮件将我的 public 密钥发送给他们)。
我试图通过添加 --private-key $HOME/.ssh/id_rsa
来明确指定我的 SSH 密钥,但错误消息完全相同。
出于好奇,我尝试使用 Python 的包 fabric
,但这对两台机器都很好:
import fabric
fabric.Connection('barfoo').run('hostname')
所以在 ansible 和这台机器配置之间似乎发生了一些奇怪的事情。有什么线索吗?
编辑
根据@GeralexGR 的建议,我在 ansible 命令中添加了 -vvvv
以获得更多输出。
在输出中,我可以看到 ansible 正在调用 SSH :
ssh -vvv -C -o ControlMaster=auto -o ControlPersist=60s -o KbdInteractiveAuthentication=no -o PreferredAuthentications=gssapi-with-mic,gssapi-keyex,hostbased,publickey -o PasswordAuthentication=no -o ConnectTimeout=10 -o 'ControlPath="/home/alice/.ansible/cp/dbd7338475"' barfoo '/bin/sh -c '"'"'echo ~ && sleep 0'"'"''
通过反复试验,我可以将这个命令简化为这个命令:
ssh -vvv -o PreferredAuthentications=publickey barfoo 'hostname'
此命令在一台机器上失败,但在另一台机器上失败。但是,如果我删除 PreferredAuthentications
选项,它在两台机器上都能正常工作。
当它失败时,它输出类似的东西:
debug1: Next authentication method: publickey
debug1: Offering public key: [...]
[...]
debug1: Server accepts key: [...]
[...]
Authenticated with partial success.
debug1: Authentications that can continue: keyboard-interactive
debug3: start over, passed a different list keyboard-interactive
debug3: preferred publickey
debug1: No more authentication methods to try.
如果我删除此选项并执行简单的 ssh -vvvv
,我将在输出中得到以下内容:
debug1: Next authentication method: publickey
debug1: Offering public key: [...]
[...]
debug1: Server accepts key: [...]
[...]
Authenticated with partial success.
debug1: Authentications that can continue: keyboard-interactive
[...]
debug1: Next authentication method: keyboard-interactive
debug2: userauth_kbdint
[...]
debug1: Authentication succeeded (keyboard-interactive).
所以,我的猜测是这台机器需要 keyboard-interactive
。事实上,如果我把 publickey
和 keyboard-interactive
都放在选项中,这有效:
ssh -vvv -o preferredauthentications=publickey,keyboard-interactive barfoo 'hostname'
所以,回到ansible,我试过这个:
ansible -vvvv --ssh-extra-args='-o preferredauthentications=publickey,keyboard-interactive' -i inventory.cfg -m ping vpn
但还是失败了,我猜这个认证机制在ansible中是不可能的?我不确定这里是否需要 why/how keyboard-interactive,因为我从来没有被提示输入密码。我去问机器的管理员
解决方案由@Zeitounator 在评论中友情提供。
我在 inventory.cfg
文件中添加了这两行(使用虚拟密码):
[vpn:vars]
ansible_ssh_pass=foo
现在初始 ansible 命令运行良好。
或者,在命令行中使用 --ask-pass
选项也可以:
ansible --ask-pass -i inventory.cfg -m ping vpn
对于上下文,我向机器的管理员询问了更多信息。这台机器不要求我输入密码或任何东西,但是,它要求一些外部用户(不是我)接受一些条款和条件。这就是为什么需要 keyboard-interactive
机制。