Python - How do I authenticate SSH connection with Fabric module? - python

I'm trying to SSH into a Raspberry Pi on a subnet via ethernet using the Fabric module but I can't figure out how to authenticate the connection.
My code so far is as follows
import fabric
c = fabric.Connection(host = "192.168.3.151", port = 22, user = "pi")
c.run("touch Desktop/new_file.txt")
Obviously I haven't put in my password, "Raspberry", anywhere in the above code to authenticate the SSH connection. I've been trying to understand the Fabric documentation but it's a little beyond me so I'm hoping someone can tell me how to input the password to authenticate the connection (and also authenticate any commands using sudo).
Thanks!

Okay, it looks like you can pass options to the Connection constructor that will be passed on to SSHClient.connect
c = fabric.Connection("192.168.3.151", port=22, user="pi", connect_kwargs={'password': 'raspberry'})
Note it's generally a bad idea to store your passwords in plain text, especially in code.
See http://docs.fabfile.org/en/2.1/concepts/authentication.html as well as http://docs.fabfile.org/en/2.1/concepts/configuration.html

Related

Paramiko session scope

I have some doubts about Paramiko. If I do the standard code found in internet:
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect(hostname='remote_host', username='...', password='...')
// TODO
ssh.close()
Let's say I have some kind of JDBC connector and I try to connect to a database placing the code below within the TODO section
ssh.connect(hostname='remote_host', username='...', password='...')
connector.connect(database_params...)
ssh.close()
My question is. In that case the client of the database server would be remote_host or my local machine where the Python script is being executed?
Or the right way would be using sshtunnel? like so:
with open_tunnel(
('remote_host', '22'),
ssh_username=...,
ssh_password=...,
remote_bind_address=('DB_ADDRESS', 'DB_PORT')
local_bind_address=('SOME_IP', 'SOME_PORT')
) as server:
connector.connect(db_host='SOME_IP', db_port='SOME_PORT', ...)
Is there any difference between those two approaches?
Thanks in advance.
Opening SSH connection using Paramiko or any other way, has no effect whatsoever on your database connection, nor any other connections, nor a file access, nor command execution. So your first code has no chance of doing, what you want.
Everything you want to do via the SSH connection, you need to do via the Paramiko API.
And that's what open_tunnel does, internally.
For an equivalent standalone code, see forward_tunnel function in Paramiko forward.py demo.

How to move multiple files from local machine to a sever using Python

We have a framework used to validate few test cases and results will be stored in local machine containing multiple text and images.
Need to move these files from our local host to server.
I have the sever IP address, username and password.
So using Python I need to move these files or copy it to server
If you are going for ssh, you'll have to use scp and there is a dedicated Python package for that: Paramiko. See this post on stackoverflow.
import paramiko
def createSSHClient(server, port, user, password):
client = paramiko.SSHClient()
client.load_system_host_keys()
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
client.connect(server, port, user, password)
return client
ssh = createSSHClient(server, port, user, password)
scp = SCPClient(ssh.get_transport())
scp.put([file1,file2],remotePath)
Of course, you have to specify the various variables according to their name. The scp.put function takes a list of local files and a destination path on the remote system as arguments.
used SCP to do the transfer
ssh -i ~/.ssh/id_rsa intel#10.223.98.165 "mkdir < Folder created >"
scp -i ~/.ssh/id_rsa < source >*.txt < destination >
using os.system()
Thanks for helping
This is not really a Python problem: You say you have a username and a password to the server, but that doesn't tell us the least in which way you can access that server. Do you have SSH access? Then use scp as a command-line program or one of the numerous Python modules that make that possible.
The same goes for protocols like FTP, WebDAV, cifs/smb, NFS, ... It all depends on what ways you have to access/modify/create files on the server. Hence, this answer is all I can give you to your extremely inaccurate question.

Remote tcp connection in python with zeromq

