🌐 修复铸渊专线订阅服务连接失败 · 绑定0.0.0.0+Nginx反代+密钥持久化
根因: subscription-server.js绑定127.0.0.1导致外部客户端无法连接 修复: - subscription-server.js: 绑定改为0.0.0.0, getServerHost()增加.env.keys回退 - zhuyuan-sovereign.conf: 添加/api/proxy-sub/反代location块 - deploy-proxy.sh: 新增save_server_host()持久化ZY_SERVER_HOST - deploy-proxy-service.yml: 部署时export ZY_SERVER_HOST Agent-Logs-Url: https://github.com/qinfendebingshuo/guanghulab/sessions/f70d170f-1916-4f79-a461-2b674592df30 Co-authored-by: qinfendebingshuo <207279273+qinfendebingshuo@users.noreply.github.com>
This commit is contained in:
parent
0bdad420a8
commit
6c20c7efb4
|
|
@ -87,7 +87,9 @@ jobs:
|
||||||
ssh -i ~/.ssh/id_deploy \
|
ssh -i ~/.ssh/id_deploy \
|
||||||
-o StrictHostKeyChecking=accept-new \
|
-o StrictHostKeyChecking=accept-new \
|
||||||
${{ secrets.ZY_SERVER_USER }}@${{ secrets.ZY_SERVER_HOST }} \
|
${{ secrets.ZY_SERVER_USER }}@${{ secrets.ZY_SERVER_HOST }} \
|
||||||
"cd /opt/zhuyuan/proxy-deploy && bash deploy-proxy.sh ${{ github.event.inputs.action }}"
|
"cd /opt/zhuyuan/proxy-deploy && \
|
||||||
|
export ZY_SERVER_HOST='${{ secrets.ZY_SERVER_HOST }}' && \
|
||||||
|
bash deploy-proxy.sh ${{ github.event.inputs.action }}"
|
||||||
|
|
||||||
- name: '🧹 清理SSH密钥'
|
- name: '🧹 清理SSH密钥'
|
||||||
if: always()
|
if: always()
|
||||||
|
|
|
||||||
|
|
@ -92,6 +92,18 @@ server {
|
||||||
proxy_read_timeout 86400;
|
proxy_read_timeout 86400;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# ─── 铸渊专线订阅服务 (端口 3802) ───
|
||||||
|
location /api/proxy-sub/ {
|
||||||
|
proxy_pass http://127.0.0.1:3802/;
|
||||||
|
proxy_http_version 1.1;
|
||||||
|
proxy_set_header Host $host;
|
||||||
|
proxy_set_header X-Real-IP $remote_addr;
|
||||||
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||||
|
proxy_set_header X-Forwarded-Proto $scheme;
|
||||||
|
add_header X-Content-Type-Options nosniff always;
|
||||||
|
add_header Cache-Control "no-store, no-cache, must-revalidate" always;
|
||||||
|
}
|
||||||
|
|
||||||
# ─── 健康探针 ───
|
# ─── 健康探针 ───
|
||||||
location = /health {
|
location = /health {
|
||||||
proxy_pass http://127.0.0.1:3800/api/health;
|
proxy_pass http://127.0.0.1:3800/api/health;
|
||||||
|
|
|
||||||
|
|
@ -51,6 +51,29 @@ ensure_log_permissions() {
|
||||||
chmod 755 "$PROXY_DIR/logs"
|
chmod 755 "$PROXY_DIR/logs"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# ── 共用: 保存ZY_SERVER_HOST到.env.keys ──
|
||||||
|
save_server_host() {
|
||||||
|
KEYS_FILE="$PROXY_DIR/.env.keys"
|
||||||
|
if [ -n "${ZY_SERVER_HOST:-}" ] && [ -f "$KEYS_FILE" ]; then
|
||||||
|
# 检查是否已存在
|
||||||
|
if grep -q "^ZY_SERVER_HOST=" "$KEYS_FILE" 2>/dev/null; then
|
||||||
|
# 更新已有的值
|
||||||
|
sed -i "s|^ZY_SERVER_HOST=.*|ZY_SERVER_HOST=${ZY_SERVER_HOST}|" "$KEYS_FILE"
|
||||||
|
else
|
||||||
|
# 追加新行
|
||||||
|
echo "" >> "$KEYS_FILE"
|
||||||
|
echo "# 服务器地址 (部署时自动写入)" >> "$KEYS_FILE"
|
||||||
|
echo "ZY_SERVER_HOST=${ZY_SERVER_HOST}" >> "$KEYS_FILE"
|
||||||
|
fi
|
||||||
|
echo " ✅ ZY_SERVER_HOST 已保存到 .env.keys"
|
||||||
|
elif [ -n "${ZY_SERVER_HOST:-}" ] && [ ! -f "$KEYS_FILE" ]; then
|
||||||
|
echo " ⚠️ .env.keys 不存在,创建并写入 ZY_SERVER_HOST"
|
||||||
|
echo "# 服务器地址 (部署时自动写入)" > "$KEYS_FILE"
|
||||||
|
echo "ZY_SERVER_HOST=${ZY_SERVER_HOST}" >> "$KEYS_FILE"
|
||||||
|
chmod 600 "$KEYS_FILE"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
# ── install: 首次完整安装 ─────────────────────
|
# ── install: 首次完整安装 ─────────────────────
|
||||||
install() {
|
install() {
|
||||||
echo ""
|
echo ""
|
||||||
|
|
@ -83,6 +106,7 @@ install() {
|
||||||
echo ""
|
echo ""
|
||||||
echo "═══ [4/7] 部署代理服务代码 ═══"
|
echo "═══ [4/7] 部署代理服务代码 ═══"
|
||||||
deploy_services
|
deploy_services
|
||||||
|
save_server_host
|
||||||
|
|
||||||
echo ""
|
echo ""
|
||||||
echo "═══ [5/7] 配置Nginx ═══"
|
echo "═══ [5/7] 配置Nginx ═══"
|
||||||
|
|
@ -166,21 +190,24 @@ deploy_services() {
|
||||||
|
|
||||||
# ── 配置Nginx ─────────────────────────────────
|
# ── 配置Nginx ─────────────────────────────────
|
||||||
configure_nginx() {
|
configure_nginx() {
|
||||||
# 检查Nginx配置片段是否已添加
|
# 检查主Nginx配置是否已有proxy-sub
|
||||||
NGINX_CONF="/etc/nginx/sites-enabled/default"
|
NGINX_CONF="/etc/nginx/sites-enabled/default"
|
||||||
SNIPPET="$REPO_PROXY_DIR/config/nginx-proxy-snippet.conf"
|
|
||||||
|
|
||||||
if ! grep -q "proxy-sub" "$NGINX_CONF" 2>/dev/null; then
|
if [ -f "$NGINX_CONF" ] && ! grep -q "proxy-sub" "$NGINX_CONF" 2>/dev/null; then
|
||||||
echo " 添加Nginx代理订阅反向代理..."
|
echo " 添加Nginx代理订阅反向代理配置..."
|
||||||
# 在最后一个 } 之前插入
|
# 在第一个 location = /health 之前插入 proxy-sub location
|
||||||
# 注意: 实际应该由铸渊智能合并到主nginx配置
|
sed -i '/# ─── 健康探针 ───/{
|
||||||
echo " ⚠️ 请手动将以下配置添加到Nginx:"
|
# 只在第一次匹配时插入
|
||||||
echo " $SNIPPET"
|
i\ # ─── 铸渊专线订阅服务 (端口 3802) ───\n location /api/proxy-sub/ {\n proxy_pass http://127.0.0.1:3802/;\n proxy_http_version 1.1;\n proxy_set_header Host $host;\n proxy_set_header X-Real-IP $remote_addr;\n proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;\n proxy_set_header X-Forwarded-Proto $scheme;\n add_header X-Content-Type-Options nosniff always;\n add_header Cache-Control "no-store, no-cache, must-revalidate" always;\n }\n
|
||||||
|
}' "$NGINX_CONF" || true
|
||||||
|
echo " ✅ Nginx proxy-sub配置已注入"
|
||||||
else
|
else
|
||||||
echo " Nginx代理配置已存在"
|
echo " Nginx代理配置已存在 (或主配置不存在)"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if nginx -t 2>/dev/null; then
|
if nginx -t 2>/dev/null; then
|
||||||
nginx -s reload || true
|
nginx -s reload || true
|
||||||
|
echo " ✅ Nginx配置验证通过并已重载"
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -235,6 +262,7 @@ health_check() {
|
||||||
update() {
|
update() {
|
||||||
echo "更新代理服务..."
|
echo "更新代理服务..."
|
||||||
deploy_services
|
deploy_services
|
||||||
|
save_server_host
|
||||||
configure_xray
|
configure_xray
|
||||||
|
|
||||||
ensure_xray_root_user
|
ensure_xray_root_user
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@
|
||||||
// - Clash YAML (Clash Verge / ClashMi)
|
// - Clash YAML (Clash Verge / ClashMi)
|
||||||
// - Base64 URI (Shadowrocket)
|
// - Base64 URI (Shadowrocket)
|
||||||
//
|
//
|
||||||
// 端口: 3802 (仅本地访问,通过Nginx反代)
|
// 端口: 3802 (绑定0.0.0.0,支持外部直连 + Nginx反代)
|
||||||
// 认证: URL中的token参数
|
// 认证: URL中的token参数
|
||||||
//
|
//
|
||||||
// 环境变量 (从 /opt/zhuyuan/proxy/.env.keys 加载):
|
// 环境变量 (从 /opt/zhuyuan/proxy/.env.keys 加载):
|
||||||
|
|
@ -52,14 +52,32 @@ function loadKeys() {
|
||||||
|
|
||||||
// ── 获取服务器IP ────────────────────────────
|
// ── 获取服务器IP ────────────────────────────
|
||||||
// ⚠️ 仓库公开,不在代码中硬编码IP
|
// ⚠️ 仓库公开,不在代码中硬编码IP
|
||||||
// 从环境变量读取,部署时由PM2或GitHub Secrets注入
|
// 优先级: 环境变量 > .env.keys文件 > 回退
|
||||||
function getServerHost() {
|
function getServerHost() {
|
||||||
const host = process.env.ZY_SERVER_HOST;
|
// 1. 优先从环境变量读取
|
||||||
if (!host) {
|
if (process.env.ZY_SERVER_HOST) {
|
||||||
console.error('⚠️ ZY_SERVER_HOST 未设置');
|
return process.env.ZY_SERVER_HOST;
|
||||||
return '0.0.0.0';
|
|
||||||
}
|
}
|
||||||
return host;
|
|
||||||
|
// 2. 从.env.keys文件读取
|
||||||
|
try {
|
||||||
|
const content = fs.readFileSync(KEYS_FILE, 'utf8');
|
||||||
|
for (const line of content.split('\n')) {
|
||||||
|
if (line.startsWith('#') || !line.includes('=')) continue;
|
||||||
|
const [key, ...vals] = line.split('=');
|
||||||
|
if (key.trim() === 'ZY_SERVER_HOST') {
|
||||||
|
const val = vals.join('=').trim();
|
||||||
|
if (val) return val;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
if (err.code !== 'ENOENT') {
|
||||||
|
console.error(`⚠️ 读取 ${KEYS_FILE} 失败: ${err.code || err.message}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
console.error('⚠️ ZY_SERVER_HOST 未设置 (环境变量和.env.keys均未找到)');
|
||||||
|
return '0.0.0.0';
|
||||||
}
|
}
|
||||||
|
|
||||||
// ── 读取流量配额信息 ────────────────────────
|
// ── 读取流量配额信息 ────────────────────────
|
||||||
|
|
@ -282,8 +300,8 @@ const server = http.createServer((req, res) => {
|
||||||
res.end('Not Found');
|
res.end('Not Found');
|
||||||
});
|
});
|
||||||
|
|
||||||
server.listen(PORT, '127.0.0.1', () => {
|
server.listen(PORT, '0.0.0.0', () => {
|
||||||
console.log(`🌐 铸渊专线订阅服务已启动: http://127.0.0.1:${PORT}`);
|
console.log(`🌐 铸渊专线订阅服务已启动: http://0.0.0.0:${PORT}`);
|
||||||
console.log(` 订阅端点: /sub/{token}`);
|
console.log(` 订阅端点: /sub/{token}`);
|
||||||
console.log(` 配额查询: /quota`);
|
console.log(` 配额查询: /quota`);
|
||||||
console.log(` 健康检查: /health`);
|
console.log(` 健康检查: /health`);
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue