【運維心得】你不知道,運維也要寫程式碼(3)

2020-08-12 17:05:09


今天繼續上一篇的內容,研究幾段常用的運維程式碼。

批次設定密碼

寫一個指令碼,批次建立10個系統帳號oldboy01-oldboy10並設定密碼(密碼爲隨機8位元字串)。
參考答案:網上找到的其中一段程式碼如下(已驗證通過):

#!/bin/bash
for i in `seq 01 10`
do
   useradd oldboy$i
   password=`tr -cd 'a-zA-Z0-9'  </dev/urandom  |head -c8`
   echo "$password |passwd --stdin oldboy$i" 
done 

當前線上使用者

寫一個指令碼,實現判斷10.0.0.0/24網路裡,當前線上使用者的IP有哪些(方法有很多)
參考答案:的確有很多方法,這裏寫一個最簡單的(已驗證通過),大家好記憶:

nmap -sP 192.168.1.0/24

解決DOS攻擊

寫一個指令碼,解決DOS攻擊生產案例
提示:根據web日誌或者或者網路連線數,監控當某個IP併發連線數或者短時內PV達到100,即呼叫防火牆命令封掉對應的IP,監控頻率每隔3分鐘。防火牆命令爲:iptables -A INPUT -s 10.0.1.10 -j DROP。(請用至少兩種方法實現!)
參考答案:
第一種方法(未經驗證):

#!/bin/bash
#tt=awk '{a[$1$4]++ }END{for (i in a) print i,a[i]}' localhost_access_log.2017-11-24.txt|sort -nk2|tail -10
#獲取同一時間段和同一IP共同作爲下標的陣列,陣列下標具有唯一性
#獲取後按照第二列IP進行排序,取最大10條.
#第二個awk獲取IP,準備下一步防火牆封IP
#tt2=$(awk '{a[$1$4]++ }END{for (i in a) print i,a[i]}' localhost_access_log.2017-11-24.txt|sort -nk2|tail -10|awk  -F'[' '{print $1}'|sort|uniq)
#
#awk '{a[$1$4]++ }END{for (i in a) print i,a[i]}' localhost_access_log.2017-11-24.txt|sort -nk2|tail -10|awk  -F'[' '{print $1,$2}'|awk '$3>3{print $1}'|sort|uniq -c
#
for i in $(awk '{a[$1$4]++ }END{for (i in a) print i,a[i]}' localhost_access_log.2017-11-24.txt|sort -nk2|tail -10|awk  -F'[' '{print $1,$2}'|awk '$3>3{print $1}'|sort|uniq)
do
	echo  $i
	echo "iptables-I INPUT -s $i -j DROP"
done

第二種方法(未經驗證):

#!/bin/bash
while true
do
  awk '{print $1}' access.log|grep -v "^$"|sort|uniq -c > /tmp/tmp.log
  exec </tmp/tmp.log
  while read line
  do
    ip=`echo $link|awk'{print $2}'`
    count=`echo $line|awk '{print $1}'`
      if [ $count -gt 3 ] && [ `iptables -L -n|grep "$ip"|wc -l` -lt 1 ]
      then
        iptables -I INPUT -s $ip -j DROP
        echo "$line is dropped" >>/tmp/droplist.log
      fi
  done
  sleep 5
done

列印字母

bash for回圈列印下面 下麪這句話中字母數不大於6的單詞。(請用至少兩種方法實現!)
I am oldboy teacher welcome to oldboy trainingclass.
參考答案:
程式碼一(已驗證):

#!/bin/sh
string="I am oldboy teacher welcome to oldboy trainingclass"
number="`echo $string|grep -o " "|wc -l`"
number=`expr $number + 1`
for n in `seq $number`
do
   char=`echo $string|awk -F " " '{print$'"$n"'}'`
   num=`echo $char|wc -L`
   if [ $num -le 6 ]
      then echo $char
   fi
done

程式碼二(已驗證):

