300字范文,内容丰富有趣,生活中的好帮手!
300字范文 > python模块之paramiko_Python模块之paramiko

python模块之paramiko_Python模块之paramiko

时间:2019-07-04 16:36:14

相关推荐

python模块之paramiko_Python模块之paramiko

一、简介

paramiko是基于实现SSH2远程安全连接,支持认证及密钥方式。可以实现远程命令执行、文件传输、中间SSH代理等功能,相对于Pexpect,封装的层次更高,更贴近SSH协议的功能

二、安装

#pip方式安装

pip install paramiko

三、简单示例

importparamiko

hostname='172.17.9.68'username='root'password='xxxx'paramiko.util.log_to_file('login.log') #发送paramiko日志到login.log文件,没有太大可读性

ssh=paramiko.SSHClient() #创建ssh客户端client对象#ssh.load_system_host_keys() #首次登录无法找到hosts_keys,会报错,默认在~/.ssh/know_hosts,非默认需指定路径,

ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) #以下标题4.4会讲解

ssh.connect(hostname=hostname,username=username,password=password)#创建ssh连接

stdin,stdout,stderr=ssh.exec_command('ps -ef') #调用远程执行命令方法exec_command()

print(stdout.read().decode('utf-8')) #read()得到的内容是Bytes字节,需要解码成utf-8

ssh.close() #关闭ssh连接

3.2 执行多条命令

importparamiko

hostname= '172.26.1.8'port= 22username= ''password= ''excute_cmds_list= ['dis cu','dis ip int brief']

ssh=paramiko.SSHClient()

ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())

ssh.connect(hostname=hostname, port=port, username=username, password=password)#将要执行的多条命令以\n间隔即可

command = '\n'.join(excute_cmds_list)

stdin, stdout, stderr=ssh.exec_command(command)

content= stdout.read().decode('utf-8') + stderr.read().decode('utf-8')print(content)

四、SSHClient类

1.connect方法

#方法定义:

connect(self,hostname,port=22,username=None,password=None,pkey=None,key_filename=None,timeout=None,allow_agent=True,look_for_keys=True,compress=False#参数说明

hostname(str类型):连接的目标主机地址

port(int类型):连接目标主机的端口,默认是22

username(str类型):校验的用户名(默认为当前的本地用户名)

password(str类型):密码用于身份校验或解锁私钥

pkey(PKey类型):私钥方式用于身份验证

key_filename(str o list(str)类型):一个文件名或文件名的列表,用于私钥的身份验证

timeout(float类型):一个可选的超时时间(已秒为单位)的TCP连接

allow_agent(bool类型):设置为False时用于禁用连接到SSH代理

look_for_keys(bool类型):设置为False时用来禁用在~/.ssh中搜索秘钥文件

compress(bool类型):设置为True时打开压缩

2.exec_command方法

#方法定义

exec_command(self,command,bufsize=-1)#参数说明

command(str类型):执行的命令

bufsize(int类型):文件缓冲区的大小,默认-1(不限制)#用处

远程命名执行方法,分别返回stdin,stdout,stderr

3.load_system_host_keys方法

#方法定义

load_system_host_keys(self,filename=None)#参数说明

filename(str类型):指定远程主机公钥记录文件#用处

加载本地公钥校验文件,默认为~/.ssh/known_hosts,非默认路径需要手工指定

4.set_missing_host_key_policy方法

ssh.set_missing_host_key_policy方法

针对连接的远程主机没有本地主机密钥或Host_keys对象时的策略。

目前支持三种参数AutoAddPolicy、RejectPolicy(默认)、WarningPolicy,仅限用于SSHClient类1.AutoAddPolicy:自动添加主机名及主机密钥到本地Host_Keys对象,不依赖load_system_host_keys()的配置,

即使~/.ssh/known_hosts不存在也不产生影响2.RejectPolicy:自动拒绝未知的主机名和密钥,依赖load_system_host_keys()的配置3.WarningPolicy:用于记录一个未知的主机密钥的Python警告,并接受它,功能上与AutoAddPolicy相似,

但未知主机会有告警

ssh=paramiko.SSHClient()

ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())

五、SFTPClient类

5.1简介

SFTPClient作为一个SFTP客户端对象,根据SSH传输协议的sftp会话,实现远程操作,比如文件上传,下载,权限,状态等,端口就是SSH端口

5.2 from_transport方法

#方法定义

