![](/img/trans.png)
[英]Paramiko / Netmiko SSH Error - 'paramiko.buffered_pipe.PipeTimeout'
[英]paramiko.ssh_exception.ProxyCommandFailure: 'Broken pipe')
我試圖從PC上運行ssh - > server1 ---> server2 ----> switch1這可以通過一個簡單的常規終端: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', 'bill', getpass.getpass(), 'show ver')
File "/Users/bill/git/tools/python/dns-check/proxy-test.py", line 28, in ssh_command
client.connect(host['hostname'], username='bill', password=getpass.getpass(), 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工作,這將是偉大的,如果有人知道更好的方式,那也將是好的。 感謝您的時間。
有一種更好的方法,仍然使用ProxyCommand
但沒有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>', 22,), ('127.0.0.1', 0))
# Finally connect to switch1 via server2 channel
switch1_client.connect('switch1', sock=server2_chan)
switch1_client.exec_command(<command>)
用其IP地址替換服務器和交換機名稱。
另請參閱基於paramiko的並行SSH客戶端,該客戶端支持本機SSH隧道。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.