#!/bin/bash # 最终验收:官网 / 管理页 / 下载 / 加速 / 功能 set -u BASE=http://127.0.0.1:8080 PUB=https://relay.xxmxxs.top KEY=$(cat /root/lanremote-relay/data/admin_key.txt 2>/dev/null) pass=0; fail=0 ok() { pass=$((pass+1)); echo " ✓ $1"; } bad() { fail=$((fail+1)); echo " ✗ $1"; } code() { curl -s -o /dev/null -w '%{http_code}' --max-time 25 "$@"; } echo "════════ 一、官网 ════════" c=$(code "$BASE/") [ "$c" = "200" ] && ok "首页 HTTP 200" || bad "首页 HTTP $c" curl -s --max-time 20 "$BASE/" -o /tmp/s.html size=$(wc -c < /tmp/s.html) [ "$size" -gt 10000 ] && ok "页面 $size 字节(内容丰富)" || bad "页面只有 $size 字节" for pair in "吸顶导航:nav-in" "Hero:hero" "功能网格:id=\"features\"" \ "三步上手:id=\"how\"" "下载区:id=\"download\"" \ "FAQ:id=\"faq\"" "页脚:foot-in"; do label="${pair%%:*}"; key="${pair#*:}" if grep -q "$key" /tmp/s.html; then ok "$label"; else bad "$label"; fi done [ "$(grep -c 'class=\"feat\"' /tmp/s.html)" = "9" ] && ok "9 张功能卡" || bad "功能卡数量不对" [ "$(grep -c '
/dev/null || echo 0) [ "$n" != "0" ] && dark=$((dark+n)) done [ "$dark" = "0" ] && ok "无深色残留" || bad "深色残留 $dark 处" [ "$(code "$BASE/admin")" = "302" ] && ok "/admin 跳转正常" || bad "/admin 跳转异常" echo echo "════════ 三、下载 ════════" for f in ykxmz-setup-1.7.1.exe ykxmz-server-1.7.1.zip ykxmz-watch-1.7.1.apk; do c=$(code "$BASE/download/$f") [ "$c" = "200" ] && ok "$f" || bad "$f HTTP $c" done [ "$(code "$BASE/v1/downloads")" = "200" ] && ok "/v1/downloads" || bad "/v1/downloads" c=$(code "$BASE/download/../relay.py") [ "$c" = "404" ] || [ "$c" = "400" ] && ok "路径穿越被挡($c)" || bad "路径穿越 HTTP $c" echo echo "════════ 四、加速 ════════" proto=$(grep -oE 'Initial protocol [a-z0-9]+' /root/lanremote-relay/tunnel.log 2>/dev/null | tail -1) echo "$proto" | grep -q http2 && ok "隧道走 HTTP/2(不是 QUIC)" || bad "隧道协议: $proto" conn=$(curl -s --max-time 5 http://127.0.0.1:20241/metrics 2>/dev/null | grep '^cloudflared_tunnel_ha_connections' | awk '{print $2}') [ "$conn" = "2" ] && ok "隧道连接数 $conn" || bad "隧道连接数 $conn" [ "$(sysctl -n net.ipv4.tcp_mtu_probing)" = "1" ] && ok "MTU 探测开着" || bad "MTU 探测关了" [ "$(sysctl -n net.ipv4.tcp_slow_start_after_idle)" = "0" ] && ok "空闲后不重置窗口" || bad "slow_start 没关" [ "$(sysctl -n net.ipv4.tcp_fastopen)" = "3" ] && ok "TCP FastOpen 开着" || bad "FastOpen 没开" [ "$(grep -c argotunnel /etc/hosts)" = "0" ] && ok "无效的 hosts 覆盖已清" || bad "hosts 还有残留" echo echo "════════ 五、功能 ════════" for api in /v1/health /favicon.ico; do c=$(code "$BASE$api") [ "$c" = "200" ] && ok "$api" || bad "$api HTTP $c" done v=$(curl -s --max-time 10 "$BASE/v1/health" | grep -o '"version": *"[^"]*"') echo " $v" echo echo "════════ 六、公网(20 次测延迟)════════" okc=0; total=0 for i in $(seq 1 20); do r=$(curl -s -o /dev/null -w '%{http_code} %{time_total}' --max-time 25 \ -H 'User-Agent: LanRemote/1.4.0' "$PUB/" 2>/dev/null) c=$(echo "$r" | cut -d' ' -f1) t=$(echo "$r" | cut -d' ' -f2) if [ "$c" = "200" ]; then okc=$((okc+1)) total=$(echo "$total + $t" | bc) fi sleep 0.5 done avg=$(echo "scale=2; $total / $okc" | bc 2>/dev/null || echo "?") [ "$okc" -ge 18 ] && ok "可用 $okc/20" || bad "可用 $okc/20" echo " 平均 ${avg} 秒" echo echo "════════════════════════════════" echo " 通过 $pass 项,失败 $fail 项" [ "$fail" = "0" ] && echo " 全部通过 ✓" || echo " 有失败"