监控日志脚本:

#!/bin/bash
#---------------------------------
#           监控日志脚本
#---------------------------------

export SITENAME=`hostname` # 名称,用于区分报警名称
export LOGFILE='/etc/ocserv/login.log' # 要监控的日志
export SHELLLOG="/root/bin/monitor.log" # 脚本运行日志
export BEFORELINENUM=`sed -n '$=' $LOGFILE` # 开始读取的行
export SECONDSPAN=5 # 每次循环间隔的时间,秒
export T1=`date '+%Y-%m-%d %H:%M:%S'` # 时间
export MONITOR_STRING='connect' # 要监控的字符串
export ACCESS_TOKEN=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx # dingding的token


function snedmsg {
    CONTENT=$1
    curl "https://oapi.dingtalk.com/robot/send?access_token=$ACCESS_TOKEN" \
    -H 'Content-Type: application/json' \
    -d "{\"msgtype\": \"text\",\"text\": {\"content\": \"${CONTENT}\" }}"
    echo -e
}


echo "$T1 $SITENAME 开始监听 $LOGFILE, $BEFORELINENUM" >> $SHELLLOG
while true
do
    afterlinenum=`sed -n '$=' $LOGFILE`
    #当日志文件清空时重置起始点,通常日志会换天写文件
    if [ $afterlinenum -lt $BEFORELINENUM ];then
        BEFORELINENUM=0
    fi
    line=$(( $afterlinenum - $BEFORELINENUM ))
    #echo " line:"$line >> $SHELLLOG
    BEFORELINENUM=$afterlinenum
    content=`tail -n $line $LOGFILE | grep -A 20 $MONITOR_STRING`
    if [ -n "$content" ]; then
        T1=`date '+%Y-%m-%d %H:%M:%S'`
        IP=`hostname -I | awk '{print $1}'`
#        IPs=`echo "$content" | grep -o "[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}" | uniq | tr "\r\n" ","`
#        Location=`curl 192.168.199.74/getiplocation.php?ip=$IPs`
#        msg="Time: $T1\nHostname: $SITENAME\nNumber: $line\nIP: $IP\nContent: $content\nLocation: $Location"
        msg="Time: $T1\nHostname: $SITENAME\nNumber: $line\nIP: $IP\nContent: $content"
        echo -e $msg >> $SHELLLOG
        echo -e "匹配到相应的字符串,准备发送告警" >> $SHELLLOG
        snedmsg "$msg"
        echo "发送完成..." >> $SHELLLOG
    fi
    sleep $SECONDSPAN
done

echo "程序退出." >> $SHELLLOG
exit

监控ocserv的脚本:

#!/bin/bash
#---------------------------------
#           监控日志脚本
#---------------------------------
 
export SITENAME=`hostname` # 名称,用于区分报警名称
export LOGFILE='/etc/ocserv/login.log' # 要监控的日志
export SHELLLOG="/home/bin/monitor.log" # 脚本运行日志
export BEFORELINENUM=`sed -n '$=' $LOGFILE` # 开始读取的行
export SECONDSPAN=10 # 每次循环间隔的时间,秒
export T1=`date '+%Y-%m-%d %H:%M:%S'` # 时间
export MONITOR_STRING='connect' # 要监控的字符串
export ACCESS_TOKEN=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx # dingding的token
export FEISHU_WEBHOOK=https://open.feishu.cn/open-apis/bot/v2/hook/xxxxxx-xxxx-xxxx-xxxx-xxxxxx


function snedmsg {
    CONTENT=$1
    curl "https://oapi.dingtalk.com/robot/send?access_token=$ACCESS_TOKEN" \
    -H 'Content-Type: application/json' \
    -d "{\"msgtype\": \"text\",\"text\": {\"content\": \"${CONTENT}\" }}"
    echo -e
}


send_message() {
    local message="$1"
    curl -s "$FEISHU_WEBHOOK" \
        -H "Content-Type: application/json" \
        -d '{
            "msg_type": "text",
            "content": {
                "text": "'"$message"'"
            }
        }'
}

echo "$T1 $SITENAME 开始监听 $LOGFILE, $BEFORELINENUM" >> $SHELLLOG
while true
do
    afterlinenum=`sed -n '$=' $LOGFILE`
    #当日志文件清空时重置起始点,通常日志会换天写文件
    if [ $afterlinenum -lt $BEFORELINENUM ];then
        BEFORELINENUM=0
    fi
    line=$(( $afterlinenum - $BEFORELINENUM ))
    #echo " line:"$line >> $SHELLLOG
    BEFORELINENUM=$afterlinenum
    content=`tail -n $line $LOGFILE | grep -A 20 $MONITOR_STRING`
    if [ -n "$content" ]; then
        T1=`date '+%Y-%m-%d %H:%M:%S'`
        IP=`hostname -I | awk '{print $1}'`
        msg="Time: $T1\nHostname: $SITENAME\nNumber: $line\nIP: $IP\nContent: $content"
        echo -e $msg >> $SHELLLOG
        echo -e "匹配到相应的字符串,准备发送告警" >> $SHELLLOG
        send_message "$msg"
        echo "发送完成..." >> $SHELLLOG
    fi
    sleep $SECONDSPAN