from_transport(cls,t)#参数

t(Transport),一个已通过验证的传输对象#应用

t=paramiko.Transport(("192.168.1.22",22))

t.connect(username='root',password='xxxxx')

sftp=paramiko.SFTPClient.from_transport(t)

5.3 put方法

#方法定义

put(self,localpath,remotepath,callback=None,confirm=True)#参数说明

localpath(str类型):需上传的本地文件(源)

remotepath(str类型):远程路径(目标)

callback(function(int,int)),获取已接收的字节数及总传输字节数,以便毁掉函数调用,默认为None

confirm(bool类型):文件上传完毕后是否调用stat()方法,以便确认文件的大小#应用

localpath='/home/access.log'remotepath='/data/logs/access.log'sftp.put(localpath,remotepath)

5.4 get方法

#方法定义

get(self,remotepath,localpath,callback=None)#参数说明

remotepath(str类型):需下载的远程文件(源)

localpath(str类型):本地路径(目标)

callback(function(int,int)),获取已接收的字节数及总传输字节数,以便回调函数调用,默认为None#应用

remotepath='/data/log/access.log'localpath='/home/access.log'sftp.get(remotepath=remotepath,localpath=localpath) #推荐使用关键字参数,因为容易与put上传的位置参数混淆

5.5 其他方法

mkdir:在SFTP服务器端创建目录,如sftp.mkdir('/home/userdir',777)

remove:删除SFTP服务端指定目录,如sftp.remove('/home/userdir')

rename:重命名SFTP服务器端文件或目录,如sftp.rename('/home/test.sh','/home/newfile.sh')

stat:获取远程SFTP服务器指定文件信息,如sftp.stat('/home/newfile.sh')

listdir:获取远程SFTP服务器端指定目录列表,以Python的列表(List)形式返回,如sftp.listdir('/home')

5.6 SFTP示例

'''实现文件上传,下载和 创建目录,删除目录等功能'''

importparamiko

username='root'password='xxxx'hostname='172.17.9.68'port=22

try:

t=paramiko.Transport((hostname,port))

t.connect(username=username,password=password)

sftp=paramiko.SFTPClient.from_transport(t)

sftp.put(remotepath='/home/test05.py',localpath='test05.py')

sftp.get(remotepath='/home/test05.py',localpath='test0555.py')#sftp.mkdir('/home/kuku327',mode=775)

sftp.rmdir('/home/kuku327')print(sftp.listdir('/home'))print(sftp.stat('/home/kuku326'))

t.close()exceptException as e:print(str(e))

六、实现密钥方式登录远程主机

#制作密钥

1.在主控端/root文件下输入ssh-keygen,一路回车到结束,此时在/root/.ssh/文件夹下会生成一对密钥(id_rsa 和id_rsa.pub)2.将id_rsa.pub下发给被控端,通过ssh-copy-id

在主控端上输入ssh-copy-id -i /root/.ssh/id_rsa.pub root@被控端ip3.输入被控端密码即可完成下发公钥到/root/.ssh/文件夹,并自动命名为authorized_keys文件4.验证,主控端直接输入ssh roo@被控端ip,无需输入密码即可登录===========================================================================

importparamikoimportos

hostname='172.17.9.68'username='root'paramiko.util.log_to_file('6_3_1_login.log')

ssh=paramiko.SSHClient()

ssh.load_system_host_keys()

privatekey=os.path.expanduser('/root/.ssh/id_rsa') #定义私钥存放路径,os.path.expanduser把path中包含的"~"和"~user"转换成用户目录

key=paramiko.RSAKey.from_private_key_file(privatekey) #创建私钥对象key

ssh.connect(hostname=hostname,username=username,pkey=key)

stdin,stdout,stderr=ssh.exec_command('free -m')print(stdout.read().decode('utf-8'))

ssh.close()

七、paramiko通过堡垒机在远程访问服务器示例

importparamikoimportsys

blip="10.254.24.100" #堡垒机地址

bluser="xxx" #堡垒机用户名

blpasswd='xxx' #堡垒机密码

hostname='10.100.255.220' #业务服务器地址

username='root' #业务服务器用户名

password='xxxx' #业务服务器密码

port=22 #堡垒机连接端口

def receive_data(match,receive_len=9999):

buff=''resp=''

while not buff.endswith(match): #接受到的数据末尾如果是match,结束循环

try:

resp= channel.recv(receive_len) #远端接受数据

