千家信息网

第十二章 Shell脚本编写及常见面试题(二)

发表于:2024-11-11 作者:千家信息网编辑
千家信息网最后更新 2024年11月11日,本章目录:12.11 屏蔽网站访问频繁的IP1)屏蔽每分钟访问超过200的IP方法1:以Nginx日志作为测试DATE=$(date +%d/%b/%Y:%H:%M)ABNORMAL_IP=$(tai
千家信息网最后更新 2024年11月11日第十二章 Shell脚本编写及常见面试题(二)

本章目录:

12.11 屏蔽网站访问频繁的IP

1)屏蔽每分钟访问超过200的IP

方法1:以Nginx日志作为测试

DATE=$(date +%d/%b/%Y:%H:%M)ABNORMAL_IP=$(tail -n5000 access.log |grep $DATE |awk '{a[$1]++}END{for(i in a)if(a[i]>100)print i}')#先tail防止文件过大,读取慢,数字可调整每分钟最大的访问量。awk不能直接过滤日志,因为包含特殊字符。for IP in $ABNORMAL_IP; do    if [ $(iptables -vnL |grep -c "$IP") -eq 0 ]; then        iptables -I INPUT -s $IP -j DROP    fidone

方法2:通过建立连接数

ABNORMAL_IP=$(netstat -an |awk '$4~/:80$/ && $6~/ESTABLISHED/{gsub(/:[0-9]+/,"",$5);{a[$5]++}}END{for(i in a)if(a[i]>100)print i}')#gsub是将第五列(客户端IP)的冒号和端口去掉for IP in $ABNORMAL_IP; do    if [ $(iptables -vnL |grep -c "$IP") -eq 0 ]; then        iptables -I INPUT -s $IP -j DROP    fidone

2)屏蔽每分钟SSH暴力破解超过10次的IP

方法1:通过lastb获取登录状态:

DATE=$(date +"%a %b %e %H:%M") #星期月天时分  %e单数字时显示7,而%d显示07ABNORMAL_IP=$(lastb |grep "$DATE" |awk '{a[$3]++}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    fidone

方法2:通过日志获取登录状态

DATE=$(date +"%b %d %H")ABNORMAL_IP="$(tail -n10000 /var/log/auth.log |grep "$DATE" |awk '/Failed/{a[$(NF-3)]++}END{for(i in a)if(a[i]>5)print i}')"for IP in $ABNORMAL_IP; do    if [ $(iptables -vnL |grep -c "$IP") -eq 0 ]; then        iptables -A INPUT -s $IP -j DROP        echo "$(date +"%F %T") - iptables -A INPUT -s $IP -j DROP" >>~/ssh-login-limit.log    fidone

12.12 判断输入是否为IP

方法1:

function check_ip(){    IP=$1    VALID_CHECK=$(echo $IP|awk -F. '$1<=255&&$2<=255&&$3<=255&&$4<=255{print "yes"}')    if echo $IP|grep -E "^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$">/dev/null; then        if [ $VALID_CHECK == "yes" ]; then            echo "$IP available."        else            echo "$IP not available!"        fi    else        echo "Format error!"    fi}check_ip 192.168.1.1check_ip 256.1.1.1

方法2:

function check_ip(){    IP=$1    if [[ $IP =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$ ]]; then        FIELD1=$(echo $IP|cut -d. -f1)        FIELD2=$(echo $IP|cut -d. -f2)        FIELD3=$(echo $IP|cut -d. -f3)        FIELD4=$(echo $IP|cut -d. -f4)        if [ $FIELD1 -le 255 -a $FIELD2 -le 255 -a $FIELD3 -le 255 -a $FIELD4 -le 255 ]; then            echo "$IP available."        else            echo "$IP not available!"        fi    else        echo "Format error!"    fi}check_ip 192.168.1.1check_ip 256.1.1.1

增加版:加个死循环,如果IP可用就退出,不可用提示继续输入,并使用awk判断

function check_ip(){    local IP=$1    VALID_CHECK=$(echo $IP|awk -F. '$1<=255&&$2<=255&&$3<=255&&$4<=255{print "yes"}')    if echo $IP|grep -E "^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$" >/dev/null; then        if [ $VALID_CHECK == "yes" ]; then            return 0        else            echo "$IP not available!"            return 1        fi    else        echo "Format error! Please input again."        return 1    fi}while true; do    read -p "Please enter IP: " IP    check_ip $IP    [ $? -eq 0 ] && break || continuedone

12.13 判断输入是否为数字

