• python实现跳板机


    公司有1000多台服务器,线上机器都是禁止root登录的,所以平时是用普通用户登录,然后在su到root,密码都是在excel表中存的,这样登录一台机器,输两次命令,搜两次密码,实在很麻烦,而且密码表都在大家手中不易控制,所以把密码放到数据库中,每次ssh登录自动去数据库中查密码,然后发送密码,实现交互,这样既方便了我们,又控制的密码,脚本的核心是用pexpect来实现交互,用MySQLdb去查询密码,把代码保存为zssh 给个执行权限,建立数据库,把密码表导入到数据库中,就可以使用zssh ip 来登录了,是不是很爽,来试试吧!

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

    代码见附件

    代码如下:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    #!/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
        = struct.pack('HHHH'0000)
        = 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
    
    

    数据库建立

    1
    2
    create database sa;
    create table password (ip varchar(15) primary key not null, muser varchar(15), mpass varchar(30), rpass varchar(30));
     

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

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    #!/usr/local/bin/python
    import MySQLdb
    conn = MySQLdb.connect(host='localhost', user='root', passwd='Te62S#^t', db='sa')
    cursor = conn.cursor()
    = open('passwd.txt')
    num = 0
    for 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.20 monitor asdf123Sfad f(adfasdfasdf

    202.106.0.21 zhswred hathell oworld

  • 相关阅读:
    织梦CMS去广告方法 for DedeCMS V5.7
    织梦网站底部的Power by DedeCms怎么去掉?
    java环境变量最佳配置
    HTML课上小结
    PHP四个阶段目标以及第一阶段学习内容
    例子:选项卡和进度条
    例子:轮播效果
    例子:下拉列表
    document对象操作:浏览器页面文件
    Windows对象操作:浏览器窗口信息
  • 原文地址:https://www.cnblogs.com/mylovelulu/p/9370798.html
Copyright © 2020-2023  润新知