小编典典

与Paramiko嵌套的SSH会话

python

我正在重写我在Python中编写的Bash脚本。该脚本的关键是

ssh -t first.com "ssh second.com very_remote_command"

我在使用paramiko进行嵌套身份验证时遇到问题。我找不到适合我具体情况的任何示例,但是我能够在远程主机上找到带有 sudo的 示例。

第一种方法写入标准输入

ssh.connect('127.0.0.1', username='jesse', password='lol')
stdin, stdout, stderr = ssh.exec_command("sudo dmesg")
stdin.write('lol\n')
stdin.flush()

第二个创建通道并使用类似于套接字的
sendrecv

我能够使 stdin.writesudo一起使用 ,但在远程主机上的 ssh 上却不起作用。

import paramiko

ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect('first.com', username='luser', password='secret')
stdin, stdout, stderr = ssh.exec_command('ssh luser@second.com')
stdin.write('secret')
stdin.flush()
print '---- out ----'
print stdout.readlines()
print '---- error ----'
print stderr.readlines()

ssh.close()

…印刷品…

---- out ----
[]
---- error ----
['Pseudo-terminal will not be allocated because stdin is not a terminal.\r\n', 'Permission denied, please try again.\r\n', 'Permission denied, please try again.\r\n', 'Permission denied (publickey,password,keyboard-interactive).\r\n']

伪终端错误使我想起了原始命令中的-t标志,因此我使用Channel切换到第二种方法。我没有ssh.exec_command和更高版本,而是:

t = ssh.get_transport()
chan = t.open_session()
chan.get_pty()
print '---- send ssh cmd ----'
print chan.send('ssh luser@second.com')
print '---- recv ----'
print chan.recv(9999)
chan = t.open_session()
print '---- send password ----'
print chan.send('secret')
print '---- recv ----'
print chan.recv(9999)

…但是它会打印’---- send ssh cmd ----‘并挂起,直到我终止该进程。

我是Python的新手,对网络的了解也不多。在第一种情况下,为什么发送密码只能用于 sudo 但不能用于 ssh
?提示是否不同?paramiko甚至是正确的库吗?


阅读 230

收藏
2020-12-20

共1个答案

小编典典

我设法找到一个解决方案,但是需要一些手工工作。如果有人有更好的解决方案,请告诉我。

ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect('first.com', username='luser', password='secret')

chan = ssh.invoke_shell()

# Ssh and wait for the password prompt.
chan.send('ssh second.com\n')
buff = ''
while not buff.endswith('\'s password: '):
    resp = chan.recv(9999)
    buff += resp

# Send the password and wait for a prompt.
chan.send('secret\n')
buff = ''
while not buff.endswith('some-prompt$ '):
    resp = chan.recv(9999)
    buff += resp

# Execute whatever command and wait for a prompt again.
chan.send('ls\n')
buff = ''
while not buff.endswith('some-prompt$ '):
    resp = chan.recv(9999)
    buff += resp

# Now buff has the data I need.
print 'buff', buff

ssh.close()

需要注意的是

t = ssh.get_transport()
chan = t.open_session()
chan.get_pty()

…你要这个

chan = ssh.invoke_shell()

这让我想起了我小时候放弃编写代码长达十年的尝试编写TradeWars脚本的过程。:)

2020-12-20