#!/bin/sh
for n in I am oldboy teacher welcome to oldboy trainingclass
do
   if [ ${#n} -le 6 ];then
   echo $n
   fi
done

列印選單

列印選擇選單,一鍵安裝Web服務:
[root@oldboyscripts]# sh menu.sh
1.[install lamp]
2.[install lnmp]
3.[exit]
pls input the num you want:
要求:
1、當使用者輸入1時,輸出「startinstalling lamp.」然後執行/server/scripts/lamp.sh,指令碼內容輸出"lamp is installed"後退出指令碼;
2、當使用者輸入2時,輸出「startinstalling lnmp.」 然後執行/server/scripts/lnmp.sh輸出"lnmp is installed"後退出指令碼;
3、當輸入3時,退出當前選單及指令碼;
4、當輸入任何其它字元,給出提示「Input error」後退出指令碼。
5、要對執行的指令碼進行相關條件判斷,例如:指令碼是否存在,是否可執行等。
參考答案(已驗證,不完全一樣,道理一致):

#!/bin/bash
RED_COLOR='\E[1;31m'
GREEN_COLOR='\E[1;32m'
YELLOW_COLOR='\E[1;33m'
BLUE_COLOR='\E[1;34m'
PINK_COLOR='\E[1;35m'
RES='\E[0m'
cat <<EOF   #要列印的選單
1.[install lamp]
2.[install lnmp]
3.[install mysql]
4.[install php]
5.[exit]
EOF
read -p"pls input the num you want:" a   #請輸入一個參數
case $a in
1)
  echo -e "$BLUE_COLOR startinstalling lamp $RES"    #給輸出的內容加上顏色
  lampScripts=/server/scripts/lamp.sh
 [-f$lampScripts] && sh $lampScripts|| exit1   #判斷要執行的lamp檔案是否存在
 ;;
 2)
  echo -e "$PINK_COLOR startinstalling lnmp $RES"
  lnmpScripts=/server/scripts/lnmp.sh
  [-f$lnmpScripts] && sh $lnmpScripts|| exit2
 ;;
 3)
  echo -e "$GREEN_COLOR startinstalling mysql $RES"
  mysqlScripts=/server/scripts/mysql.sh
  [-f$mysqlScripts] && sh $mysqlScripts|| exit3
 ;;
 4)
 echo-e "$PINK_COLOR startinstalling php $RES"
 phpScripts=/server/scripts/mysql.sh
  [-f$phpScripts] && sh $phpScripts|| exit4
  ;;
 *)
  echo -e "$RED_COLOR input error $RES"
esac

rsync系統啓動指令碼

寫一個網路服務獨立進程模式下rsync的系統啓動指令碼
例如:/etc/init.d/rsyncd {start|stop|restart} 。
要求:
1.要使用系統函數庫技巧。
2.要用函數,不能一坨SHI的方式。
3.可被chkconfig管理。
網上參考答案(已驗證):
下面 下麪的程式碼執行之前,首先要把rsync的組態檔修改一下:

vi /etc/rsyncd.conf

把這句的註釋去掉pid file=/var/run/rsyncd.pid
否則後面執行sh rsyncd.sh stop的時候,並不會停止服務。
驗證的時候要會使用ps -ef|grep rsyncss -lntup|grep rsync,檢視服務是否被啓動和停止。

#!/bin/bash
# chkconfig: 2345 99 98
#author:oldyang
choice=$1
STOP=/var/run/rsyncd.pid
start(){
    [ -f $STOP ] || rsync --daemon
}
stop(){
    [ -f $STOP ] && kill `cat /var/run/rsyncd.pid`
}
restart(){
    [ -f $STOP ] && kill `cat /var/run/rsyncd.pid`
}
case "$choice" in
        start)
        start
        ;;
        stop)
        stop
        ;;
        restart)
        restart
    sleep 1
    rsync --daemon
        ;;
        *)
        echo "Usage: input right CMD. EX: {start|restart|stop}"
        exit 1
