Name resolution may fail because there is no ip associated with the hostname, or because the DNS server cannot be reached. Unfortunately, Python's socket.create_connection and socket.gethostbyname functions seem to raise the same error in both situations:
$ python3 -c 'import socket; socket.create_connection(("www.google.com_bar", 80))'
Traceback (most recent call last):
File "<string>", line 1, in <module>
File "/usr/lib/python3.4/socket.py", line 491, in create_connection
for res in getaddrinfo(host, port, 0, SOCK_STREAM):
File "/usr/lib/python3.4/socket.py", line 530, in getaddrinfo
for res in _socket.getaddrinfo(host, port, family, type, proto, flags):
socket.gaierror: [Errno -2] Name or service not known
$ python3 -c 'import socket; socket.gethostbyname("www.google_bar.com")'
Traceback (most recent call last):
File "<string>", line 1, in <module>
socket.gaierror: [Errno -5] No address associated with hostname
$ sudo vim /etc/resolv.conf # point to non-existing nameserver
$ python3 -c 'import socket; socket.create_connection(("www.google.com", 80))'
Traceback (most recent call last):
File "<string>", line 1, in <module>
File "/usr/lib/python3.4/socket.py", line 491, in create_connection
for res in getaddrinfo(host, port, 0, SOCK_STREAM):
File "/usr/lib/python3.4/socket.py", line 530, in getaddrinfo
for res in _socket.getaddrinfo(host, port, family, type, proto, flags):
socket.gaierror: [Errno -2] Name or service not known
$ python3 -c 'import socket; socket.gethostbyname("www.google.com")'
Traceback (most recent call last):
File "<string>", line 1, in <module>
socket.gaierror: [Errno -5] No address associated with hostname
Is there any way to distinguish these two cases that does not require me to perform a second lookup for a "known-good" hostname?
The solution should work under Linux.
You can use the dnslib library client to make the DNS request yourself. The client provides dig like functionality that can indicate if an address fails to resolve (NXDOMAIN) compared to just failing to resolve (which unfortunately just blocks - see patch below).
You use it like so:
from dnslib import DNSRecord, RCODE
# I have dnsmasq running locally, so I can make requests to localhost.
# You need to find the address of the DNS server.
# The /etc/resolv.conf file is quite easily parsed, so you can just do that.
DNS_SERVER = "127.0.0.1"
query = DNSRecord.question("google.com")
response = DNSRecord.parse(query.send(DNS_SERVER, 53, False))
print RCODE[response.header.rcode] # prints 'NOERROR'
query = DNSRecord.question("google.com_bar")
response = DNSRecord.parse(query.send(DNS_SERVER, 53, False))
print RCODE[response.header.rcode] # prints 'NXDOMAIN'
# To avoid making the DNS request again when using the socket
# you can get the resolved IP address from the response.
The problem comes when making a connection to a non existant DNS Server. Every time I have tried this the request just hangs. (When I make the same requests on the command line, using something like netcat, the request also just hangs. I may be picking random IPs poorly and suffering from firewalls that just drop the packets)
Anyway you can alter the source code to add a timeout. You can view the relevant method in the source here (also mirrored on github). What I changed was:
--- a/dns.py
+++ b/dns.py
## -357,6 +357,7 ##
response = response[2:]
else:
sock = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
+ sock.settimeout(10)
sock.sendto(self.pack(),(dest,port))
response,server = sock.recvfrom(8192)
sock.close()
After doing this the DNS request timed out.
Related
I wanted to connect to a extender for a Wi-Fi project, but I don't know if I can connect to an extender using the Fabric module for Python...
I was trying to connect to a server using it's name, but I'm sure that the name is wrong, but I don't know if I'm connecting wrong. Here is my code:
from fabric import Connection
node = Connection('KIN-AP23')
letsgo = node.run('help')
I don't know how to connect since I got this error:
Traceback (most recent call last):
File "main.py", line 5, in <module>
letsgo = node.run('help')
File "<decorator-gen-3>", line 2, in run
File "/home/runner/FLIPPER1/venv/lib/python3.8/site-packages/fabric/connection.py", line 29, in opens
self.open()
File "/home/runner/FLIPPER1/venv/lib/python3.8/site-packages/fabric/connection.py", line 636, in open
self.client.connect(**kwargs)
File "/home/runner/FLIPPER1/venv/lib/python3.8/site-packages/paramiko/client.py", line 349, in connect
to_try = list(self._families_and_addresses(hostname, port))
File "/home/runner/FLIPPER1/venv/lib/python3.8/site-packages/paramiko/client.py", line 203, in _families_and_addresses
addrinfos = socket.getaddrinfo(
File "/nix/store/2vm88xw7513h9pyjyafw32cps51b0ia1-python3-3.8.12/lib/python3.8/socket.py", line 918, in getaddrinfo
for res in _socket.getaddrinfo(host, port, family, type, proto, flags):
socket.gaierror: [Errno -2] Name or service not known
I know for sure that's not the right name but is there any extra stuff I have to do, if so tell me, if not still tell me how to do it!
I'm trying to connect to my server using SSH with port 2022 (not 22) in Python. So I wrote the following code that uses Paramiko package:
import sys
import paramiko
try:
client = paramiko.SSHClient()
client.load_system_host_keys()
client.set_missing_host_key_policy(paramiko.WarningPolicy)
client.connect('ccap#10.40.2.222', '2022', '', 'ccap')
finally:
client.close()
But when I'm running it in my IDE (PyCharm) I get the following error:
/usr/local/lib/python3.5/dist-packages/paramiko/ecdsakey.py:164: CryptographyDeprecationWarning: Support for unsafe construction of public numbers from encoded data will be removed in a future version. Please use EllipticCurvePublicKey.from_encoded_point
self.ecdsa_curve.curve_class(), pointinfo
Traceback (most recent call last):
File "/home/mshapirs/PycharmProjects/OnlineTest.py/OnlineTest.py", line 9, in
client.connect('ccap#10.40.2.222', '2022', '', 'ccap')
File "/usr/local/lib/python3.5/dist-packages/paramiko/client.py", line 334, in connect
to_try = list(self._families_and_addresses(hostname, port))
File "/usr/local/lib/python3.5/dist-packages/paramiko/client.py", line 204, in _families_and_addresses
hostname, port, socket.AF_UNSPEC, socket.SOCK_STREAM
File "/usr/lib/python3.5/socket.py", line 733, in getaddrinfo
for res in _socket.getaddrinfo(host, port, family, type, proto, flags):
socket.gaierror: [Errno -2] Name or service not known
You should provide username as a separate parameter, not prepended to the host address.
Look at the docs for .connect. It has username and hostnamelisted separately.
I need to create simple code that will upload a .csv file to an FTP server. The code is below.
import ftplib
import os
import sys
sourceFilePath = '/home/user/dir/'
filename = 'testing.csv'
destinationDirectory = 'anotherDirectory'
server = 'ftp://12.123.12.234'
username = 'aUser'
password = 'passwd1234'
myFTP = ftplib.FTP(server, username, password)
myFTP.cwd('/anotherDirectory/')
myFTP.storbinary('STOR '+filename, open(filename,'rb'))
myFTP.quit()
However, when I run the code, I get the following error:
Traceback (most recent call last):
File "./UploadToFTP.py", line 20, in <module>
File "./UploadToFTP.py", line 13, in uploadFileFTP
myFTP = ftplib.FTP(server, username, password)
File "/usr/lib64/python2.6/ftplib.py", line 119, in __init__
self.connect(host)
File "/usr/lib64/python2.6/ftplib.py", line 134, in connect
self.sock = socket.create_connection((self.host, self.port),
self.timeout)
File "/usr/lib64/python2.6/socket.py", line 553, in create_connection
for res in getaddrinfo(host, port, 0, SOCK_STREAM):
socket.gaierror: [Errno -3] Temporary failure in name resolution
Has anyone seen this before? It seems rather generic to me and doesn't tell me much. So far as other code I've seen performing this same task, I don't have any currently visible errors. Any help would be appreciated.
The host argument of ftplib.FTP constructor is a hostname/IP address, not a URL.
So this is wrong:
server = 'ftp://12.123.12.234'
It should be:
server = '12.123.12.234'
If your URL contains a custom port, see Python ftplib - specify port.
I am working on file transfer in python. I've been searching a lot but still haven't found a simple demo of a working ftp client-server using pyftpdlib. I think this library is very useful but I don't know how to start using it.
Thank you so much for any help!
EDIT:
OK, I followed the tutorial. My goal is to be able to send/receive files within local machine first.
I run the basic_ftpd.py and get this:
[I 14-07-09 15:08:27] >>> starting FTP server on 127.0.0.1:2121, pid=7000 <<<
[I 14-07-09 15:08:27] poller: <class 'pyftpdlib.ioloop.Select'>
[I 14-07-09 15:08:27] masquerade (NAT) address: None
[I 14-07-09 15:08:27] passive ports: None
Then I run winnt_ftpd.py and I get error:
Traceback (most recent call last):
File "***\lib\winnt_ftpd.py", line 41, in <module>
from pyftpdlib.authorizers import WindowsAuthorizer
ImportError: cannot import name WindowsAuthorizer
Let's assume that I want to send some file in C:/share and in local address I think it should be 127.0.0.1:2121 or localhost:2121. Then from client side I want to get directory listing:
import ftplib
ftp = ftplib.FTP("127.0.0.1:2121")
ftp.login("user", "12345")
data = []
ftp.dir(data.append)
ftp.quit()
for line in data:
print "-", line
But this is not working, I get following error:
Traceback (most recent call last):
File "C:\Users\***\src\client1.py", line 8, in <module>
ftp = ftplib.FTP("127.0.0.1:2121")
File "C:\Python27\lib\ftplib.py", line 117, in __init__
self.connect(host)
File "C:\Python27\lib\ftplib.py", line 132, in connect
self.sock = socket.create_connection((self.host, self.port), self.timeout)
File "C:\Python27\lib\socket.py", line 551, in create_connection
for res in getaddrinfo(host, port, 0, SOCK_STREAM):
socket.gaierror: [Errno 11004] getaddrinfo failed
EDIT:
I changed
ftp = ftplib.FTP("127.0.0.1:2121")
to
ftp = ftplib.FTP("127.0.0.1")
Then I get this error:
socket.error: [Errno 10061] No connection could be made because the target machine actively refused it
Any suggestion?
What about trying this:
conn = ftplib.FTP()
conn.connect('127.0.0.1', 2121)
conn.login('user','12345')
the FTP() constructor accept only the hostname or IP address, instead if you pass nothing and then you configure all with connect() you can pass a tuple with (IP, port)
This should make the trick
I am using poplib to get email from the POP3 server.
But this error occurred:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "C:\Python26\lib\site-packages\myutils.py", line 251, in dxDown
m=poplib.POP3('pop3.126.com')
File "C:\Python26\lib\poplib.py", line 83, in __init__
self.sock = socket.create_connection((host, port), timeout)
File "C:\Python26\lib\socket.py", line 500, in create_connection
for res in getaddrinfo(host, port, 0, SOCK_STREAM):
socket.gaierror: [Errno 11004] getaddrinfo failed
My laptop is in an local network and using a server(ip 192.168.0.1:8080) as proxy to access internet. The error seems poplib cannot interpret the domain "pop3.126.com". How to solve this problem?Thanks!
Your proxy is for http, it doesn't effect the pop3 traffic.
A cursory glance suggests that it's probably not able to resolve the hostname to an IP address.
Can you try one of these:
pop3.126.idns.yeah.net
220.181.15.128
Or paste the output of:
nslookup pop3.126.com