linux实现一键互信,优化版

使用Python和协程多线程技术优化了之前的Linux互信脚本,提高校验和互信速度。输入文件包含IP、用户名、密码和端口信息。已小规模测试,可能存在未发现的bug,欢迎交流解决。
摘要由CSDN通过智能技术生成

之前编写了用python ,paramiko包实现linux互信,但是在大规模上有点问题,且速度不是很快,所以这次重新编写了下,流程一样,采用了协程配合多线程实现,下面是代码,可能有些地方写的不是很优美,这次的改进主要是加快校验,互信速度

#!/usr/bin/python3
# _*_coding:utf-8 _*_
# @Time  :2020/6/24   11:46
# @Author  : liwentong
#@ File    :main.py
import os
import sys
import threading
from gevent import monkey
monkey.patch_all()
import gevent
from myautossh import *
from config import *
Allresult={}
def read_macinfo(filepath):
    infoList=[]
    with open(filepath,'r') as f:
        for line in f.readlines():
            #一个空格切分数据
            lines=line.strip().split(' ')
            if len(lines)==4:
                infoList.append(lines)
    return infoList
#校验服务器情况
def conn_ssh(line):
    global Allresult
    aush = Myautossh(line[0], line[1], line[2], line[3])
    rec = aush.testPub()
    if len(rec)==0:
        if "no" not in Allresult.keys():
            Allresult["no"]=[]
            Allresult["no"].append(line[0])
        else:
            Allresult["no"].append(line[0])
    else:
        if "yes" not in Allresult.keys():
            Allresult["yes"] = {}
            Allresult["yes"][line[0]]=rec
        else:
            Allresult["yes"][line[0]]=rec
#携程配合多线程校验
def gevent_run(infoList):

    task_list=[]
    for line in infoList:
        task=gevent.spawn(conn_ssh,line)
        task_list.append(task)
    gevent.joinall(task_list)

#做互信
def addPublic(tcc):
    global Allresult
    ip=tcc[0]
    ic=tcc[1]
    try:
        myautossh=Myautossh(ip, ic[ip][0], ic[ip][1], ic[ip][2], Allresult["yes"])
        myautossh.addPub()
    except Exception as f:
        print(f)
#协程搭配多线程做户型
def gvent_run_add(ipList,ic):
    task_list=[]
    for line in ipList:
        task=gevent.spawn(addPublic,[line,ic])
        task_list.append(task)
    gevent.joinall(task_list)

def main():
    filepath='./1.txt'
    infoList=read_macinfo(filepath)

    #默认线程数为核心数
    step=int(len(infoList)/Pnum)
    if step==0:
        t=threading.Thread(target=gevent_run,args=(infoList,))
        t.start()
        t.join()
    else:
        tp=[]
        alist=[infoList[i:i+step] for i in range(0,len(infoList),step)]
        #print(alist)
        for linec in alist:
            t=threading.Thread(target=gevent_run,args=(linec,))
            t.start()
            tp.append(t)
        for i in tp:
            i.join()
    print("功能选项:1,1对N互信  2,N对N互信")
    #选出存活的已经获得公匙的服务器
    isActive=[i for i,value in Allresult["yes"].items()]
    isActiveInfo={}
    for i in infoList:
        if i[0] in isActive:
            isActiveInfo["%s"%i[0]]=i[1:]
    choice=input("输入你要做的功能选项:")
    if choice=='1':
        print("存活服务器列表:%s"%isActive)
        ipc=''
        while ipc!="break":
            ipc = input("输入你要做1对N互信的服务器ip(输入break退出):")
            if ipc in isActive:
                Myautossh(ipc,isActiveInfo[ipc][0],isActiveInfo[ipc][1],isActiveInfo[ipc][2],Allresult["yes"]).addPub()
            else:
                print("没有这个服务器" if ipc!='break' else '')
    elif choice=='2':
        #分任务
        step = int(len(isActive) / Pnum)
        print(step)
        if step == 0:
            t=threading.Thread(target=gvent_run_add, args=(isActive,isActiveInfo))
            t.start()
        else:
            tp=[]
            alist=[isActive[i:i+step] for i in range(0,len(isActive),step)]
            for line in alist:
                t=threading.Thread(target=gvent_run_add,args=(line,isActiveInfo))
                t.start()
                tp.append(t)
            for t in tp:
                t.join()

