The trick to accept sudo password is ‘-S’ option in sudo, which accept sudo password piped from stdin.It seems to be safe, I turned on debug and I couldn’t see the password recorded in secure/messages logs.
There are two versions of the script: the command line one and the class/module one.
The command line version.
if the clear text password is an concern, you can wrap the script by getpasswd module in Python,which read password from stdin.Read password once and apply the password to multiple servers.[root@~]# ./pyssh.py -s server1 -u admin -p Passwd123 date Thu Oct 30 15:36:27 EST 2014 #'service sshd status' command ran successfully with sudo enabled '-t' [root@~]# ./pyssh.py -t -s server1 -u admin -p Passwd123 'service sshd status' openssh-daemon (pid 15686) is running... #!/usr/bin/env python import sys import paramiko import argparse import socket parser = argparse.ArgumentParser() parser.add_argument("-s", "--servername", help="hostname or IP", required=True) parser.add_argument("-P", "--port", help="ssh port default=22", default=22) parser.add_argument("-t", "--sudo", help="enable sudo,sudo password will use the value of --password",action='store_true') parser.add_argument("-u","--username",help="username",required=True) parser.add_argument("-p","--password",help="password",required=True) parser.add_argument("cmd",help="command to run") args=parser.parse_args() host = args.servername port = args.port user = args.username password = args.password cmd = args.cmd if args.sudo: fullcmd="echo " + password + " | sudo -S -p '' " + cmd else: fullcmd=cmd #if __name__ == "__main__": client = paramiko.SSHClient() #Don't use host key auto add policy for production servers client.set_missing_host_key_policy(paramiko.AutoAddPolicy()) client.load_system_host_keys() try: client.connect(host,port,user,password) transport=client.get_transport() except (socket.error,paramiko.AuthenticationException) as message: print "ERROR: SSH connection to "+host+" failed: " +str(message) sys.exit(1) session=transport.open_session() session.set_combine_stderr(True) if args.sudo: session.get_pty() session.exec_command(fullcmd) stdout = session.makefile('rb', -1) print stdout.read() transport.close() client.close()
The class version
The class version allow multiple commands to run in an existing SSH transport,which is more efficient.To use the class,copy pyssh.sh to a folder and create a new script to import the class 'from pyssh import PySSH',then reference the code in MAIN section without if statement.#!/usr/bin/env python import sys import socket import paramiko #================================= # Class: PySSH #================================= class PySSH(object): def __init__ (self): self.ssh = None self.transport = None def disconnect (self): if self.transport is not None: self.transport.close() if self.ssh is not None: self.ssh.close() def connect(self,hostname,username,password,port=22): self.hostname = hostname self.username = username self.password = password self.ssh = paramiko.SSHClient() #Don't use host key auto add policy for production servers self.ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) self.ssh.load_system_host_keys() try: self.ssh.connect(hostname,port,username,password) self.transport=self.ssh.get_transport() except (socket.error,paramiko.AuthenticationException) as message: print "ERROR: SSH connection to "+self.hostname+" failed: " +str(message) sys.exit(1) return self.transport is not None def runcmd(self,cmd,sudoenabled=False): if sudoenabled: fullcmd="echo " + self.password + " | sudo -S -p '' " + cmd else: fullcmd=cmd if self.transport is None: return "ERROR: connection was not established" session=self.transport.open_session() session.set_combine_stderr(True) #print "fullcmd ==== "+fullcmd if sudoenabled: session.get_pty() session.exec_command(fullcmd) stdout = session.makefile('rb', -1) #print stdout.read() output=stdout.read() session.close() return output #=========================================== # MAIN #=========================================== if __name__ == '__main__': hostname = 'server1' username = 'admin' password = 'password123' ssh = PySSH() ssh.connect(hostname,username,password) output=ssh.runcmd('date') print output output=ssh.runcmd('service sshd status',True) print output ssh.disconnect()