我正在重写我在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()
第二个创建通道并使用类似于套接字的 send 和 recv 。
我能够使 stdin.write 与 sudo一起使用 ,但在远程主机上的 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甚至是正确的库吗?
我设法找到一个解决方案,但是需要一些手工工作。如果有人有更好的解决方案,请告诉我。
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脚本的过程。:)