shell--作业2

shell--作业2

1.监控2台服务器硬盘利用率 使用率

输出内容如下
ip:xxxx
磁盘总容量:     40GB
使用磁盘容量:17GB


#前提(打通免密)
ssh-keygen
ls .ssh/
ssh-copy-id root@10.0.0.1
ssh root@10.0.1.142 df -h



#!/bin/bash

SERVERS=("10.0.1.142" "10.0.1.143")

for SERVER_IP in "${SERVERS[@]}"; do
    DISK_USAGE=$(ssh root@$SERVER_IP 'df -h / | awk '\''NR==2{print $5}'\''')
    TOTAL_DISK=$(ssh root@$SERVER_IP 'df -hT / | awk '\''NR==2{print $2}'\''')
    USED_DISK=$(ssh root@$SERVER_IP 'df -hT / | awk '\''NR==2{print $3}'\''')

    echo "IP: $SERVER_IP"
    echo "磁盘总容量: $TOTAL_DISK"
    echo "使用磁盘容量: $USED_DISK"

    # 这里可以添加逻辑判断,如果使用率超过5%,则发送邮件通知
    # 如需邮件通知功能,需确保服务器已配置好邮件发送功能
done






测试效果

[root@centos7mage ~]# sh jk.sh 
IP: 10.0.1.142
磁盘总容量: xfs
使用磁盘容量: 94G
IP: 10.0.1.143
磁盘总容量: xfs
使用磁盘容量: 94G

2.批量检查 5个网站域名是否正常

#!/bin/bash

domains=("www.baidu.com" "www.sansi.com" "www.abc.com" "www.jkkcss.cn" "bbs.sansi.fun")

for domain in "${domains[@]}"; do
    response_code=$(curl -s -o /dev/null -w "%{http_code}" "$domain")

    case $response_code in
        200)
            echo "$domain is up with status code $response_code (OK)"
            ;;
        301|302)
            echo "$domain is redirected with status code $response_code"
            ;;
        403)
            echo "$domain is up but returning a 403 Forbidden status code"
            ;;
        404)
            echo "$domain is up but returning a 404 Not Found status code"
            ;;
        500|501|502)
            echo "$domain is up but returning an error status code $response_code"
            ;;
        *)
            echo "$domain is down or returned unknown status code $response_code"
            ;;
    esac
done







效果测试
[root@centos7mage ~]# sh jc.sh 
www.baidu.com is up with status code 200 (OK)
www.sansi.com is redirected with status code 301
www.abc.com is redirected with status code 301
www.jkkcss.cn is redirected with status code 301
bbs.sansi.fun is redirected with status code 301



3.统计磁盘使用率

磁盘大于%5 就打印mail  小于 硬盘正常

 内存使用使用率   内存使用率大于%5就打印mail  小于 就 内存正常

#!/bin/bash

# 定义发送邮件函数
function send_email() {
    local SUBJECT=$1
    local MESSAGE=$2
    echo "$MESSAGE" | mail -s "$SUBJECT" "15178374440@163.com"
}

function check_and_send_alert() {
    local USAGE=$1
    local RESOURCE=$2
    local THRESHOLD=5
    if (( $(echo "$USAGE >= $THRESHOLD" | bc -l) )); then
        ALERT_BODY="系统${RESOURCE}资源可能过大,请及时解决。当前使用率为${USAGE}%"
        send_email "[$RESOURCE]资源警告" "$ALERT_BODY"
    fi
}

function cpu() {
    util=$(vmstat | awk 'NR==3{print $13+$14}')
    iowait=$(vmstat | awk 'NR==3{print $16}')
    echo "CPU - 使用率: ${util}%, 等待磁盘IO响应使用率: ${iowait}%"
    check_and_send_alert "$util" "CPU"
}

function memory() {
    total=$(free -m | awk 'NR==2{print $2}')
    used=$(free -m | awk 'NR==2{print $3}')
    usage=$((100 * used / total))
    echo "内存 - 总大小: ${total}MB, 已使用:${used}MB, 使用率:${usage}%"
    check_and_send_alert "$usage" "内存"
}

