如何使用 Python 的 Paramiko 模块 ssh 进入需要两个密码身份验证的服务器?

How can I ssh into a server that requires two password authentication using Python's Paramiko module?

如何使用 Paramiko ssh 连接到需要双重密码身份验证的服务器?

当使用特定用户时,它首先提示输入用户密码,然后提示输入另一个密码,因此我的会话需要是交互式的。 我已经使用 pexpect 模块在 Linux 上生成了一个 ssh 进程,但由于我无法在 Windows 中执行此操作,因此我需要一种使用 Paramiko 来执行此操作的方法。

服务器是我们的产品,是CentOS的一个小改动版本。我正在编写自动化代码来测试一些功能,这需要我通过 ssh 进入服务器并验证一些命令。我能够以 root 用户身份登录,但对于我感兴趣的用户,它要求输入第二个密码。

这是 ssh -vvv 命令的输出:

ssh -vvv -p2222 nobrk1n@10.213.23.112
OpenSSH_6.4,OpenSSL 1.0.1e-fips 2013 年 2 月 11 日
debug1:读取配置数据 /etc/ssh/ssh_config
debug1: /etc/ssh/ssh_config 第 51 行:为 * 应用选项
debug2: ssh_connect: needpriv 0
debug1:连接到 10.213.23.112 [10.213.23.112] 端口 2222。
debug1:连接已建立。
调试 1:permanently_set_uid:0/0
debug3:不正确的 RSA1 标识符
debug3:无法加载“/root/.ssh/id_rsa”作为 RSA1 public 密钥
debug1: 身份文件 /root/.ssh/id_rsa 类型 1
debug1: 身份文件 /root/.ssh/id_rsa-cert type -1
debug1: 身份文件 /root/.ssh/id_dsa 类型 -1
debug1: 身份文件 /root/.ssh/id_dsa-cert type -1
debug1: 身份文件 /root/.ssh/id_ecdsa 类型 -1
debug1: 身份文件 /root/.ssh/id_ecdsa-cert type -1
debug1:为协议 2.0 启用兼容模式
debug1: 本地版本字符串 SSH-2.0-OpenSSH_6.4
debug1:远程协议版本2.0,远程软件版本OpenSSH_7.4
debug1:匹配:OpenSSH_7.4 pat OpenSSH*
debug2: fd 3 设置 O_NONBLOCK
调试 3: put_host_port: [10.213.23.112]:2222
debug3:load_hostkeys:从文件“/root/.ssh/known_hosts”加载主机“[10.213.23.112]:2222”的条目
debug3: load_hostkeys: 在文件 /root/ 中找到密钥类型 ECDSA。ssh/known_hosts:1
debug3: load_hostkeys: 已加载 1 个键
debug3: order_hostkeyalgs: 更喜欢 hostkeyalgs: ecdsa-sha2-nistp256-cert-v01@openssh.com,ecdsa-sha2-nistp384-cert-v01@openssh.com,ecdsa-sha2-nistp521-cert -v01@openssh.com,ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521
debug1: SSH2_MSG_KEXINIT 已发送
debug1: SSH2_MSG_KEXINIT 收到
debug2: kex_parse_kexinit: ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521,diffie-hellman-group-exchange-sha256,diffie-hellman-group-exchange-sha1,diffie-hellman- group14-sha1,diffie-hellman-group1-sha1
debug2: kex_parse_kexinit: ecdsa-sha2-nistp256-cert-v01@openssh.com,ecdsa-sha2-nistp384-cert-v01@openssh.com,ecdsa-sha2-nistp521-cert-v01@ openssh.com、ecdsa-sha2-nistp256、ecdsa-sha2-nistp384、ecdsa-sha2-nistp521、ssh-rsa-cert-v01@openssh.com、ssh-dss-cert-v01@openssh.com,ssh-rsa-cert-v00@openssh.com,ssh-dss-cert-v00@openssh.com,ssh-rsa,ssh-dss
debug2: kex_parse_kexinit: aes128-ctr,aes192-ctr,aes256-ctr,arcfour256,arcfour128,aes128-gcm@openssh.com,aes256-gcm@openssh.com,aes128-cbc,3des- cbc,blowfish-cbc,cast128-cbc,aes192-cbc,aes256-cbc,arcfour,rijndael-cbc@lysator.liu.se
debug2: kex_parse_kexinit: aes128-ctr,aes192-ctr,aes256-ctr,arcfour256,arcfour128,aes128-gcm@openssh.com,aes256-gcm@openssh.com,aes128-cbc,3des- cbc,blowfish-cbc,cast128-cbc,aes192-cbc,aes256-cbc,arcfour,rijndael-cbc@lysator.liu.se
debug2: kex_parse_kexinit: hmac-md5-etm@openssh.com,hmac-sha1-etm@openssh.com,umac-64-etm@openssh.com,umac-128-etm@ openssh.com,hmac-sha2-256-etm@openssh.com,hmac-sha2-512-etm@openssh.com,hmac-ripemd160-etm@openssh.com,hmac-sha1- 96-etm@openssh.com,hmac-md5-96-etm@openssh.com,hmac-md5,hmac-sha1,umac-64@openssh.com,umac-128@openssh.com,hmac-sha2-256,hmac-sha2-512,hmac-ripemd160,hmac-ripemd160@openssh.com,hmac-sha1-96,hmac-md5-96
debug2: kex_parse_kexinit: hmac-md5-etm@openssh.com,hmac-sha1-etm@openssh.com,umac-64-etm@openssh.com,umac-128-etm@ openssh.com,hmac-sha2-256-etm@openssh.com,hmac-sha2-512-etm@openssh.com,hmac-ripemd160-etm@openssh.com,hmac-sha1- 96-etm@openssh.com,hmac-md5-96-etm@openssh.com,hmac-md5,hmac-sha1,umac-64@openssh.com,umac-128@openssh.com,hmac-sha2-256,hmac-sha2-512,hmac-ripemd160,hmac-ripemd160@openssh.com,hmac-sha1-96,hmac-md5-96
debug2: kex_parse_kexinit: none,zlib@openssh.com,zlib
debug2: kex_parse_kexinit: none,zlib@openssh.com,zlib
调试 2:kex_parse_kexinit:
调试 2:kex_parse_kexinit:
调试 2:kex_parse_kexinit:first_kex_follows 0
debug2: kex_parse_kexinit: 保留 0
debug2: kex_parse_kexinit: curve25519-sha256,curve25519-sha256@libssh.org,ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521,diffie-hellman-group-exchange-sha256, diffie-hellman-group16-sha512,diffie-hellman-group18-sha512,diffie-hellman-group-exchange-sha1,diffie-hellman-group14-sha256,diffie-hellman-group14-sha1,diffie-hellman-group1-sha1
debug2: kex_parse_kexinit: ssh-rsa,rsa-sha2-512,rsa-sha2-256,ecdsa-sha2-nistp256,ssh-ed25519
debug2: kex_parse_kexinit: aes128-ctr,aes192-ctr,aes256-ctr,aes128-gcm@openssh.com,aes256-gcm@openssh.com
debug2: kex_parse_kexinit: aes128-ctr,aes192-ctr,aes256-ctr,aes128-gcm@openssh.com,aes256-gcm@openssh.com
debug2: kex_parse_kexinit: hmac-sha2-256,hmac-sha2-512
debug2: kex_parse_kexinit: hmac-sha2-256,hmac-sha2-512
debug2: kex_parse_kexinit: none,zlib@openssh.com
debug2: kex_parse_kexinit: none,zlib@openssh.com
调试 2:kex_parse_kexinit:
调试 2:kex_parse_kexinit:
调试 2:kex_parse_kexinit:first_kex_follows 0
debug2: kex_parse_kexinit: 保留 0
debug2: mac_setup: 发现 hmac-sha2-256
debug1: kex: server->client aes128-ctr hmac-sha2-256 none
debug2: mac_setup: 发现 hmac-sha2-256
debug1: kex: 客户端-> 服务器 aes128-ctr hmac-sha2-256 none
debug1:发送 SSH2_MSG_KEX_ECDH_INIT
调试 1:期待 SSH2_MSG_KEX_ECDH_REPLY
debug1:服务器主机密钥:ECDSA 30:5c:e6:be:81:31:79:b8:71:80:bf:49:95:a9:79:12
调试 3: put_host_port: [10.213.23.112]:2222
调试 3: put_host_port: [10.213.23.112]:2222
debug3:load_hostkeys:从文件“/root/.ssh/known_hosts”加载主机“[10.213.23.112]:2222”的条目
debug3: load_hostkeys: 在文件 /root/ 中找到密钥类型 ECDSA。ssh/known_hosts:1
debug3: load_hostkeys: 已加载 1 个键
debug3:load_hostkeys:从文件“/root/.ssh/known_hosts”加载主机“[10.213.23.112]:2222”的条目
debug3: load_hostkeys: 在文件 /root/ 中找到密钥类型 ECDSA。ssh/known_hosts:1
debug3: load_hostkeys: 已加载 1 个键
debug1:主机“[10.213.23.112]:2222”已知且与 ECDSA 主机密钥匹配。
debug1:在 /root/ 中找到密钥。ssh/known_hosts:1
debug1: ssh_ecdsa_verify: 签名正确
调试 2:kex_derive_keys
debug2: set_newkeys: 模式 1
debug1: SSH2_MSG_NEWKEYS 已发送
调试 1:期待 SSH2_MSG_NEWKEYS
调试 2:set_newkeys:模式 0
debug1: SSH2_MSG_NEWKEYS 收到
debug1:服务器不允许漫游
debug1: SSH2_MSG_SERVICE_REQUEST 已发送
debug2: service_accept: ssh-userauth
debug1: SSH2_MSG_SERVICE_ACCEPT 收到
debug2: 键: /root/.ssh/id_rsa (0x55f959096720),
debug2: key: /root/.ssh/id_dsa ((nil)),
debug2: key: /root/.ssh/id_ecdsa ((nil)),
debug1:可以继续的身份验证:publickey,gssapi-keyex,gssapi-with-mic,password
debug3:重新开始,传递了一个不同的列表 publickey,gssapi-keyex,gssapi-with-mic,password
debug3: 首选 gssapi-keyex,gssapi-with-mic,publickey,keyboard-interactive,password
debug3: authmethod_lookup gssapi-keyex
debug3: 其余首选: gssapi-with-mic,publickey,keyboard-interactive,password
debug3: authmethod_is_enabled gssapi-keyex
debug1:下一个认证方式:gssapi-keyex
debug1:没有有效的密钥交换上下文
debug2:我们没有发送数据包,禁用方法
debug3: authmethod_lookup gssapi-with-mic
debug3: 剩余首选: publickey,keyboard-interactive,password
debug3: authmethod_is_enabled gssapi-with-mic
debug1:下一个认证方式:gssapi-with-mic
debug1:未指定的 GSS 故障。次要代码可能会提供更多信息
没有可用的 Kerberos 凭据(默认缓存:KEYRING:persistent:0)
  
