feat(dual-link-proxy): 新增双链路代理搭建与运维技能(已脱敏)
把「在已跑 nginx 的 VPS 上从零搭起橙云 + 灰云双链路、并用 3x-ui 管多用户」 的全过程沉淀成技能:五阶段工作流、五条硬性前提、三条易踩反的判据、19 条避坑。 - references/01 前置取证与选型:泛解析不等通、端口取证、nginx 约束下的选型 - references/02 服务端落地:3x-ui 与 sing-box 两条路线,含包名与 2096 冲突 - references/03 nginx 与证书:80 → 签证书 → 443 的顺序、AEAD 套件、口令文件位置 - references/04 面板与多用户:3x-ui 三层模型、加人步骤、CSRF 登录法 - references/05 避坑清单:19 条,正向写做法、括号里附踩过的坑 - scripts/verify-links.sh 与 scripts/3xui-api.py:两个脚本均对真实环境跑通 正文已脱敏,域名/端口/口令/UUID/主机 全部改为占位符。
This commit is contained in:
1 parent
310a964a94
commit
a9d2adaf72
9 files changed
+759
No files matched your search
@@ -0,0 +1,87 @@
|
||||
#!/usr/bin/env bash
|
||||
# 双链路代理验收:链路 101、站点 200、面板 200(带浏览器 UA)
|
||||
#
|
||||
# 用法:
|
||||
# ./verify-links.sh \
|
||||
# --link <域名A>:/<路径> \
|
||||
# --link <域名B>:/<路径> \
|
||||
# --site <站点域名> \
|
||||
# --panel https://<面板域名>/ --panel-auth user:secret
|
||||
#
|
||||
# 退出码:全部通过为 0,任一失败为 1
|
||||
|
||||
set -u
|
||||
UA="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36"
|
||||
WS_KEY="dGhlIHNhbXBsZSBub25jZQ=="
|
||||
FAIL=0
|
||||
|
||||
check_link() {
|
||||
local spec="$1"
|
||||
local host="${spec%%:*}"
|
||||
local path="${spec#*:}"
|
||||
local out
|
||||
out=$(curl -s -i --http1.1 \
|
||||
-H "Upgrade: websocket" -H "Connection: Upgrade" \
|
||||
-H "Sec-WebSocket-Version: 13" -H "Sec-WebSocket-Key: $WS_KEY" \
|
||||
--max-time 20 "https://${host}${path}" 2>/dev/null | grep -oE "HTTP/1.1 (101|4[0-9][0-9]|5[0-9][0-9])" | head -1)
|
||||
if echo "$out" | grep -q "101"; then
|
||||
echo " PASS link ${host}${path} ${out}"
|
||||
else
|
||||
echo " FAIL link ${host}${path} 期望 101,实际 ${out:-无响应}"
|
||||
FAIL=1
|
||||
fi
|
||||
}
|
||||
|
||||
check_site() {
|
||||
local host="$1"
|
||||
local code
|
||||
code=$(curl -s -o /dev/null -w "%{http_code}" --max-time 20 "https://${host}/" 2>/dev/null)
|
||||
if [ "$code" = "200" ]; then
|
||||
echo " PASS site ${host} ${code}"
|
||||
else
|
||||
echo " FAIL site ${host} 期望 200,实际 ${code:-无响应}"
|
||||
FAIL=1
|
||||
fi
|
||||
}
|
||||
|
||||
check_panel() {
|
||||
local url="$1"
|
||||
local auth="$2"
|
||||
local code
|
||||
if [ -n "$auth" ]; then
|
||||
code=$(curl -s -L -o /dev/null -w "%{http_code}" -u "$auth" -A "$UA" --max-time 25 "$url" 2>/dev/null)
|
||||
else
|
||||
code=$(curl -s -L -o /dev/null -w "%{http_code}" -A "$UA" --max-time 25 "$url" 2>/dev/null)
|
||||
fi
|
||||
if [ "$code" = "200" ]; then
|
||||
echo " PASS panel ${url} ${code}"
|
||||
else
|
||||
echo " FAIL panel ${url} 期望 200,实际 ${code:-无响应}"
|
||||
echo " 提示:aaPanel 及同类面板对非浏览器 UA 返回 404,本脚本已带浏览器 UA"
|
||||
FAIL=1
|
||||
fi
|
||||
}
|
||||
|
||||
while [ $# -gt 0 ]; do
|
||||
case "$1" in
|
||||
--link) check_link "$2"; shift 2 ;;
|
||||
--site) check_site "$2"; shift 2 ;;
|
||||
--panel) PANEL_URL="$2"; shift 2 ;;
|
||||
--panel-auth) PANEL_AUTH="$2"; shift 2 ;;
|
||||
-h|--help)
|
||||
sed -n '2,12p' "$0"; exit 0 ;;
|
||||
*) echo "未知参数:$1"; exit 2 ;;
|
||||
esac
|
||||
done
|
||||
|
||||
if [ -n "${PANEL_URL:-}" ]; then
|
||||
check_panel "$PANEL_URL" "${PANEL_AUTH:-}"
|
||||
fi
|
||||
|
||||
echo
|
||||
if [ "$FAIL" -eq 0 ]; then
|
||||
echo "全部通过"
|
||||
else
|
||||
echo "存在失败项,按上面的 FAIL 行定位"
|
||||
fi
|
||||
exit "$FAIL"
|
||||
Reference in new issue
Block a user