如何使用Paramiko通过中间主机进行SSH连接?

时间:2016-04-26 04:39:22

标签: python linux shell ssh paramiko

基本上,我需要访问一台计算机,比如机器A,只能通过我公司的内部网络访问。我曾经能够设置tcprelay端口转发来完成此任务,但由于一些潜在的安全漏洞,该管道已被禁用。

假设我的公司通用网络在 company@10.0.0.1 我想要使​​用的具体机器是 machine@10.0.0.3

这两个帐户都有密码'password'

通过terminal和shell命令,我可以使用一个命令跳转到那里: https://askubuntu.com/a/311457

或者,在步骤中,它将是:

[on my account] ssh company@10.0.0.1
[on my account] enter password
[on company network] ssh machine @10.0.0.3
[on company network] enter password again

我将登录我需要与之通信的机器。

然而,在整个下午砍伐之后,我无法与Paramiko合作。我尝试设置连接然后发出client.exec_command(),但只是无法获取特定计算机的句柄。我的其余脚本依赖于拥有一个可以接收命令并返回响应的paramiko客户端,因此对于我来说,传播所有更改将是一个非常繁重的开销,我将切换到结构或子进程。

我最接近的是:

ssh.connect(’10.0.0.1', username=‘company', password=‘password’)
chan = ssh.get_transport().open_session()
chan.get_pty()
chan.exec_command(‘ssh machine@10.0.0.3’)
print chan.recv(1024)

返回了“输入密码”提示,但运行chan.send(‘password’)只是以挂起结束。

我现在正在拔头发,我正在阅读文档,希望找到我缺少的概念。

如果有人能提出一些建议,我会非常感激。

谢谢!

2 个答案:

答案 0 :(得分:0)

替代方法是在登录其他计算机时避免输入密码。 这可以通过使用ssh-keygen来完成。

  1. 使用用户'首先登录第一台机器(A): $ ssh-keygen -t rsa - >请求时不要输入任何密码 - >记下这行"您的公钥已保存在/home/first/.ssh/" - >此文件是机器'

  2. 的公钥
  3. 现在使用ssh登录第二台机器(B)。 然后检查〜/ .ssh文件夹。如果没有文件夹,请创建一个。 创建一个名为' authorized_keys'的文件。在〜/ .ssh / authorized_keys

  4. 从第一个'复制文件的内容用户到文件' authorized_keys'。  是一个带有' id_rsa.pub'的文件。来自' first'用户登录(在/home/first/.ssh/id_rsa.pub下)

  5. 现在您可以从第一台机器登录而无需通过脚本输入密码。

答案 1 :(得分:0)

我参与了一个项目,它必须通过SSH使用用户名/密码登录,然后再次向另一个主机执行相同的操作。我无法控制网络ACL,并且由于某种原因不允许使用SSH密钥。您需要添加paramiko_expect。以下是我如何使用它:

import paramiko
from paramiko_expect import SSHClientInteraction

user1 = 'admin'
pass1 = 'admin'
user2 = 'root'
pass2 = 'root'

# not needed for this example, but included for reference
user_prompt = '.*\$ '   

# will match root user prompt
root_prompt = '.*$ '

# will match Password: or password:
pass_prompt = '.*assword: '

# SSH to host1
ssh_client = paramiko.SSHClient()
ssh_client.set_missing_host_key_policy(
    paramiko.AutoAddPolicy())
ssh_client.connect(hostname='host1', username=user1, password=pass1)

# Interact with SSH client
with SSHClientInteraction(ssh_client, display=True) as interact:
    # Send the command to SSH as root to the final host
    interact.send('ssh {}@host2'.format(user2)
    # Expect the password prompt
    interact.expect(pass_prompt)
    # Send the root password
    interact.send(pass2)
    # Expect the root prompt
    interact.expect(root_prompt)

ssh_client.close()

一个警告:如果host1从未使用SSH连接到host2,则会收到有关主机密钥检查和超时的警告。您可以在host1上更改配置,或者只需将SSH更改为host1,然后从host1 SSH更改为host2,然后输入yes并按Enter键。