Paramiko SSHClient.connect fails while SSH works - python

in the terminal, the following works just fine:
> ssh me#host -p 22
but the following python code gives me a TimeoutError:
from paramiko import SSHClient
client = SSHClient()
client.connect(hostname='host', port=22, username='me', look_for_keys=True)
Any idea why that would be the case? The connection uses RSA keys for authentication, and I'm over a VPN. Seems like I'm missing some context I need to tell paramiko about, but I can't figure out what it is.

I usually connect to a remote server by adding an explicit link to my private key:
HOST = 'hostname'
USER = 'username'
PKEY = '/path/to/rsa_private_key'
PKEY_PASS = 'xxx'
k = paramiko.RSAKey.from_private_key_file(PKEY, PKEY_PASS)
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
print "connecting"
ssh.connect(HOST, username=USER, pkey=k)
connect_status = 'connected' if ssh else 'failed to connect'
print connect_status

Related

Attempting to do remote login over SSH connection using python script

I am trying to log in to a remote server after setting up an SSH connection. I can get the SSH Tunnel to work, but from there I'm stumped on how to log in.
I am currently using Python's sshtunnel extension, which successfully connects me to the place I need. Now I need to be able to log in which I would usually do through a terminal with the command "ssh remotepc-ssh" (I have all the information stored in a /.ssh/config file)
I have already tried paramiko but it continuously gives me errors or won't load in the end. I also tried pysftp which is what I show in the code below but when I try to get the my known_hosts it tells me that it isn't finding any known ones, and when I try to set hosts to None, the system won't connect.
from sshtunnel import SSHTunnelForwarder
#import paramiko
import pprint
import pysftp
# create SSH tunnel
SERVER_HOST = "hostname"
SERVER_PASS = "********"
LOGIN_HOST = "loginUsername"
LOGIN_PASS = "*********"
server = SSHTunnelForwarder(
SERVER_HOST,
ssh_password = SERVER_PASS,
remote_bind_address=('127.0.0.1', 8080)
)
try:
server.start()
print("Connected to SSH Tunnel with local bind port %s" %server.local_bind_port)
###################################
# BROKEN PART BELOW
# establish remote connection
try:
print("\nEstablishing connection to %s" %LOGIN_HOST)
cnopts = pysftp.CnOpts()
cnopts.hostkeys.load = ("known_hosts")
with pysftp.Connection(LOGIN_HOST, password = LOGIN_PASS, cnopts = cnopts) as sftp:
print("CONNECTED")
except:
print("Unable to connect")
pass
##################################
server.stop()
print("\nServer stopped. Goodbye")
except:
print("Could not connect")
pass
I've just came by and solved the same issue, so let me share my working example:
with SSHTunnelForwarder(
("SSH_HOST",22),
ssh_username="SSH_USERNAME",
ssh_pkey="SSH_KEY",
remote_bind_address=("SFTP_HOST", 22),
) as tunnel:
# do some operations with client session
with pysftp.Connection(host='127.0.0.1', port=server.local_bind_port, username="SFTP_USERNAME",
private_key="SFTP_KEY", cnopts=cnopts) as sftp:
print("Connection succesfully stablished ... ")
print(sftp.listdir('public'))
print('FINISH!')

Connecting to SFTP client using proxy command in Python

I need to connect to SFTP server using proxy command.
I know how to connect to SFTP server directly:
paramiko's sshclient with sftp
I can open an SSH connection via proxy command using this code:
import paramiko
client = paramiko.SSHClient()
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
target_host = 'sftp.XXXXX.co'
target_port = 22
proxy = paramiko.proxy.ProxyCommand('/usr/bin/nc --proxy proxy_host:8080 %s %d' % (target_host, target_port) )
client.connect(hostname=target_host,username='username', port=target_port, password='XXXXXXXX', sock=proxy)
But I need to create SFTPClient, not SSHClient. But I do not know how to pass the ProxyCommand to the SFTPClient.
To connect to SFTP server using a "custom socket", do:
proxy = paramiko.proxy.ProxyCommand(...)
transport = paramiko.Transport(proxy)
transport.connect(username = username, password = password)
sftp = paramiko.SFTPClient.from_transport(transport)

paramiko allows sftp connection without key