方法1:if [[ $1 =~ ^[0-9]+$ ]]; then    echo "Is Number."else    echo "No Number."fi方法2:if [ $1 -gt 0 ] 2>/dev/null; then    echo "Is Number."else    echo "No Number."fi

方法3:

echo $1 |awk '{print $0~/^[0-9]+$/?"Is Number.":"No Number."}'  #三目运算符12.14 找出包含关键字的文件DIR=$1KEY=$2for FILE in $(find $DIR -type f); do    if grep $KEY $FILE &>/dev/null; then        echo "--> $FILE"    fidone

12.15 监控目录,将新创建的文件名追加到日志中

需安装inotify-tools软件包。

#!/bin/bashMON_DIR=/optinotifywait -mq --format %f -e create $MON_DIR |\while read files; do  echo $files >> test.logdone12.16 多个网卡选择function local_nic() {    local NUM ARRAY_LENGTH    NUM=0    for NIC_NAME in $(ls /sys/class/net|grep -vE "lo|docker0"); do        NIC_IP=$(ifconfig $NIC_NAME |awk -F'[: ]+' '/inet addr/{print $4}')        if [ -n "$NIC_IP" ]; then            NIC_IP_ARRAY[$NUM]="$NIC_NAME:$NIC_IP"    #将网卡名和对应IP放到数组            let NUM++        fi    done    ARRAY_LENGTH=${#NIC_IP_ARRAY[*]}    if [ $ARRAY_LENGTH -eq 1 ]; then     #如果数组里面只有一条记录说明就一个网卡        NIC=${NIC_IP_ARRAY[0]%:*}        return 0    elif [ $ARRAY_LENGTH -eq 0 ]; then   #如果没有记录说明没有网卡        echo "No available network card!"        exit 1    else        #如果有多条记录则提醒输入选择        for NIC in ${NIC_IP_ARRAY[*]}; do            echo $NIC        done        while true; do            read -p "Please enter local use to network card name: " INPUT_NIC_NAME            COUNT=0            for NIC in ${NIC_IP_ARRAY[*]}; do                NIC_NAME=${NIC%:*}                if [ $NIC_NAME == "$INPUT_NIC_NAME" ]; then                    NIC=${NIC_IP_ARRAY[$COUNT]%:*}                    return 0                else                   COUNT+=1                fi            done            echo "Not match! Please input again."        done    fi}local_nic

如果有只有一个网卡就不选择。

12.17 查看网卡实时流量

#!/bin/bash# Description: Only CentOS6traffic_unit_conv() {    local traffic=$1    if [ $traffic -gt 1024000 ]; then        printf "%.1f%s" "$(($traffic/1024/1024))" "MB/s"    elif [ $traffic -lt 1024000 ]; then        printf "%.1f%s" "$(($traffic/1024))" "KB/s"    fi}NIC=$1echo -e " In ------ Out"while true; do    OLD_IN=$(awk -F'[: ]+' '$0~"'$NIC'"{print $3}' /proc/net/dev)    OLD_OUT=$(awk -F'[: ]+' '$0~"'$NIC'"{print $11}' /proc/net/dev)    sleep 1    NEW_IN=$(awk -F'[: ]+' '$0~"'$NIC'"{print $3}' /proc/net/dev)    NEW_OUT=$(awk -F'[: ]+' '$0~"'$NIC'"{print $11}' /proc/net/dev)    IN=$(($NEW_IN-$OLD_IN))    OUT=$(($NEW_OUT-$OLD_OUT))    echo "$(traffic_unit_conv $IN) $(traffic_unit_conv $OUT)"    sleep 1done# 也可以通过ficonfig命令获取收发流量while true; do    OLD_IN=$(ifconfig $NIC |awk -F'[: ]+' '/bytes/{print $4}')      OLD_OUT=$(ifconfig $NIC |awk -F'[: ]+' '/bytes/{print $9}')    sleep 1    NEW_IN=$(ifconfig $NIC |awk -F'[: ]+' '/bytes/{print $4}')    NEW_OUT=$(ifconfig $NIC |awk -F'[: ]+' '/bytes/{print $9}')    IN=$(($NEW_IN-$OLD_IN))    OUT=$(($NEW_OUT-$OLD_OUT))    echo "$(traffic_unit_conv $IN) $(traffic_unit_conv $OUT)"    sleep 1done

12.18 MySQL数据库备份

