refactor: remove VLESS/Xray, Hy2-only stack
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env bash
|
||||
# 生成 Reality 密钥;若 .env 无面板密码则一并生成
|
||||
# 生成面板密码与 Clash API 密钥(如 .env 中尚未配置)
|
||||
set -euo pipefail
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
@@ -22,17 +22,6 @@ else
|
||||
SB="sing-box"
|
||||
fi
|
||||
|
||||
if command -v xray &>/dev/null; then
|
||||
KEYPAIR="$(xray x25519)"
|
||||
REALITY_PRIVATE_KEY="$(echo "$KEYPAIR" | awk '/Private key/ {print $3; exit} /PrivateKey/ {print $3; exit}')"
|
||||
REALITY_PUBLIC_KEY="$(echo "$KEYPAIR" | awk '/Public key/ {print $3; exit} /Password/ {print $3; exit}')"
|
||||
else
|
||||
KEYPAIR="$("$SB" generate reality-keypair)"
|
||||
REALITY_PRIVATE_KEY="$(echo "$KEYPAIR" | grep 'PrivateKey:' | awk '{print $2}')"
|
||||
REALITY_PUBLIC_KEY="$(echo "$KEYPAIR" | grep 'PublicKey:' | awk '{print $2}')"
|
||||
fi
|
||||
REALITY_SHORT_ID="$("$SB" generate rand --hex 8)"
|
||||
|
||||
GENERATE_PANEL_PASSWORD=1
|
||||
if [[ -f "$ENV_FILE" ]] && grep -q "^PANEL_PASSWORD=.\+" "$ENV_FILE" 2>/dev/null; then
|
||||
GENERATE_PANEL_PASSWORD=0
|
||||
@@ -43,9 +32,6 @@ if (( GENERATE_PANEL_PASSWORD )); then
|
||||
fi
|
||||
|
||||
echo "========== 生成的密钥 =========="
|
||||
echo "REALITY_PRIVATE_KEY: $REALITY_PRIVATE_KEY"
|
||||
echo "REALITY_PUBLIC_KEY: $REALITY_PUBLIC_KEY"
|
||||
echo "REALITY_SHORT_ID: $REALITY_SHORT_ID"
|
||||
if (( GENERATE_PANEL_PASSWORD )); then
|
||||
echo "PANEL_PASSWORD: $PANEL_PASSWORD"
|
||||
else
|
||||
@@ -54,14 +40,6 @@ fi
|
||||
echo "================================"
|
||||
|
||||
if [[ -f "$ENV_FILE" ]]; then
|
||||
for var in REALITY_PRIVATE_KEY REALITY_PUBLIC_KEY REALITY_SHORT_ID; do
|
||||
val="${!var}"
|
||||
if grep -q "^${var}=" "$ENV_FILE" 2>/dev/null; then
|
||||
sed -i "s|^${var}=.*|${var}=${val}|" "$ENV_FILE"
|
||||
else
|
||||
echo "${var}=${val}" >> "$ENV_FILE"
|
||||
fi
|
||||
done
|
||||
if (( GENERATE_PANEL_PASSWORD )); then
|
||||
if grep -q "^PANEL_PASSWORD=" "$ENV_FILE" 2>/dev/null; then
|
||||
sed -i "s|^PANEL_PASSWORD=.*|PANEL_PASSWORD=${PANEL_PASSWORD}|" "$ENV_FILE"
|
||||
@@ -73,11 +51,6 @@ if [[ -f "$ENV_FILE" ]]; then
|
||||
echo "PANEL_USERNAME=dekun" >> "$ENV_FILE"
|
||||
fi
|
||||
echo "已写入 $ENV_FILE"
|
||||
echo ""
|
||||
echo "重要: 密钥已变更,必须重新生成配置并重启:"
|
||||
echo " python3 ${ROOT_DIR}/scripts/render-xray.py"
|
||||
echo " python3 ${ROOT_DIR}/scripts/render-server.py"
|
||||
echo " systemctl restart xray sing-box"
|
||||
else
|
||||
echo "提示: 先复制 .env.example 为 .env 并填写 VPS_IP、DOMAIN 等,再重新运行本脚本" >&2
|
||||
echo "提示: 先复制 .env.example 为 .env 并填写 VPS_IP、DOMAIN 等" >&2
|
||||
fi
|
||||
|
||||
+3
-21
@@ -37,15 +37,8 @@ source "$ENV_FILE"
|
||||
: "${VPS_IP:?请在 .env 中设置 VPS_IP}"
|
||||
: "${DOMAIN:?请在 .env 中设置 DOMAIN}"
|
||||
: "${ACME_EMAIL:?请在 .env 中设置 ACME_EMAIL}"
|
||||
: "${REALITY_SERVER_NAME:=www.microsoft.com}"
|
||||
: "${PANEL_USERNAME:=admin}"
|
||||
|
||||
if [[ -z "${REALITY_PRIVATE_KEY:-}" ]]; then
|
||||
log "未检测到 Reality 密钥,运行 generate-keys.sh ..."
|
||||
bash "$SCRIPT_DIR/generate-keys.sh"
|
||||
source "$ENV_FILE"
|
||||
fi
|
||||
|
||||
if [[ -z "${PANEL_PASSWORD:-}" ]]; then
|
||||
PANEL_PASSWORD="$(sing-box generate rand --base64 32 | tr -d '/+=' | head -c 20)"
|
||||
if grep -q "^PANEL_PASSWORD=" "$ENV_FILE" 2>/dev/null; then
|
||||
@@ -56,9 +49,6 @@ if [[ -z "${PANEL_PASSWORD:-}" ]]; then
|
||||
source "$ENV_FILE"
|
||||
fi
|
||||
|
||||
: "${REALITY_PRIVATE_KEY:?}"
|
||||
: "${REALITY_PUBLIC_KEY:?}"
|
||||
: "${REALITY_SHORT_ID:?}"
|
||||
: "${PANEL_PASSWORD:?}"
|
||||
|
||||
if [[ -z "${CLASH_API_SECRET:-}" ]]; then
|
||||
@@ -126,7 +116,6 @@ ufw default deny incoming
|
||||
ufw default allow outgoing
|
||||
ufw allow 22/tcp comment 'SSH'
|
||||
ufw allow 80/tcp comment 'HTTP-ACME-Panel'
|
||||
ufw allow 443/tcp comment 'Reality'
|
||||
ufw allow 8443:8499/udp comment 'Hysteria2-multi-node'
|
||||
ufw --force enable
|
||||
|
||||
@@ -187,12 +176,6 @@ log "初始化节点数据库 ..."
|
||||
log "生成 sing-box 服务端配置 (Hysteria2) ..."
|
||||
python3 "$ROOT_DIR/scripts/render-server.py"
|
||||
|
||||
log "安装 Xray (VLESS Reality 443) ..."
|
||||
bash -c "$(curl -fsSL https://github.com/XTLS/Xray-install/raw/main/install-release.sh)" @ install
|
||||
|
||||
log "生成 Xray 服务端配置 ..."
|
||||
python3 "$ROOT_DIR/scripts/render-xray.py"
|
||||
|
||||
log "创建 sing-box systemd 服务 ..."
|
||||
cat > /etc/systemd/system/sing-box.service <<'UNIT'
|
||||
[Unit]
|
||||
@@ -215,7 +198,7 @@ log "创建管理面板 systemd 服务 ..."
|
||||
cat > /etc/systemd/system/jiedian-panel.service <<UNIT
|
||||
[Unit]
|
||||
Description=jiedian admin panel
|
||||
After=network.target xray.service sing-box.service
|
||||
After=network.target sing-box.service
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
@@ -232,7 +215,7 @@ WantedBy=multi-user.target
|
||||
UNIT
|
||||
|
||||
systemctl daemon-reload
|
||||
systemctl enable xray sing-box jiedian-panel
|
||||
systemctl enable sing-box jiedian-panel
|
||||
|
||||
log "注册证书续期 reload 命令 ..."
|
||||
/root/.acme.sh/acme.sh --install-cert -d "$DOMAIN" \
|
||||
@@ -241,7 +224,7 @@ log "注册证书续期 reload 命令 ..."
|
||||
--reloadcmd "systemctl restart sing-box && systemctl reload nginx" \
|
||||
|| log "acme reloadcmd 注册失败,可忽略"
|
||||
|
||||
systemctl restart xray sing-box jiedian-panel
|
||||
systemctl restart sing-box jiedian-panel
|
||||
|
||||
log "部署完成!"
|
||||
echo ""
|
||||
@@ -255,6 +238,5 @@ echo ""
|
||||
echo "节点链接请在面板中添加/复制。"
|
||||
echo ""
|
||||
log "sing-box: systemctl status sing-box"
|
||||
log "Xray: systemctl status xray"
|
||||
log "面板: systemctl status jiedian-panel"
|
||||
log "卸载重装: bash scripts/uninstall.sh && bash scripts/install.sh"
|
||||
|
||||
@@ -1,30 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
# 已有 VPS:将 VLESS Reality 从 sing-box 迁移到 Xray(443)
|
||||
set -euo pipefail
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
ROOT_DIR="$(dirname "$SCRIPT_DIR")"
|
||||
|
||||
[[ $EUID -eq 0 ]] || { echo "请使用 root 运行"; exit 1; }
|
||||
|
||||
if ! command -v xray &>/dev/null; then
|
||||
echo "[+] 安装 Xray ..."
|
||||
bash -c "$(curl -fsSL https://github.com/XTLS/Xray-install/raw/main/install-release.sh)" @ install
|
||||
fi
|
||||
|
||||
export JIEDIAN_ROOT="$ROOT_DIR"
|
||||
|
||||
echo "[+] 更新 sing-box 配置(仅 Hysteria2)..."
|
||||
python3 "$ROOT_DIR/scripts/render-server.py"
|
||||
|
||||
echo "[+] 生成 Xray 配置(VLESS Reality 443)..."
|
||||
python3 "$ROOT_DIR/scripts/render-xray.py"
|
||||
|
||||
systemctl enable xray 2>/dev/null || true
|
||||
systemctl restart xray sing-box jiedian-panel
|
||||
|
||||
echo ""
|
||||
echo "[+] 迁移完成。请运行诊断:"
|
||||
bash "$ROOT_DIR/scripts/verify-reality.sh"
|
||||
echo ""
|
||||
echo "客户端无需改参数,直接测速 VLESS 节点即可。"
|
||||
@@ -0,0 +1,29 @@
|
||||
#!/usr/bin/env bash
|
||||
# 已有 VPS:停用 Xray/VLESS,仅保留 Hysteria2
|
||||
set -euo pipefail
|
||||
|
||||
ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
||||
|
||||
[[ $EUID -eq 0 ]] || { echo "请使用 root 运行: sudo bash scripts/remove-vless.sh"; exit 1; }
|
||||
|
||||
export JIEDIAN_ROOT="$ROOT"
|
||||
|
||||
echo "[1/4] 停止并禁用 Xray ..."
|
||||
systemctl stop xray 2>/dev/null || true
|
||||
systemctl disable xray 2>/dev/null || true
|
||||
|
||||
echo "[2/4] 更新代码并重载 sing-box 配置 ..."
|
||||
if [[ -d "$ROOT/.git" ]]; then
|
||||
git -C "$ROOT" pull --ff-only || echo "(git pull 跳过,请手动同步)"
|
||||
fi
|
||||
python3 "$ROOT/scripts/render-server.py"
|
||||
|
||||
echo "[3/4] 重启服务 ..."
|
||||
systemctl restart sing-box jiedian-panel
|
||||
|
||||
echo "[4/4] 可选:关闭防火墙 443(若不再需要) ..."
|
||||
ufw delete allow 443/tcp 2>/dev/null || true
|
||||
|
||||
echo ""
|
||||
echo "完成。VLESS 已停用,面板仅显示 Hysteria2 链接。"
|
||||
echo "客户端请删除旧 VLESS 节点,从面板复制 hy2:// 链接导入。"
|
||||
@@ -11,37 +11,21 @@ OUT_DIR="${ROOT_DIR}/client/generated"
|
||||
# shellcheck disable=SC1090
|
||||
source "$ENV_FILE"
|
||||
|
||||
for var in VPS_IP DOMAIN UUID REALITY_SERVER_NAME REALITY_PUBLIC_KEY REALITY_SHORT_ID HY2_PASSWORD; do
|
||||
for var in DOMAIN HY2_PASSWORD; do
|
||||
[[ -n "${!var:-}" ]] || { echo "缺少 .env 变量: $var"; exit 1; }
|
||||
done
|
||||
|
||||
mkdir -p "$OUT_DIR"
|
||||
|
||||
urlencode_sni() {
|
||||
python3 -c "import sys; print(sys.argv[1])" "$1"
|
||||
}
|
||||
|
||||
REALITY_SNI_ENC="$(urlencode_sni "$REALITY_SERVER_NAME")"
|
||||
REALITY_PBK_ENC="$REALITY_PUBLIC_KEY"
|
||||
REALITY_SID_ENC="$REALITY_SHORT_ID"
|
||||
HY2_PASSWORD_ENC="$(python3 -c "import sys, urllib.parse; print(urllib.parse.quote(sys.argv[1], safe=''))" "$HY2_PASSWORD")"
|
||||
DOMAIN_SNI_ENC="$(urlencode_sni "$DOMAIN")"
|
||||
|
||||
sed -e "s|\${VPS_IP}|${VPS_IP}|g" \
|
||||
-e "s|\${DOMAIN}|${DOMAIN}|g" \
|
||||
-e "s|\${UUID}|${UUID}|g" \
|
||||
-e "s|\${REALITY_SERVER_NAME}|${REALITY_SERVER_NAME}|g" \
|
||||
-e "s|\${REALITY_PUBLIC_KEY}|${REALITY_PUBLIC_KEY}|g" \
|
||||
-e "s|\${REALITY_SHORT_ID}|${REALITY_SHORT_ID}|g" \
|
||||
sed -e "s|\${DOMAIN}|${DOMAIN}|g" \
|
||||
-e "s|\${HY2_PASSWORD}|${HY2_PASSWORD}|g" \
|
||||
"$ROOT_DIR/client/sing-box-client.json.template" > "$OUT_DIR/sing-box-client.json"
|
||||
|
||||
cat > "$OUT_DIR/share-links.txt" <<EOF
|
||||
========== VLESS + Reality (主力) ==========
|
||||
vless://${UUID}@${VPS_IP}:443?type=tcp&security=reality&encryption=none&flow=xtls-rprx-vision&sni=${REALITY_SNI_ENC}&fp=chrome&pbk=${REALITY_PBK_ENC}&sid=${REALITY_SID_ENC}&spx=%2F#Reality-Main
|
||||
|
||||
========== Hysteria2 (备用) ==========
|
||||
hy2://${HY2_PASSWORD_ENC}@${DOMAIN}:8443?sni=${DOMAIN_SNI_ENC}#Hysteria2-Backup
|
||||
========== Hysteria2 ==========
|
||||
hy2://${HY2_PASSWORD_ENC}@${DOMAIN}:8443?sni=${DOMAIN}#Hysteria2
|
||||
EOF
|
||||
|
||||
echo "已生成:"
|
||||
|
||||
@@ -43,14 +43,8 @@ def load_nodes(db_path: Path) -> list[dict]:
|
||||
|
||||
|
||||
def build_config(env: dict[str, str], nodes: list[dict]) -> dict:
|
||||
required = [
|
||||
"REALITY_SHORT_ID",
|
||||
"REALITY_SERVER_NAME",
|
||||
"DOMAIN",
|
||||
]
|
||||
for key in required:
|
||||
if not env.get(key):
|
||||
raise SystemExit(f".env 缺少 {key}")
|
||||
if not env.get("DOMAIN"):
|
||||
raise SystemExit(".env 缺少 DOMAIN")
|
||||
|
||||
hy2_base_port = 8443
|
||||
|
||||
|
||||
@@ -1,133 +0,0 @@
|
||||
#!/usr/bin/env python3
|
||||
"""根据 data/nodes.db 与 .env 生成 Xray VLESS+Reality 配置(443 端口)。"""
|
||||
from __future__ import annotations
|
||||
|
||||
import json
|
||||
import os
|
||||
import sqlite3
|
||||
import subprocess
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
ROOT = Path(os.environ.get("JIEDIAN_ROOT", Path(__file__).resolve().parents[1]))
|
||||
ENV_FILE = ROOT / ".env"
|
||||
DB_FILE = ROOT / "data" / "nodes.db"
|
||||
OUT_FILE = Path("/usr/local/etc/xray/config.json")
|
||||
ACCESS_LOG = Path("/var/log/xray/access.log")
|
||||
|
||||
|
||||
def load_env(path: Path) -> dict[str, str]:
|
||||
env: dict[str, str] = {}
|
||||
if not path.exists():
|
||||
raise SystemExit(f"缺少 .env: {path}")
|
||||
for line in path.read_text(encoding="utf-8").splitlines():
|
||||
line = line.strip()
|
||||
if not line or line.startswith("#") or "=" not in line:
|
||||
continue
|
||||
key, _, value = line.partition("=")
|
||||
env[key.strip()] = value.strip()
|
||||
return env
|
||||
|
||||
|
||||
def load_nodes(db_path: Path) -> list[dict]:
|
||||
if not db_path.exists():
|
||||
raise SystemExit(f"缺少节点数据库: {db_path},请先运行 install.sh")
|
||||
conn = sqlite3.connect(db_path)
|
||||
conn.row_factory = sqlite3.Row
|
||||
rows = conn.execute(
|
||||
"SELECT id, name, uuid, hy2_password FROM nodes WHERE enabled = 1 ORDER BY id"
|
||||
).fetchall()
|
||||
conn.close()
|
||||
if not rows:
|
||||
raise SystemExit("没有可用节点,请在管理面板中添加节点")
|
||||
return [dict(row) for row in rows]
|
||||
|
||||
|
||||
def build_config(env: dict[str, str], nodes: list[dict]) -> dict:
|
||||
required = [
|
||||
"REALITY_PRIVATE_KEY",
|
||||
"REALITY_SHORT_ID",
|
||||
"REALITY_SERVER_NAME",
|
||||
]
|
||||
for key in required:
|
||||
if not env.get(key):
|
||||
raise SystemExit(f".env 缺少 {key}")
|
||||
|
||||
short_id = env["REALITY_SHORT_ID"]
|
||||
clients = [
|
||||
{"id": node["uuid"], "flow": "xtls-rprx-vision", "email": node["uuid"]}
|
||||
for node in nodes
|
||||
]
|
||||
|
||||
return {
|
||||
"log": {
|
||||
"access": str(ACCESS_LOG),
|
||||
"loglevel": "warning",
|
||||
},
|
||||
"inbounds": [
|
||||
{
|
||||
"tag": "vless-reality-in",
|
||||
"listen": "0.0.0.0",
|
||||
"port": 443,
|
||||
"protocol": "vless",
|
||||
"settings": {
|
||||
"clients": clients,
|
||||
"decryption": "none",
|
||||
},
|
||||
"streamSettings": {
|
||||
"network": "tcp",
|
||||
"security": "reality",
|
||||
"realitySettings": {
|
||||
"show": False,
|
||||
"dest": f"{env['REALITY_SERVER_NAME']}:443",
|
||||
"xver": 0,
|
||||
"serverNames": [env["REALITY_SERVER_NAME"]],
|
||||
"privateKey": env["REALITY_PRIVATE_KEY"],
|
||||
"shortIds": ["", short_id],
|
||||
},
|
||||
},
|
||||
"sniffing": {
|
||||
"enabled": True,
|
||||
"destOverride": ["http", "tls", "quic"],
|
||||
},
|
||||
}
|
||||
],
|
||||
"outbounds": [
|
||||
{"protocol": "freedom", "tag": "direct"},
|
||||
{"protocol": "blackhole", "tag": "block"},
|
||||
],
|
||||
"routing": {
|
||||
"rules": [
|
||||
{
|
||||
"type": "field",
|
||||
"ip": ["geoip:private"],
|
||||
"outboundTag": "block",
|
||||
}
|
||||
]
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
def main() -> None:
|
||||
env = load_env(ENV_FILE)
|
||||
nodes = load_nodes(DB_FILE)
|
||||
config = build_config(env, nodes)
|
||||
|
||||
OUT_FILE.parent.mkdir(parents=True, exist_ok=True)
|
||||
ACCESS_LOG.parent.mkdir(parents=True, exist_ok=True)
|
||||
OUT_FILE.write_text(json.dumps(config, indent=2, ensure_ascii=False) + "\n", encoding="utf-8")
|
||||
|
||||
xray = subprocess.run(
|
||||
["xray", "run", "-test", "-c", str(OUT_FILE)],
|
||||
capture_output=True,
|
||||
text=True,
|
||||
)
|
||||
if xray.returncode != 0:
|
||||
sys.stderr.write(xray.stderr or xray.stdout)
|
||||
raise SystemExit(xray.returncode)
|
||||
|
||||
print(f"已生成 {OUT_FILE}({len(nodes)} 个 VLESS 用户)")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -1,39 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
# 一键修复 VLESS Reality:拉代码、重渲染配置、重启服务、诊断
|
||||
set -euo pipefail
|
||||
|
||||
ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
||||
|
||||
[[ $EUID -eq 0 ]] || { echo "请使用 root 运行: sudo bash scripts/repair-reality.sh"; exit 1; }
|
||||
|
||||
export JIEDIAN_ROOT="$ROOT"
|
||||
|
||||
echo "[1/5] 更新代码 ..."
|
||||
if [[ -d "$ROOT/.git" ]]; then
|
||||
git -C "$ROOT" pull --ff-only || echo "(git pull 跳过,请手动同步代码)"
|
||||
fi
|
||||
|
||||
echo "[2/5] 检查 443 监听进程 ..."
|
||||
if ss -tlnp 2>/dev/null | grep -q ':443'; then
|
||||
ss -tlnp | grep ':443' || true
|
||||
else
|
||||
echo " 443 端口未监听"
|
||||
fi
|
||||
|
||||
if [[ -f /etc/sing-box/config.json ]] && grep -q vless-reality /etc/sing-box/config.json 2>/dev/null; then
|
||||
echo "[!] sing-box 仍含 VLESS Reality,执行迁移 ..."
|
||||
bash "$ROOT/scripts/migrate-xray-reality.sh"
|
||||
else
|
||||
echo "[3/5] 渲染 Xray + sing-box 配置 ..."
|
||||
python3 "$ROOT/scripts/render-xray.py"
|
||||
python3 "$ROOT/scripts/render-server.py"
|
||||
echo "[4/5] 重启服务 ..."
|
||||
systemctl restart xray sing-box jiedian-panel
|
||||
fi
|
||||
|
||||
echo "[5/5] 诊断 ..."
|
||||
bash "$ROOT/scripts/verify-reality.sh"
|
||||
|
||||
echo ""
|
||||
echo "完成。请在面板重新复制 VLESS 链接,删除 v2rayNG 旧节点后重新导入。"
|
||||
echo "若仍失败,请执行: journalctl -u xray -n 50 --no-pager"
|
||||
@@ -6,17 +6,16 @@ set -euo pipefail
|
||||
[[ $EUID -eq 0 ]] || { echo "请使用 root 运行"; exit 1; }
|
||||
|
||||
echo "[*] 停止服务 ..."
|
||||
systemctl stop jiedian-panel xray sing-box 2>/dev/null || true
|
||||
systemctl disable jiedian-panel xray sing-box 2>/dev/null || true
|
||||
systemctl stop jiedian-panel sing-box xray 2>/dev/null || true
|
||||
systemctl disable jiedian-panel sing-box xray 2>/dev/null || true
|
||||
|
||||
echo "[*] 删除 systemd 单元 ..."
|
||||
rm -f /etc/systemd/system/jiedian-panel.service
|
||||
rm -f /etc/systemd/system/sing-box.service
|
||||
systemctl daemon-reload
|
||||
|
||||
echo "[*] 删除 sing-box / Xray 配置 ..."
|
||||
echo "[*] 删除 sing-box 配置 ..."
|
||||
rm -rf /etc/sing-box
|
||||
rm -f /usr/local/etc/xray/config.json
|
||||
|
||||
echo "[*] 删除 nginx 站点 ..."
|
||||
rm -f /etc/nginx/sites-enabled/panel
|
||||
@@ -36,5 +35,4 @@ rm -rf "${ROOT}/client/generated"
|
||||
echo ""
|
||||
echo "卸载完成。重新安装:"
|
||||
echo " cd ${ROOT}"
|
||||
echo " bash scripts/generate-keys.sh # 可选,重置 Reality 密钥与面板密码"
|
||||
echo " bash scripts/install.sh"
|
||||
|
||||
@@ -1,71 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
# 核对 Reality 密钥是否一致,并验证 Xray 配置
|
||||
set -euo pipefail
|
||||
|
||||
ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
||||
ENV_FILE="${ROOT}/.env"
|
||||
XRAY_CFG="/usr/local/etc/xray/config.json"
|
||||
SB_CFG="/etc/sing-box/config.json"
|
||||
|
||||
[[ -f "$ENV_FILE" ]] || { echo "缺少 $ENV_FILE"; exit 1; }
|
||||
# shellcheck disable=SC1090
|
||||
source "$ENV_FILE"
|
||||
|
||||
echo "========== .env =========="
|
||||
grep ^REALITY_ "$ENV_FILE" | grep -v PRIVATE || true
|
||||
echo "REALITY_PRIVATE_KEY=***(已隐藏)"
|
||||
|
||||
if command -v xray &>/dev/null && [[ -f "$XRAY_CFG" ]]; then
|
||||
echo ""
|
||||
echo "========== Xray config.json =========="
|
||||
ENV_FILE="$ENV_FILE" XRAY_CFG="$XRAY_CFG" python3 - <<'PY'
|
||||
import json, os
|
||||
from pathlib import Path
|
||||
env = {}
|
||||
for line in Path(os.environ["ENV_FILE"]).read_text().splitlines():
|
||||
line = line.strip()
|
||||
if not line or line.startswith("#") or "=" not in line:
|
||||
continue
|
||||
k, _, v = line.partition("=")
|
||||
env[k.strip()] = v.strip()
|
||||
cfg = json.load(open(os.environ["XRAY_CFG"]))
|
||||
rs = cfg["inbounds"][0]["streamSettings"]["realitySettings"]
|
||||
pk = rs["privateKey"]
|
||||
print("privateKey:", pk[:8] + "..." if pk else "(empty)")
|
||||
print("shortIds:", rs.get("shortIds"))
|
||||
print("serverNames:", rs.get("serverNames"))
|
||||
print("clients:", len(cfg["inbounds"][0]["settings"]["clients"]))
|
||||
match = pk == env.get("REALITY_PRIVATE_KEY", "")
|
||||
print("privateKey 与 .env 一致:", "是" if match else "否 ← 需运行 render-xray.py")
|
||||
PY
|
||||
echo ""
|
||||
echo "========== xray -test =========="
|
||||
xray run -test -c "$XRAY_CFG"
|
||||
else
|
||||
echo ""
|
||||
echo "Xray 未安装或配置不存在。VLESS Reality 需 Xray:"
|
||||
echo " bash -c \"\$(curl -L https://github.com/XTLS/Xray-install/raw/main/install-release.sh)\" @ install"
|
||||
echo " python3 ${ROOT}/scripts/render-xray.py"
|
||||
fi
|
||||
|
||||
if [[ -f "$SB_CFG" ]] && grep -q vless-reality "$SB_CFG" 2>/dev/null; then
|
||||
echo ""
|
||||
echo "[!] sing-box 仍含 vless-reality inbound,会与 Xray 争抢 443。"
|
||||
echo " 请运行: python3 ${ROOT}/scripts/render-server.py && systemctl restart sing-box"
|
||||
fi
|
||||
|
||||
if command -v xray &>/dev/null && [[ -n "${REALITY_PRIVATE_KEY:-}" ]]; then
|
||||
echo ""
|
||||
echo "========== 公钥配对 =========="
|
||||
DERIVED="$(xray x25519 -i "$REALITY_PRIVATE_KEY" 2>/dev/null | awk '/Public key/ {print $3; exit} /Password/ {print $3; exit}')"
|
||||
if [[ -n "$DERIVED" ]]; then
|
||||
if [[ "$DERIVED" == "${REALITY_PUBLIC_KEY:-}" ]]; then
|
||||
echo "公钥与私钥配对: 是"
|
||||
else
|
||||
echo "公钥与私钥配对: 否"
|
||||
echo " .env PUBLIC: ${REALITY_PUBLIC_KEY:-}"
|
||||
echo " 推导 PUBLIC: $DERIVED"
|
||||
echo " 请重新运行 generate-keys.sh 并 render-xray.py"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
Reference in New Issue
Block a user