I am trying SSH to hosts (number in hundreds) using paramiko with multithreading.
Here is my code with multithreading,
import paramiko
from concurrent.futures import ThreadPoolExecutor
# Initialising paramiko SSH Client
client = paramiko.SSHClient()
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
# Fetching hosts
file = open("hosts.txt")
content = file.readlines()
hosts = [host.strip() for host in content]
def ssh(host):
try:
print("Connecting to", host)
client.connect(host,
username="SOMEUSER",
password="SOMEPASS",
timeout=1,
banner_timeout=1,
auth_timeout=1)
print("Connected to", host)
# Need to check something here...
client.close()
print(f"Connection to {host} closed.")
return True
except:
print("FAILED to connect", host)
return False
with ThreadPoolExecutor(max_workers=4) as executor:
results = list(executor.map(ssh, hosts))
for i, host in enumerate(hosts):
print(host, "=>", results[i])
Q1: I am getting false results compared to the code without any multithreading. What is wrong with my multithreading here and how can I make this work?
Q2: Somehow the below exception is being raised (multiple times) and I have no idea how this exception is not getting caught?
Exception: Error reading SSH protocol banner
Traceback (most recent call last):
File "/home/tesit/.local/lib/python3.6/site-packages/paramiko/transport.py", line 2211, in _check_banner
buf = self.packetizer.readline(timeout)
File "/home/tesit/.local/lib/python3.6/site-packages/paramiko/packet.py", line 380, in readline
buf += self._read_timeout(timeout)
File "/home/tesit/.local/lib/python3.6/site-packages/paramiko/packet.py", line 619, in _read_timeout
raise EOFError()
EOFError
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/home/tesit/.local/lib/python3.6/site-packages/paramiko/transport.py", line 2039, in run
self._check_banner()
File "/home/tesit/.local/lib/python3.6/site-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
Moving the initialization of Paramiko SSH Client inside the function definition done the trick for me! Now code works correctly as compared to the one without multithreading.
Here is my code after fixing the problem
import paramiko
from concurrent.futures import ThreadPoolExecutor
file = open("hosts.txt")
content = file.readlines()
hosts = [host.strip() for host in content]
def ssh(host):
try:
client = paramiko.SSHClient()
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
print("Connecting to", host)
client.connect(host,
username="SOMEUSER",
password="SOMEPASS",
timeout=1,
banner_timeout=1,
auth_timeout=1)
print("Connected to", host)
# Need to check something here...
client.close()
print(f"Connection to {host} closed.")
return True
except:
print("FAILED to connect", host)
return False
with ThreadPoolExecutor(max_workers=4) as executor:
output = list(executor.map(ssh, hosts))
for i, host in enumerate(hosts):
print(host, "=>", output[i])
Even though now the code works well as I intended, the below exception is not getting caught!
Traceback (most recent call last):
File "/home/tesit/.local/lib/python3.6/site-packages/paramiko/transport.py", line 2211, in _check_banner
buf = self.packetizer.readline(timeout)
File "/home/tesit/.local/lib/python3.6/site-packages/paramiko/packet.py", line 380, in readline
buf += self._read_timeout(timeout)
File "/home/tesit/.local/lib/python3.6/site-packages/paramiko/packet.py", line 607, in _read_timeout
x = self.__socket.recv(128)
ConnectionResetError: [Errno 104] Connection reset by peer
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/home/tesit/.local/lib/python3.6/site-packages/paramiko/transport.py", line 2039, in run
self._check_banner()
File "/home/tesit/.local/lib/python3.6/site-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 104] Connection reset by peer
Related
I use Paramiko Python module to write a simple multiple ssh connections throw:
import paramiko
import time
i=0
while i<20 :
ssh = paramiko.SSHClient()
starttime=time.clock()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
try:
ssh.connect('127.0.0.1', username="user", password="password")
except:
endtime=time.clock()
except OSError:
print("Os error")
except paramiko.SSHException:
print("Ssh error")
total=endtime-starttime
print(total)
i=i+1
The problem is that the code does not capture all the raised exceptions, i.e. :
Exception: Error reading SSH protocol banner[Errno 104] Connection reset by peer
Traceback (most recent call last):
File "/usr/local/lib/python3.5/dist-packages/paramiko/transport.py", line 2000, in _check_banner
buf = self.packetizer.readline(timeout)
File "/usr/local/lib/python3.5/dist-packages/paramiko/packet.py", line 353, in readline
buf += self._read_timeout(timeout)
File "/usr/local/lib/python3.5/dist-packages/paramiko/packet.py", line 531, in _read_timeout
x = self.__socket.recv(128)
ConnectionResetError: [Errno 104] Connection reset by peer
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 1854, in run
self._check_banner()
File "/usr/local/lib/python3.5/dist-packages/paramiko/transport.py", line 2005, in _check_banner
'Error reading SSH protocol banner' + str(e)
paramiko.ssh_exception.SSHException: Error reading SSH protocol banner[Errno 104] Connection reset by peer
Exception: Error reading SSH protocol banner
Traceback (most recent call last):
File "/usr/local/lib/python3.5/dist-packages/paramiko/transport.py", line 2000, in _check_banner
buf = self.packetizer.readline(timeout)
File "/usr/local/lib/python3.5/dist-packages/paramiko/packet.py", line 353, in readline
buf += self._read_timeout(timeout)
File "/usr/local/lib/python3.5/dist-packages/paramiko/packet.py", line 533, in _read_timeout
raise EOFError()
EOFError
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 1854, in run
self._check_banner()
File "/usr/local/lib/python3.5/dist-packages/paramiko/transport.py", line 2005, in _check_banner
'Error reading SSH protocol banner' + str(e)
paramiko.ssh_exception.SSHException: Error reading SSH protocol banner
I would capture all the raised exceptions in order to total control my std-output.
I have some piece of code like this
import paramiko
try:
client = paramiko.SSHClient()
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
client.connect(IP, username=myusername,password=mypassword,timeout=3)
except:
print ("[-] Wrong : "+ip+" : "+username+" : "+password)
And when I run it, it keeps giving tracebacks about SSH problem such as this:
Traceback (most recent call last):
paramiko.ssh_exception.SSHException: Error reading SSH protocol banner
I would like to know if it is possible to not print at all on the screen any Traceback messages?
Thanks
Here's the full error:
Traceback (most recent call last):
File "test123.py", line 50, in function1
client.connect(ip, username=myusername, password=mypassword,timeout=3)
File "/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/site-packages/paramiko/client.py", line 380, in connect
look_for_keys, gss_auth, gss_kex, gss_deleg_creds, gss_host)
File "/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/site-packages/paramiko/client.py", line 621, in _auth
raise saved_exception
File "/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/site-packages/paramiko/client.py", line 608, in _auth
self._transport.auth_password(username, password)
File "/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/site-packages/paramiko/transport.py", line 1271, in auth_password
return self.auth_handler.wait_for_response(my_event)
File "/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/site-packages/paramiko/auth_handler.py", line 208, in wait_for_response
raise e
paramiko.ssh_exception.AuthenticationException: Authentication failed.
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/work.py", line 920, in _bootstrap_inner
self.run()
File "/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/work.py", line 868, in run
self._target(*self._args, **self._kwargs)
File "test123.py", line 56, in slaveWork
except paramiko.ssh_exception:
TypeError: catching classes that do not inherit from BaseException is not allowed
Exception: Error reading SSH protocol banner
Traceback (most recent call last):
File "/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/site-packages/paramiko/transport.py", line 1888, in _check_banner
buf = self.packetizer.readline(timeout)
File "/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/site-packages/paramiko/packet.py", line 331, in readline
buf += self._read_timeout(timeout)
File "/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/site-packages/paramiko/packet.py", line 498, in _read_timeout
raise EOFError()
EOFError
You could just finish your try and just do a general catch and then do nothing with it.
import paramiko
try:
client = paramiko.SSHClient()
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
client.connect(IP, username=myusername,password=mypassword,timeout=3)
except Exception as e:
pass
Probably the best alternative would be to use the tracebacklimit module.
For Python 2.x you could do:
import sys
import paramiko
sys.tracebacklimit = 0
try:
client = paramiko.SSHClient()
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
client.connect(IP, username=myusername,password=mypassword,timeout=3)
except:
print ("[-] Wrong : "+ip+" : "+username+" : "+password)
For Python 3.5 (tracebacklimit) some people have reported that this should be set to None to work, i.e.:
sys.tracebacklimit = None
For multiple exception raised some people reported is not guaranteed to work (In Python, how do I print an error message without printing a traceback and close the program when a condition is not met?).
I am having an issue handling a timeout error in Paramiko. Below is similar to what I am using to connect.
try:
dssh = paramiko.SSHClient()
dssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
dssh.connect(IP, username, password)
stdin, stdout, stderr = dssh.exec_command('sho run')
status = 'success'
except paramiko.AuthenticationException:
status = 'fail'
When a host is down I get an error such as the one below and the script aborts.
Traceback (most recent call last):
File "ssh3.py", line 23, in <module>
dssh.connect(IP, username, password)
File "/usr/lib/python2.7/site-packages/paramiko/client.py", line 296, in connect
sock.connect(addr)
File "/usr/lib/python2.7/socket.py", line 224, in meth
return getattr(self._sock,name)(*args)
socket.error: [Errno 116] Connection timed out
Is there a way to catch this error and allow the script to run beginning to end?
Surely. You just need to catch the exception that is being raised.
# At the beginning of your code:
import socket
# In your loop
try:
# Your stuff
# Replace the existing exception handler:
except (socket.error, paramiko.AuthenticationException):
status = 'fail'
I trying use tor proxy for ssh.
First simple connection without ~/.ssh/config
~$ ssh -p <SERVER_POST> <USER>#<SERVER_HOST>
<USER>#<SERVER_HOST>'s password:
~$ echo $SSH_CONNECTION
<MY_REAL_HOST> <MY_REAL_PORT> <SERVER_HOST> <SERVER_PORT>
Second with next ~/.ssh/config:
Host *
ProxyCommand connect -4 -S 127.0.0.1:9050 $(tor-resolve %h 127.0.0.1:9050) %p
and connect:
~$ ssh -p <SERVER_POST> <USER>#<SERVER_HOST>
<USER>#<SERVER_HOST>'s password:
~$ echo $SSH_CONNECTION
<NOT_MY_REAL_HOST> <NOT_MY_REAL_HOST> <SERVER_HOST> <SERVER_PORT>
Now with paramiko:
>>> import paramiko
>>> client = paramiko.SSHClient()
>>> proxy = None
>>> client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
>>> client.connect(hostname=host, username=user, password=password,
... port=port, sock=proxy)
>>> stdin, stdout, stderr = client.exec_command('echo $SSH_CONNECTION')
>>> print((stdout.read() + stderr.read()).decode('utf8'))
<MY_REAL_HOST> <MY_REAL_PORT> <SERVER_HOST> <SERVER_PORT>
All work fine. But when I try set up proxy:
>>> import paramiko
>>> client = paramiko.SSHClient()
>>> proxy = paramiko.ProxyCommand(
... 'connect -4 -S 127.0.0.1:9050 $(tor-resolve %h 127.0.0.1:9050) %p')
>>> client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
>>> client.connect(hostname=host, username=user, password=password,
... port=port, sock=proxy)
>>> stdin, stdout, stderr = client.exec_command('echo $SSH_CONNECTION')
>>> print((stdout.read() + stderr.read()).decode('utf8'))
I have next exception for python 3.4:
Exception: Error reading SSH protocol bannersequence item 0: expected str instance, bytes found
Traceback (most recent call last):
File "/home/tbicr/Project/env34/lib/python3.4/site-packages/paramiko/transport.py", line 1535, in _check_banner
buf = self.packetizer.readline(timeout)
File "/home/tbicr/Project/env34/lib/python3.4/site-packages/paramiko/packet.py", line 271, in readline
buf += self._read_timeout(timeout)
File "/home/tbicr/Project/env34/lib/python3.4/site-packages/paramiko/packet.py", line 424, in _read_timeout
x = self.__socket.recv(128)
File "/home/tbicr/Project/env34/lib/python3.4/site-packages/paramiko/proxy.py", line 93, in recv
result = ''.join(self.buffer)
TypeError: sequence item 0: expected str instance, bytes found
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/home/tbicr/Project/env34/lib/python3.4/site-packages/paramiko/transport.py", line 1412, in run
self._check_banner()
File "/home/tbicr/Project/env34/lib/python3.4/site-packages/paramiko/transport.py", line 1539, in _check_banner
raise SSHException('Error reading SSH protocol banner' + str(e))
paramiko.ssh_exception.SSHException: Error reading SSH protocol bannersequence item 0: expected str instance, bytes found
Traceback (most recent call last):
File "/home/tbicr/Project/env34/lib/python3.4/site-packages/paramiko/transport.py", line 1535, in _check_banner
buf = self.packetizer.readline(timeout)
File "/home/tbicr/Project/env34/lib/python3.4/site-packages/paramiko/packet.py", line 271, in readline
buf += self._read_timeout(timeout)
File "/home/tbicr/Project/env34/lib/python3.4/site-packages/paramiko/packet.py", line 424, in _read_timeout
x = self.__socket.recv(128)
File "/home/tbicr/Project/env34/lib/python3.4/site-packages/paramiko/proxy.py", line 93, in recv
result = ''.join(self.buffer)
TypeError: sequence item 0: expected str instance, bytes found
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/home/tbicr/Project/registrator/main.py", line 70, in <module>
client.connect(hostname=host, username=user, password=password, port=port, sock=proxy)
File "/home/tbicr/Project/env34/lib/python3.4/site-packages/paramiko/client.py", line 242, in connect
t.start_client()
File "/home/tbicr/Project/env34/lib/python3.4/site-packages/paramiko/transport.py", line 346, in start_client
raise e
File "/home/tbicr/Project/env34/lib/python3.4/site-packages/paramiko/transport.py", line 1412, in run
self._check_banner()
File "/home/tbicr/Project/env34/lib/python3.4/site-packages/paramiko/transport.py", line 1539, in _check_banner
raise SSHException('Error reading SSH protocol banner' + str(e))
paramiko.s
For python 2.7 same exception with other stacktrace:
No handlers could be found for logger "paramiko.transport"
Traceback (most recent call last):
File "/home/tbicr/Project/registrator/main.py", line 70, in <module>
client.connect(hostname=host, username=user, password=password, port=port, sock=proxy)
File "/home/tbicr/Project/env27/local/lib/python2.7/site-packages/paramiko/client.py", line 242, in connect
t.start_client()
File "/home/tbicr/Project/env27/local/lib/python2.7/site-packages/paramiko/transport.py", line 339, in start_client
raise e
paramiko.ssh_exception.SSHException: Error reading SSH protocol banner
So connection with ssh client and tor work fine, but with paramiko not.
Why it's not work and how I can fix it for python?
I am trying to write a python script to establish a telnet connection (using telnetlib) to a range of hosts:
for i in range(len(HOST)):
print "scanning " + HOST[i] + " ...\n"
tn = telnetlib.Telnet(HOST[i],23,3)
The problem is when one of the connections times out, the script executions interrupts and returns the following error:
Traceback (most recent call last):
File "C:\Python27\telnet.py", line 24, in <module>
tn = telnetlib.Telnet(HOST[i],23,3)
File "C:\Python27\lib\telnetlib.py", line 209, in __init__
self.open(host, port, timeout)
File "C:\Python27\lib\telnetlib.py", line 225, in open
self.sock = socket.create_connection((host, port), timeout)
File "C:\Python27\lib\socket.py", line 571, in create_connection
raise err
socket.timeout: timed out
Anyone knows how to skip this error and continue the script?
You need to use a try...except block to catch the exception and tell the interpreter to ignore it. For example:
import socket
for i in range(len(HOST)):
print "scanning " + HOST[i] + " ...\n"
try:
tn = telnetlib.Telnet(HOST[i],23,3)
except socket.timeout:
pass
In this case it's a good idea to explicitly state which exception you want to catch (socket.timeout). Sockets can throw many different types of exceptions so using a generic except: statement might mask a problem with opening, reading or writing to the socket.