paramiko是基于python实现的ssh2远程安全连接,支持秘钥认证,实现远程命令执行,文件传输,中间ssh代理等功能
安装paramiko
paramiko依赖第三方的crypto,ecdsa,python-devel
yum install -y python-devel
打开https://pypi.org/project/ecdsa/#files 下载
https://files.pythonhosted.org/packages/f9/e5/99ebb176e47f150ac115ffeda5fedb6a3dbb3c00c74a59fd84ddf12f5857/ecdsa-0.13.tar.gz
tar zxf ecdsa-0.13.tar.gz
cd ecdsa-0.13/
python setup.py install
打开https://pypi.org/project/pycrypto/#files 下载
https://files.pythonhosted.org/packages/60/db/645aa9af249f059cc3a368b118de33889219e0362141e75d4eaf6f80f163/pycrypto-2.6.1.tar.gz
tar zxf pycrypto-2.6.1.tar.gz
cd pycrypto-2.6.1/
python setup.py install
下载paramiko
wget https://github.com/paramiko/paramiko/archive/v1.12.2.tar.gz
tar zxf v1.12.2.tar.gz
cd paramiko-1.12.2/
python setup.py install
paramiko的两个核心组件 SSHClient 和 SFTPClient
远程ssh运行命令示例:
#!/usr/bin/env python # -*- coding: utf-8 -*- import paramiko hostname='192.168.1.124' username='root' password='123456' paramiko.util.log_to_file('syslogin.log') ssh=paramiko.SSHClient() ssh.load_system_host_keys() ssh.connect(hostname=hostname,username=username,password=password) stdin,stdout,stderr=ssh.exec_command('free -m') print stdout.read() ssh.close()
sftpclient应用示例:
#!/usr/bin/env python # -*- coding: utf-8 -*- import paramiko username="root" hostname="192.168.1.124" password="lkj123456" port=22 try: t=paramiko.Transport((hostname,port)) t.connect(username=username,password=password) sftp=paramiko.SFTPClient.from_transport(t) sftp.put("/home/test","/tmp/test") sftp.get("/tmp/test.txt","/home/test.txt") sftp.mkdir("/home/test.py") sftp.rmdir("/home/test.info") sftp.rename("/home/test.tt","home/testfile.tt") print sftp.stat("/home/test.info") print sftp.listdir("/home") t.close() except Exception,e: print str(e)
运行ssh秘钥方式登录主机示例:
#!/usr/bin/env python # -*- coding: utf-8 -*- import paramiko import os username="root" hostname="192.168.1.124" paramiko.util.log_to_file('syslogin.log') ssh=paramiko.SSHClient() ssh.load_system_host_keys() privatekey=os.path.expanduser('/home/key/id_rsa') key=paramiko.RSAKey.from_private_key_file(privatekey) ssh.connect(hostname=hostname,username=username,pkey=key) stdin,stdout,stderr=ssh.exec_command('free -m') print stdout.read() ssh.close()
通过堡垒机远程执行命令示例:
#!/usr/bin/env python # -*- coding: utf-8 -*- import paramiko import os,sys,time blip="192.168.1.2" #定义堡垒机 bluser="root" blpasswd="lkj123456" hostname="192.168.1.124" #业务机器 username="root" password="lkj123456" passinfo='\'s password: ' paramiko.util.log_to_file('syslogin.log') ssh=paramiko.SSHClient() ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) ssh.connect(hostname=blip,username=bluser,password=blpasswd) channel=ssh.invoke_shell() #开启命令调用 channel.settimeout(10) buff='' resp='' channel.send('ssh '+username+'@'+hostname+'\n') while not buff.endswith(passinfo): try: resp=channel.recv(9999) except Exception,e: print 'Error info: %s connection time.' % (str(e)) channel.close() ssh.close() sys.exit() buff += resp if not buff.find('yes/no')==-1: channel.send('yes\n') buff='' channel.send(password+'\n') buff='' while not buff.endswith('# '): resp=channel.recv(9999) if not resp.find(passinfo)==-1: print 'Error info: Authentication failed' channel.close() ssh.close() sys.exit() buff += resp channel.send('free -m\n') buff='' try: while buff.find('# ')==-1: resp=channel.recv(9999) buff += resp except Exception,e: print "error info:"+str(e) print buff channel.close() ssh.close()
使用堡垒机模式下上传文件示例:
#!/usr/bin/env python # -*- coding: utf-8 -*- import paramiko import os,sys,time blip="192.168.1.2" #定义堡垒机 bluser="root" blpasswd="lkj123456" hostname="192.168.1.124" #业务机器 username="root" password="lkj123456" passinfo='\'s password: ' paramiko.util.log_to_file('syslogin.log') tmpdir="/tmp" remotedir="/data" localpath="/home/nginx.tar.gz" tmppath=tmpdir+"/nginx.tar.gz" remotepath=remotedir+"nginx_access.tar.gz" port=22 t=paramiko.Transport((blip,port)) t.connect(username=bluser,password=blpasswd) sftp=paramiko.SFTPClient.from_transport(t) sftp.put(localpath,tmppath) sftp.close() ssh=paramiko.SSHClient() ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) ssh.connect(hostname=blip,username=bluser,password=blpasswd) channel=ssh.invoke_shell() channel.settimeout(10) buff='' resp='' channel.send('scp '+tmppath+' '+username+'@'+hostname+':'+remotepath+'\n') while not buff.endswith(passinfo): try: resp=channel.recv(9999) except Exception,e: print 'Error info: %s connection time.' % (str(e)) channel.close() ssh.close() sys.exit() buff += resp if not buff.find('yes/no')==-1: channel.send('yes\n') buff='' while not buff.endswith('# '): resp=channel.recv(9999) if not resp.find(passinfo)==-1: print 'Error info: Authentication failed' channel.close() ssh.close() sys.exit() buff += resp print buff channel.close() ssh.close()
一次连接多次执行命令的示例:
#!/usr/bin/env python # -*- coding: utf-8 -*- import paramiko import sys import os import socket import select import getpass import tty import termios # from paramiko.py3compat import u py27需要注释 tran = paramiko.Transport(('192.168.1.124',22,)) tran.start_client() tran.auth_password('root','123456') #打开一个通道 chan = tran.open_session() #获取一个通道 chan.get_pty() #激活器 chan.invoke_shell() #获取原tty属性,目的是为了在操作完以后恢复终端原型 oldtty = termios.tcgetattr(sys.stdin) try: #为tty设置新属性 #默认当前tty设备属性 #输入一行回车,执行 #ctrl +c 进程退出,遇到特殊字符,特殊处理 #这是为原始模式,不认识特殊字符号 #放置特殊字符应用在当前终端,如此设置,将所有的用户输入均发送到 远程服务器 tty.setraw(sys.stdin.fileno()) chan.settimeout(0.0) while True: #监视用户输入和服务器返回数据 #阻塞,直到句柄可读 readable,writeable,error = select.select([chan,sys.stdin,],[],[],1) if chan in readable: try: #x = u(chan.recv(1024)) x = chan.recv(1024) #py27写法 if len(x) == 0: print('\r\n*** EOF\r\n') break sys.stdout.write(x) sys.stdout.flush() except socket.timeout: pass if sys.stdin in readable: inp = sys.stdin.read(1) if len(inp) == 0: break chan.send(inp) finally: #重新设置终端属性 termios.tcsetattr(sys.stdin,termios.TCSADRAIN,oldtty) chan.close() tran.close()
示例仅供参考