I am using Python's paramiko package to connect to a remote Unix machine. I have written this code:
import paramiko
import sys
import os
import os.path
passwd = "XXX"
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect("173.15.13.28", "root", password=passwd)
stdin, stdout, stderr = ssh.exec_command('ls')
x = stdout.readlines()
print x
for line in x:
print line
ssh.close()
after executing I am getting this error:
Traceback (most recent call last):
File "<pyshell#9>", line 1, in <module>
ssh.connect("173.15.13.28", "root", password="--------")
File "C:\Python27\lib\site-packages\paramiko\client.py", line 282, in connect
for (family, socktype, proto, canonname, sockaddr) in socket.getaddrinfo(hostname, port,socket.AF_UNSPEC, socket.SOCK_STREAM):
gaierror: [Errno 10109] getaddrinfo failed
I don't know what the problem is.
The second argument of the connect() method is the port number, which defaults to 22. You are putting "root" there, which won't work. Use the keyword argument username="root". That is, try this:
ssh.connect("173.15.13.28", username="root", password=passwd)
See also: python paramiko, getaddrinfo error when trying to establish an SSH connection
Related
I am trying to connect to SFTP server but it returns error:
[Errno 11001] getaddrinfo failed
I am using Python 3.7.3 and Paramiko version is 2.6.0
import paramiko
host_name = "sftp://81.149.151.143"
user_name = "******"
password = "******"
ssh_client = paramiko.SSHClient()
ssh_client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh_client.connect(hostname=host_name, port=220, username=user_name, password=password)
ftp_client=ssh_client.open_sftp()
ftp_client.put('***/issue_1.docx', '/issue_1.docx')
ftp_client.close()
This is the full error:
Traceback (most recent call last):
File "/sftp/paramiko_bot.py", line 10, in <module>
ssh_client.connect(hostname=host_name, port=22, username=user_name, password=password)
File "\Local\Programs\Python\Python37\lib\site-packages\paramiko\client.py", line 340, in connect
to_try = list(self._families_and_addresses(hostname, port))
File "\Local\Programs\Python\Python37\lib\site-packages\paramiko\client.py", line 204, in _families_and_addresses
hostname, port, socket.AF_UNSPEC, socket.SOCK_STREAM
File "\AppData\Local\Programs\Python\Python37\lib\socket.py", line 748, in getaddrinfo
for res in _socket.getaddrinfo(host, port, family, type, proto, flags):
socket.gaierror: [Errno 11001] getaddrinfo failed
The hostname parameter of SSHClient.connect should contain a hostname only (or in your case an IP address) – not any kind of URL.
ssh_client.connect(hostname="81.149.151.143", port=220, username=..., password=...)
Obligatory warning: Do not use AutoAddPolicy this way – You are losing a protection against MITM attacks by doing so. For a correct solution, see Paramiko "Unknown Server".
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.
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.
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
If this fails:
ssh = paramiko.SSHClient()
ssh.connect( host, username = USER , pkey = MY_KEY, timeout = 2)
I get a traceback like:
File "<stdin>", line 1, in <module>
File "<stdin>", line 7, in bs_process
File "/usr/lib/python2.7/site-packages/paramiko/client.py", line 282, in connect
for (family, socktype, proto, canonname, sockaddr) in socket.getaddrinfo(hostname, port, socket.AF_UNSPEC, socket.SOCK_STREAM):
socket.gaierror: [Errno -2] Name or service not known
I cant figure what kind/kinds of errors Paramiko throws for bad connect attempts. Which are the exception classes and how can I import them?
You can start by looking at the API documentation, for all classes ending in Exception:
http://docs.paramiko.org/en/1.15/api/client.html#paramiko.client.SSHClient.connect
Then, you should also catch socket.error. I think that will get you pretty much everything. socket.gaierror is a subclass of socket.error, for example.
The accepted answer has a broken link. The documentation for Paramiko now lives at:
http://docs.paramiko.org/en/1.15/api/client.html#paramiko.client.SSHClient.connect
It the "connect" method will raise the following:
BadHostKeyException – if the server’s host key could not be verified
AuthenticationException – if authentication failed
SSHException – if there was any other error connecting or establishing an SSH session
socket.error – if a socket error occurred while connecting
The problem is with the call to ssh.connect().
In this case, is necessarily specified the connection port.
Example:
ssh.connect(server, port=22, username=user, pkey=key)
That work for me.