📜 ⬆️ ⬇️

Working with ssh in Python

Good day everyone.

I want to tell you about paramiko - a module for working with ssh in python.
With it, you can write a script that will access the remote server (or many) and do something on it.

Who cares - I ask under the cat.

Quite often, at work, it was necessary to perform very similar actions on client servers. The actions are trivial, like “correct line 12 in the configuration file” or “replace the file„ version_017 “with„ version_018 “. It was easy until the servers had accumulated * eleven pieces. Also, such tasks were bored very quickly, so they tried to entrust similar work to beginners with the wording “to acquire skills in working with ssh”.
')
At first, the simplest tasks could be solved using standard ssh tools — file copying and remote code execution. Also tried using the empty utility.

At that time I was beginning to learn python, I decided to see what it has for these purposes. Google helpfully prompted about paramiko.

Paramiko (a combination of Eperanto words “paranoid” and “friend” - “paranoja" + "amiko") is a module for python version 2.3 and higher that implements the ssh2 protocol for a secure (encrypted and authenticated) connection to a remote computer. connection provides a high-level API for working with ssh - an SSHClient object is created.For greater control, you can transfer a socket (or similar object) to the Transport class and work with a remote host as a server or client. For authentication, you can use a password or a private key and verify at the server key.

A small example of the use of this module. Comments will be lower.

import paramiko host = '192.168.0.8' user = 'login' secret = 'password' port = 22 client = paramiko.SSHClient() client.set_missing_host_key_policy(paramiko.AutoAddPolicy()) client.connect(hostname=host, username=user, password=secret, port=port) stdin, stdout, stderr = client.exec_command('ls -l') data = stdout.read() + stderr.read() client.close() 


You can get data for access to a remote server in any convenient way - write it directly in the code, put it into the config, database, etc. Obviously, if there are several hosts, you need to do a loop to bypass them.

The main class for connectivity and remote work is SSHClient. He provides us with a “session” with which we can work further.

In the client.set_missing_host_key_policy line (paramiko.AutoAddPolicy ()) we add the server key to the list of known hosts - the .ssh / known_hosts file. If the key is not found in it when connecting to the server, then by default the key “fights back” and causes an SSHException.

To connect to the server, use client.connect (). You can log in as a combination of login-password and the keys. When connecting, you can specify a host, username, password, port, key, and other parameters.

The string client.exec_command ('ls -l') - executes the command on the remote server. Program I / O streams are returned in file-like objects - stdin, stdout, stderr.

Perhaps, I didn’t understand, but I didn’t manage to get root rights on a dedicated server. I would be grateful if I was told how to do it. To perform actions with superuser rights, do the following:

 stdin, stdout, stderr = ssh.exec_command('sudo -S rm *') stdin.write('password' + '\n') stdin.flush() 


UPD: meph1st0 in the comments suggested for this purpose to use the class Channel

 import paramiko client = paramiko.SSHClient() client.set_missing_host_key_policy(paramiko.AutoAddPolicy()) client.connect(...) channel = lient.get_transport().open_session() channel.get_pty() channel.settimeout(5) channel.exec_command('sudo ls') channel.send(password+'\n') print channel.recv(1024) channel.close() client.close() 


To transfer files via sftp, you can use the Transport class. To transfer files directly, use the put and get commands.

 host = "example.com" port = 22 transport = paramiko.Transport((host, port)) transport.connect(username='login', password='password') sftp = paramiko.SFTPClient.from_transport(transport) remotepath = '/path/to/remote/file.py' localpath = '/path/to/local/file.py' sftp.get(remotepath, localpath) sftp.put(localpath, remotepath) sftp.close() transport.close() 


In short everything. Project site and documentation - http://www.lag.net/paramiko/

UPD. The comments suggested that there are a number of other tool libraries that can also be used to work on ssh solutions for similar tasks. Of the above: fabric, chef, puppet, libbsh2 (pylibbsh2), exscript and net-ssh-telnet on Ruby. Thanks to all the commentators.

Source: https://habr.com/ru/post/150047/


All Articles