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.
Related
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
I am working on a script to pull configs from Cisco devices in GNS3. The script should be looping through a text file and slicing the IP & Port from each line into variables. These variable are then fed into the telnet connection as the IP & Port parameters of Telnetlib.
import telnetlib
#Open file with list of switches
f = open ("C:\ProgramData\ports.txt")
#Telnet to each switch and configure it
for line in f:
linePort = line[10:]
lineIP = line[:-6]
print "Getting running-config " + lineIP + " " + linePort
tn = telnetlib.Telnet(lineIP,linePort)
However using the variables always ends up in an error being thrown (see below) but if I hard code the same values I am able to create the connection without issue. As it works with a hard coded value I tried forcing a string type with str() on the two variables but it didn't change the result and it still throws the below error.
C:\Users\SomeUser>python %userprofile%\desktop\config.py
Getting running-config 127.0.0.1 5000
Traceback (most recent call last):
File "C:\Users\Michael\desktop\config.py", line 11, in <module>
tn = telnetlib.Telnet(lineIP,linePort)
File "C:\python27amd64\lib\telnetlib.py", line 211, in __init__
self.open(host, port, timeout)
File "C:\python27amd64\lib\telnetlib.py", line 227, in open
self.sock = socket.create_connection((host, port), timeout)
File "C:\python27amd64\lib\socket.py", line 557, in create_connection
for res in getaddrinfo(host, port, 0, SOCK_STREAM):
socket.gaierror: [Errno 10109] getaddrinfo failed
The error being thrown is socket.gaierrr: [Errno 10109] getaddrinfo failed which I have tried looking into but have not been able to find a resolution for that works for me. Given that this process is supposed to be automated and in a loop it is vital to get it working with variable. As such any help that you all could provide would be much appreciated.
I stumbled across the answer to this in another question and it makes me feel like an idiot for the oversight.
When using variables for the parameters of Telnet the port needs to be an integer. As such the solution was to force it by using int(var) and then it connected without issue. The now working code is as follows.
import telnetlib
#Open file with list of switches
f = open ("C:\ProgramData\ports.txt")
#Telnet to each switch and configure it
for line in f:
linePort = line[10:]
lineIP = line[:-6]
print "Getting running-config " + lineIP + " " + linePort
tn = telnetlib.Telnet(lineIP,int(linePort))
Part of my script:
def testConnection(self):
# This code doesn't work
try:
self.imap.login(self.user, self.password)
return True
except:
return False
When I try to connect with imaplib to mail server with wrong settings, script always crashes with this error:
Traceback (most recent call last):
File "./mail-notifier.py", line 198, in <module>
mail_check()
File "./mail-notifier.py", line 161, in mail_check
if (SettingsExist() == True and Mail().testConnection() == True):
File "./mail-notifier.py", line 142, in __init__
self.imap = imaplib.IMAP4_SSL(settings.value("MailServer"), settings.value("Port"))
File "/usr/lib64/python3.4/imaplib.py", line 1221, in __init__
IMAP4.__init__(self, host, port)
File "/usr/lib64/python3.4/imaplib.py", line 181, in __init__
self.open(host, port)
File "/usr/lib64/python3.4/imaplib.py", line 1234, in open
IMAP4.open(self, host, port)
File "/usr/lib64/python3.4/imaplib.py", line 257, in open
self.sock = self._create_socket()
File "/usr/lib64/python3.4/imaplib.py", line 1224, in _create_socket
sock = IMAP4._create_socket(self)
File "/usr/lib64/python3.4/imaplib.py", line 247, in _create_socket
return socket.create_connection((self.host, self.port))
File "/usr/lib64/python3.4/socket.py", line 512, in create_connection
raise err
File "/usr/lib64/python3.4/socket.py", line 503, in create_connection
sock.connect(sa)
socket.timeout: timed out
I can't catch timeout exception and print error message and continue to work. I thought " except: " catches all errors that happen. I tried to set " except socket.timeout: " but unsuccessfully. What did I wrong?
socket.connect(address)
Connect to a remote socket at address. (The format of address depends on the address family — see above.)
If the connection is interrupted by a signal, the method waits until the connection completes, or raise a socket.timeout on timeout, if the signal handler doesn’t raise an exception and the socket is blocking or has a timeout. For non-blocking sockets, the method raises an InterruptedError exception if the connection is interrupted by a signal (or the exception raised by the signal handler).
Changed in version 3.5: The method now waits until the connection completes instead of raising an InterruptedError exception if the connection is interrupted by a signal, the signal handler doesn’t raise an exception and the socket is blocking or has a timeout (see the PEP 475 for the rationale).
In case of remote connection you should check if the Internet connection can be established (you and remote destination are reachable) and connection setting to perform actions you want are correct.
I am trying to create a telnet to Teamspeak 3 Server Query through python, this is my code:
__author__ = 'Khailz'
import telnetlib, socket
HOST = "unlightedgaming.com"
port = 10011
timeout = 5
for i in range(len(HOST)):
print "scanning " + HOST[i] + " ...\n"
try:
tn = telnetlib.Telnet(HOST[i],23,3)
except socket.timeout:
pass
#tn = telnetlib.Telnet(host, port, timeout)
#telnetlib.Telnet(host, port, timeout)
tn.read_until("Welcome to the TeamSpeak 3 ServerQuery interface")
print tn.read_all()
But i seem to get the error from socket saying that it cannot get the address.
C:\Python27\python.exe C:/Users/Khailz/PycharmProjects/Teamspeak-IRC/test.py
scanning 1 ...
Traceback (most recent call last):
File "C:/Users/KhailzXsniper/PycharmProjects/Teamspeak-IRC/test.py", line 14, in <module>
tn = telnetlib.Telnet(HOST[i],23,3)
File "C:\Python27\lib\telnetlib.py", line 211, in __init__
self.open(host, port, timeout)
File "C:\Python27\lib\telnetlib.py", line 227, in open
self.sock = socket.create_connection((host, port), timeout)
File "C:\Python27\lib\socket.py", line 553, in create_connection
for res in getaddrinfo(host, port, 0, SOCK_STREAM):
socket.gaierror: [Errno 11004] getaddrinfo failed
What am I doing wrong
For each character in HOST, you are attempting to resolve that character; this is due to your use of a for loop in combination with indexing HOST. For example in the first iteration you attempt to connect to a host with an I.P. of "1"- that is what produces the gaierror.
To fix it, just don't attempt to connect to a specific index of HOST: get rid of HOST[i] and replace it with HOST alone in the call to telnetlib.Telnet:
tn = telnetlib.Telnet(HOST, 23, 3)
As to what you're trying to do with that loop, however, I'm baffled.
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'