Kushal Das: Working over ssh in Python

Working with the remote servers is a common scenario for most of us. Sometimes,
we do our actual work over those remote computers, sometimes our code does
something for us in the remote systems. Even Vagrant instances on your laptop
are also remote systems, you still have to ssh into those systems to get things
done.

Setting up of the remote systems

Ansible is the tool we use in Fedora
Infrastructure. All of our servers are configured using Ansible, and all of
those playbooks/roles are in a public git
repository
. This
means you can also setup your remote systems or servers in the exact same way
Fedora Project does.

I also have many friends who manage their laptops or personal servers using
Ansible. Setting up new development systems means just a run of a playbook for
them. If you want to start doing the same, I suggest you have a look at the
lightsaber built by Ralph
Bean
.

Working on the remote systems using Python

There will be always special cases where you will have to do something on a
remote system from your application directly than calling an external tool
(read my previous blog post on the same topic). Python has an excellent module
called Paramiko to help us out. This is a
Python implementation of SSHv2 protocol.

def run(host='127.0.0.1', port=22, user='root',
                  command='/bin/true', bufsize=-1, key_filename='',
                  timeout=120, pkey=None):
    """
    Excecutes a command using paramiko and returns the result.
    :param host: Host to connect
    :param port: The port number
    :param user: The username of the system
    :param command: The command to run
    :param key_filename: SSH private key file.
    :param pkey: RSAKey if we want to login with a in-memory key
    :return:
    """
    client = paramiko.SSHClient()
    client.set_missing_host_key_policy(paramiko.AutoAddPolicy())

    client.connect(hostname=host, port=port,
            username=user, key_filename=key_filename, banner_timeout=10)
    chan = client.get_transport().open_session()
    chan.settimeout(timeout)
    chan.set_combine_stderr(True)
    chan.get_pty()
    chan.exec_command(command)
    stdout = chan.makefile('r', bufsize)
    stdout_text = stdout.read()
    status = int(chan.recv_exit_status())
    client.close()
    return stdout_text, status

The above function is a modified version of the run function from
Tunir codebase. We are creating a new client,
and then connecting to the remote system. If you have an in-memory
implementation of the RSA Key, then you can use the pkey parameter the
connect method, otherwise, you can provide the full path to the private key
file as shown in the above example. I also don’t want to verify or store the
host key, the second line of the function adds a policy to make sure of that.

Working on the remote systems using Golang

Now, if you want to do the same in golang, it will not be much different. We
will use golang’s crypto/ssh
package. The following is taken from gotun
project. Remember to fill in the proper error handling as required by your
code. I am just copy-pasting the important parts from my code as an example.

func (t TunirVM) FromKeyFile() ssh.AuthMethod {
	file := t.KeyFile
	buffer, err := ioutil.ReadFile(file)
	if err != nil {
		return nil
	}

	key, err := ssh.ParsePrivateKey(buffer)
	if err != nil {
		return nil
	}
	return ssh.PublicKeys(key)
}

sshConfig := &ssh.ClientConfig{
	User: viper.GetString("USER"),
	Auth: []ssh.AuthMethod{
		vm.FromKeyFile(),
	},
}

connection, err := ssh.Dial("tcp", fmt.Sprintf("%s:%s", ip, port), sshConfig)
session, err = connection.NewSession()
defer session.Close()
output, err = session.CombinedOutput(actualcommand)

Creating an ssh connection to a remote system using either Python or Golang is
not that difficult. Based on the use case choose to either have that power in
your code or reuse an existing powerful tool like Ansible.


Source From: fedoraplanet.org.
Original article title: Kushal Das: Working over ssh in Python.
This full article can be read at: Kushal Das: Working over ssh in Python.

Advertisement


Random Article You May Like

Leave a Reply

Your email address will not be published. Required fields are marked *

*
*