【Bash脚本】Nginx 日志分析工具:统计网站的总数据流量、请求数、和各个IP的具体数据 1

最近小破站被恶意刷流了,在调查的时候用GPT写了这个东西,希望能帮到大家

脚本

#!/bin/bash

LOG_DIR="/opt/1panel/apps/openresty/openresty/www/sites"

# 人类可读的流量格式化函数
format_size() {
    local size=$(printf "%.0f" "$1")
    if (( size < 1024 )); then
        echo "${size} B"
    elif (( size < 1048576 )); then
        echo "$(( size / 1024 )) KB"
    elif (( size < 1073741824 )); then
        echo "$(( size / 1048576 )) MB"
    else
        echo "$(( size / 1073741824 )) GB"
    fi
}

# 列出所有网站并统计汇总数据
list_sites() {
    local total_requests=0
    local total_traffic=0
    declare -A site_requests
    declare -A site_traffic

    echo "📌 站点列表:"
    for site in "$LOG_DIR"/*; do
        [[ -d "$site" ]] || continue
        site_name=$(basename "$site")
        log_path="$site/log/access.log"

        if [[ ! -f "$log_path" ]]; then
            echo "  ❌ $site_name (无日志)"
            continue
        fi

        # 统计该站点请求数 & 总流量
        requests=$(wc -l  "$output_file"  # 清空输出文件

    for site in "$LOG_DIR"/*; do
        [[ -d "$site" ]] || continue
        log_path="$site/log/access.log"

        if [[ -f "$log_path" ]]; then
            # 检测日志文件类型
            if file "$log_path" | grep -q "gzip compressed data"; then
                zgrep -a -F "$ip" "$log_path" >> "$output_file"
            else
                grep -a -F "$ip" "$log_path" >> "$output_file"
            fi
            found=1
        fi
    done

    if [[ $found -eq 1 ]]; then
        echo "✅ 日志已保存到: $output_file"
    else
        echo "❌ 没有找到与 $ip 相关的日志!"
    fi
}

# 解析命令行参数
if [[ $# -eq 2 && "$1" == "-n" ]]; then
    SITE="$2"
    LOG_PATH="$LOG_DIR/$SITE/log/access.log"

    if [[ ! -f "$LOG_PATH" ]]; then
        echo "错误: 访问日志 $LOG_PATH 不存在!"
        exit 1
    fi

    echo "日志文件: $LOG_PATH"

    # 统计请求最多的 10 个 IP
    echo -e "
📊 请求数最多的 IP:"
    awk '{print $1}' "$LOG_PATH" | sort | uniq -c | sort -nr | head -n 10 | awk '{printf "  %-15s 请求数: %s
", $2, $1}'

    # 统计流量最多的 10 个 IP
    echo -e "
📊 消耗带宽最多的 IP:"
    awk '{ip=$1; size=$10} size ~ /^[0-9] $/ {traffic[ip]  = size} END {for (ip in traffic) printf "%.0f %s
", traffic[ip], ip}' "$LOG_PATH" \
        | sort -nr | head -n 10 | while read -r size ip; do
        echo "  $ip 流量: $(format_size "$size")"
    done

elif [[ $# -eq 1 && "$1" == "-v" ]]; then
    list_sites

elif [[ $# -eq 3 && "$1" == "-i" ]]; then
    extract_ip_logs "$2" "$3"

else
    echo "用法:"
    echo "  $0 -n          # 查看指定站点的流量信息"
    echo "  $0 -v                # 列出所有站点并显示汇总数据"
    echo "  $0 -i      # 筛选出指定 IP 的日志并保存"
    exit 1
fi

说明:

脚本默认使用 1panel 的路径,你可以修改该脚本内部的 LOG_DIR来改变 access.log 的默认位置

如果 access.log 采用 gzip 压缩 (.log.gz),脚本会自动处理。

🚀 参数说明

参数 说明 示例
-n 查看指定站点的流量 & 请求统计 ./statics.bash -n example.com
-v 列出所有站点的流量 & 请求数汇总 ./statics.bash -v
-i 筛选指定 IP 访问日志并输出到文件 ./statics.bash -i 1.1.1.1 ./sus.log

1️⃣ 查看单个站点

./statics.bash -n example.com

示例输出:

日志文件: /opt/1panel/apps/openresty/openresty/www/sites/example.com/log/access.log

📊 请求数最多的 IP:
  192.168.1.10       请求数: 5241
  203.0.113.45       请求数: 3124
  8.8.8.8            请求数: 2678
  1.1.1.1            请求数: 2395
  10.0.0.5           请求数: 1982

📊 消耗带宽最多的 IP:
  203.0.113.45       流量: 1.2 GB
  8.8.8.8            流量: 987 MB
  192.168.1.10       流量: 730 MB
  1.1.1.1            流量: 450 MB
  10.0.0.5           流量: 380 MB

2️⃣ 列出所有站点汇总

./statics.bash -v

示例输出:

📌 站点列表:
  ✅ example.com     请求数: 105432, 流量: 4.2 GB
  ✅ site2.net       请求数: 50210,  流量: 1.7 GB
  ✅ blog.xyz        请求数: 34987,  流量: 890 MB

📊 站点总览
  🌐 站点总数: 3
  📥 总请求数: 190629
  📊 总流量: 6.8 GB

3️⃣ 筛选指定 IP 的访问日志

./statics.bash -i 203.0.113.45 ./sus.log

示例输出:

📂 正在搜索与 IP 203.0.113.45 相关的日志...
✅ 日志已保存到: ./sus.log

后话

之后可能会继续完善,希望大家的网站都安安全全不被攻击,每日IP破万!

点赞
  1. namegen说道:

    不错

  2. jsllxx说道:
    curl -fsSL https://raw.githubusercontent.com/jsllxx77/script/refs/heads/main/caddy.sh -o caddy.sh
    chmod +x caddy.sh
    ./caddy.sh
    

    整了个同款caddy的

发表回复

电子邮件地址不会被公开。必填项已用 * 标注

×
订阅图标按钮