I was running the demo_sftp.py file from the demo folder in the paramiko github. I was stepping through it in PyDev and expected to get an error because I didn't have a key to the server I was trying to connect to but I got the print statement saying that the script couldn't open the host key file and then it went ahead and did the get and put.
Here's a code snippet.
try:
host_keys = paramiko.util.load_host_keys(os.path.expanduser('~/.ssh/known_hosts'))
except IOError:
try:
# try ~/ssh/ too, because windows can't have a folder named ~/.ssh/
host_keys = paramiko.util.load_host_keys(os.path.expanduser('~/ssh/known_hosts'))
except IOError:
print '*** Unable to open host keys file'
host_keys = {}
if host_keys.has_key(hostname):
hostkeytype = host_keys[hostname].keys()[0]
hostkey = host_keys[hostname][hostkeytype]
print 'Using host key of type %s' % hostkeytype
# now, connect and use paramiko Transport to negotiate SSH2 across the connection
try:
t = paramiko.Transport((hostname, port))
t.connect(username=username, password=password, hostkey=hostkey)
sftp = paramiko.SFTPClient.from_transport(t)
# dirlist on remote host
dirlist = sftp.listdir('.')
print "Dirlist:", dirlist
I really expected it to go to the except on the t.connect line because hostkey is NoneType.
When I open an ssh connection with
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
try:
ssh.connect('.'.join([self.name, self.domain]),
username=self.username, password=self.password)
stdin, stdout, stderr = ssh.exec_command("ps aux | grep Xvnc | wc -l")
I have to have the AutoAddPolicy() line or it fails. So what's the difference? Obviously I'm just learning this but I thought that sftp would be just as strict as ssh.
It looks like this is an acceptable practice.
Comment from Transport.connect
'''
Negotiate an SSH2 session, and optionally verify the server's host key
and authenticate using a password or private key. This is a shortcut
for L{start_client}, L{get_remote_server_key}, and
L{Transport.auth_password} or L{Transport.auth_publickey}. Use those
methods if you want more control.
You can use this method immediately after creating a Transport to
negotiate encryption with a server. If it fails, an exception will be
thrown. On success, the method will return cleanly, and an encrypted
session exists. You may immediately call L{open_channel} or
L{open_session} to get a L{Channel} object, which is used for data
transfer.
#note: If you fail to supply a password or private key, this method may
succeed, but a subsequent L{open_channel} or L{open_session} call may
fail because you haven't authenticated yet.
'''
Comment from SSHClient.connect
'''
Connect to an SSH server and authenticate to it. The server's host key
is checked against the system host keys (see L{load_system_host_keys})
and any local host keys (L{load_host_keys}). If the server's hostname
is not found in either set of host keys, the missing host key policy
is used (see L{set_missing_host_key_policy}). The default policy is
to reject the key and raise an L{SSHException}.
'''
Maybe it is due to the fact that sftp can only transport data while ssh can run terminal commands. I do find it interesting that a man-in-the-middle attack doesn't seem to be a concern.
You can use below syntax
import pysftp
cnopts = pysftp.CnOpts()
cnopts.hostkeys = None
with pysftp.Connection(hostname, port=port, username=user_id, password=password,
cnopts=cnopts) as sftp:
with sftp.cd(self.directory): # temporarily chdir to public
sftp.put(filepath)

Paramiko SFTPClient - Setting missing host key policy?

I know with Paramiko's SSHClient class, you can set a relaxed missing host key policy like so:
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
However, I'm opening a file stream via SFTP (not SSHClient), like so:
t = paramiko.Transport((process['hostname'], 22))
keyfile = paramiko.DSSKey.from_private_key_file('./id_dsa')
t.connect(username = 'user', pkey = keyfile)
sftp = paramiko.SFTPClient.from_transport(t)
I couldn't locate anything in the docs for setting a missing host key policy via Transport, or SFTPClient.
Is there any way to achieve the same thing using SFTPClient?
Cheers,
Victor
One can get SFTP client from SSH client by using open_sftp().
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
sftp = ssh.open_sftp()
sftp.get('remotefile', 'localfile')
Though I haven't tested this.

paramiko can't open SFTP connection

I'm having some trouble opening an SFTP connection with paramiko. My current code is:
client = SSHClient()
client.set_missing_host_key_policy(AutoAddPolicy())
client.load_system_host_keys()
client.connect('some.example.com', username="myuser", password="mypassword")
sftp_client = client.open_sftp()
sftp_client.put(my_local_file)
But at the point where I hit client.open_sftp(), I get an exception of "Unable to open channel."
Any idea what might cause this? I've been able to open the connection to the server with a command-line sftp client.
I'm guessing about my invocation here, if anyone can point me to an example, that would be great.
You need to first create and connect to a transport:
transport = Transport((host, port))
transport.connect(username = username, pkey = mykey) # or password = mypassword
Now to can start the SFTP client:
sftp_client = SFTPClient.from_transport(transport)
Then you can
sftp_client.put(my_local_file)
and when you're done
sftp_client.close()
transport.close()

Categories