debug1:未指定的 GSS 故障。次要代码可能会提供更多信息
没有可用的 Kerberos 凭据(默认缓存:KEYRING:persistent:0)
  
debug2:我们没有发送数据包,禁用方法
debug3: authmethod_lookup public 密钥
debug3:其余首选:键盘交互,密码
debug3: authmethod_is_enabled public键
debug1:下一个身份验证方法:publickey
debug1:提供 RSA public 密钥:/root/.ssh/id_rsa
调试 3:send_pubkey_test
debug2: 我们发送了一个 publickey 数据包,等待回复
debug1:可以继续的身份验证:publickey,gssapi-keyex,gssapi-with-mic,password
debug1:尝试私钥:/root/.ssh/id_dsa
debug3: 没有这样的身份: /root/.ssh/id_dsa: 没有这样的文件或目录
debug1:尝试私钥:/root/.ssh/id_ecdsa
debug3: 没有这样的身份: /root/.ssh/id_ecdsa: 没有这样的文件或目录
debug2:我们没有发送数据包,禁用方法
debug3: authmethod_lookup 密码
debug3:剩余首选:,密码
debug3: authmethod_is_enabled 密码
debug1:下一个认证方式:密码
nobrk1n@10.213.23.112的密码:
debug3: packet_send2: 添加 64 (len 60 padlen 4 extra_pad 64)
debug2:我们发送了一个密码包,等待回复
debug1:身份验证成功(密码)。
已通过 10.213.23.112 ([10.213.23.112]:2222) 的身份验证。
debug1: 通道 0: 新 [客户端会话]
调试 3:ssh_session2_open:channel_new:0
debug2: 通道 0: 发送打开
debug1:请求不再有会话@openssh.com
debug1:进入交互式会话。
debug1: client_input_global_request: rtype hostkeys-00@openssh.com want_reply 0
debug2:回调开始
debug2: fd 3 设置 TCP_NODELAY
debug3: packet_set_tos: 设置 IP_TOS 0x10
调试 2: client_session2_setup: id 0
debug2: 通道 0: 请求 pty-req 确认 1
debug1:发送环境。
debug3:忽略环境 XDG_SESSION_ID
debug3:忽略 env HOSTNAME
debug3:忽略环境术语
debug3:忽略环境 SHELL
debug3:忽略环境 HISTSIZE
debug3:忽略环境 SSH_CLIENT
debug3:忽略环境 SSH_TTY
debug3:忽略环境用户
debug3:忽略环境 LS_COLORS
debug3:忽略环境邮件
debug3:忽略环境路径
debug3:忽略环境密码
debug1:发送环境 LANG = en_US.UTF-8
debug2: 通道 0: 请求 env 确认 0
debug3:忽略环境 HISTCONTROL
debug3:忽略环境 SHLVL
debug3: 忽略 env HOME
debug3:忽略了 env LOGNAME
debug3:忽略环境 XDG_DATA_DIRS
debug3:忽略环境 SSH_CONNECTION
debug3: 忽略 env LESSOPEN
debug3:忽略环境 XDG_RUNTIME_DIR
debug3:忽略环境_
debug2: 通道 0: 请求 shell 确认 1
debug2:回调完成
debug2: 通道 0: 打开确认 rwindow 0 rmax 32768
debug2: channel_input_status_confirm: 输入 99 id 0
debug2:通道 0 上接受的 PTY 分配请求
debug2: 通道 0: rcvd 调整 2097152
debug2: channel_input_status_confirm: 输入 99 id 0
debug2: shell 请求在通道 0 上被接受
上次登录:2018 年 12 月 11 日星期二 21:17:10 来自 10.213.23.201
请输入 shell 密码:debug3:收到 SSH2_MSG_IGNORE
debug3:收到 SSH2_MSG_IGNORE
debug3:收到 SSH2_MSG_IGNORE
debug3:收到 SSH2_MSG_IGNORE
debug3:收到 SSH2_MSG_IGNORE
debug3:收到 SSH2_MSG_IGNORE
debug3:收到 SSH2_MSG_IGNORE
debug3:收到 SSH2_MSG_IGNORE
debug3:收到 SSH2_MSG_IGNORE
debug3:收到 SSH2_MSG_IGNORE
debug3:收到 SSH2_MSG_IGNORE
debug3:收到 SSH2_MSG_IGNORE
debug3:收到 SSH2_MSG_IGNORE
debug3:收到 SSH2_MSG_IGNORE
debug3:收到 SSH2_MSG_IGNORE
debug3:收到 SSH2_MSG_IGNORE
debug3:收到 SSH2_MSG_IGNORE
  
正在输入 shell...
[root@atd-reg root]# 

我无法执行这样的命令:

ssh -vvv -p2222 nobrk1n@10.213.23.112 ls

在执行上述命令时,系统提示我输入 nobrk1n 用户的密码。但是在输入密码时它会卡住。我已将上述命令的输出粘贴到 https://pastebin.com/hSfiCmdi。通常我首先使用 ssh -p2222 user@host ssh 进入服务器,当建立连接并成功登录后,我开始执行命令。

您的服务器对第一个密码使用标准密码验证。

仅在 shell 开始时才询问第二个密码。简单的 I/O 用于此。

此外,您的服务器似乎不支持 "exec" interface/channel 执行命令(因为 ssh user@host command 不起作用)。什么可能与 "shell password" 功能有关。所以你可能必须使用 "shell" 通道来执行你的命令,否则 不推荐

ssh = paramiko.SSHClient()
ssh.connect(hostname, username = username, password = password1)
channel = ssh.invoke_shell()
channel.send(password2 + "\n")
channel.send(command + "\n")
while not channel.recv_ready():
    time.sleep(1)
out = channel.recv(9999)