done
 
echo "程序退出." >> $SHELLLOG
exit

监控openvpn脚本:

#!/bin/bash
#---------------------------------
#           监控日志脚本
#---------------------------------
 
export SITENAME=`hostname` # 名称,用于区分报警名称
export LOGFILE='/var/log/openvpn/server.log' # 要监控的日志
export SHELLLOG="/home/bin/monitor-openvpn.log" # 脚本运行日志
export BEFORELINENUM=`sed -n '$=' $LOGFILE` # 开始读取的行
export SECONDSPAN=10 # 每次循环间隔的时间,秒
export T1=`date '+%Y-%m-%d %H:%M:%S'` # 时间
export MONITOR_STRING='eceive' # 要监控的字符串
export MONITOR_STRING2='primary' # 要监控的字符串
export ACCESS_TOKEN=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx # dingding的token
export FEISHU_WEBHOOK=https://open.feishu.cn/open-apis/bot/v2/hook/xxxxxx-xxxx-xxxx-xxxx-xxxxxx


function snedmsg {
    CONTENT=$1
    curl "https://oapi.dingtalk.com/robot/send?access_token=$ACCESS_TOKEN" \
    -H 'Content-Type: application/json' \
    -d "{\"msgtype\": \"text\",\"text\": {\"content\": \"${CONTENT}\" }}"
    echo -e
}


send_message() {
    local message="$1"
    curl -s "$FEISHU_WEBHOOK" \
        -H "Content-Type: application/json" \
        -d '{
            "msg_type": "text",
            "content": {
                "text": "'"$message"'"
            }
        }'
}

echo "$T1 $SITENAME 开始监听 $LOGFILE, $BEFORELINENUM" >> $SHELLLOG
while true
do
    afterlinenum=`sed -n '$=' $LOGFILE`
    #当日志文件清空时重置起始点,通常日志会换天写文件
    if [ $afterlinenum -lt $BEFORELINENUM ];then
        BEFORELINENUM=0
    fi
    line=$(( $afterlinenum - $BEFORELINENUM ))
    #echo " line:"$line >> $SHELLLOG
    BEFORELINENUM=$afterlinenum
    content=`tail -n $line $LOGFILE | grep $MONITOR_STRING`
    if [ -n "$content" ]; then
        T1=`date '+%Y-%m-%d %H:%M:%S'`
        IP=`hostname -I | awk '{print $1}'`
        msg="Time: $T1\nHostname: $SITENAME\nNumber: $line\nIP: $IP\nContent: $content"
        echo -e $msg >> $SHELLLOG
        echo -e "匹配到相应的字符串,准备发送告警" >> $SHELLLOG
        send_message "$msg"
        echo "发送完成..." >> $SHELLLOG
    fi
    sleep $SECONDSPAN
done
 
echo "程序退出." >> $SHELLLOG
exit

监控异常IP并加入到黑名单:

#!/bin/bash
#---------------------------------
#           监控日志脚本
#---------------------------------
 
export SITENAME=`hostname` # 名称,用于区分报警名称
export LOGFILE='/var/log/openvpn/server.log' # 要监控的日志
export SHELLLOG="/home/bin/monitor-openvpn-blacklist-check.log" # 脚本运行日志
export BEFORELINENUM=`sed -n '$=' $LOGFILE` # 开始读取的行
export SECONDSPAN=10 # 每次循环间隔的时间,秒
export T1=`date '+%Y-%m-%d %H:%M:%S'` # 时间
export FEISHU_WEBHOOK=https://open.feishu.cn/open-apis/bot/v2/hook/xxxxxx-xxxx-xxxx-xxxx-xxxxxx

send_message() {
    local message="$1"
    curl -s "$FEISHU_WEBHOOK" \
        -H "Content-Type: application/json" \
        -d '{
            "msg_type": "text",
            "content": {
                "text": "'"$message"'"
            }
        }'
}

echo "$T1 $SITENAME 开始监听 $LOGFILE, $BEFORELINENUM" >> $SHELLLOG
while true
do
    afterlinenum=`sed -n '$=' $LOGFILE`
    #当日志文件清空时重置起始点,通常日志会换天写文件
    if [ $afterlinenum -lt $BEFORELINENUM ];then
        BEFORELINENUM=0
    fi
    line=$(( $afterlinenum - $BEFORELINENUM ))
    #echo " line:"$line >> $SHELLLOG
    BEFORELINENUM=$afterlinenum
    content=`tail -n $line $LOGFILE | grep -oP '\d{1,3}(\.\d{1,3}){3}' | sort |uniq -c | awk '{print $2}' | grep -v 10.88.0`
    if [ -n "$content" ]; then
        location=`getiplocation $content`
        echo $location | grep '中国'
        if [ $? -ne 0 ]; then
            /usr/sbin/ipset add blacklist $content
            content="${location} add to blacklist"
        else
            content="${location}"
        fi
        T1=`date '+%Y-%m-%d %H:%M:%S'`
        IP=`hostname -I | awk '{print $1}'`
        msg="Time: $T1\nHostname: $SITENAME\nNumber: $line\nIP: $IP\nContent: $content"
        echo -e $msg >> $SHELLLOG
        echo -e "匹配到相应的字符串,准备发送告警" >> $SHELLLOG
        send_message "$msg"
        echo "发送完成..." >> $SHELLLOG
    fi
    sleep $SECONDSPAN