#!/bin/bashDATE=$(date +%F_%H-%M-%S)HOST=192.168.1.120DB=testUSER=bakPASS=123456MAIL="zhangsan@example.com lisi@example.com"BACKUP_DIR=/data/db_backupSQL_FILE=${DB}_full_$DATE.sqlBAK_FILE=${DB}_full_$DATE.zipcd $BACKUP_DIRif mysqldump -h$HOST -u$USER -p$PASS --single-transaction --routines --triggers -B $DB > $SQL_FILE; then    zip $BAK_FILE $SQL_FILE && rm -f $SQL_FILE    if [ ! -s $BAK_FILE ]; then            echo "$DATE 内容" | mail -s "主题" $MAIL    fielse    echo "$DATE 内容" | mail -s "主题" $MAILfifind $BACKUP_DIR -name '*.zip' -ctime +14 -exec rm {} \;

12.19 Nginx启动脚本

#!/bin/bash# Description: Only support RedHat system. /etc/init.d/functionsWORD_DIR=/data/project/nginx1.10DAEMON=$WORD_DIR/sbin/nginxCONF=$WORD_DIR/conf/nginx.confNAME=nginxPID=$(awk -F'[; ]+' '/^[^#]/{if($0~/pid;/)print $2}' $CONF)if [ -z "$PID" ]; then    PID=$WORD_DIR/logs/nginx.pidelse    PID=$WORD_DIR/$PIDfistop() {    $DAEMON -s stop    sleep 1    [ ! -f $PID ] && action "* Stopping $NAME"  /bin/true || action "* Stopping $NAME" /bin/false}start() {    $DAEMON    sleep 1    [ -f $PID ] && action "* Starting $NAME"  /bin/true || action "* Starting $NAME" /bin/false}reload() {    $DAEMON -s reload}test_config() {    $DAEMON -t}case "$1" in    start)        if [ ! -f $PID ]; then            start        else            echo "$NAME is running..."            exit 0        fi        ;;    stop)        if [ -f $PID ]; then            stop        else            echo "$NAME not running!"            exit 0        fi        ;;    restart)        if [ ! -f $PID ]; then            echo "$NAME not running!"             start        else            stop            start        fi        ;;    reload)        reload        ;;    testconfig)        test_config        ;;     status)        [ -f $PID ] && echo "$NAME is running..." || echo "$NAME not running!"        ;;    *)        echo "Usage: $0 {start|stop|restart|reload|testconfig|status}"        exit 3        ;;esac

12.20 选择SSH连接主机

写一个配置文件保存被监控主机SSH连接信息,文件内容格式:主机名 IP User Port

#!/bin/bashPS3="Please input number: "HOST_FILE=hostwhile true; do    select NAME in $(awk '{print $1}' $HOST_FILE) quit; do        [ ${NAME:=empty} == "quit" ] && exit 0        IP=$(awk -v NAME=${NAME} '$1==NAME{print $2}' $HOST_FILE)        USER=$(awk -v NAME=${NAME} '$1==NAME{print $3}' $HOST_FILE)        PORT=$(awk -v NAME=${NAME} '$1==NAME{print $4}' $HOST_FILE)        if [ $IP ]; then            echo "Name: $NAME, IP: $IP"            ssh -o StrictHostKeyChecking=no -p $PORT -i id_rsa $USER@$IP  # 密钥登录            break        else            echo "Input error, Please enter again!"            break        fi    donedone

本章写的Shell脚本例子都比较实用,在面试题中也经常出现,希望大家参考着多动手写写,不要复制粘贴就拿来跑,这样是学不会的!有问题请加×××流:323779636(Shell/Python运维开发群)


方法 网卡 文件 日志 输入 选择 主机 内容 数字 登录 脚本 主题 只有 数组 流量 状态 目录 监控 特殊 频繁 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 中信国安网络安全审查 网络安全的认识800字 山东省科技厅农民互联网 长津湖实时票房数据库 南阳炒币量化交易软件开发价格 干软件开发都要学什么东西 深圳软件开发厂家 学生网络安全承诺承诺书 全国职业技能大赛网络安全 云服务器怎么看主机地址 软件开发公司数量怎么选 青岛比较好的软件开发公司 汕尾通讯软件开发平均价格 网络安全实习报告总结4000字 网络安全审查法几日通知运营者 服务器安全狗设置共享文件 福州财务软件开发多少钱 搭建p2p监控平台服务器 服务器如何做网站空间 数据库索引的特点 计算机网络技术就业很惨 软件开发上海平均工资 58同城调用服务器异常 双网卡服务器如何添加路由器 做软件开发容易吗 北京放心软件开发服务参考价格 软件开发两大类 华为信息和网络技术学院 北京乐逛网络技术有限公司 n75服务器繁忙
0