exceptException as e:print('Eroor info:%s connection time' %str(e))

channel.close()

ssh.close()

sys.exit()

buff+= resp.decode('utf-8') #resp为bytes,需转成str,才可进行字符串拼接成buff

returnbuffdefsave_file(filename,mode,content):

with open(filename,mode,encoding='utf-8') as f:

f.write(content)if __name__ == '__main__':

sum=''paramiko.util.log_to_file('login.log')

ssh=paramiko.SSHClient()

ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())

ssh.connect(hostname=blip,port=port,username=bluser,password=blpasswd)

channel=ssh.invoke_shell() #创建会话,开启命令调用

channel.settimeout(20) #20秒超时

match_list=['page:','account:','Input account:',"'s password:",'#','#']

send_list=['0\n','%s\n'%blip,'1\n','%s\n'%username,'%s\n'%password,'ifconfig\n']for index,per_match inenumerate(match_list):

channel.send(send_list[index])

buff=receive_data(per_match)

sum+=buff#print(buff)

print(sum) #打印真个过程的交互数据

save_file('6_3_2_operate.log','w',sum)

channel.close()

ssh.close()

八、通过堡垒机登录业务机上传文件

#客户端先上传文件到堡垒机,在通过堡垒机上传文件到业务服务器

importparamikoimportos,sys,time

blip='172.17.9.68' #堡垒机信息

bluser='root'blpasswd='xxx'hostname='172.17.9.70' #定义业务服务器信息

username='root'password='xxxx'tmpdir="/root"remotedir='/root'localpath='6_1_login.log' #本地源文件路径

tmppath=tmpdir+'/6_1_login.log' #堡垒机临时路径

remotepath=remotedir+'/6_1_login.log' #业务主机目标路径

port =22passinfo="'s password:"paramiko.util.log_to_file('syslogin.log')

t=paramiko.Transport((blip,port))

t.connect(username=bluser,password=blpasswd)

sftp=paramiko.SFTPClient.from_transport(t)

sftp.put(localpath=localpath,remotepath=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(20)

buff=""resp=""

print ('scp'+tmpdir+' '+username+'@'+hostname+':'+remotepath+'\n')#scp中转目录文件到目标主机

channel.send('scp'+tmppath+' '+username+'@'+hostname+':'+remotepath+'\n')while notbuff.endswith(passinfo):try:

resp=channel.recv(9999)exceptException as e:print('Error info:%s connection time.'%(str(e)))

channel.close()

ssh.close()

sys.exit()

buff+=resp.decode('utf-8')#print(buff)

if not buff.find('yes/no') == -1: #找到yes/no字符,执行以下语句

channel.send('yes\n')

buff=''channel.send(password+'\n')

buff=''

while not buff.endswith('#'): #buff末尾不是'# '字符,就执行以下语句

resp=channel.recv(9999)if not resp.decode('utf-8').find(passinfo) ==-1: #找到‘s password:字符就执行以下语句,说明密码错误

print ('Error info:Authentication failed.')

channel.cholse()

ssh.close()

sys.exit()

buff+=resp.decode('utf-8')print(buff)

channel.close()

ssh.close()

堡垒机模式下的文件上传

九、常见问题

1.出现编码错误

UnicodeDecodeError: 'utf-8' codec can't decode byte 0xff in position 0: invalid start byte

原因分析

从远端传回来的是bytes字节流,需要将其编码成utf-8,保存在文件里,而有些特殊字符无法编码成utf-8,因此需要这些特殊字符在远端删除

解决办法

经过逐行将bytes编码成utf-8,发现在

ip route-static 192.168.1.0 24 192.168.2.1description To—_XX

出现了问题,经测试—_编码有问题,删除—即可

2.关于H3C设备使用paramiko的问题

2.1 使用paramiko.SSHClient().exec_command方法,出现paramiko.ssh_exception.SSHException: Channel closed.错误

遇见此问题的H3C硬件型号和软件型号如下:1.硬件型号:S5560-30C-EI1.软件版本:Version 7.1.045, Release 1109

2.硬件型号:H3C MSR 36-60

2.软件版本:Version 7.1.059, Release 0304P15

(并非所有H3C设备都会报错)

解决办法:

使用paramiko.SSHClient().invoke_shell()代替paramiko.SSHClient().exec_command(),只适用上述软件型号:V7.1.059,而V7.1.045仍然不行

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。