done
 
echo "程序退出." >> $SHELLLOG
exit

获取IP地理位置信息并加入黑名单:

<?php

// 获取IP地址的地理位置
function get_ip_location($ip) {
    $url = "https://ip.taobao.com/outGetIpInfo?ip={$ip}&accessKey=alibaba-inc";
    
    // 获取API响应
    $response = file_get_contents($url);
    $data = json_decode($response, true);
    
    // 检查返回的数据结构和状态
    if (isset($data['code']) && $data['code'] == 0 && isset($data['data']['country'])) {
        return $data['data'];
    } else {
        return null;
    }
}

// 使用系统命令添加IP到黑名单
function add_to_blacklist($ip) {
    $command = "/usr/sbin/ipset add blacklist $ip";
    exec($command, $output, $return_var);
    
    return $return_var === 0; // 返回是否成功
}

// 主函数,处理IP地址
function main($logData) {
    // 正则表达式匹配IP地址
    preg_match_all('/(?<!\d)(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)(?!\d)/', $logData, $matches);

    // 收集有效的公共IP
    $publicIPs = [];
    foreach ($matches[0] as $ip) {
        // 检查是否为私有IP
        if (!preg_match('/^(10\.|172\.16\.|172\.17\.|172\.18\.|172\.19\.|172\.20\.|172\.21\.|172\.22\.|172\.23\.|172\.24\.|172\.25\.|172\.26\.|172\.27\.|172\.28\.|172\.29\.|172\.30\.|172\.31\.|192\.168\.)/', $ip)) {
            $publicIPs[] = $ip;
        }
    }

    // 使用唯一IP进行地理位置查询
    $publicIPs = array_unique($publicIPs);
    foreach ($publicIPs as $ip) {
        $locationData = get_ip_location($ip);
        
        if ($locationData === null) {
            echo "$ip,无法获取归属地信息,未加入黑名单\n";
            continue;
        }

        $country = $locationData['country'];
        $city = $locationData['city'];
        $locationString = "$country$city";
        
        if (strpos($country, "中国") !== false) { // 检查地址中是否包含“中国”
            echo "$ip,$locationString,未加入黑名单\n";
        } else {
            $isAdded = add_to_blacklist($ip); // 将非中国IP加入黑名单
            $status = $isAdded ? "已加入黑名单" : "已在黑名单中";
            echo "$ip,$locationString,$status\n"; // 输出国家和城市
        }
    }
}

// 调用主函数
main(file_get_contents('/home/bin/openvpn-log.temp'));
?>

shell部分脚本:

#!/bin/bash
#---------------------------------
#           监控日志脚本
#---------------------------------
 
export SITENAME=`hostname` # 名称,用于区分报警名称
export LOGFILE='/var/log/openvpn/server.log' # 要监控的日志
export SHELLLOG="/home/bin/monitor-openvpn-blacklist-check.log" # 脚本运行日志
export BEFORELINENUM=`sed -n '$=' $LOGFILE` # 开始读取的行
export SECONDSPAN=10 # 每次循环间隔的时间,秒
export T1=`date '+%Y-%m-%d %H:%M:%S'` # 时间
export FEISHU_WEBHOOK=https://open.feishu.cn/open-apis/bot/v2/hook/d609331f-cd5e-4ad8-9a0a-4322857a0a29

send_message() {
    local message="$1"
    curl -s "$FEISHU_WEBHOOK" \
        -H "Content-Type: application/json" \
        -d '{
            "msg_type": "text",
            "content": {
                "text": "'"$message"'"
            }
        }'
}

echo "$T1 $SITENAME 开始监听 $LOGFILE, $BEFORELINENUM" >> $SHELLLOG
while true
do
    afterlinenum=`sed -n '$=' $LOGFILE`
    #当日志文件清空时重置起始点,通常日志会换天写文件
    if [ $afterlinenum -lt $BEFORELINENUM ];then
        BEFORELINENUM=0
    fi
    line=$(( $afterlinenum - $BEFORELINENUM ))
    #echo " line:"$line >> $SHELLLOG
    BEFORELINENUM=$afterlinenum
    tail -n $line $LOGFILE > /home/bin/openvpn-log.temp
    content=`php /usr/local/bin/getip.php`
    if [ -n "$content" ]; then
        T1=`date '+%Y-%m-%d %H:%M:%S'`
        IP=`hostname -I | awk '{print $1}'`
        msg="Time: $T1\nHostname: $SITENAME\nNumber: $line\nIP: $IP\nContent: $content"
        echo -e $msg >> $SHELLLOG
        echo -e "匹配到相应的字符串,准备发送告警" >> $SHELLLOG
        send_message "$msg"
        echo "发送完成..." >> $SHELLLOG
    fi
    sleep $SECONDSPAN
done
 
echo "程序退出." >> $SHELLLOG
exit