Files
IP-Sentinel/core/mod_google.sh

271 lines
11 KiB
Bash
Executable File
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/bin/bash
# ==========================================================
# 脚本名称: mod_google.sh
# 核心功能: 区域网络模拟、行为轨迹拉伸、地理定位锚定
# ==========================================================
MODULE_NAME="Google"
CONFIG_FILE="/opt/ip_sentinel/config.conf"
# --- [环境预载] ---
if [ -f "$CONFIG_FILE" ]; then
source "$CONFIG_FILE"
else
echo "配置文件丢失!退出执行。"
exit 1
fi
# [容灾机制] 若宿主环境未注入日志函数,则启动 Fallback 接管
if ! type log >/dev/null 2>&1; then
log() {
# [版本锚定] 提取运行时动态版本标识
local local_ver="${AGENT_VERSION:-未知}"
mkdir -p "${INSTALL_DIR}/logs"
# [时区对齐] 强制采用绝对 UTC 时间消除跨域日志偏移
local core_msg=$(printf "[v%-5s] [%-5s] [%-7s] [%s] %s" "$local_ver" "$2" "$1" "$REGION_CODE" "$3")
echo "[$(date -u '+%Y-%m-%d %H:%M:%S UTC')] $core_msg" >> "${INSTALL_DIR}/logs/sentinel.log"
# [系统挂载] 桥接至 Systemd Journal 守护日志
if command -v logger >/dev/null 2>&1; then
logger -t ip-sentinel "$core_msg"
else
echo "$core_msg"
fi
}
fi
log "$MODULE_NAME" "START" "========== 唤醒网络模拟器 [区域: $REGION_NAME] =========="
# --- [数据装配] ---
UA_FILE="${INSTALL_DIR}/data/user_agents.txt"
KW_FILE="${INSTALL_DIR}/data/keywords/kw_${REGION_CODE}.txt"
if [ ! -f "$UA_FILE" ] || [ ! -f "$KW_FILE" ]; then
log "$MODULE_NAME" "ERROR" "热数据缺失,请检查 data 目录。放弃本次执行。"
exit 1
fi
mapfile -t UA_POOL < <(grep -v '^$' "$UA_FILE")
mapfile -t KEYWORDS < <(grep -v '^$' "$KW_FILE")
# --- [辅助运算] ---
get_random_coord() {
local base=$1
local range=$2
local offset=$(awk "BEGIN {print ( ( ($RANDOM % ($range * 2)) - $range ) / 10000 )}")
awk "BEGIN {print ($base + $offset)}"
}
# --- [身份画像构建] ---
# [防线提取] 优先捕获固化的公网面孔作为种子
CURRENT_IP="${PUBLIC_IP:-${BIND_IP:-Unknown}}"
# -----------------------------------------------------------
# [指纹固化] 哈希锚定法 (Hash-Seeded Persona)
# 基于 IP 算力固定会话指纹池,彻底破除僵尸网络同质化特征
# -----------------------------------------------------------
TOTAL_UA=${#UA_POOL[@]}
if [ "$TOTAL_UA" -gt 0 ]; then
SEED=$(echo -n "$CURRENT_IP" | cksum | awk '{print $1}')
IDX1=$(( SEED % TOTAL_UA ))
IDX2=$(( (SEED * 17) % TOTAL_UA ))
IDX3=$(( (SEED * 31) % TOTAL_UA ))
MY_UA_POOL=("${UA_POOL[$IDX1]}" "${UA_POOL[$IDX2]}" "${UA_POOL[$IDX3]}")
SESSION_UA=${MY_UA_POOL[$RANDOM % 3]}
else
# [极简兜底] 降维指纹防御崩溃
SESSION_UA="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36"
fi
# [LBS 锚定] 在基准战区内生成固定范围内的微抖动咖啡馆坐标
SESSION_BASE_LAT=$(get_random_coord $BASE_LAT 270)
SESSION_BASE_LON=$(get_random_coord $BASE_LON 270)
# [行为学控制] 随机指派本次会话的动作深度
TOTAL_ACTIONS=$((5 + RANDOM % 4))
log "$MODULE_NAME" "INFO " "当前出网 IP: $CURRENT_IP"
log "$MODULE_NAME" "INFO " "设备指纹锁定: ${SESSION_UA:0:45}..."
log "$MODULE_NAME" "INFO " "虚拟驻留坐标: $SESSION_BASE_LAT, $SESSION_BASE_LON"
# -----------------------------------------------------------
# [网络栈探底] 协议自适应与出站死锁
# -----------------------------------------------------------
CURL_BIND_OPT=""
DYNAMIC_IP_PREF="-${IP_PREF:-4}"
if [[ -n "$BIND_IP" && "$BIND_IP" =~ ^[0-9a-fA-F:\.]+$ ]]; then
# [防线校验] 探测物理网卡存活状态,防 IP 漂移引发通信雪崩
RAW_BIND_IP=$(echo "$BIND_IP" | tr -d '[]')
if ! ip addr show 2>/dev/null | grep -qw "$RAW_BIND_IP"; then
log "$MODULE_NAME" "WARN " "检测到配置的出口 IP ($RAW_BIND_IP) 已丢失,自动降级为系统默认路由出网!"
CURL_BIND_OPT=""
else
CURL_BIND_OPT="--interface $BIND_IP"
if [[ "$BIND_IP" == *":"* ]]; then
DYNAMIC_IP_PREF="-6"
log "$MODULE_NAME" "INFO " "底层路由锁定: 绑定 IPv6 出口及协议 ($BIND_IP)"
elif [[ "$BIND_IP" == *"."* ]]; then
DYNAMIC_IP_PREF="-4"
log "$MODULE_NAME" "INFO " "底层路由锁定: 绑定 IPv4 出口及协议 ($BIND_IP)"
fi
fi
fi
# --- [会话漫游模拟] ---
for ((i=1; i<=TOTAL_ACTIONS; i++)); do
# [LBS 微抖动] 模拟人类手持设备时的 GPS 细微漂移
ACTION_LAT=$(get_random_coord $SESSION_BASE_LAT 1)
ACTION_LON=$(get_random_coord $SESSION_BASE_LON 1)
RAND_KEY=${KEYWORDS[$RANDOM % ${#KEYWORDS[@]}]}
ENCODED_KEY=$(echo "$RAND_KEY" | jq -sRr @uri)
# [动作轮盘] 随机指派单次行为类型
ACTION_TYPE=$((1 + RANDOM % 4))
# [协议挂载] 注入双栈与网卡死锁参数
case $ACTION_TYPE in
1) # 搜索引擎交互
CODE=$(curl $CURL_BIND_OPT $DYNAMIC_IP_PREF -m 15 -s -L -o /dev/null -w "%{http_code}" -A "$SESSION_UA" \
"https://www.google.com/search?q=${ENCODED_KEY}&${LANG_PARAMS}")
;;
2) # 区域新闻阅读
CODE=$(curl $CURL_BIND_OPT $DYNAMIC_IP_PREF -m 15 -s -L -o /dev/null -w "%{http_code}" -A "$SESSION_UA" \
"https://news.google.com/home?${LANG_PARAMS}")
;;
3) # 坐标系 LBS 查询
CODE=$(curl $CURL_BIND_OPT $DYNAMIC_IP_PREF -m 15 -s -o /dev/null -w "%{http_code}" -A "$SESSION_UA" \
"https://www.google.com/maps/search/$${ENCODED_KEY}/@${ACTION_LAT},${ACTION_LON},17z?${LANG_PARAMS}")
;;
4) # 底层系统级网络探测连通性握手
CODE=$(curl $CURL_BIND_OPT $DYNAMIC_IP_PREF -m 10 -s -o /dev/null -w "%{http_code}" -A "$SESSION_UA" \
"https://connectivitycheck.gstatic.com/generate_204")
;;
esac
log "$MODULE_NAME" "EXEC " "动作[$i/$TOTAL_ACTIONS]完成 | HTTP状态: $CODE | 抖动坐标: $ACTION_LAT, $ACTION_LON"
# [行为拉伸] 动作间隔注入泊松长尾睡眠,模拟人类真实阅读思考时间
if [ $i -lt $TOTAL_ACTIONS ]; then
SLEEP_TIME=$((45 + RANDOM % 31))
log "$MODULE_NAME" "WAIT " "阅读当前页面内容,模拟停留 $SLEEP_TIME 秒..."
sleep $SLEEP_TIME
fi
done
# -----------------------------------------------------------
# [态势感知] 三核探测雷达 (跳转 / Premium / Music)
# -----------------------------------------------------------
log "$MODULE_NAME" "INFO " "启动三核交叉验证 (URL跳转 + YT Premium + YT Music) 穿透获取 GeoIP..."
# 探针 1: URL 区域重定向嗅探
JUMP_HDR=$(curl $CURL_BIND_OPT $DYNAMIC_IP_PREF -m 10 -sI "http://www.google.com/")
JUMP_LOC=$(echo "$JUMP_HDR" | grep -i "^location:" | tr -d '\r\n')
JUMP_GL=""
if [ -z "$JUMP_LOC" ]; then
JUMP_GL="US"
elif [[ "$JUMP_LOC" == *".google.cn"* ]] || [[ "$JUMP_LOC" == *"gl=CN"* ]]; then
JUMP_GL="CN"
elif [[ "$JUMP_LOC" == *"gl="* ]]; then
JUMP_GL=$(echo "$JUMP_LOC" | grep -o 'gl=[A-Za-z]\{2\}' | head -n 1 | cut -d'=' -f2 | tr 'a-z' 'A-Z')
else
JUMP_DOMAIN=$(echo "$JUMP_LOC" | grep -o 'google\.[a-z\.]*' | head -n 1 | sed 's/google\.//')
case "$JUMP_DOMAIN" in
"com") JUMP_GL="US" ;;
"com.hk") JUMP_GL="HK" ;;
"com.tw") JUMP_GL="TW" ;;
"co.jp") JUMP_GL="JP" ;;
"co.uk") JUMP_GL="GB" ;;
"co.kr") JUMP_GL="KR" ;;
"co.in") JUMP_GL="IN" ;;
"co.id") JUMP_GL="ID" ;;
"co.th") JUMP_GL="TH" ;;
"com.sg") JUMP_GL="SG" ;;
"com.my") JUMP_GL="MY" ;;
"com.au") JUMP_GL="AU" ;;
"com.br") JUMP_GL="BR" ;;
"com.mx") JUMP_GL="MX" ;;
"com.ar") JUMP_GL="AR" ;;
"co.za") JUMP_GL="ZA" ;;
"cn") JUMP_GL="CN" ;;
"") JUMP_GL="" ;;
*)
LAST_EXT=$(echo "$JUMP_DOMAIN" | awk -F'.' '{print $NF}' | tr 'a-z' 'A-Z')
if [ ${#LAST_EXT} -eq 2 ]; then
JUMP_GL="$LAST_EXT"
else
JUMP_GL="US"
fi
;;
esac
fi
# 探针 2: YouTube Premium 区域锁嗅探
YT_PR_GL=""
YT_PR_HTML=$(curl $CURL_BIND_OPT $DYNAMIC_IP_PREF -m 10 -s -L -A "$SESSION_UA" "https://www.youtube.com/premium")
if [[ "$YT_PR_HTML" == *"www.google.cn"* ]]; then
YT_PR_GL="CN"
else
YT_PR_GL=$(echo "$YT_PR_HTML" | grep -o '"contentRegion":"[A-Za-z]\{2\}"' | head -n 1 | cut -d'"' -f4 | tr 'a-z' 'A-Z')
[ -z "$YT_PR_GL" ] && YT_PR_GL=$(echo "$YT_PR_HTML" | grep -o '"countryCode":"[A-Za-z]\{2\}"' | head -n 1 | cut -d'"' -f4 | tr 'a-z' 'A-Z')
[ -z "$YT_PR_GL" ] && YT_PR_GL=$(echo "$YT_PR_HTML" | grep -o '"INNERTUBE_CONTEXT_GL":"[A-Za-z]\{2\}"' | head -n 1 | cut -d'"' -f4 | tr 'a-z' 'A-Z')
fi
# 探针 3: YouTube Music 区域锁嗅探
YT_MU_GL=""
YT_MU_HTML=$(curl $CURL_BIND_OPT $DYNAMIC_IP_PREF -m 10 -s -L -A "$SESSION_UA" "https://music.youtube.com/")
if [[ "$YT_MU_HTML" == *"www.google.cn"* ]]; then
YT_MU_GL="CN"
else
YT_MU_GL=$(echo "$YT_MU_HTML" | grep -o '"INNERTUBE_CONTEXT_GL":"[A-Za-z]\{2\}"' | head -n 1 | cut -d'"' -f4 | tr 'a-z' 'A-Z')
[ -z "$YT_MU_GL" ] && YT_MU_GL=$(echo "$YT_MU_HTML" | grep -o '"countryCode":"[A-Za-z]\{2\}"' | head -n 1 | cut -d'"' -f4 | tr 'a-z' 'A-Z')
[ -z "$YT_MU_GL" ] && YT_MU_GL=$(echo "$YT_MU_HTML" | grep -o '"GL":"[A-Za-z]\{2\}"' | head -n 1 | cut -d'"' -f4 | tr 'a-z' 'A-Z')
fi
# [坐标规整] 兼容横杠分割体系,并修正英区缩写
TARGET_CC="${REGION_CODE%%-*}"
[ "$TARGET_CC" == "UK" ] && TARGET_CC="GB"
# -----------------------------------------------------------
# [终极审判] 异常过滤与一致性裁决机制
# -----------------------------------------------------------
IS_CN=0
VALID_PROBES=0
for val in "$JUMP_GL" "$YT_PR_GL" "$YT_MU_GL"; do
if [ -n "$val" ]; then
((VALID_PROBES++))
[ "$val" == "CN" ] && IS_CN=1
fi
done
if [ $VALID_PROBES -eq 0 ]; then
STATUS="🚨 探针失效 (三核全部熔断,可能遭严重风控拦截)"
elif [ $IS_CN -eq 1 ]; then
STATUS="❌ 严重高危!三核雷达判定 IP 已被中国大陆锁定 (送中)"
else
# [权重仲裁] 以流媒体核心解锁状态为主导,允许基础网段跨国漂移
YT_MATCH=0
[ "$YT_PR_GL" == "$TARGET_CC" ] && YT_MATCH=1
[ "$YT_MU_GL" == "$TARGET_CC" ] && YT_MATCH=1
if [ $YT_MATCH -eq 1 ]; then
if [ -n "$JUMP_GL" ] && [ "$JUMP_GL" != "$TARGET_CC" ]; then
STATUS="✅ 目标区域达成 (YT主导成功, Jump副雷达漂移至 ${JUMP_GL}) | Prem: ${YT_PR_GL:-} | Music: ${YT_MU_GL:-}"
else
STATUS="✅ 目标区域达成 (Jump: ${JUMP_GL:-} | Prem: ${YT_PR_GL:-} | Music: ${YT_MU_GL:-})"
fi
else
STATUS="⚠️ 区域发生漂移!目标 $TARGET_CC,实际 (Jump: ${JUMP_GL:-} | Prem: ${YT_PR_GL:-} | Music: ${YT_MU_GL:-})"
fi
fi
log "$MODULE_NAME" "SCORE" "自检结论: $STATUS"
log "$MODULE_NAME" "END " "========== 会话结束,释放进程 =========="