I have a python client that needs to talk to a remote server I manage. They communicate using zeromq. When I tested the client/server locally everything worked. But now I have the client and server deployed on the cloud, each using a different provider. My question is, what's the simplest way (that is safe) to make the connection? I'm assuming I can't pass the password over, and even if I could I'm guessing there are safer alternatives.
I know how to set an ssh connection without a password using ssh-keygen. Would that work? Would the client need to make an ssh connection with the server before sending the tcp req? If there's a python library that helps with this it'd be a big help.
Thanks!
Update:
So more than 24 hours passed and no one replied/answered. I think I'm getting closer to solve this, but not quite there yet. I added my client's key to .ssh/authorized_key on the server, and now I can ssh from the client to the server without a password. Next, I followed this post about "Tunneling PyZMQ Connections with SSH". Here's what I have in my client code:
1 context = zmq.Context()
2 socket = context.socket(zmq.REQ)
3 socket.connect("tcp://localhost:5555")
4 ssh.tunnel_connection(socket, "tcp://locahost:5555", "myuser#remote-server-ip:5555")
5 socket.send_string(some_string)
6 reply = socket.recv()
This doesn't work. I don't really understand lines 3 & 4 and I assume I do something wrong there. Also, my server (hosted on linode) has a "Default Gateway" IP and a "Public IP" -- in the tunnel connection I only specify the public ip, which is also the ip I use to ssh to the machine.
Indeed, ZMQ way is - tunnelling connection with the SSH. Your example is exactly what needs to be done, except that one should either use connect or tunnel_connection, not both.
Also, when specifying server to connect to, make sure to define the SSH port, not the ZMQ REP socket port. That is, instead of myuser#remote-server-ip:5555 you might try myuser#remote-server-ip or myuser#remote-server-ip:22.
import zmq
import zmq.ssh
context = zmq.Context()
socket = context.socket(zmq.REQ)
zmq.ssh.tunnel_connection(socket, "tcp://locahost:5555", "myuser#remote-server-ip")
socket.send(b"Hello")
reply = socket.recv()
Finally, make sure you've installed either pexpect or paramiko - they will do the tunnelling actually. Note that if you're using Windows, paramiko is the only solution which will work - pexpect openssh tunnelling won't work on Windows.
If you use paramiko instead of pexpect, make sure to set paramiko=True in the tunnel_connection arguments.
I have found ssh in Python to be iffy at best, even with paramiko and fabric libraries, so to debug, you might try setting up a tunnel separately, just to see if that's the issue with the broken connection.
For example:
ssh myuser#remote-server-ip -L 5050:localhost:5555 -N
This says: connect to myuser#remote-server-ip, and whenever I request a connection to localhost:5050 on my machine, forward it across the ssh connection so that the server at remote-server-ip thinks it's receiving a connection from localhost:5555.
-L constructs the tunnel, and -N means don't do anything else on the connection.
With that running in another shell, e.g., a different Terminal window, on your local development machine, try to connect to a zeromq server at localhost:5050, which will actually be the zeromq running on the remote server.
You could use 5555:localhost:5555 in the ssh command above, but I find that can be confusing and often conflicts with a local copy of the same service.

SSH connection with python

I'd like to make a python script that connect with an SSH server, but as I can't send password as an argv, how could I do that?
os.system("user#server password")
And if it fails, what would be the return?
You should probably looking into doing this with a library or wrapper to make this work out properly and with more support. Here are some examples.
You can use some 3rd libraries like fabric or Paramiko
Use Paramiko:
client = paramiko.SSHClient()
client.connect('my.example.com', username='brandon', password=mypass)

Unexpected session close error is thrown when connecting netconf

I am using ncclient to connect to the netconf. However when ever i try to connect through python
"ncclient.transport.errors.SessionCloseError: Unexpected session close" error is thrown. the code snippet that i am using is given below
manager.connect('<servername>',22,username='<username>')
Any help on this is much appriciated. I am able to connect to the remote server by using public key, hence i didnt provide passwordk in connect
And in the netconf server logs i am able to see access-denied error. (I got the same prob even when i tried with username and pwd)
You haven't given a lot of information.
Which version of ncclient are you using?
Which version of Python are you using?
Which NETCONF implementation are you trying to connect to? Is this to an actual switch or router, or something like a Linux server running libnetconf or yuma?
Based on the info here, I could imagine a couple of things being wrong:
paramiko isn't using the right key to establish SSH transport.
You're attempting to establish a NETCONF session with an SSH server rather than a NETCONF server.
In your script, create some logs with something like manager.logging.basicConfig(filename='ncclient.log', level=manager.logging.DEBUG) and then re-run your script - do you get anything more informative?
This is an old question, but I hope I can point you in the right direction at least.
its possible that your machines don't know each other (like when you connect via normal ssh and get the "unknown key, really connect (y/n)?" error. In that case, by default the session will not connect. To change this behavior use the "unknown_host_cb" parameter:
def allowUnknownHosts(host,fingerprint):
return True
self.manager = manager.connect(host=host, port=port, username=user,password=password, unknown_host_cb=allowUnknownHosts)

Categories