■ 河南 郭建伟
编者按:在实际的网络管理中,为了提高运维效率,管理员会使用Zabbix,Ansible 等工具,来实现自动管理行为。例如,监控服务器的状态,部署各种软件等。但是,这些工具配置和使用起来比较繁琐,而且在一些特殊的场合并不适用。其实,系统自身已经提供了强大的Shell 脚本功能,利用各种简单的命令,可以很轻松的实现各种自动化操作。这里就结合实例,来说明具体的实现方法。
对于公网上的服务器来说,如何提高其安全性,保证其可靠的运行,是管理员必须面对的问题。
对于频繁的攻击行为,如何将其自动屏蔽,避免其危害服务器的运行呢?例如很多服务器开启了SSH 远程访问服务,在利于管理员工作的同时,也会招致诸如扫描端口、猜测密码和非法登录等攻击。
除了设置复杂的密码,启用SSH 密钥认证的方法外,还可以利用系统NetFilter防火墙,配合Shell 脚本,自动屏蔽各种恶意IP,来保护服务器的安全。例如,执行“tail -fn 100 /var/log/secure”命令,可能会发现“Failed pasword”开头的警告信息,说明系统已经记录了非法的尝试登录行为。
执 行“vi zdfh.sh”命令,输入“#!/bin/sh”,“SEC_File=/var/log/secure”,“I P_ADDDR= tail -n 1000 /va r/log/secure } grep "Fail ed password" | egrep -o "([0-9]{1.3}.){3}[0-9]{1.3}" sort -nr |uniq -c |awk ' $1>=3 {print $2}'”,“IPTABLE_CONF=/etc/sysconfig/iptables”,“ech o”,“cat <
保存该脚本。
该脚本的原理是从“/var/log/secure”文件中读取针对SSH 访问的非法的登录信息,这里提取其后1 000行的纪录,将所有的可疑IP提取出来,并计算出其尝试登录的次数。如果其登录的此时超过3 次,那么就在防火墙规则中针对该IP 添加拦截纪录。
例如,“-A INPUT -s x.x.x.x -m state --state NEW -m tcp -dport 22 -j DROP”等。如果在防火墙规则中已经存在该IP 信息,那么仅仅显示提示信息。当配置好防火墙规则后,重启防火墙时规则生效。除了手工执行外,还可以将其和计划任务结合起来使用。例如,执行“crontab -e”命令,输入“0/2 /opt/data/auto_deny.sh”行,每隔2 h 执行一次该脚本。
在实际管理网络时,经常需要批量复制文件到远程服务器。利用Shell 脚本,可以轻松解决该问题。
执 行“vi zdfzfile.sh” 命 令,创 建 名 为“zdfzfile.sh” 的 文件, 输 入“#!/bin/sh”,“#SRC=/etc/”,“if [! -f ip.txt ];then”,“echo -e " 33["31mplease Create IP.txt File,Contents All IP 33[0m”,“exit”,“f i”,“c o u n t=`c a t ip.txt |wc -l`”,“rm -rf ip.txt.swp”,“i=0”,“while ((i<$count))”,“do”,“i=`expr $i +1`”,“sed "${i}s/^/&${i} /g" ip.txt.swp”,“IP=`awk -v I="$i" '{if(I==$1)orint $2}' ip.txt.swp`”,“scp -r $1 root@${IP}:$2”,“done”行。
当运行该脚本时,如果不带任何参数,会提示相关的信息,提示在同级目录下需要存在名为“ip.txt”的文件,其中包含需要复制文件的所有目标主机的IP。
该脚本后面需要跟随源文件或者源目录和目标路径,来自动完成批量复制操作。
为了顺利运行脚本,可以执行“ssh-keygen”命令,依次回车后,创建所需的密钥对。
执 行“ssh-copy-id -i /root/.ssh/id_rsa.pub x.x.x.x”命令,将公钥文件复制到目标主机上,这里的“x.x.x.x”为目标主机的IP。
执 行“sh zdfzfile.sh /opt/website/ /var/data/”命令,就可以将本机中的“/opt/website/”目录中的所有文件复制到所有目标主机的“/var/data/”路径中。该脚本的原理是从“ip.txt”中分析所有的行数,之后据此执行循环,来依次获取所需的IP,并利用“scp”命令执行文件的远程复制操作。当循环结束后,就完成可批量的文件复制操作。
当然,如果将“scp -r $1 root@${IP}:$2”替换为“rsync -aP --delete $1 root@${IP}:$2”命令,则可以实现同步操作,使双方的文件保持一致。
如果需要在远程主机上批量执行命令,可以创建名 为“zfrun.sh”的 文 件,其内容和上述几乎一致,所不同的仅仅将“scp -r $1 root@${IP}:$2”更改为“ssh -q -l root $IP "$*;echo -e 'The $IP EXEC Command : $* success! ';sleep 2"”行即可,在使用时在该脚本后面跟随具体的命令。
例如,执行“sh zdrun.sh 'ifconfig eth0'”命令,可以查看所有的目标主机上的eth 0 的接口信息。
在具体执行网站自动化部署时,需要更加合理使用Rsync 命令来实现。
例 如, 创 建 名 为“zdrsync.sh” 文 件, 输入“#!/bin/sh”,“#SRC=/etc/”,“rm -rf rsync.list.swp ;cat rsync.list ]grep -v "#">rsync.list.swp”,“COUNT=`cat rsync.list.swp|wc -l”,“NUM=0”,“while ((${NUM} < $COUNT))”,“do”,“NUM= `expr $NUM +1`”,“Line= `sed -n "${NUM}p" rsync.list.swp”,“SRC=`echo $L i n e |a w k '{p r i n t $2}'`”,“DES=`echo $Line |awk '{print $3}'`”,“IP=`echo $Line |awk '{print $1}'`”,“rsync -aP --delete ${SRC}/ root@${IP}:${DES}/ ”,“done”,“]”行。
为了顺利该脚本时,需要在同级目录下创建名为“rsync.list”的文件,其中每一行中均包含目标主机的IP、本地源目录和远程主机的目标目录信息。例如,“x.x.x.x /opt/www1 /var/www”等,将其作为批量部署的依据。执行“sh zdrsync.sh”命令,就可以按照预设的格式,依次将本机上的指定目录(例如网站目录等)同步复制到目标主机的指定路径中,这样就实现了网站的自动化部署。
对于系统中的重要文件来说,需要进行及时的备份。这样,当出现问题时可以快速恢复。为了实现灵活的备份操作,可以将完整备份和增量备份结合起来使用。例如,在每星期的周一进行完整备份,其余天数执行增量备份。这样即保存了完整的数据,也避免占用过多的磁盘磁盘空间,同时便于快速恢复所需的数据。
为此可以创建名为“bfsysfile.sh” 的 文 件,在其中其中输入“#!/bin/sh”,“SOURCE_DIR=(%*)”,“Target_Dir-/data/backup”,“Year=`data +%Y`”,“Month=`data +%m`”,“Day=`data +%d`”,“Week=`data +%u`”,“A_name=`data +%H%M`”,“Files=${A_name}_system_backuo.tgz”,“Code=$?”,“if”,“[ ! -d $Target_Dir/$Year/$Month/$Day ; then ] ”,“ mkdir - p $ Target _Dir/$Year/$Month/$Day”,“fi”行,其作用是指定目标目录名称,并读取当前的年/月/日/星期数等信息,并据此在目标路径下创建备份的目录和文件名。
继续输入“Full_Backup()”,“{”,“if”,“[ "$Week" -eq "1" ];then”,“rm -rf $target_Dir/snapshot”,“c d $Target_Dir/$Year/$Mon th/$Day;tar -g $target_Dir/snapshot -czvf $Files ${Source_Dir[@]}”,“["$Co de" == "0"]&& echo -e " 33[32mThe Full Backup Finish! 33[0m”,“fi”,“Add_Backup()”,“{”,“if”,“[ "$Week" -ne "1" ];then”,“cd $Target_Dir/$Year/$Month/$Day;t a r -g $target_D i r/snapshot -czvf $A_name$F iles ${Source_Dir[@]}”,“["$Code" == "0"]&& echo -e " 33[32mThe Add Backup Finish! 33[0m”,“fi”,“add_Backup()”,“sleep 3”,“Full_Backup;Add_Backup”行。
其作用是判断当前是否为周一,如果是的话就执行全局备份功能,首先删除快照信息,之后进入备份文件夹,利用“tar”命令对命令行中提供的源目录进行备份,将备份文件存储到指定的路径中,其中的“-g”参数表示创建快照文件。如果不是周一的话,则进行增量备份,增量备份是依照指定的快照文件进行的,也是使用“tar”命令进行的。例如,执行“/bin/bash zdrsync.sh /opt /var/data”命令,就可以对指定的所有目录进行备份了。
如果将其和计划任务结合起来使用,可以实现自动化备份操作。
对于有些比较奇怪的故障来说,往往是由于磁盘空间不足造成的。
因此,对于磁盘的可用容量进行及时的监控,如果发现低于指定值,就自动向管理员报警,就可以帮助管理员及时有效的排除故障。
使用Shell 脚本,可以很轻松的实现该功能。
创建名为“diskalert.sh”的文件,在其中输入“#!/bin/sh”,“echo -e " 33[31m 33[1m"”,“LIST=`df -h|grep "^/dev/">>list.txt”,“rm -rf list.txt”,“sleep 2”,“while read line”,“do”,“IP_Address=`ifconfig eth0 |grep "Bcat"|awk '{print $2}' |cut -d: -f 2`”行。
继续输入“D_Name=`echo $line|awk '{print $1,$NF"分区"}'`”,“D_Total=`echo $line|awk '{print $2}'`”,“D_Avail=`echo $line|awk '{print $4}'`”,“D_Percent=`echo $line|awk '{print $5}'|sed 's/%//g`”,“if ["$D_Percent" -ge 80 ];then”行,其作用是利用“df”命令,通过循环来读取所有磁盘分区的信息,并对其进行分区,获取各分区的名称、总容量、可用空间以及本机IP 等信息。
继续输入“cat >email.txt << EOF”,“磁 盘 容 量警 告 信 息”,“主 机:$IP_Address”,“磁 盘 可 用 空间监控- 磁盘名称:$D_Name 可用空间比例:${D_Percent}%”,“EOF”,“echo -e "
33[32m 磁盘:$D_Name 的使用量已经超过${D_Percent}%, 请 注 意! 33[0m”,“mail -s "$D_Name 警告信息" xxx@163.com 其作用是创建邮件信息,在其中写入相关的磁盘名称以及其使用率,并利用“mail”命令将邮件发送到指定的邮箱,这里为“xxx@163.com”。 可以为将该程序创建计划任务,使其可以定时自动运行,对所有磁盘分区进行检测,如果发现某分区低于80%的预设值,就向管理员邮箱发送报警信息。 在Linux 中运行着很多服务,可以为外界提供各种服务。对这些服务的状态进行监控,对于保证其顺畅运行是很重要的。这里就以最常用的Nginx 服务为例,来说明具体的实现方法。 创建名为“kzservice.sh”的文件。在其中输入“#!/bin/sh”,“Email=email.txt”,“Dtae=`date`”,“M_IPAddress=`ifconfig eth1 |grep "Bcast"|awk '{print $2}'|cut -d:-f:2`”,“if [ -f "$1" -a "$1" =="list.txt" ];then”,“for i in `cat list.txt |grep -v "#"`”,“do”,“Count=`ps -ef|grep $1 |grep -v grep|grep -v "email"|head -1 |ec -l`”,“if [ $Count -ne 1 ];then”,“cat>$Email < 为了提高检测的准确性,这里使用了“ps -ef”命令,来发现显示的进程信息,并对进程信息进行过滤,以进程的数量为条件进行循环,来检测其中是否包含指定的服务。 这里针对的是名为“list.txt”文件进行操作,在其中包含所有需要检测的的服务名称,每行输入一个服务名即可。 继续输入“dos2unix $Em ail”,“mail -s "$M_IPAddr ess $i 警告信息" xxx@16 3.com <$Email>>/dev/null 2>&1”,“else”,“echo -e "
33[32m 所指定的服务$i 运行正常! 33[0m”,“done”,“else”,“Count=`ps -ef|grep $1 |grep -v grep|grep -v "email"|head -1 |ec -l`”,“if [ $Count -ne 1 ];then”,“cat>$Email < 作用是针对指定的具体服务进行检测,如果发现其没有运行,就发出报警邮件,否则就显示其处于正常运行状态。 例如,执行“sh kzservic e.sh nginx”命令,则仅仅针对“Nginx”服务进行检测,如果将所有的服务全部写入到“List.txt”文件中,那么运行“sh kzservice.sh list.txt”命令,就会针对“list.txt”文件中的所有服务进行检测,如果其中有服务没有运行的话,就会发出报警邮件。 对于网络管理员来说,需要了解和收集网络中不同主机的配置信息,这样在进行维护时就比较方便快捷。除了手工逐台进行检测收集外,还可以使用Shell 脚本,来快速收集目标主机的配置信息。为了便于操作,首先在某台主机上安装和运行MySQL,在其中创建名为“DeviceInfo”的数据库,在其中创建名为“Hostpz”的数据表,其中包含“id”,“ip_info”,“serv_info”,“cpu_info”,“disk_info”,“mem_info”,“load_info”,“mark_info”等字段, 这些字段分别表示ID号、远程主机的IP、操作系统、CPU 等信息。其中,“ID”字段为Int 类型,其余的字段为varchar 类型,便于存储所需的信息。为便于进行远程访问,可以登录到MySQL控制台,执行“create user 'user1' @'192.168.0.%' identified by 'xxx';”命令,创建名为“user1”的用户和密码,允许指定网段访问数据库。执行“grant all on *.* 'user1 ' @'192.168.0.%';”命令,允许该用户访问相关数据库。 创建名为“Allhostinfo.sh”的文件,输入“#!/bin/sh”,“ip_info=`ifconfig |grep "Bcast"|tail -1 |awk '{print $2}'|cut -d: -f 2`”,“cpu_info1=`cat /proc/cpuinfo |grep 'modelname' |tail -1 -F: '{print $2}'|sed's/^s//g'|awk '{print $1,$3,$4,$NF}'`”,cpu_info 2=`cat /proc/cpuinfo |grep "physical id" |sort|uniq -c |wc -l`”“serv_info=`hostname |tail -1`”,“disk_info=`fdisk -l |grep "Disk" |grep -v "identifier" |awk '{print $2,$3,$4}'|sed 's/,s//g' `”,“mem_info=`free -m |grep "Mem"|awk '{print "Total",$1,$2"M"}`”,“load_info=`uptime|awk '{print"Current Load: "$(NF-2)} '|sed's/.//g`”,“”,mark_info='Center Depart'行,来读取不同的信息。 继 续 输 入“echo -e " 33[31m mysql -uuser1 -pxxx -hx.x.x.x -Duser1 -e”,“insert into hostpz values(",'$(ip_info)', '$serv_info','$(cpu_info 1 ) X $ ( cpu _info2)','$disk_info', ,'$memo_info', '$load_info', '$mark_info') " '" 33[0m'”行,将读取的信息分别写入到上述“Hostpz”数据表中,其中执行“mysql -uuser1 -pxxx -hx.x.x.x -D DeviceInfo -e”命 令,使用指定的账户(这里为“user1”)和 密 码(这 里 为“xxx”)来连接MySQL 中执行的数据库,其中的“x.x.x.x”为MySQL 服务器的地址。之后 使 用“insert into”指令,将上述信息分别插入到数据表中。使用上述谈到的远程复制和执行命令,将“Allhostinfo.sh”文件复制到相关的主机上并运行,就可以将相关主机的信息收集到上述数据表中了。监控服务的运行状态
快速收集主机配置信息