Python SSH Tutorial

Advertisement

Advertisement

Introduction

SSH (secure shell) is good for remotely managing machines using a secure connection. Typically you will log in to a server using the command-line ssh tool, or something like PuTTy or MobaXTerm. This guide will show you how to use Python to connect and run commands over SSH using the Paramiko package.

Installation

The easiest way to install paramiko is using pip.

python -m pip install paramiko

To install from source, clone from GitHub and then install using setup.py.

git clone https://github.com/paramiko/paramiko
cd paramiko
python setup.py install

Connect to SSH

Connect to an SSH server using paramiko.client.SSHClient.connect(). The hostname is the only required parameter.

connect(hostname, port=22, username=None, password=None, pkey=None, key_filename=None, timeout=None, allow_agent=True, look_for_keys=True, compress=False, sock=None, gss_auth=False, gss_kex=False, gss_deleg_creds=True, gss_host=None, banner_timeout=None, auth_timeout=None, gss_trust_dns=True, passphrase=None, disabled_algorithms=None)

One thing to consider is what trusted known host keys you have. You can use paramiko.client.SSHClient.load_system_host_keys(). You can also explicitly load a specific known hosts file with load_host_keys() and set the client to automatically accept and add unknown hosts with set_missing_host_key_policy() to paramiko.AutoAddPolicy. Use these options as needed. The AutoAddPolicy is not very secure since it will trust any remote host.

Connect using password

from paramiko import SSHClient

client = SSHClient()
#client.load_system_host_keys()
#client.load_host_keys('~/.ssh/known_hosts')
#client.set_missing_host_key_policy(AutoAddPolicy())

client.connect('example.com', username='user', password='secret')
client.close()

Connect using SSH key

Using an SSH key is more secure than using a password. Call connect() just like using the password, but instead of providing the user password, we will provide a key_filename and maybe a passphrase for the key. The passphrase may not be needed if your private key file does not have a passphrase.

You can also omit the key file and let Paramiko try to find the right key automatically in your ~/.ssh/ directory. You can turn that on by calling client.look_for_keys(True). The first example will show how to explicitly provide the key and passphrase and the second one will show how to look for keys.

# Explicitly provide key and passphrase
from paramiko import SSHClient, AutoAddPolicy

client = SSHClient()
#client.load_system_host_keys()
#client.load_host_keys('~/.ssh/known_hosts')
#client.set_missing_host_key_policy(AutoAddPolicy())

client.connect('example.com', username='user', key_filename='mykey.pem', passphrase='mysshkeypassphrase')
client.close()

This example show hows to look for keys in ~/.ssh/ automatically.

from paramiko import SSHClient

client = SSHClient()
#client.load_system_host_keys()
#client.load_host_keys('~/.ssh/known_hosts')
#client.set_missing_host_key_policy(AutoAddPolicy())

client.look_for_keys(True)
client.connect('example.com', username='user')
client.close()

Run commands over SSH

Once you have a connection open, you can execute any command just like you would if you were in a regular interactive SSH session.

This example shows how to:

  • Run a command on the server
  • Provide standard input data to command
  • Read standard output and error from command
  • Get the return code of the command

The command run in this example is the PHP interpreter with the code provided via standard input. The output is then printed out and the return code is checked.

from paramiko import SSHClient

# Connect
client = SSHClient()
client.load_system_host_keys()
client.connect('example.com', username='user', password='secret')

# Run a command (execute PHP interpreter)
stdin, stdout, stderr = client.exec_command('php')
print(type(stdin))  # <class 'paramiko.channel.ChannelStdinFile'>
print(type(stdout))  # <class 'paramiko.channel.ChannelFile'>
print(type(stderr))  # <class 'paramiko.channel.ChannelStderrFile'>

# Optionally, send data via STDIN, and shutdown when done
stdin.write('<?php echo "Hello!"; sleep(2); ?>')
stdin.channel.shutdown_write()

# Print output of command. Will wait for command to finish.
print(f'STDOUT: {stdout.read().decode("utf8")}')
print(f'STDERR: {stderr.read().decode("utf8")}')

# Get return code from command (0 is default for success)
print(f'Return code: {stdout.channel.recv_exit_status()}')

# Because they are file objects, they need to be closed
stdin.close()
stdout.close()
stderr.close()

# Close the client itself
client.close()

Conclusion

After reading this guide you should know how to connect to an SSH server using a password or SSH key. You should also know how to run a command, pass data to standard input, and read the output from standard output and error.

References

Advertisement

Advertisement