function disk() {
    fs=$(df -h | awk '/^\/dev/{print $1}')
    for p in $fs; do
        mounted=$(df -h | awk -v p="$p" '$1==p{print $NF}')
        size=$(df -h | awk -v p="$p" '$1==p{print $2}')
        used=$(df -h | awk -v p="$p" '$1==p{print $3}')
        user_percent=$(df -h | awk -v p="$p" '$1==p{print $5}' | tr -d '%')
        echo "硬盘 - 挂载点: $mounted, 总大小: $size, 已使用: $used, 使用率:${user_percent}%"
        check_and_send_alert "$user_percent" "硬盘(挂载点:$mounted)"
    done
}

function tcp_status() {
    if ! command -v netstat &>/dev/null; then
        echo "检测到netstat未安装,正在尝试安装..."
        yum -y install net-tools >&2
    fi

    if command -v netstat &>/dev/null; then
        summary=$(netstat -antp | awk '{a[$6]++} END{for(i in a) print i ": " a[i] " "}')
        echo "TCP连接状态 - $summary"
    else
        echo "安装netstat失败,请手动安装并重试。"
    fi
}

# 检查mailx工具是否已安装
if ! command -v mailx &>/dev/null; then
    echo "邮件发送工具mailx未安装,正在尝试安装..."
    yum -y install mailx >&2
fi

# 执行各项监控并发送邮件报警
cpu
memory
disk
tcp_status





测试
 dd if=/dev/zero of=/bigfile bs=1G count=10


4 使用for循环安装 批量安装3台服务器 php环境 使用(LAMP)脚本实现 环境yum 安装都可以 主要测试语法

工作结果就是   每台服务器 都可以打开php 测试页面

模板一(yum安装)
#!/bin/bash

# 定义服务器列表
SERVERS=("10.0.1.142" "10.0.1.143" "10.0.1.145")

# 安装LAMP环境的函数
function install_lamp() {
    server_ip=$1
    
    # 更新Yum源和安装必要软件包
    ssh root@$server_ip << EOF
        set -e
        yum update -y
        yum install epel-release -y
        yum install httpd mariadb-server php php-mysqlnd -y
        systemctl enable httpd
        systemctl start httpd
        systemctl enable mariadb
        systemctl start mariadb
        firewall-cmd --permanent --add-service=http
        firewall-cmd --reload
EOF
}

# 遍历服务器列表并安装LAMP环境
for server in "${SERVERS[@]}"; do
    echo "开始在服务器 $server 上安装 LAMP 环境..."
    install_lamp "$server"
    echo "完成在服务器 $server 上安装 LAMP 环境。"
done





模板一(2)
#!/bin/bash

# 定义网段和起始结束IP范围
NETWORK="10.0.1."
START=1
END=254

# 扫描指定网段并找出在线主机
ONLINE_SERVERS=()
MENU_OPTIONS=()

for i in $(seq $START $END); do
    IP="$NETWORK$i"
    if nmap -q -Pn -p22 $IP | grep -q 'open'; then
        ONLINE_SERVERS+=("$IP")
        MENU_OPTIONS+=("$((i-START+1)) $IP")
        echo "在线: $IP"
    else
        echo "离线: $IP"
    fi
done

# 安装LAMP环境的函数
install_lamp() {
    server_ip=$1
    
    # 更新Yum源和安装必要软件包
    ssh root@$server_ip << EOF
        set -e
        yum update -y
        yum install epel-release -y
        yum install httpd mariadb-server php php-mysqlnd -y
        systemctl enable httpd
        systemctl start httpd
        systemctl enable mariadb
        systemctl start mariadb
        firewall-cmd --permanent --add-service=http
        firewall-cmd --reload
EOF
}

# 显示在线主机列表并编号
echo "请选择要安装LAMP环境的服务器:"
COUNTER=1
for option in "${MENU_OPTIONS[@]}"; do
    echo "$option"
done
echo "$((COUNTER+1)) 全部安装"
echo "$((COUNTER+2)) 退出"

read -p "请选择: " CHOICE

# 处理用户选择
if [[ $CHOICE -eq $((COUNTER+1)) ]]; then
    for ip in "${ONLINE_SERVERS[@]}"; do
        install_lamp "$ip"
    done