esac

抓鬮指令碼

運維派提供外出企業專案實踐機會(第6次)來了(本月中旬),但是,名額有限,隊員限3人(班長帶隊)。需要一個抓鬮的程式挑選學生:
要求:
1、執行指令碼後,想去的同學輸入英文名字全拼,產生亂數01-99之間的數位,數位越大就去參加專案實踐,前面已經抓到的數位,下次不能在出現相同數位。
2、第一個輸入名字後,螢幕輸出資訊,並將名字和數位記錄到檔案裡,程式不能退出繼續等待別的學生輸入。
網上參考答案(已驗證):

#!/bin/bash
##############################################################
# File Name: zhuajiu.sh
# Version: V1.0
# Author: oldboy
# Organization: www.oldboyedu.com
##############################################################
>/tmp/name.log
random(){
    random="$((RANDOM%100))"
    if [ `egrep -w "$random" /tmp/name.log|wc -l` -ge 1 ]
    then
        continue
    fi
}
name(){
    read -p "請輸入你的名字的全拼:" name
    if [ "$name" = "exit" ];
    then
        break
    fi
    if [ `egrep -w "$name" /tmp/name.log|wc -l` -ge 1 ]
    then
        echo "名字重複,請重新輸入"
        continue
    fi
    echo -e "$random\t\t$name"|tee -a /tmp/name.log
}
main(){
    while true
    do
        random
        name
    done
    echo "抓鬮結束,排序結果如下:"
    sort -rn -k1 /tmp/name.log|head -3
}
main

很有意思的一段程式碼,碰到抓鬮的事情,就可以用上了

檢測網址

批次檢查多個網站地址是否正常
要求:shell陣列方法實現,檢測策略儘量模擬使用者存取思路
http://www.yunweipai.com
http://www.taobao.com
http://www.chengxuyuan.com
http://10.0.0.7
網上參考答案(已驗證):

#!/bin/bash
##############################################################
# File Name: check_url.sh
# Version: V1.0
# Author: gaobo
# Organization: [email protected]
# Created Time : 2017-12-05 19:07:45
# Description:
##############################################################
#!/bin/bash
web_array=(
http://blog.oldboyedu.com
http://blog.etiantian.org
http://oldboy.blog.51cto.com
http://10.0.0.7
)
while true
do
for ((i=0;i<${#web_array[*]};i++))
	do
		wget -T 10 --tries=2 --spider ${web_array[$i]} >/dev/null 2>&1
	if [ $? -eq 0 ]
	then
    	echo "${web_array[$i]} is ok" 
	else
    	echo "${web_array[$i]} is bad"
	fi
	sleep 3
	done
done

解密指令碼

已知下面 下麪的字串是通過RANDOM亂數變數md5sum|cut -c 1-8擷取後的結果,請破解這些字串對應的md5sum前的RANDOM對應數位?
21029299
00205d1c
a3da1677
1f6d12dd
890684b
網上參考答案(已驗證):
此題首先要建立一個文字檔案,把上面的處理後的數位放進去,比如aa.txt,然後就可以使用下面 下麪的程式碼了:

#!/bin/bash
##############################################################
# File Name: rd_mat.sh
# Version: V1.0
# Author: gaobo
# Organization: [email protected]
# Created Time : 2017-12-07 19:57:59
# Description:
##############################################################
for ((i=0;i<=32767;i++))
do
     for j in `cat /server/scripts/aa.txt`
     do
           #echo "$(echo $i|md5sum|cut -c 1-8)    ${j}"
        if [ "$(echo $i|md5sum|cut -c 1-8)" == "${j}" ]
        then
          echo  $i
       	fi
     done
done

程式碼很簡單易懂,不過缺點是效率比較低,解密一個,基本需要半分鐘左右,答案也公佈一下:
1346
7041
25345
25667
可見,加密很快,但是解密非常費時間,爲解密的科學家們點贊!大家如果有效率更高的演算法,可以留言,謝謝!