简单的自动化运维工具(shell+except+whiptail+功能模块化函数+循环)
--------------------------------------------------> 代码如下<----------------------------------------------------------
1 #!/bin/bash 2 # 3 # 功能:实现基于SSH密钥对通信的主机自动化运维和快速部署 4 # 须知:此脚本目前只实现了,批量SSH无密码登录,更多跨主机自动化执行操作,需要后期根据功能写成函数模块 5 # 联系:QQ-765482322 email:login_532_gajun@sina.com 6 7 # variable define 8 script_path="/etc/keepalived/$(basename $0)" 9 ssh_user=root 10 ssh_passwd="s23gajun" 11 12 # function define 13 check_int(){ 14 local char=$1 15 if [[ $char =~ ^[1-9][0-9]*$ ]];then 16 return 0 17 else 18 return 1 19 fi 20 } 21 22 check_ip(){ 23 local IP=$1 24 valid_check=$(echo "$IP" | egrep "^([0-9][0-9]*\.){3}[0-9][0-9]*$" | awk -F. '{if (NF==4&&($1>=1&&$1<=239)&&($2>=0&&$2<=255)&&($3>=0&&$3<=255)&&($4>=1&&$4<=254))print "yes"}') 25 26 if [[ "$valid_check" == "yes" ]];then 27 active_check=$(wget --connect-timeout=2 -t2 $IP:22 -O /dev/null &> /dev/null;echo $?) 28 if [[ "$active_check" -ne 0 ]];then 29 return 2 30 else 31 return 0 32 fi 33 else 34 return 1 35 fi 36 } 37 38 ssh_keygen(){ 39 /usr/bin/expect << EOF 40 set timeout 5 41 spawn ssh-keygen -t rsa 42 expect { 43 "*save the key*" {send "\n";exp_continue} 44 "Enter passphrase*" {send "\n";exp_continue} 45 "*passphrase again:" {send "\n"} 46 } 47 expect eof 48 EOF 49 50 } 51 52 push_sshkey(){ 53 local host=$1 54 /usr/bin/expect << EOF 55 set timeout 10 56 spawn scp -p /root/.ssh/id_rsa.pub $ssh_user@$host:/root/.ssh/authorized_keys 57 expect { 58 "(yes/no)" {send "yes\n"; exp_continue} 59 "password:" {send "$ssh_passwd\n"} 60 "id_rsa.pub" {puts "(^_^)\n";exit 2\n} 61 } 62 expect eof 63 EOF 64 65 } 66 67 # main 68 read -p "Please enter a number of hosts that need to be operated: " Host_Num 69 echo "=============================================================" 70 71 # 通过函数check_int判断输入的字符是否为整型 72 check_int $Host_Num 73 74 if [ ! $? -eq 0 ];then 75 echo -e "\033[31mError:Not an integer\033[0m" 76 exit 1 77 fi 78 79 # 确定主机数量后,开始记录主机的IP地址 80 for i in `seq 0 $[$Host_Num-1]`;do 81 while true;do 82 read -p "Please enter a IP for IP[$i]: " IP[$i] 83 check_ip ${IP[$i]} #调用函数判断IP地址是否合法,SSH服务是否可用 84 code=`echo $?` 85 if [ $code -eq 0 ];then 86 Host[$i]=${IP[$i]} 87 break 88 elif [ $code -eq 1 ];then 89 echo -e "\033[31mError:IP address not available\033[0m" 90 continue 91 elif [ $code -eq 2 ];then 92 echo -e "\033[31mError:Remote host $IP SSH failed\033[0m" 93 continue 94 95 fi 96 done 97 done 98 99 # 统计可用主机,并显示给用户 100 echo -e "================\033[32m[IP Address is as follow]\033[0m=====================" 101 if [ $[${#Host[*]}] -eq 0 ];then 102 echo -e "\033[31mWarning:There is no available target host\033[0m" 103 else 104 for i in `seq 0 $[${#Host[*]}-1]`;do echo "Host[$i] IP: ${Host[$i]}";done 105 fi 106 107 read -p 'Confirm continue to enter [yes], otherwise please restart [r]: ' confirm 108 109 case $confirm in 110 yes) 111 echo -e "================\033[32m[Push public key to remote host]\033[0m===================" 112 ;; 113 r) 114 if [ -f $script_path ];then 115 bash $script_path 116 else 117 echo -e '\033[31mError: please manually modify the value of the script variable "script_path" is correct\033[0m' 118 exit 1 119 fi 120 ;; 121 *) 122 exit 1 123 esac 124 125 # 判断ssh密钥对是否存在且有效,只要其中一个不存在就重新生成新的密钥对 126 if [ ! -f /root/.ssh/id_rsa -o ! -f /root/.ssh/id_rsa.pub ];then 127 \mv -f /root/.ssh/id_rsa{,.bak} &> /dev/null 128 \mv -f /root/.ssh/id_rsa.pub{,.bak} &> /dev/null 129 ssh_keygen 130 131 if [ ! $? -eq 0 ];then 132 echo -e "\033[31mError:Key generation failed\033[0m" 133 exit 1 134 else 135 chmod 600 /root/.ssh/id_rsa.pub 136 fi 137 fi 138 139 # 对SSH的密钥对做哈希计算,防止私钥丢失会被篡改 140 [ ! -f /root/.ssh/id_rsa.md5 ] && md5sum /root/.ssh/id_rsa > /root/.ssh/id_rsa.md5 141 [ ! -f /root/.ssh/id_rsa.pub.md5 ] && md5sum /root/.ssh/id_rsa.pub > /root/.ssh/id_rsa.pub.md5 142 md5_chk1=`md5sum -c /root/.ssh/id_rsa.md5 &> /dev/null;echo $?` 143 md5_chk2=`md5sum -c /root/.ssh/id_rsa.pub.md5 &> /dev/null;echo $?` 144 145 # 根据密钥对判断是否向远端主机推送公钥,并记录推送密钥总的次数 146 count=0 147 for i in ${Host[*]};do 148 if [ $[md5_chk1+md5_chk2] -eq 0 ];then 149 push_sshkey $i 150 push_code=`echo $?` 151 if [ $push_code -eq 0 ];then 152 ssh root@$i 'chmod 600 /root/.ssh/authorized_keys' 153 elif [ $push_code -eq 1 ];then 154 echo -e "\033[31mError:Host address $i Key push failed\033[0m" 155 continue 156 elif [ $push_code -eq 2 ];then 157 echo -e "\033[32mUsing the key to login to the remote host $i successfully, no need to push again\033[0m" 158 fi 159 160 let count++ 161 # 对推送的主机状态结果做日志,以便统计和查看 162 case $push_code in 163 0) 164 echo "[Time]:`date +'%F-%T'` [Push Host]:$i [Push State]:Success " >> /var/log/push_sshkey.log 165 ;; 166 1) 167 echo "[Time]:`date +'%F-%T'` [Push Host]:$i [Push State]:Failure " >> /var/log/push_sshkey.log 168 ;; 169 2) 170 echo "[Time]:`date +'%F-%T'` [Push Host]:$i [Push State]:Again " >> /var/log/push_sshkey.log 171 esac 172 else 173 echo -e '\033[31mWarning: SSH key change, please delete the "/root/.ssh/id-rsa*", restart this script\033[0m' 174 exit 1 175 fi 176 echo "*-----------------------------------------------------------oo----------------------------------------------*" 177 done 178 179 echo -e "================================\033[32m[Push information statistics]\033[0m=================================" 180 count=${count:-6} 181 tail -n $count /var/log/push_sshkey.log
----------------------------------------------------->演示结果<----------------------------------------------------------
说明:
1.目前此脚本功能模块只限于推送密钥,批量执行某个任务,还要添加功能函数,现在只是个模板,后期我会加上一些基本应用的功能函数
2.此自动化批量执行脚本依赖公钥验证,所以请确保你的ssh公钥访问没有问题
3.此脚本批量执行一个任务时,并不能做到并发处理,因为我考虑批量执行用的是for循环,不过你可以通过其他脚本同时多调用几次该脚本,也可实现简单地并行处理
4.目前此脚本有很多需要改进的地方,希望脚本达人们,以此为模板扩展模块功能,你只需要把实现的一个任务写成函数即可
5.期望此脚本也能实现ansible一样的功能,也可以通过source提供配置文件,通过一个选项来调用一个功能函数模块,在此需要大家的共同努力,谢谢