• python实现跳板机


    公司有1000多台服务器,线上机器都是禁止root登录的,所以平时是用普通用户登录,然后在su到root,密码都是在excel表中存的,这样登录一台机器,输两次命令,搜两次密码,实在很麻烦,有一天备份6台机器上的redis,登录就把我登录烦了,于是就用python来实现登录操作,密码表存到mysql中,用python的pexpect来实现交互。

    pexpect的用法看http://www.ibm.com/developerworks/cn/linux/l-cn-pexpect1/

    最后用  ./passwdbox.py   ip即可自动登录

    #!/usr/local/bin/python
    # coding: utf-8
    
    ##导入模块
    import os
    import sys
    import pexpect
    import MySQLdb
    import struct
    import fcntl
    import termios
    import signal
    
    ##传入的参数
    opt = sys.argv
    
    ##如果没跟参数,就提示
    if len(opt) == 1:
        print '''
        ----------------------------
        'Useage: ./zssh.py ServerIP'
        ----------------------------
        '''
        sys.exit(2)
        
    ##下面两个函数更改pexpect模拟的窗口大小,
    ##参见http://guweigang.com/blog/2012/10/25/using-python-ssh-landing-module-performs-pexpect/
    def sigwinch_passthrough (sig, data):
        winsize = getwinsize()
        global foo
        foo.setwinsize(winsize[0],winsize[1])
    
    def getwinsize():
        if 'TIOCGWINSZ' in dir(termios):
            TIOCGWINSZ = termios.TIOCGWINSZ
        else:
            TIOCGWINSZ = 1074295912L # Assume
        s = struct.pack('HHHH', 0, 0, 0, 0)
        x = fcntl.ioctl(sys.stdout.fileno(), TIOCGWINSZ, s)
        return struct.unpack('HHHH', x)[0:2]
    
    ##传入的ip
    ip = opt[1]
    ##用MySQLdb驱动连接mysql
    conn = MySQLdb.connect(host='localhost', user='root', passwd='Te62S#^t', db='sa')
    cursor = conn.cursor()
    ##查找该ip的普通用户名,密码,还有root的密码,用来ssh连接
    cursor.execute('select muser,mpass,rpass from password where ip=%s', ip)
    result = cursor.fetchall()
    
    ##如果没在数据库中发现该ip信息,提示用户输入,并保存,如果发现就准备连接
    if len(result) == 0:
        muser = raw_input('输入用户名:')
        mpass = raw_input('输入用户密码: ')
        rpass = raw_input('输入root密码: ')
        cursor.execute('insert into password values (%s,%s,%s,%s)', (ip, muser, mpass, rpass))
        conn.commit()
    elif len(result) == 1:
        muser = result[0][0]
        mpass = result[0][1]
        rpass = result[0][2]
        
    ##用pexpect模块的spawn类,连接ssh
    foo = pexpect.spawn('ssh %s@%s' % (muser,ip))
    while True:
        ##期望得到列表里的东西
        index = foo.expect(['continue', 'assword', pexpect.EOF, pexpect.TIMEOUT],timeout=10)
        ##如果得到的是continue,也就是第一次连接输入yes/no那,那就发送yes
        if index == 0:
            foo.sendline('yes')
            continue
        ##如果是提示输入password,那就发送密码
        elif index == 1:
            foo.sendline(mpass)
            ##发送密码后有两种情况,登录成功或密码错误
            index2 = foo.expect(['password', ']$'])
            ##如果得密码正确
            if index2 == 1:
                print '%s 登录成功' % muser
                break
            ##如果密码错误,提示输入密码
            elif index2 == 0:
                while True:
                    muser = raw_input('输入用户名:')
                    mpass = raw_input('用户密码不对,重新输入: ')
                    foo.sendline(mpass)
                    index3 = foo.expect([']$', 'assword'], timeout=5)
                    ##如果密码对了,就保存到数据库
                    if index3 == 0:
                        cursor.execute('update sys_pass set muser=%s, mpass=%s where ip=%s ', (muser, mpass, ip))
                        conn.commit()
                        foo.sendline('')
                        break
                    ##如果不对,再循环一次
                    else:
                        continue
        else:
            print '连接超时' 
        break
    
    ##下面su 到root与上面类似
    while True:
        foo.expect('$')
        foo.sendline('su - root')
        #index4 = foo.expect(['口令', '密码', 'assword', pexpect.TIMEOUT, pexpect.EOF],timeout=5)
        foo.sendline(rpass)
        index5 = foo.expect([']#', 'monitor', pexpect.EOF, pexpect.TIMEOUT], timeout=5)
        if index5  == 0:
            print 'root 登录成功'
            foo.sendline('')
            break
        elif index5 == 1:
            while True:
                rpass = raw_input('root密码不对,请输入: ')
                foo.expect('$')
                foo.sendline('su - root')
                #index6 = foo.expect(['口令', '密码', 'assword', pexpect.TIMEOUT, pexpect.EOF],timeout=5)
                foo.sendline(rpass)
                index7 = foo.expect([']#', 'monitor', pexpect.EOF, pexpect.TIMEOUT], timeout=5)
                if index7 == 0:
                    cursor.execute('update sys_pass set rpass=%s where ip=%s', (rpass, ip))
                    conn.commit()
                    print 'root 登录成功'
                    break
                elif index7 == 1:
                    continue
                else:
                    print 'error'
        else:
            print 'error'
    
    ##这个是利用那两个函数来调节子线程窗口大小
    signal.signal(signal.SIGWINCH, sigwinch_passthrough)
    size = getwinsize()
    foo.setwinsize(size[0], size[1])
    ##进入interact交互模式
    foo.interact()
    pass

    数据库建立

    create database sa;
    create table password (ip varchar(15), muser varchar(15), mpass varchar(30), rpass varchar(30));

    将密码表的中的ip,普通用户名,密码,root密码插入库中我用的是一个脚本

    #!/usr/local/bin/python
    import MySQLdb
    
    conn = MySQLdb.connect(host='localhost', user='root', passwd='Te62S#^t', db='sa')
    cursor = conn.cursor()
    
    f = open('passwd.txt')
    num = 0
    for i in f:
        ilist = i.split()
        if len(ilist) == 4:
            ip = ilist[0]
            muser = ilist[1]
            mpass = ilist[2]
            rpass = ilist[3]
            try:
                cursor.execute('insert into password values (%s,%s,%s,%s)', (ip, muser, mpass, rpass))
                num += 1
            except:
                pass
    
    print num
     
    conn.commit()
    cursor.close()
    conn.commit()

    将密码保存到passwd.txt格式类似

    IP普通用户名密码root密码

    202.106.0.20monitorasdf123Sfadf(adfasdfasdf

    202.106.0.21zhswredhathelloworld

  • 相关阅读:
    产品设计理应遵循哪些原则?
    产品经理必读的九步法
    exec
    Class convert
    Connecting method
    ASP.NET读写操作
    Encrypt Decrypt
    EventHandler, EventArgs
    Convert using code
    Dictionary List
  • 原文地址:https://www.cnblogs.com/cmsd/p/3432475.html
Copyright © 2020-2023  润新知