shell的综合应用

对交换机配置进行批量配置备份

while read ip add
do
{
if ping $ip -c1 -W1 &> /dev/null ;then
 a=`echo $ip|sed -rn 's/^10\.50\.(.*)$/\1/p'`
{
expect &>/dev/null <<EOF
set timeout 10
spawn telnet $ip
expect "Username:" { send "admin\n" }
expect "Password:" { send "123456\n" }
expect {
 ">" { send "en\n";exp_continue }
 "Password:" {send "luoyt,123\n";exp_continue}
 "#" { send "\n" }
}
send "copy flash:config.text tftp://10.0.0.5/$add-$a-config.text\n"
send "exit\n"
expect eof
EOF
}
echo -e "\033[36;1m$add-$a 配置导出成功!\033[0m"
else
 echo "$ip 不通!" >> /data/no.log
fi
} &
done < /data/ip
wait

对主机进行ssh免密验证以及在各主机上添加本地主机名解析

#/bin/bash
file='host.txt'
password='111111'
expect << EOF
spawn ssh-keygen
expect { 
  "(/root/.ssh/id_rsa):" { send "\n" } 
} 
expect {
  "(y/n)?" { send "y\n";exp_continue }
  "(empty for no passphrase):" { send "\n" }
}
expect {
  "again:" { send "\n" }
}
expect eof
EOF
while read -r i v 
do
   echo $i "----->" $v
   expect << EOF
   spawn ssh-copy-id $i
   expect {
     "(yes/no)?" { send "yes\n";exp_continue }
     "s password:" { send "$password\n" }
   }
   expect {
     "s password:" { send "$password\n" }
   }
   expect eof
EOF
   ssh $i 'date&&hostname' < /dev/null
   if [[ $? -eq 0 ]];then
      echo "$i 免密成功"
   fi
   echo '未修改前'
   ssh $i 'cat /etc/hosts' < /dev/null
   while read -r m n
   do
      ssh $i "sed -ri '/($m)|($n)/d' /etc/hosts" < /dev/null
      ssh $i "echo $m $n >> /etc/hosts" < /dev/null
   done < $file
   echo '修改后'
   ssh $i 'cat /etc/hosts' < /dev/null
   echo "$i 处理完!"
done < $file

host.txt文件

10.0.0.7 CentOS7907
10.0.0.6 CentOS7906
10.0.0.8 CentOS7908
10.0.0.9 CentOS7909
10.0.0.10 CentOS7910
10.0.0.5 CentOS7905

遇到的问题

问题:当while循环遇见了ssh时,利用read读取文件,交给while,发现循环只能执行一遍,就结束了。

解析:是因为重定向或者管道符传入的内容被ssh命令提前吞掉了,所以后面相当于没有内容,所以只循环了一遍

只需要在命令后面加上< /dev/null就可以了

例如

ssh $i 'date&&hostname'

修改成

ssh $i 'date&&hostname' < /dev/null

总结

while read时,如果遇到处理标准输入的命令cat,mail,ssh,grep,sed,awk等等,都应该考虑这个问题。

安全巡检脚本

实现的功能:

  • 读取防火墙iptables 中的filter的INPUT表
  • 读取/var/log/secure日志,并对ip进行过滤和排序
  • 设置白名单,对白名单中的ip,不记录
  • 有新增的ip会在日志中体现,也会在钉钉机器人上告警

执行的账户需要有sudo权限

#!/usr/bin/bash
shijian=`date`
#记录结果的路径
path='/home/hexug/logs/iptables.log'
#用来历史ip的记录
ippath='/data/shell/1.ip'
#用来设置白名单的文件
allow_ip='/data/shell/allow_ip'
echo "---------------- $shijian -----------------------------" >> $path
#查看iptables的filter中的INPUT表的记录
sudo iptables -t filter -L INPUT -nv | egrep -v "(^Chain)|(IN_HIDS_MYSQLD)" | awk '{printf"%-7s %-8s %-8s %-6s %-17s %-6s %-20s\n",$1,$2,$3,$4,$8,$10,$11}' >> $path
echo "访问的IP地址-----------------------------------------------------------------------" >> $path
#获取/var/log/secure文件中所有的ip
all_ip=`sudo cat  /var/log/secure | egrep -o "([0-9]{1,3}\.){3}[0-9]{1,3}" | sort | uniq -c | sort -rn | awk '{printf"%-5s %-15s\n",$1,$2 }'`
#设置接收白名单过滤后接收的数据
new_ip_list=''
#把分隔符设置成回车换行符
IFS=$'\n'
#遍历所有的数据
for j in $all_ip;do
#取出ip字段
ip1=`echo $j| awk '{print $2}'`
#设置白名单标记,当在白名单中旧把标记置true
FL=false
#循环白名单来验证取出的ip字段是否在白名单中
while read -r ip2;do
if [[ $ip1 = $ip2 ]];then
FL=true
fi
done < $allow_ip
#如果标记为false,则表明不在白名单中,就将字符串拼接到接收变量中
if [[ $FL = false  ]];then
if [[ $new_ip_list = '' ]];then
new_ip_list=$j
else
new_ip_list=`echo "${new_ip_list}\n${j}"`
fi
fi
done
#恢复分隔符设置
IFS=$' \n'
#将结果写入日志文件
echo -e $new_ip_list >> $path
#将过滤后的字符串中的ip字段取出来
a=`echo -e $new_ip_list | awk '{print $2}'`
#遍历与历史ip文件中的ip进行对比,如果不在历史文件中,就是新增的ip,需要记录到历史文件中,并在日志中体现
for i in $a;do
flag=false
while read -r ip sj;do
if [[ $i = $ip ]];then
 flag=true
fi
done < $ippath
if [[ $flag != true  ]];then
echo "$i `date +'%Y-%m-%d %T'`" | awk '{printf"%-15s %-10s %-8s\n",$1,$2,$3}' >> $ippath
t=`date +'%Y-%m-%d %T'`
text2=`echo $i 新增 $t | awk '{printf"%-15s %-4s %-10s %-8s\n",$1,$2,$3,$4}'`
echo $text2 >> $path

#当出现新增ip,钉钉告警
url='https://oapi.dingtalk.com/robot/send?access_token=xxxxxxxxxxxxxxxxxxx'
text1=`echo -e "$new_ip_list\n----"`
text=`echo -e "${text1}\n${text2}"`

curl $url \
 -H 'Content-Type: application/json' \
 -d "{'msgtype': 'markdown','markdown': {'title':'告警','text':'$text'}}" &> /dev/null
fi                                                                                                          
done

白名单文件的设置格式,每个ip一行

例如

1.2.3.4
2.5.2.5

加入循环任务

$ crontab -e
*/30 * * * *  /usr/bin/bash /data/shell/1.sh

每30分钟执行一次

注意事项

  • 对数据遍历时,需要修改分隔符IFS 修改完了需要修改回来IFS=$' \n'
  • 钉钉告警的数据要符合json格式都要带引号
posted @ 2023-02-23 15:08  厚礼蝎  阅读(17)  评论(0编辑  收藏  举报