自动化运维基础实例解析-Python批量登录到服务器执行任务

开发背景:
根据信息系统安全等级保护的要求,需要对IDC所有数据库服务器进行安全检查,以确认服务器的安全设置是否符合等级保护要求,需要在所有数据库服务器上执行以下命令:
wget http://10.4.4.140/tools/check.sh
bash check.sh
对于目前现状,我们总共目前约有mysql数据库约60台左右,加上oracle数据库会更多,如果通过单一的登录到每个数据库服务器执行,效率是非常低的,所以写了一个批量执行的Python脚本。该脚本会读取一个定义好的服务器列表和命令列表,然后利用了python的多进程特性,每个服务器一个独立进程,自动登录到对应的服务器,运行相应的脚本。登录认证方式包括密码登录和密钥登录,如果定义了密钥,则脚本会使用密钥登录,否则则使用密码登录。该脚本比较通用,在自动化监控和运维过程中比较实用,下面将对脚本做简单的分析。

代码解析:
该脚本共有两个文件,linux_batch_command.py和linux_servers.list。linux_batch_command.py用于执行自动登录和运行脚本。linux_servers.list用于定义主机列表。

linux_batch_command.py代码如下:需要执行的命令定义在cmds=‘’‘ ’‘’里面,需要执行多个命令用,分隔。timeout用于定义登录服务器和执行脚本的超时时间,运行时间比较长的话该值请修改的比较大些。

#!//bin/env python
#ssh_cmd_ver2.py
#coding:utf-8
import pexpect
import os, sys, string, time, datetime, traceback;
from multiprocessing import Process;

cmds= '''cd /tmp && wget http://10.4.4.140/tools/check.sh && bash check.sh'''

def ssh_cmd(ip,port,user,keyfile,passwd,cmd):
    if keyfile <> '':
        ssh = pexpect.spawn('ssh -p%s -i %s %s@%s "%s"' % (port,keyfile, user, ip, cmd))

        try:
            i = ssh.expect(["Enter passphrase for key '"+keyfile+"': ", 'continue connecting (yes/no)?'],timeout=60)
            if i == 0 :
                ssh.sendline(passwd)
                r = ssh.read()
            elif i == 1:
               ssh.sendline('yes\n')
               ssh.expect("Enter passphrase for key '"+keyfile+"': ")
               ssh.sendline(passwd)
               r = ssh.read()
        except pexpect.EOF:
            ssh.close()
            r=ip+":EOF"
        except pexpect.TIMEOUT:
            #ssh.close()
            r="ip:TIMEOUT"
        return r

    else:
        ssh = pexpect.spawn('ssh -p%s %s@%s "%s"' % (port, user, ip, cmd))
        try:
            i = ssh.expect(['password: ', 'continue connecting (yes/no)?'],timeout=60)
            if i == 0 :
                ssh.sendline(passwd)
                r = ssh.read()
            elif i == 1:
                ssh.sendline('yes\n')
                ssh.expect('password: ')
                ssh.sendline(passwd)
                r = ssh.read()
        except pexpect.EOF:
            ssh.close()
            r="EOF"
        except pexpect.TIMEOUT:
            #ssh.close()
            r="TIMEOUT"
        return r

def job_task(ip,port,user,keyfile,passwd):
    for cmd in cmds.split(","):
        r=ssh_cmd(ip,port,user,keyfile,passwd,cmd)
        print r

def main():
    print("%s: controller started." % (time.strftime('%Y-%m-%d %H:%M:%S', time.localtime()),));
    hosts = open('./linux_servers.list');
    plist = []
    for host in hosts:
        if host:
            ip,port,user,keyfile,passwd = host.split(":")
            p = Process(target = job_task, args = (ip,port,user,keyfile,passwd))
            plist.append(p)
            #print plist
            p.start();
    for p in plist:
        p.join();
    print("%s: controller finished." % (time.strftime('%Y-%m-%d %H:%M:%S', time.localtime()),))

if __name__=='__main__':
    main()

linux_servers.list文件内容如下:

该文件里面定义需要登录执行命令的服务器,示例如下,每个服务器以单独行写在文件里面,第一行为密码登录的服务器格式示例,第二行为密码方式登录的服务器格式示例,定义好服务器后执行脚本,脚本会根据定义的格式自动选择登录方式

[root@hadoop-master servers]# cat linux_servers.list
10.0.2.100:22:ruzuojun:/home/ruzuojun/.ssh/id_rsa:keypasswd
10.0.2.200:22:root::passwd

执行脚本,查看运行结果:

执行命令后,在终端会返回每个机器的执行输出结果,如果某个主机执行有异常则会输出EOF,执行超时则会输出数据TIMEOUT.

[root@hadoop-master servers]# ./linux_batch_command.py

******************** 检查是否开启X-Window系统 *************************************************
[ OK ] 检查通过
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
0 0 0 0 0 0 0 0 –:–:– –:–:– –:–:– 0

******************** 检查系统关机热键是否启用 ***********************************
[ FAILED ] 系统关机热键已启用
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
0 0 0 0 0 0 0 0 –:–:– –:–:– –:–:– 0

******************** 检查是否禁止root用户远程登录 ****************************************
grep: /etc/ssh/sshd_config: Permission denied
[ FAILED ] PermitRootLogin 未设置
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
0 0 0 0 0 0 0 0 –:–:– –:–:– –:–:– 0

******************** 检查历史命令缓存 ************************************
[ FAILED ] HISTFILESIZE 未设置
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
0 0 0 0 0 0 0 0 –:–:– –:–:– –:–:– 0
[ FAILED ] HISTSIZE 设置不当(参考值30),当前值为: 1000
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
0 0 0 0 0 0 0 0 –:–:– –:–:– –:–:– 0

******************** 检查umask **********************************************
[ FAILED ] UMASK设置不当,当前值为: 0002
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
0 0 0 0 0 0 0 0 –:–:– –:–:– –:–:– 0

******************** 检查主机信任关系 *****************************************
find: /home/caojie: Permission denied
find: /home/zabbix: Permission denied
find: /home/liyong: Permission denied
find: /home/willy: Permission denied
find: /home/oracle: Permission denied
find: /home/liuyang: Permission denied
find: /home/lost+found: Permission denied
find: /home/nagios: Permission denied
find: /home/lengzhenguo: Permission denied
find: /home/mysql: Permission denied
[ OK ] 检查通过
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
0 0 0 0 0 0 0 0 –:–:– –:–:– –:–:– 0

******************** 检查进程、内存资源访问限制 ***********************
[ FAILED ] HARD CORE设置不当,当前值为: unlimited
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
0 0 0 0 0 0 0 0 –:–:– –:–:– –:–:– 0
[ FAILED ] HARD RSS 未设置
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
0 0 0 0 0 0 0 0 –:–:– –:–:– –:–:– 0
[ FAILED ] HARD NPROC设置不当,当前值为: 131072
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
0 0 0 0 0 0 0 0 –:–:– –:–:– –:–:– 0

******************** 检查su命令限制 **********************************
auth sufficient pam_rootok.so auth include system-auth
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
0 0 0 0 0 0 0 0 –:–:– –:–:– –:–:– 0

******************** 检查sudoer账户 *********************************************
grep: /etc/sudoers: Permission denied

% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
0 0 0 0 0 0 0 0 –:–:– –:–:– –:–:– 0

******************** 检查SUID权限文件 ***********************************************
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 1519 0 0 100 1519 0 2026 –:–:– –:–:– –:–:– 3273

……………