微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

python – paramiko.ssh_exception.ProxyCommandFailure:’断管’)

我正试图从PC上ssh隧道 – > server1 —> server2 —->交换机1
这可以通过一个简单的常规终端来实现:ssh switch1它引用我的ssh_config,它读取:

Host server1
  user bill
  Hostname server1
  ForwardAgent yes
  IdentityFile ~/.ssh/id_rsa
  ProxyCommand none

 Host server2
  user bill
  Hostname server2
  IdentityFile ~/.ssh/id_rsa
  ProxyCommand ssh server1 /usr/bin/nc %h %p

 Host switch1
  user bill
  Hostname %h.omniture.com
  ProxyCommand ssh server2 /usr/bin/nc %h %p

常规终端不是问题.但是,尝试构建一个python脚本来实现它已经证明是困难的.

脚本如下:

import paramiko
 import subprocess
 import getpass
 import os


 def ssh_command(ip,user,passwd,command):
     client = paramiko.SSHClient()
     client.load_host_keys('/Users/bill/.ssh/kNown_hosts')
     client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
     config = paramiko.SSHConfig()
     if os.path.exists('/etc/ssh/ssh_config'):
         config.parse(open('/etc/ssh/ssh_config'))
     if os.path.exists(os.path.expanduser('~/.ssh/config')):
         config.parse(open(os.path.expanduser('~/.ssh/config')))

     host = config.lookup(ip)
     if 'proxycommand' in host:
                 proxy = paramiko.ProxyCommand(
                 subprocess.check_output(
                 [os.environ['SHELL'],'-c','echo %s' %
                 host['proxycommand']]
                 ).strip()
             )
     else:
         proxy = None

     client.connect(host['hostname'],username='bill',password=getpass.getpass(),sock=proxy)
     ssh_session = client.get_transport().open_session()
     if ssh_session.active:
         ssh_session.exec_command(command)
         print ssh_session.recv(1024)
     return
 ssh_command('sw-a-102.sin2','bill',getpass.getpass(),'show ver')

我得到的错误是:

No handlers Could be found for logger "paramiko.transport"
Traceback (most recent call last):
  File "/Users/bill/git/tools/python/dns-check/proxy-test.py",line 34,in <module>
    ssh_command('switch1','show ver')
  File "/Users/bill/git/tools/python/dns-check/proxy-test.py",line 28,in ssh_command
    client.connect(host['hostname'],sock=proxy)
  File "/Library/Python/2.7/site-packages/paramiko/client.py",line 265,in connect
    t.start_client()
  File "/Library/Python/2.7/site-packages/paramiko/transport.py",line 406,in start_client
    raise e
paramiko.ssh_exception.ProxyCommandFailure: ('ssh server2 /usr/bin/nc switch1 22','broken pipe')

如果我可以使用paramiko工作,这将是伟大的,如果有人知道更好的方式,那也将是好的.感谢您的时间.

解决方法

有一种更好的方法,仍然使用Paramiko但没有ProxyCommand配置.

原因是paramiko的代理命令支持错误的并且容易出现竞争条件,这是上述错误的原因.

OTOH,SSH本身支持协议本身的隧道,并且不需要外部工具来实现它.

import paramiko

# Make clients
client = paramiko.SSHClient()
client.set_missing_host_key_policy(paramiko.MissingHostKeyPolicy())
server2_client = paramiko.SSHClient()
server2_client.set_missing_host_key_policy(paramiko.MissingHostKeyPolicy())
switch1_client = paramiko.SSHClient()
switch1_client.set_missing_host_key_policy(paramiko.MissingHostKeyPolicy())

# Connect to server1 normally
client.connect('server1')

# Make channel server1 -> server2
server2_chan = client.get_transport().open_channel('direct-tcpip',('<server2 ip>',22,),('127.0.0.1',0))

# Connect to server2 via server1's channel
server2_client.connect('<server2 ip>',sock=server1_chan)

# Make channel server2 -> switch1
switch1_chan = server2_client.get_transport().open_channel('direct-tcpip',('<switch1 ip>',0))

# Finally connect to switch1 via server2 channel
switch1_client.connect('switch1',sock=server2_chan)
switch1_client.exec_command(<command>)

用其IP地址替换服务器和交换机名称.

另请参阅支持本机SSH隧道的parallel SSH client based on paramiko.

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