paramiko模块提供了ssh及sft进行远程登录服务器执行命令和上传下载文件的功能。这是一个第三方的软件包,使用之前需要安装。
1. 基于用户名和密码的 sshclient 方式登录 1 2 3 4 5 6 7 8 9 10 11 12 ssh = paramiko.SSHClient() ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) ssh.connect(hostname='192.168.2.129' , port=22 , username='super' , password='super' ) stdin, stdout, stderr = ssh.exec_command('df -hl' ) print(stdout.read().decode()) ssh.close()
2. 基于用户名和密码的 transport 方式登录 方法1是传统的连接服务器、执行命令、关闭的一个操作,有时候需要登录上服务器执行多个操作,比如执行命令、上传/下载文件,方法1则无法实现,可以通过如下方式来操作
1 2 3 4 5 6 7 8 9 10 11 12 trans = paramiko.Transport(('192.168.2.129' , 22 )) trans.connect(username='super' , password='super' ) ssh = paramiko.SSHClient() ssh._transport = trans stdin, stdout, stderr = ssh.exec_command('df -hl' ) print(stdout.read().decode()) trans.close()
3 基于公钥密钥的 SSHClient 方式登录 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 pkey = paramiko.RSAKey.from_private_key_file('/home/super/.ssh/id_rsa' , password='12345' ) ssh = paramiko.SSHClient() ssh.connect(hostname='192.168.2.129' , port=22 , username='super' , pkey=pkey) stdin, stdout, stderr = ssh.exec_command('df -hl' ) print(stdout.read().decode()) ssh.close()
以上需要确保被访问的服务器对应用户.ssh目录下有authorized_keys文件,也就是将服务器上生成的公钥文件保存为authorized_keys。并将私钥文件作为paramiko的登陆密钥
4. 基于密钥的 Transport 方式登录 指定本地的RSA私钥文件,如果建立密钥对时设置的有密码,password为设定的密码,如无不用指定password参数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 pkey = paramiko.RSAKey.from_private_key_file('/home/super/.ssh/id_rsa' , password='12345' ) trans = paramiko.Transport(('192.168.2.129' , 22 )) trans.connect(username='super' , pkey=pkey) ssh = paramiko.SSHClient() ssh._transport = trans stdin, stdout, stderr = ssh.exec_command('df -hl' ) print(stdout.read().decode()) trans.close() trans = paramiko.Transport(('192.168.2.129' , 22 )) trans.connect(username='super' , password='super' ) sftp = paramiko.SFTPClient.from_transport(trans) sftp.put(localpath='/tmp/11.txt' , remotepath='/tmp/22.txt' ) trans.close()
5. 实现输入命令立马返回结果的功能 以上操作都是基本的连接,如果我们想实现一个类似xshell工具的功能,登录以后可以输入命令回车后就返回结果:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 import paramikoimport osimport selectimport systrans = paramiko.Transport(('192.168.2.129' , 22 )) trans.start_client() ''' default_key_file = os.path.join(os.environ['HOME'], '.ssh', 'id_rsa') prikey = paramiko.RSAKey.from_private_key_file(default_key_file) trans.auth_publickey(username='super', key=prikey) ''' trans.auth_password(username='super' , password='super' ) channel = trans.open_session() channel.get_pty() channel.invoke_shell() while True : readlist, writelist, errlist = select.select([channel, sys.stdin,], [], []) if sys.stdin in readlist: input_cmd = sys.stdin.read(1 ) channel.sendall(input_cmd) if channel in readlist: result = channel.recv(1024 ) if len(result) == 0 : print("\r\n**** EOF **** \r\n" ) break sys.stdout.write(result.decode()) sys.stdout.flush() channel.close() trans.close()
6. 支持tab自动补全 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 import paramikoimport osimport selectimport sysimport ttyimport termios''' 实现一个xshell登录系统的效果,登录到系统就不断输入命令同时返回结果 支持自动补全,直接调用服务器终端 ''' trans = paramiko.Transport(('192.168.2.129' , 22 )) trans.start_client() ''' default_key_file = os.path.join(os.environ['HOME'], '.ssh', 'id_rsa') prikey = paramiko.RSAKey.from_private_key_file(default_key_file) trans.auth_publickey(username='super', key=prikey) ''' trans.auth_password(username='super' , password='super' ) channel = trans.open_session() channel.get_pty() channel.invoke_shell() oldtty = termios.tcgetattr(sys.stdin) try : tty.setraw(sys.stdin) channel.settimeout(0 ) while True : readlist, writelist, errlist = select.select([channel, sys.stdin,], [], []) if sys.stdin in readlist: input_cmd = sys.stdin.read(1 ) channel.sendall(input_cmd) if channel in readlist: result = channel.recv(1024 ) if len(result) == 0 : print("\r\n**** EOF **** \r\n" ) break sys.stdout.write(result.decode()) sys.stdout.flush() finally : termios.tcsetattr(sys.stdin, termios.TCSADRAIN, oldtty) channel.close() trans.close()
7. SSH批量登陆执行命令(1) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 import paramikoimport threadingdef ssh2 (ip,username,passwd,cmd) : try : ssh = paramiko.SSHClient() ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) ssh.connect(ip,22 ,username,passwd,timeout=5 ) for m in cmd: stdin, stdout, stderr = ssh.exec_command(m) out = stdout.readlines() for o in out: print o, print '%s\tOK\n' %(ip) ssh.close() except : print '%s\tError\n' %(ip) if __name__=='__main__' : cmd = ['cal' ,'echo hello!' ] username = "" passwd = "" threads = [] print "Begin......" for i in range(1 ,254 ): ip = '192.168.1.' +str(i) a=threading.Thread(target=ssh2,args=(ip,username,passwd,cmd)) a.start()
8. SSH批量登陆执行命令(2) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 import pexpectdef ssh_cmd (ip, passwd, cmd) : ret = -1 ssh = pexpect.spawn('ssh root@%s "%s"' % (ip, cmd)) try : i = ssh.expect(['password:' , 'continue connecting (yes/no)?' ], timeout=5 ) if i == 0 : ssh.sendline(passwd) elif i == 1 : ssh.sendline('yes\n' ) ssh.expect('password: ' ) ssh.sendline(passwd) ssh.sendline(cmd) r = ssh.read() print r ret = 0 except pexpect.EOF: print "EOF" ssh.close() ret = -1 except pexpect.TIMEOUT: print "TIMEOUT" ssh.close() ret = -2 return ret