if __name__=='__main__':
    main()

#!/usr/bin/python3
# _*_coding:utf-8 _*_
# @Time  :2020/6/24   14:17
# @Author  : liwentong
#@ File    :myautossh.py
import paramiko
import sys
import os
import socket
from config import *
class Myautossh(object):
    def __init__(self,ip,username,password,port,*args):
        self.ip=ip
        self.username=username
        self.password=password
        self.port=port
        self.result=''
        self.success=False
        self.server=paramiko.SSHClient()
        self.macInfoList='' if len(args)==0 else args[0]

    def checkHostExist(self):
        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        try:
            s.connect((self.ip, int(self.port)))
            s.settimeout(2)
            self.success=True
        except Exception as f:
            self.success=False
    def check_pub(self):
        self.server.set_missing_host_key_policy(paramiko.AutoAddPolicy())
        self.server.connect(self.ip,int(self.port),self.username,self.password)
        stdin, stdout, stderr = self.server.exec_command(readPubCmd)
        pubresult=stdout.read().decode('utf-8').replace('\n','')
        if len(pubresult)>0:
            self.result=pubresult
        else:
            retry=0
            #尝试执行三次
            while retry<3:
                stdin,stdout,stderr=self.server.exec_command(keygenCmd)
                rec=stdout.read().decode('utf-8')
                if rec=="yes":
                    break
                retry+=1
            stdin,stdout,stderr=self.server.exec_command(readPubcmd)
            rec=stdout.read().decode('utf-8').replace('\n','')
            if len(rec)>0:
                self.result=rec
    #单增加公匙到
    def addPub(self):
        self.server.set_missing_host_key_policy(paramiko.AutoAddPolicy())
        self.server.connect(self.ip, int(self.port), self.username, self.password)
        for uip,pub in self.macInfoList.items():
            addcmd = addKeyCmd % (pub)
            stdin, stdout, stderr = self.server.exec_command(addcmd)
            if stdout.read().decode("utf-8").strip()=="yes":
                print("%s 对 %s 互信成功"%(uip,self.ip))
            else:
                print("%s 对 %s 互信失败"%(uip,self.ip))

#测试公匙是否存在,不存在创建
    def testPub(self):
        self.checkHostExist()
        if self.success:
            self.check_pub()
        if len(self.result)!=0:
            return self.result
        else:
            return ''
#!/usr/bin/python3
# _*_coding:utf-8 _*_
# @Time  :2020/6/24   14:19
# @Author  : liwentong
#@ File    :config.py
import multiprocessing
import encodings.idna
PingHost=""
''' ssh-keygen 命令 '''
keygenCmd="ssh-keygen -q -t rsa -P '' -f ~/.ssh/id_rsa && echo yes || echo no"
''' 读取pub文件 '''
readPubCmd="test -f ~/.ssh/id_rsa.pub && cat ~/.ssh/id_rsa.pub || echo"
''' 查看pub文件是否存在 '''
testExistsCmd="test -f ~/.ssh/id_rsa.pub && echo yes || echo no"
''' 追加公钥至authorized_keys中'''
addKeyCmd="echo %s >> ~/.ssh/authorized_keys && chmod 700 ~/.ssh && chmod 600 ~/.ssh/authorized_keys &&  echo yes || echo no"
'''进程数'''
Pnum=3

下面是输入文件,主要记录ip,username,password,port 中间以一个空格隔开

192.168.1.1 test test 22

程序我已经在小规模集群测试过,;测试可能不到位,可能有些地方有bug,有问题可以私信大家一起解决。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值