使用Python paramiko模块利用多线程实现ssh并发执行操作


Posted in Python onDecember 05, 2019

1.paramiko概述

ssh是一个协议,OpenSSH是其中一个开源实现,paramiko是Python的一个库,实现了SSHv2协议(底层使用cryptography)。

有了Paramiko以后,我们就可以在Python代码中直接使用SSH协议对远程服务器执行操作,而不是通过ssh命令对远程服务器进行操作。

由于paramiko属于第三方库,所以需要使用如下命令先行安装

2.安装paramiko

pip install paramiko

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.使用方法

import paramiko
  # 实例化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/env python3
import sys
import getpass
import paramiko
import threading
import os
#创建函数实现远程连接主机、服务器密码以及在远程主机上执行的命令的功能
def remote_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()
#如果有输出
  if out:
#打印主机输出内容
    print('[%s] OUT:\n%s' % (host, out.decode('utf8')))
#如果有错误
  if error:
#打印主机错误信息
    print('[%s] ERROR:\n%s' % (host, error.decode('utf8')))
#程序结束
  ssh.close()
if __name__ == '__main__':
#设定sys.argv长度,确保remote_comm函数中参数数量
  if len(sys.argv) != 3:
    print('Usage: %s ipaddr_file "command"' % sys.argv[0])
    exit(1)
#判断命令行上输入如果不是文件,确保输入的是文件 
  if not os.path.isfile(sys.argv[1]):
    print('No such file:', 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的文件
  with open(fname) as fobj:
#将遍历文件将ip以列表形式存入ips,line.strip()可以去掉每行ip后\n
    ips = [line.strip() for line in fobj]
#循环遍历列表,获取ip地址,ip为remote_comm函数第一个参数
  for ip in ips:
#将读取到的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 -sP 176.130.7.0/24 | grep 176 | awk '{print $5}' > /mnt/server_addr.txt
[root@room9pc01 ~]#cat /mnt/server_addr.txt
Nmap scan report for 176.130.7.1
Nmap scan report for 176.130.7.24
Nmap scan report for 176.130.7.46
Nmap scan report for 176.130.7.53
Nmap scan report for 176.130.7.57

.....................

步骤三:执行脚本 

执行脚本,此脚本有两个参数,一个是文件参数,一个是执行命令

[root@room9pc01 mnt]# python3 ssh.py server_addr.txt 'who'
[176.130.7.57] OUT:
student :0      2019-12-02 09:04 (:0)
student pts/0    2019-12-02 15:03 (:0)
[176.130.7.169] OUT:
student :0      2019-12-02 08:17 (:0)
student pts/0    2019-12-02 08:23 (:0)
student pts/4    2019-12-02 08:24 (:0)
[176.130.7.162] OUT:
student :0      2019-12-02 08:17 (:0)
student pts/0    2019-12-02 15:03 (:0)
[176.130.7.178] OUT:
student :0      2019-12-02 08:06 (:0)

总结

以上所述是小编给大家介绍的使用Python paramiko模块利用多线程实现ssh并发执行操作,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对三水点靠木网站的支持!
如果你觉得本文对你有帮助,欢迎转载,烦请注明出处,谢谢!

Python 相关文章推荐
Flask SQLAlchemy一对一,一对多的使用方法实践
Feb 10 Python
Python中操作文件之write()方法的使用教程
May 25 Python
python从入门到精通(DAY 1)
Dec 20 Python
Python使用中文正则表达式匹配指定中文字符串的方法示例
Jan 20 Python
python 输出上个月的月末日期实例
Apr 11 Python
flask框架中勾子函数的使用详解
Aug 01 Python
Python hexstring-list-str之间的转换方法
Jun 12 Python
Python之——生成动态路由轨迹图的实例
Nov 22 Python
Python3 集合set入门基础
Feb 10 Python
Django 解决阿里云部署同步数据库报错的问题
May 14 Python
如何在python中实现线性回归
Aug 10 Python
Python办公自动化之教你用Python批量识别发票并录入到Excel表格中
Jun 26 Python
Python使用指定字符长度切分数据示例
Dec 05 #Python
python从zip中删除指定后缀文件(推荐)
Dec 05 #Python
python3 求约数的实例
Dec 05 #Python
python生成特定分布数的实例
Dec 05 #Python
python 实现生成均匀分布的点
Dec 05 #Python
pd.DataFrame统计各列数值多少的实例
Dec 05 #Python
python使用beautifulsoup4爬取酷狗音乐代码实例
Dec 04 #Python
You might like
WINDOWS下php5.2.4+mysql6.0+apache2.2.4+ZendOptimizer-3.3.0配置
2008/03/28 PHP
PHP+SQL 注入攻击的技术实现以及预防办法
2011/01/27 PHP
提高PHP编程效率的方法
2013/11/07 PHP
php实现简单的MVC框架实例
2015/09/23 PHP
javascript中的一些注意事项 更新中
2010/12/06 Javascript
让textarea自动调整大小的js代码
2011/04/12 Javascript
jQuery解决下拉框select设宽度时IE 6/7/8下option超出显示不全
2013/05/27 Javascript
基于Jquery实现键盘按键监听
2014/05/11 Javascript
js onmousewheel事件多次触发问题解决方法
2014/10/17 Javascript
javascript解三阶幻方(九宫格)
2015/04/22 Javascript
BootStrap学习系列之Bootstrap Typeahead 组件实现百度下拉效果(续)
2016/07/07 Javascript
JS使用正则表达式过滤多个词语并替换为相同长度星号的方法
2016/08/03 Javascript
第一次动手实现bootstrap table分页效果
2016/09/22 Javascript
百度地图API之百度地图退拽标记点获取经纬度的实现代码
2017/01/12 Javascript
Webpack中css-loader和less-loader的使用教程
2017/04/27 Javascript
Vue学习笔记进阶篇之vue-router安装及使用方法
2017/07/19 Javascript
AngularJS监听ng-repeat渲染完成的两种方法
2018/01/16 Javascript
Bootstrap实现可折叠分组侧边导航菜单
2018/03/07 Javascript
echarts同一页面中四个图表切换的js数据交互方法示例
2018/07/03 Javascript
详解ES6系列之私有变量的实现
2018/11/21 Javascript
详解Vue组件之间通信的七种方式
2019/04/14 Javascript
解决layui下拉框监听问题(监听不到值的变化)
2019/09/28 Javascript
vue之组件内监控$store中定义变量的变化详解
2019/11/08 Javascript
解决vant中 tab栏遇到的坑 van-tabs
2020/11/04 Javascript
Python translator使用实例
2008/09/06 Python
在python 中split()使用多符号分割的例子
2019/07/15 Python
python实现人性化显示金额数字实例详解
2020/09/25 Python
英国现代绅士品牌:Hackett
2017/12/17 全球购物
后勤副校长自我鉴定
2013/10/13 职场文书
外贸采购员求职的自我评价
2013/11/26 职场文书
2014年高三毕业生自我评价
2014/01/11 职场文书
优秀信贷员先进事迹
2014/01/31 职场文书
销售会计岗位职责
2014/03/15 职场文书
电大毕业个人生自我鉴定
2014/03/26 职场文书
原型和原型链 prototype和proto的区别详情
2021/11/02 Javascript
Nginx 安装SSL证书完成HTTPS部署
2022/04/28 Servers