elif [[ $CHOICE -gt 0 && $CHOICE -le $COUNTER ]]; then
    install_lamp "${ONLINE_SERVERS[$(($CHOICE-1))]}"
else
    echo "无效的选择,请重新运行脚本。"
fi









模板二(编译安装)
#!/bin/bash
NGINX_V=1.15.6
PHP_V=5.6.36
TMP_DIR=/tmp
INSTALL_DIR=/usr/local
PWD_C=$PWD
echo
echo -e "\tMenu\n"
echo -e "1. Install Nginx"
echo -e "2. Install PHP"
echo -e "3. Install MySQL"
echo -e "4. Deploy LNMP"
echo -e "9. Quit"
function command_status_check() {
if [ $? -ne 0 ]; then
echo $1
exit
fi
}
function install_nginx() {
cd $TMP_DIR
yum install -y gcc gcc-c++ make openssl-devel pcre-devel wget
wget http://nginx.org/download/nginx-${NGINX_V}.tar.gz
tar zxf nginx-${NGINX_V}.tar.gz
cd nginx-${NGINX_V}
./configure --prefix=$INSTALL_DIR/nginx \
--with-http_ssl_module \
--with-http_stub_status_module \
--with-stream
command_status_check "Nginx - 平台环境检查失败!"
make -j 4
command_status_check "Nginx - 编译失败!"
make install
command_status_check "Nginx - 安装失败!"
mkdir -p $INSTALL_DIR/nginx/conf/vhost
alias cp=cp ; cp -rf $PWD_C/nginx.conf $INSTALL_DIR/nginx/conf
rm -rf $INSTALL_DIR/nginx/html/*
echo "ok" > $INSTALL_DIR/nginx/html/status.html
echo '<?php echo "ok"?>' > $INSTALL_DIR/nginx/html/status.php
$INSTALL_DIR/nginx/sbin/nginx
command_status_check "Nginx - 启动失败!"
}
function install_php() {
cd $TMP_DIR
yum install -y gcc gcc-c++ make gd-devel libxml2-devel \
libcurl-devel libjpeg-devel libpng-devel openssl-devel \
libmcrypt-devel libxslt-devel libtidy-devel
wget http://docs.php.net/distributions/php-${PHP_V}.tar.gz
tar zxf php-${PHP_V}.tar.gz
cd php-${PHP_V}
./configure --prefix=$INSTALL_DIR/php \
--with-config-file-path=$INSTALL_DIR/php/etc \
--enable-fpm --enable-opcache \
--with-mysql --with-mysqli --with-pdo-mysql \
--with-openssl --with-zlib --with-curl --with-gd \
--with-jpeg-dir --with-png-dir --with-freetype-dir \
--enable-mbstring --enable-hash
command_status_check "PHP - 平台环境检查失败!"
make -j 4
command_status_check "PHP - 编译失败!"
make install
command_status_check "PHP - 安装失败!"
cp php.ini-production $INSTALL_DIR/php/etc/php.ini
cp sapi/fpm/php-fpm.conf $INSTALL_DIR/php/etc/php-fpm.conf
cp sapi/fpm/init.d.php-fpm /etc/init.d/php-fpm
chmod +x /etc/init.d/php-fpm
/etc/init.d/php-fpm start
command_status_check "PHP - 启动失败!"
}
read -p "请输入编号:" number
case $number in
1)
install_nginx;;
2)
install_php;;
3)
install_mysql;;
4)
install_nginx
install_php
;;
9)
exit;;
esac





5 有人攻击我服务器 就拉黑异常ip


模板一
#!/bin/bash
DATE=$(date +%d/%b/%Y:%H:%M)
#nginx日志
LOG_FILE=/usr/local/nginx/logs/demo2.access.log
#分析ip的访问情况
ABNORMAL_IP=$(tail -n5000 $LOG_FILE |grep $DATE |awk '{a[$1]++}END{for(i in
a)if(a[i]>10)print i}')
for IP in $ABNORMAL_IP; do
if [ $(iptables -vnL |grep -c "$IP") -eq 0 ]; then
iptables -I INPUT -s $IP -j DROP
echo "$(date +'%F_%T') $IP" >> /tmp/drop_ip.log
fi
done






模板二
#!/bin/bash
################################################################################
#### 根据web访问日志,封禁请求量异常的IP,如IP在半小时后恢复正常,则解除封禁
################################################################################
#### 定义参数
LOGFILE=/usr/local/nginx/logs/access.log
THRESHOLD=100
PORT=80
BLOCK_TIME=1800 # 设置封禁时间(秒),例如半小时为1800秒
BADIPS_LOG=/tmp/badip.log
IPS_FILE=/tmp/ips.txt
NOW=$(date +%s)

# 获取一分钟前的完整时间戳
MINUTE_AGO=$((NOW - 60))

# 计算一分钟前的小时和分钟
HOUR_MINUTE=$(date -d "@$MINUTE_AGO" "+%d/%b/%Y:%H:%M")

# 分析日志并找出一分钟内请求次数超过阈值的IP
grep "$HOUR_MINUTE:" $LOGFILE | awk '{print $1}' | sort | uniq -c | awk -v th="$THRESHOLD" '$1 > th {print $2}' > $IPS_FILE

# 封禁异常IP
block() {
  while IFS= read -r IP; do
    if ! iptables -L INPUT -n --line-numbers -v | grep -q "^ *[[:digit:]]*:.* -s $IP -p tcp --dport $PORT .*REJECT"; then
      iptables -I INPUT -p tcp --dport $PORT -s $IP -j REJECT
      echo "`date +%F-%T` $IP" >> $BADIPS_LOG
      # 添加一个计划任务,在封禁时间过后自动解封
      (sleep $BLOCK_TIME && unblock_ip "$IP") &
    fi
  done < "$IPS_FILE"
}

# 解封IP
unblock_ip() {
  IP=$1
  iptables -D INPUT -p tcp --dport $PORT -s $IP -j REJECT
  echo "`date +%F-%T` $IP - Unblocked" >> $BADIPS_LOG
}

# 在整点和半点时解封所有IP并重新检查日志
if [ $(date +%M) -eq 00 ] || [ $(date +%M) -eq 30 ]; then
  unblock_all
  block
else
  block
fi

# 解封所有IP
unblock_all() {
  iptables -L INPUT -n --line-numbers -v | grep '^ *[[:digit:]]*:.* -s .* -p tcp --dport $PORT .*REJECT' | awk '{print $1}' | xargs -n1 iptables -D INPUT
  iptables -Z
}

# 执行封禁操作
block



#tips: 
cat ips.txt  #经过统计分析后,一分钟内访问次数超过阈值的IP地址列表
cat badip.log     #被封禁的IP地址及其封禁时间







#测试
模拟压测(脚本)
#!/bin/bash

while true; do
    ab -n 9000 -c 1000 http://10.0.1.145/  #模拟1000个并发用户向http://10.0.1.145/这个URL发送总计9000个HTTP GET请求
    sleep 3  # 延迟一段时间再执行下一轮,这里设置为每60秒执行一次
done





#效果
[root@centos7mage tmp]# cat ips.txt        #经过统计分析后,一分钟内访问次数超过阈值的IP地址列表
10.0.1.135
[root@centos7mage tmp]# cat badip.log     #被封禁的IP地址及其封禁时间
2024-04-07-22:45:49 10.0.1.139
2024-04-07-22:45:50 10.0.1.139
2024-04-07-22:49:02 10.0.1.135
2024-04-07-22:49:02 10.0.1.135
2024-04-07-22:49:03 10.0.1.135
2024-04-07-22:49:03 10.0.1.135
2024-04-07-22:49:04 10.0.1.135
2024-04-07-22:49:04 10.0.1.135
2024-04-07-22:49:05 10.0.1.135


Benchmarking 10.0.1.145 (be patient)
apr_socket_recv: Connection refused (111)
This is ApacheBench, Version 2.3 <$Revision: 1430300 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/






posted @ 2024-04-07 22:58  三思博客  阅读(10)  评论(0编辑  收藏  举报