Thursday 25 August 2016

Python based SSH / password client

Previously I have used expect to be able to automating doing ssh to hosts that don't have password-less configured yet.
expect is a bit confusing to use and it took me a bit of time to compile a good reusable expect script. (you can find more info about it in this older post)

Python provides a more elegant solution using the Paramiko SSH2 liberary.
Using this library we can create a simple ssh client that can take a host, a username, a base64 encrypted password and a command string from the command line and then execute it on the remote host.

This can then be used further inside any script similar to the SSH command.

Those scripts are created on Centos 7 using the Python 2.7 Centos packages. Paramiko came along with my Python installation but stil you can install it if it is missing using:

# pip install paramiko

Centos doesn't come with pip, so you need to install it using yum.

Now, let me show a very small password encoder so we can use the base64 encryption to hid the password used on command line:

[root@feanor ~]# cat ./b64encode.py
#!/usr/bin/python

import base64
import sys

string = sys.argv[1]
codedstring = ''
codedstring = base64.b64encode(string)

print string, codedstring
[root@feanor ~]#


[root@feanor ~]# ./b64encode.py mypassword
mypassword bXlwYXNzd29yZA==
[root@feanor ~]#



The above will generate the coded password and can be run in a secure machine, the base64 encoded password then needs to stored in a secured file (user only access , eg: mod 600) and used for our script as below:

[root@feanor ~]# ./sshconnect.py localhost root "`cat ~/passwordfile`" "uname -a;hostname"



Some might argue that this base64 can be cracked easily, but I would say it is better than using a plan text password.



The actual script can be found below:

#!/usr/bin/python

import sys
import paramiko
import base64

if len(sys.argv) < 5:
    print "args missing"
    sys.exit(1)

hostname = sys.argv[1]
username = sys.argv[2]
b64password = sys.argv[3]
command = sys.argv[4]

password = base64.b64decode(b64password)

port = 22
 

try:
    clientSession = paramiko.SSHClient()
    clientSession.load_system_host_keys()
    clientSession.set_missing_host_key_policy(paramiko.WarningPolicy())
    clientSession.connect(hostname, port=port, username=username, password=password)
    stdin, stdout, stderr = clientSession.exec_command(command)
    print stdout.read()
finally:
    clientSession.close()





Again it is always better to use SSH public key authentication, most of the time i use this method once so that i can set the keys and never use the password for logging into a machine any more.
Passwords need to be strong and long 15 chars at least if they must be used.

An example random password generators can be found at:

http://passwordsgenerator.net/  (Should be using https for this site, though it offers a good set of password generation options)
https://www.random.org/passwords/ (Use advanced mode and change the seed)
https://strongpasswordgenerator.com/
https://www.grc.com/passwords.htm   (Really strong 64 char passwords !!)

No comments:

Post a Comment