In our lab we have setup passwordless SSH between some systems, using SSH keys. A python script was required that could login to a remote system where passwordless SSH is in place, execute the given command, and obtain its output. I used Paramiko module for doing this task. Here is the script.
import paramiko
remote_system = 'your.ip.address.here'
remote_user = 'jdoe'
remote_port = 22
remote_cmd = 'ls'
remote_ssh_client = paramiko.SSHClient()
# Create SSH client object
remote_ssh_client.load_system_host_keys()
# Load host keys from a system (read-only) file
remote_ssh_client.set_missing_host_key_policy(paramiko.WarningPolicy())
# Set policy to use when connecting to servers without a known host key
# WarningPolicy = Policy for logging a Python-style warning for an unknown
# host key, but accepting it
ssh_connect_timeout = 10
# in seconds
remote_ssh_client.connect(remote_system, port=remote_port, look_for_keys=True, timeout=ssh_connect_timeout)
# Connect to an SSH server and authenticate to it.
# The server's host key is checked against the system host keys (see
# load_system_host_keys) and any local host keys (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 set_missing_host_key_policy)
#
# look_for_keys set to True to enable searching for discoverable private
# key files in ~/.ssh/
#
# Raises : SSHException if the server fails to execute the command
exec_command_timeout = 10
# in seconds
remote_stdin, remote_stdout, remote_stderr = remote_ssh_client.exec_command(remote_cmd, timeout=exec_command_timeout)
# Execute a command on the SSH server. A new Channel is opened and the
# requested command is executed. The command's input and output streams
# are returned as Python file-like objects representing stdin, stdout, and stderr
for line in remote_stdout:
print line.strip('\n')
remote_ssh_client.close()
# Close this SSHClient and its underlying Transport
And how is this script different than the usual way of login using SSH when username and password are given. In this script, I have told SSH to look for private key files of the mentioned user. You'd have noticed that I have not provided a password to the connect function. Instead, I am sending a parameter named look_for_keys along with value True. This makes a search of discoverable private key files in ~/.ssh/ and if found, it is used for login to the remote system.
What if we were using Spur module instead of Paramiko? Spur module does provide the functionality that we are looking for. Instead of sending a password, we could mention our private key file using argument private_key_file. Or we could pass the optional argument look_for_private_keys, in case name of private key is not known beforehand. Here is an example.
import spur
remote_system = 'your.ip.address.here'
remote_user = 'jdoe'
remote_port = 22
remote_cmd = 'ls'
remote_shell = spur.SshShell(
hostname = remote_system,
port = remote_port,
username = remote_user,
look_for_private_keys = True, # Search for discoverable private key files in ~/.ssh/
)
remote_result = remote_shell.run([remote_cmd])
# Execute the given command
print (remote_result.output)
# Display the output obtained from executing the given command
And if you are wondering how to do passwordless SSH setup, well there are plenty of HOW-TOs available all over the Internet.
import paramiko
remote_system = 'your.ip.address.here'
remote_user = 'jdoe'
remote_port = 22
remote_cmd = 'ls'
remote_ssh_client = paramiko.SSHClient()
# Create SSH client object
remote_ssh_client.load_system_host_keys()
# Load host keys from a system (read-only) file
remote_ssh_client.set_missing_host_key_policy(paramiko.WarningPolicy())
# Set policy to use when connecting to servers without a known host key
# WarningPolicy = Policy for logging a Python-style warning for an unknown
# host key, but accepting it
ssh_connect_timeout = 10
# in seconds
remote_ssh_client.connect(remote_system, port=remote_port, look_for_keys=True, timeout=ssh_connect_timeout)
# Connect to an SSH server and authenticate to it.
# The server's host key is checked against the system host keys (see
# load_system_host_keys) and any local host keys (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 set_missing_host_key_policy)
#
# look_for_keys set to True to enable searching for discoverable private
# key files in ~/.ssh/
#
# Raises : SSHException if the server fails to execute the command
exec_command_timeout = 10
# in seconds
remote_stdin, remote_stdout, remote_stderr = remote_ssh_client.exec_command(remote_cmd, timeout=exec_command_timeout)
# Execute a command on the SSH server. A new Channel is opened and the
# requested command is executed. The command's input and output streams
# are returned as Python file-like objects representing stdin, stdout, and stderr
for line in remote_stdout:
print line.strip('\n')
remote_ssh_client.close()
# Close this SSHClient and its underlying Transport
And how is this script different than the usual way of login using SSH when username and password are given. In this script, I have told SSH to look for private key files of the mentioned user. You'd have noticed that I have not provided a password to the connect function. Instead, I am sending a parameter named look_for_keys along with value True. This makes a search of discoverable private key files in ~/.ssh/ and if found, it is used for login to the remote system.
What if we were using Spur module instead of Paramiko? Spur module does provide the functionality that we are looking for. Instead of sending a password, we could mention our private key file using argument private_key_file. Or we could pass the optional argument look_for_private_keys, in case name of private key is not known beforehand. Here is an example.
import spur
remote_system = 'your.ip.address.here'
remote_user = 'jdoe'
remote_port = 22
remote_cmd = 'ls'
remote_shell = spur.SshShell(
hostname = remote_system,
port = remote_port,
username = remote_user,
look_for_private_keys = True, # Search for discoverable private key files in ~/.ssh/
)
remote_result = remote_shell.run([remote_cmd])
# Execute the given command
print (remote_result.output)
# Display the output obtained from executing the given command
And if you are wondering how to do passwordless SSH setup, well there are plenty of HOW-TOs available all over the Internet.
Can you have a python script for setting up passwordless connection to remote server.
ReplyDelete