【发布时间】:2019-12-03 04:27:19
【问题描述】:
在 python3 中,我使用 multiprocessing.Pool 并行运行 paramiko 以连接到子网上的每个 ssh 设备。我遇到了一系列似乎无法捕获的错误。
我在这里放了各种 try/except 语句,但没有一个能捕捉到这个错误。我什至用 try/except 包装了 Pool 设置和语句,但那里没有任何改变。所有 paramiko 的东西都在 try_login 函数中,所以它应该来自那里,但所有这些都在 try/except 中,甚至还有一个通用的 except 应该得到所有东西。
我也尝试过组合导致此输出的异常。
#!/usr/bin/env python3
import paramiko
import socket
import ipaddress
network_address = '192.168.50.0/24'
username = ''
password = ''
timeout = 3
num_threads = 30
def trylogin(ipaddress):
global username, password
try:
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect(ipaddress, username=username, password=password, timeout=timeout)
(stdin, stdout, stderr) = ssh.exec_command('cat /var/serial_number')
imei = stdout.readline()
if imei != '': print("[+] {}: Success! Found ".format(ipaddress))
return [ipaddress, imei]
except paramiko.AuthenticationException:
print("[-] {}: Authentication Exception!".format(ipaddress))
except paramiko.SSHException:
print("[-] {}: SSH Exception!".format(ipaddress))
except (paramiko.ssh_exception.SSHException, OSError, EOFError):
pass
except EOFError:
pass
except OSError:
pass
except paramiko.ssh_exception.NoValidConnectionsError:
pass
except paramiko.ssh_exception.SSHException:
pass
except Exception as e:
print('caught a new fish')
print(e)
pass
finally:
try:
ssh.close()
except:
pass
return
network = ipaddress.ip_network(network_address)
for ipaddr in network.hosts():
print('Checking {}'.format(str(ipaddr)))
trylogin(str(ipaddr))
运行时会发生大部分应该发生的事情。但我收到一个错误,显示我认为已处理的两个异常。首先是 OSError,然后是 paramiko.ssh_exception.SSHException。我不明白为什么我不能捕获这些。
$ ./find_ssh.py
[-] 192.168.50.1 trying...
[-] 192.168.50.2 trying...
[-] 192.168.50.3 trying...
[-] 192.168.50.4 trying...
[-] 192.168.50.5 trying...
[-] 192.168.50.6 trying...
[-] 192.168.50.7 trying...
[-] 192.168.50.8 trying...
[-] 192.168.50.9 trying...
[-] 192.168.50.10 trying...
[-] 192.168.50.10: Authentication Exception!
[-] 192.168.50.11 trying...
[-] 192.168.50.12 trying...
[-] 192.168.50.13 trying...
[-] 192.168.50.14 trying...
[-] 192.168.50.14: SSH Exception!
[-] 192.168.50.15 trying...
Exception: Error reading SSH protocol banner[Errno 9] Bad file descriptor
Traceback (most recent call last):
File "/usr/local/lib/python3.5/dist-packages/paramiko/transport.py", line 2211, in _check_banner
buf = self.packetizer.readline(timeout)
File "/usr/local/lib/python3.5/dist-packages/paramiko/packet.py", line 380, in readline
buf += self._read_timeout(timeout)
File "/usr/local/lib/python3.5/dist-packages/paramiko/packet.py", line 607, in _read_timeout
x = self.__socket.recv(128)
OSError: [Errno 9] Bad file descriptor
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/usr/local/lib/python3.5/dist-packages/paramiko/transport.py", line 2039, in run
self._check_banner()
File "/usr/local/lib/python3.5/dist-packages/paramiko/transport.py", line 2216, in _check_banner
"Error reading SSH protocol banner" + str(e)
paramiko.ssh_exception.SSHException: Error reading SSH protocol banner[Errno 9] Bad file descriptor
[-] 192.168.50.16 trying...
[-] 192.168.50.17 trying...
[-] 192.168.50.18 trying...
[-] 192.168.50.19 trying...
[-] 192.168.50.20 trying...
编辑:修改为删除多处理调用。它更慢但更清晰。
【问题讨论】:
-
尝试不使用 map (这不会导致错误),而是(也不要使用 list comprehensions)使用旧的 for 循环,并在 trylogin 调用之间添加 print,您会发现事情会变得简单得多。当简单的事情不清楚时,最好远离复杂的事情:)
-
虽然是个好建议,但它不再买我了。我确实这样做了,但没有新的错误。我添加了一些日志记录以确定导致问题的设备,即 192.168.50.15。当我手动 ssh -vvv 到该设备时,与没有错误的设备相比,我没有看到任何不同的行为。
标签: python python-3.x error-handling try-catch paramiko