#!/bin/bash # ========================================================== # 脚本名称: tg_report.sh # 核心功能: 收集并聚合终端特征、提取执行快照、侦测云端版本并生成简报 # ========================================================== INSTALL_DIR="/opt/ip_sentinel" CONFIG_FILE="${INSTALL_DIR}/config.conf" LOG_FILE="${INSTALL_DIR}/logs/sentinel.log" # --- [基础自检] --- if [ ! -f "$CONFIG_FILE" ]; then exit 1; fi source "$CONFIG_FILE" if [ -z "$TG_TOKEN" ] || [ -z "$CHAT_ID" ]; then echo "⚠️ 未配置 Telegram 机器人参数,取消播报。" exit 0 fi # ========================================================== # [防线 1] 并发风暴熔断机制 (60s 冷却池) # ========================================================== LOCK_FILE="${INSTALL_DIR}/core/.report_lock" if [ -f "$LOCK_FILE" ]; then LAST_RUN=$(cat "$LOCK_FILE" 2>/dev/null) NOW=$(date +%s) # 严格校验最后执行时间的合法性,防御密集回调 if [[ "$LAST_RUN" =~ ^[0-9]+$ ]]; then if [ $((NOW - LAST_RUN)) -lt 60 ]; then echo "[$(date -u '+%Y-%m-%d %H:%M:%S UTC')] [v${AGENT_VERSION:-未知}] [WARN ] [Report ] [SYSTEM] ⚠️ 战报请求过于频繁,触发 60 秒防并发风暴拦截。" >> "${INSTALL_DIR}/logs/sentinel.log" exit 0 fi fi fi echo $(date +%s) > "$LOCK_FILE" # ========================================================== # 1. 节点元数据与双轨身份解析 # ========================================================== if [ -z "$NODE_NAME" ]; then IP_HASH=$(echo "${PUBLIC_IP:-127.0.0.1}" | md5sum | cut -c 1-4 | tr 'a-z' 'A-Z') NODE_NAME="$(hostname | cut -c 1-10)-${IP_HASH}" fi NODE_ALIAS="${NODE_ALIAS:-$NODE_NAME}" # ---------------------------------------------------------- # [容灾探针 1] 底层路由锁定与多节点出口 IP 嗅探 # ---------------------------------------------------------- CURL_BIND_OPT="" DYNAMIC_IP_PREF="-${IP_PREF:-4}" if [[ -n "$BIND_IP" && "$BIND_IP" =~ ^[0-9a-fA-F:\.]+$ ]]; then RAW_BIND_IP=$(echo "$BIND_IP" | tr -d '[]') if ! ip addr show 2>/dev/null | grep -qw "$RAW_BIND_IP"; then CURL_BIND_OPT="" else CURL_BIND_OPT="--interface $BIND_IP" if [[ "$BIND_IP" == *":"* ]]; then DYNAMIC_IP_PREF="-6" elif [[ "$BIND_IP" == *"."* ]]; then DYNAMIC_IP_PREF="-4" fi fi fi # 结合协议自适应进行外部 IP 回显探测 CURRENT_IP=$( (curl $CURL_BIND_OPT $DYNAMIC_IP_PREF -s -m 5 api.ip.sb/ip || curl $CURL_BIND_OPT $DYNAMIC_IP_PREF -s -m 5 ifconfig.me) 2>/dev/null | tr -d '[:space:]' ) # 强制兜底逻辑:网络完全阻断时回退使用配置文件锚点 [ -z "$CURRENT_IP" ] && CURRENT_IP="${PUBLIC_IP:-$BIND_IP}" # 为 IPv6 环境追加方括号安全护甲 [[ "$CURRENT_IP" == *":"* ]] && [[ "$CURRENT_IP" != *"["* ]] && CURRENT_IP="[${CURRENT_IP}]" # ---------------------------------------------------------- # [容灾探针 2] 多级 ISP 情报探测链路 # ---------------------------------------------------------- ISP_INFO="" # 优先级 A: 高吞吐极速纯文本接口 ISP_INFO=$(curl $CURL_BIND_OPT $DYNAMIC_IP_PREF -s -m 5 ipinfo.io/org 2>/dev/null) # 优先级 B: 备用纯文本接口 if [ -z "$ISP_INFO" ] || [[ "$ISP_INFO" == *"error"* ]]; then ISP_INFO=$(curl $CURL_BIND_OPT $DYNAMIC_IP_PREF -s -m 5 ip-api.com/line/?fields=isp 2>/dev/null) fi # 优先级 C: 需构建环境依赖的 JSON 接口 if [ -z "$ISP_INFO" ] || [[ "$ISP_INFO" == *"error"* ]]; then if command -v jq &> /dev/null; then ISP_INFO=$(curl $CURL_BIND_OPT $DYNAMIC_IP_PREF -s -m 5 api.ip.sb/geoip | jq -r '.organization' 2>/dev/null) fi fi # 数据清洗过滤与类型渲染 ISP_INFO=$(echo "$ISP_INFO" | sed -E 's/^AS[0-9]+ //') [ -z "$ISP_INFO" ] || [ "$ISP_INFO" == "null" ] && ISP_INFO="未知 ISP" if [[ "$ISP_INFO" == *"Cloudflare"* ]]; then IP_TYPE="Cloudflare Warp 🛰️" else IP_TYPE="$ISP_INFO 🏠" fi # [全视界旗帜引擎] 动态国旗渲染装配 BASE_CC="${REGION_CODE%%-*}" case "$BASE_CC" in US) FLAG="🇺🇸" ;; JP) FLAG="🇯🇵" ;; HK) FLAG="🇭🇰" ;; TW) FLAG="🇹🇼" ;; SG) FLAG="🇸🇬" ;; UK|GB) FLAG="🇬🇧" ;; DE) FLAG="🇩🇪" ;; FR) FLAG="🇫🇷" ;; NL) FLAG="🇳🇱" ;; CA) FLAG="🇨🇦" ;; AU) FLAG="🇦🇺" ;; KR) FLAG="🇰🇷" ;; IN) FLAG="🇮🇳" ;; BR) FLAG="🇧🇷" ;; RU) FLAG="🇷🇺" ;; CH) FLAG="🇨🇭" ;; SE) FLAG="🇸🇪" ;; NO) FLAG="🇳🇴" ;; DK) FLAG="🇩🇰" ;; FI) FLAG="🇫🇮" ;; IT) FLAG="🇮🇹" ;; ES) FLAG="🇪🇸" ;; PT) FLAG="🇵🇹" ;; IE) FLAG="🇮🇪" ;; PL) FLAG="🇵🇱" ;; AT) FLAG="🇦🇹" ;; BE) FLAG="🇧🇪" ;; TR) FLAG="🇹🇷" ;; ZA) FLAG="🇿🇦" ;; AE) FLAG="🇦🇪" ;; MY) FLAG="🇲🇾" ;; ID) FLAG="🇮🇩" ;; VN) FLAG="🇻🇳" ;; TH) FLAG="🇹🇭" ;; PH) FLAG="🇵🇭" ;; NZ) FLAG="🇳🇿" ;; AR) FLAG="🇦🇷" ;; CL) FLAG="🇨🇱" ;; MX) FLAG="🇲🇽" ;; IL) FLAG="🇮🇱" ;; SA) FLAG="🇸🇦" ;; EG) FLAG="🇪🇬" ;; NG) FLAG="🇳🇬" ;; KE) FLAG="🇰🇪" ;; RO) FLAG="🇷🇴" ;; BG) FLAG="🇧🇬" ;; CZ) FLAG="🇨🇿" ;; HU) FLAG="🇭🇺" ;; GR) FLAG="🇬🇷" ;; UA) FLAG="🇺🇦" ;; MO) FLAG="🇲🇴" ;; KH) FLAG="🇰🇭" ;; MM) FLAG="🇲🇲" ;; LA) FLAG="🇱🇦" ;; MN) FLAG="🇲🇳" ;; NP) FLAG="🇳🇵" ;; BD) FLAG="🇧🇩" ;; *) FLAG="🌐" ;; esac # ========================================================== # 2. 行为日志萃取与快照分析 # ========================================================== LOG_CONTENT=$(tail -n 1000 "$LOG_FILE" 2>/dev/null) if [ -z "$LOG_CONTENT" ]; then read -r -d '' MSG <> "${INSTALL_DIR}/logs/error.log" else echo "✅ 战报推送成功!" fi