繁体   English   中英

paramiko ssh客户端不适用于HP交换机

[英]paramiko ssh client does not work with HP switches

我一直在将脚本用于Unix服务器,并且运行良好。 但是,当我使用相同的脚本(进行一些小的命令更改)连接到HP Procurve交换机时,脚本会崩溃,并显示错误。 该脚本的一部分如下:

ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect(address, username=userna, password=passwd)

stdin,stdout,stderr= ssh.exec_command("show ver")

for line in stdout:
    print '... ' + line.strip('\n')

ssh.close()

这给了错误

Traceback (most recent call last):
File "C:/Users/kucar/Desktop/my_python/switchmodel", line 34, in <module>
stdin,stdout,stderr= ssh.exec_command("show ver")
File "C:\Python27\lib\site-packages\paramiko\client.py", line 379, in exec_command
chan.exec_command(command)
File "C:\Python27\lib\site-packages\paramiko\channel.py", line 218, in exec_command
self._wait_for_event()
File "C:\Python27\lib\site-packages\paramiko\channel.py", line 1122, in _wait_for_event
raise e
SSHException: Channel closed.

我在网上发现了类似的投诉,但是似乎根本没有提供解决方案。 开关对ssh开放并且可以与腻子配合使用。 感谢您提出任何可以帮助我的想法。 我不能为100个交换机手动执行“ show ver”命令。

正如上面提到的@dobbo,您必须在通道上执行invoke_shell(),以便可以执行多个命令。 另外,HP ProCurve在输出中具有ANSI转义码,因此您必须将其去除。 最后,HP ProCurve会显示一条“按任意键继续”的消息,至少在某些设备上,该消息必须通过。

我在此库中有一个HP ProCurve处理程序https://github.com/ktbyers/netmiko

将device_type设置为“ hp_procurve”。

Exscript还具有某种ProCurve处理程序,尽管我还没有对其进行足够的研究以使其正常工作。

使用ssh服务器连接到Samsung s4手机时,我有相同的经验。 连接到SUSE VM或Rasperry Pi时我没有任何问题,还尝试了MobaXterm(上周输入的是SO)。

我没有找到答案,但是会分享我的研究。

我查看了源代码,并在channel.py中找到了1122行(复制如下)。

使用电话(可能还有您的HP交换机),我注意到根本没有登录消息或MOTD,并且退出(使用Putty / mobaXterm)时,会话无法正常结束。

在其他一些阅读中,我发现parameko不再得到作者的太多支持,但是其他人正在努力将其移植到python 3x。

这是我找到的源代码。

def _wait_for_send_window(self, size):
    """
    (You are already holding the lock.)
    Wait for the send window to open up, and allocate up to C{size} bytes
    for transmission.  If no space opens up before the timeout, a timeout
    exception is raised.  Returns the number of bytes available to send
    (may be less than requested).
    """
    # you are already holding the lock
    if self.closed or self.eof_sent:
        return 0
    if self.out_window_size == 0:
        # should we block?
        if self.timeout == 0.0:
            raise socket.timeout()
        # loop here in case we get woken up but a different thread has filled the buffer
        timeout = self.timeout
        while self.out_window_size == 0:
            if self.closed or self.eof_sent:
                return 0
            then = time.time()
            self.out_buffer_cv.wait(timeout)
            if timeout != None:
                timeout -= time.time() - then
                if timeout <= 0.0:
                    raise socket.timeout()
    # we have some window to squeeze into

看来,如果不清理连接缓冲区,则在使用HP Procurves时,Paramiko会发疯。 首先,您需要调用Shell,否则Paramiko会在第一个命令之后简单地删除连接(正常行为,但会造成混乱)。

ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect(switch_ip, username=switch_user, password=switch_pass,look_for_keys=False)
conn = ssh.invoke_shell()
recieveData() # <-- see below

实际处理数据很重要,据我了解,您需要确保Paramiko在收到要求处理数据之前确实收到了所有数据。 我通过使用以下功能来做到这一点。 您可以根据需要调整睡眠时间,在某些情况下0.050可以正常工作。

def recieveData():
    tCheck = 0
    while not conn.recv_ready():
        time.sleep(1)
        tCheck+=1
        if tCheck >=10:
            print "time out"
    cleanThatStuffUp(conn.recv(1024)) # <-- see below

这是返回到ssh客户端的垃圾的示例。

[1;24r[24;1H[24;1H[2K[24;1H[?25h[24;1H[24;1HProCurve Switch 2650# [24;1H[24;23H[24;1H[?5h[24;23H[24;23Hconfigure[24;23H[?25h[24;32H[24;0HE[24;1H[24;32H[24;1H[2K[24;1H[?5h[24;1H[1;24r[24;1H[1;24r[24;1H[24;1H[2K[24;1H[?25h[24;1H[24;1H

每个“ [”之前都有退出代码要处理。 因此,为了解决这个问题,我想出了一些正则表达式来清理所有“东西”。

procurve_re1 = re.compile(r'(\[\d+[HKJ])|(\[\?\d+[hl])|(\[\d+)|(\;\d+\w?)')
procurve_re2 = re.compile(r'([E]\b)')
procurve_re3 = re.compile(ur'[\u001B]+') #remove stupid escapes

def cleanThatStuffUp(message):
   message = procurve_re1.sub("", message)
   message = procurve_re2.sub("", message)
   message = procurve_re3.sub("", message)
   print message

现在您可以输入命令了,只需确保每次使用recieveData()清除缓冲区即可。

conn.send("\n") # Get past "Press any key"
recieveData()

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM