使用Python paramiko模块利用多线程实现ssh并发执行操作
1.paramiko概述
ssh是一个协议,OpenSSH是其中一个开源实现,paramiko是Python的一个库,实现了SSHv2协议(底层使用cryptography)。
有了Paramiko以后,我们就可以在Python代码中直接使用SSH协议对远程服务器执行操作,而不是通过ssh命令对远程服务器进行操作。
由于paramiko属于第三方库,所以需要使用如下命令先行安装
2.安装paramiko
pipinstallparamiko
3.常用方法
connect():实现远程服务器的连接与认证,对于该方法只有hostname是必传参数。
常用参数
hostname连接的目标主机
port=SSH_PORT指定端口
username=None 验证的用户名
password=None 验证的用户密码
pkey=None 私钥方式用于身份验证
key_filename=None 一个文件名或文件列表,指定私钥文件
timeout=None 可选的tcp连接超时时间
allow_agent=True,是否允许连接到ssh代理,默认为True 允许
look_for_keys=True 是否在~/.ssh中搜索私钥文件,默认为True 允许
compress=False,是否打开压缩
set_missing_host_key_policy():设置远程服务器没有在know_hosts文件中记录时的应对策略。目前支持三种策略:
设置连接的远程主机没有本地主机密钥或HostKeys对象时的策略,目前支持三种:
AutoAddPolicy自动添加主机名及主机密钥到本地HostKeys对象,不依赖load_system_host_key的配置。即新建立ssh连接时不需要再输入yes或no进行确认
WarningPolicy用于记录一个未知的主机密钥的python警告。并接受,功能上和AutoAddPolicy类似,但是会提示是新连接
RejectPolicy自动拒绝未知的主机名和密钥,依赖load_system_host_key的配置。此为默认选项
exec_command():在远程服务器执行Linux命令的方法。
如 exec_command("ls/") exec_command("df-h")
4.使用方法
importparamiko #实例化SSHClient client=paramiko.SSHClient() #自动添加策略,保存服务器的主机名和密钥信息,如果不添加,那么不再本地know_hosts文件中记录的主机将无法连接 client.set_missing_host_key_policy(paramiko.AutoAddPolicy()) #连接SSH服务端,以用户名和密码进行认证 client.connect(hostname='192.168.1.1',port=22,username='root',password='123456') #打开一个Channel并执行命令 stdin,stdout,stderr=client.exec_command('df-h')#stdout为正确输出,stderr为错误输出,同时是有1个变量有值 #打印执行结果 print(stdout.read().decode('utf-8')) #关闭SSHClient client.close()
5.利用多线程实现ssh并发访问
要求:
编写一个remote_comm.py脚本,实现以下功能:
- 在文件中取出所有远程主机IP地址
- 在shell命令行中接受远程服务器IP地址文件、远程服务器密码以及在远程主机上执行的命令
- 通过多线程实现在所有的远程服务器上并发执行命令
步骤一:编写脚本
#!/usr/bin/envpython3 importsys importgetpass importparamiko importthreading importos #创建函数实现远程连接主机、服务器密码以及在远程主机上执行的命令的功能 defremote_comm(host,pwd,command): #创建用于连接ssh服务器的实例 ssh=paramiko.SSHClient() #设置自动添加主机密钥 ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) #连接ssh服务器,添加连接的主机、用户名、密码填好,捕获异常,有异常则跳出函数 try: ssh.connect(hostname=host,username='root',password=pwd) except: return #在ssh服务器上执行指定命令,返回3项类文件对象,分别是,输入、输出、错误 stdin,stdout,stderr=ssh.exec_command(command) #读取输出 out=stdout.read() #读取错误 error=stderr.read() #如果有输出 ifout: #打印主机输出内容 print('[%s]OUT:\n%s'%(host,out.decode('utf8'))) #如果有错误 iferror: #打印主机错误信息 print('[%s]ERROR:\n%s'%(host,error.decode('utf8'))) #程序结束 ssh.close() if__name__=='__main__': #设定sys.argv长度,确保remote_comm函数中参数数量 iflen(sys.argv)!=3: print('Usage:%sipaddr_file"command"'%sys.argv[0]) exit(1) #判断命令行上输入如果不是文件,确保输入的是文件 ifnotos.path.isfile(sys.argv[1]): print('Nosuchfile:',sys.argv[1]) exit(2) #fname为存储远程主机ip的文件,用sys.argv方法,可以在执行脚本时再输入文件名,更为灵活 fname=sys.argv[1] #command为在远程主机上执行的命令,用sys.argv方法,可以在执行脚本时再输入相应命令,command为remote_comm函数第三个参数 command=sys.argv[2] #通过getpass输入远程服务器密码,pwd为remote_comm函数第二个参数 #pwd=getpass.getpass() pwd='Taren1.bgsn' #打开存有远程主机ip的文件 withopen(fname)asfobj: #将遍历文件将ip以列表形式存入ips,line.strip()可以去掉每行ip后\n ips=[line.strip()forlineinfobj] #循环遍历列表,获取ip地址,ip为remote_comm函数第一个参数 foripinips: #将读取到的ip地址作为remote_comm函数实际参数传递给函数,ips中有几个ip地址循环几次 #创建多线程 t=threading.Thread(target=remote_comm,args=(ip,pwd,command)) #启用多线程 t.start()
步骤二:编写ssh名单
创建一个文件,输入某个网段所有可以ping通的ip,可以先用nmap出活跃主机扫描,或者自己编写一个python脚本
[root@room9pc01~]#nmap-n-sP176.130.7.0/24|grep176|awk'{print$5}'>/mnt/server_addr.txt [root@room9pc01~]#cat/mnt/server_addr.txt Nmapscanreportfor176.130.7.1 Nmapscanreportfor176.130.7.24 Nmapscanreportfor176.130.7.46 Nmapscanreportfor176.130.7.53 Nmapscanreportfor176.130.7.57
.....................
步骤三:执行脚本
执行脚本,此脚本有两个参数,一个是文件参数,一个是执行命令
[root@room9pc01mnt]#python3ssh.pyserver_addr.txt'who' [176.130.7.57]OUT: student:02019-12-0209:04(:0) studentpts/02019-12-0215:03(:0) [176.130.7.169]OUT: student:02019-12-0208:17(:0) studentpts/02019-12-0208:23(:0) studentpts/42019-12-0208:24(:0) [176.130.7.162]OUT: student:02019-12-0208:17(:0) studentpts/02019-12-0215:03(:0) [176.130.7.178]OUT: student:02019-12-0208:06(:0)
总结
以上所述是小编给大家介绍的使用Pythonparamiko模块利用多线程实现ssh并发执行操作,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对毛票票网站的支持!
如果你觉得本文对你有帮助,欢迎转载,烦请注明出处,谢谢!
声明:本文内容来源于网络,版权归原作者所有,内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎发送邮件至:czq8825#qq.com(发邮件时,请将#更换为@)进行举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。