Make Nginx the default public gateway

This commit is contained in:
Codex committed 2026-10-26 15:07:21 +08:00
1 parent 6d5973bea3
commit ff4c36bcce
10 files changed
+136 -66

No files matched your search

+5 -8
View File
@@ -900,7 +900,7 @@
"domain": "Configured domain",
"activeDomain": "Active domain",
"saveDomain": "Save domain",
"restartRequired": "Gateway mode saved; switching between Go and Nginx requires restarting the management service",
"restartRequired": "Public entry saved; check the gateway site status",
"siteActivationRequired": "Entry saved; prepare and enable the Nginx site below for first use",
"pendingEntry": "Nginx still serves {address}; save to validate and apply the new entry",
"applied": "Public entry updated; Nginx configuration is active",
@@ -917,14 +917,11 @@
"automatic": "Automatic (autocert)",
"ports": "HTTP / HTTPS ports",
"externalPorts": "Managed by external Nginx; listener status not checked",
"setupHint": "Changes to an active Nginx gateway apply on save. Prepare a certificate for initial setup. Only switching between Go and Nginx modes requires a restart.",
"setupHint": "Nginx owns the public gateway. Active sites reload on save; initial HTTPS setup needs a certificate.",
"refresh": "Refresh status",
"openHttps": "Open HTTPS health check",
"loadFailed": "Could not load certificate status",
"mode": "Public entry mode",
"goMode": "Go automatic certificate (binds 80/443)",
"nginxMode": "Nginx proxy (external 80/443)",
"saveMode": "Save entry mode",
"legacyModeHint": "This server still uses the legacy Go public listener. Migrate to Nginx using the deployment guide before editing the gateway.",
"nginxHint": "An active Nginx gateway reloads on save. Initial setup requires enabling the site separately; the management service remains on port 18080.",
"externalRenewal": "Managed by Certbot",
"previewNginx": "Preview Nginx configuration",
@@ -940,13 +937,13 @@
"siteReady": "HTTPS site and certificate are ready",
"siteFailed": "Gateway or certificate setup failed; see output",
"directPortWarning": "The management service still listens publicly on port 18080, bypassing Nginx path rules. Migrate clients using the old HTTP address, then bind the service to 127.0.0.1:18080.",
"setupTitle": "Optional HTTPS public gateway",
"setupTitle": "Nginx gateway and certificate",
"setupStepCheck": "Detect system",
"setupStepInstall": "Install dependencies",
"setupStepConfigure": "Configure gateway and certificate",
"detectedSystem": "Server OS",
"setupUnsupported": "Automatic setup requires root on Ubuntu or TencentOS Server 4",
"setupScope": "Use only if you choose the Nginx gateway. Installs Nginx / Certbot and prepares the validation directory. It does not install VPN protocol dependencies, enable ports, or issue certificates.",
"setupScope": "Installs Nginx / Certbot and prepares the validation directory. It does not install VPN protocol dependencies, enable ports, or issue certificates.",
"setupButton": "Prepare Nginx / Certbot",
"setupComplete": "Dependencies are ready; configure the site and certificate next",
"setupFailed": "Initialization failed; inspect the output",
+5 -8
View File
@@ -900,7 +900,7 @@
"domain": "配置域名",
"activeDomain": "当前监听域名",
"saveDomain": "保存域名",
"restartRequired": "入口模式已保存;切换 Go 与 Nginx 模式需重启管理服务",
"restartRequired": "公网入口配置已保存;请检查站点状态",
"siteActivationRequired": "入口已保存;首次启用站点请到下方准备并启用 Nginx",
"pendingEntry": "当前 Nginx 仍使用 {address};点击保存将校验并更新入口",
"applied": "公网入口已更新,Nginx 配置已生效",
@@ -917,14 +917,11 @@
"automatic": "自动(autocert)",
"ports": "HTTP / HTTPS 端口",
"externalPorts": "由外部 Nginx 管理,尚未检测监听状态",
"setupHint": "已启用的 Nginx 入口保存后立即生效;首次启用站点需准备证书。只有切换 Go 与 Nginx 模式才需重启。",
"setupHint": "由 Nginx 管理公网入口;已启用的站点保存后立即重载,首次启用 HTTPS 需准备证书。",
"refresh": "刷新状态",
"openHttps": "打开 HTTPS 健康检查",
"loadFailed": "读取证书状态失败",
"mode": "公网入口模式",
"goMode": "Go 自动证书(进程监听 80/443)",
"nginxMode": "Nginx 代理(外部监听 80/443)",
"saveMode": "保存入口模式",
"legacyModeHint": "当前仍由旧版 Go 模式直接监听公网。请按部署文档迁移至 Nginx 后修改入口。",
"nginxHint": "已启用的 Nginx 入口保存后立即重载;首次配置需单独启用站点。管理服务继续监听 18080。",
"externalRenewal": "由 Certbot 管理",
"previewNginx": "预览 Nginx 配置",
@@ -940,13 +937,13 @@
"siteReady": "HTTPS 站点与证书已就绪",
"siteFailed": "站点或证书配置失败,请查看输出",
"directPortWarning": "管理服务仍直接监听公网 18080,访问该端口会绕过 Nginx 的路径限制。请先迁移使用旧 HTTP 地址的客户端,再将管理服务改为仅监听 127.0.0.1:18080。",
"setupTitle": "可选 · HTTPS 公网入口",
"setupTitle": "Nginx 入口与证书",
"setupStepCheck": "检测系统",
"setupStepInstall": "安装依赖",
"setupStepConfigure": "配置入口与证书",
"detectedSystem": "服务器系统",
"setupUnsupported": "自动初始化仅支持以 root 运行的 Ubuntu 或 TencentOS Server 4",
"setupScope": "仅在选择 Nginx 入口时点击:按需安装 Nginx / Certbot 并准备验证目录;不会安装 VPN 协议依赖、启用端口或签发证书。",
"setupScope": "按需安装 Nginx / Certbot 并准备验证目录;不会安装 VPN 协议依赖、启用端口或签发证书。",
"setupButton": "准备 Nginx / Certbot",
"setupComplete": "依赖已准备,继续配置站点与证书",
"setupFailed": "初始化失败,请查看输出",
@@ -9,6 +9,7 @@
</div>
</template>
<el-alert type="info" :closable="false" :title="$t('tls.publicEntryDesc')" style="margin-bottom:16px" />
<el-alert v-if="legacyMode" type="warning" :closable="false" :title="$t('tls.legacyModeHint')" style="margin-bottom:16px" />
<el-form label-position="top" @submit.prevent="savePublicEntry">
<el-form-item :label="$t('tls.scheme')">
@@ -44,18 +45,12 @@
</el-input>
<div class="tls-hint">{{ $t('tls.publicBaseHint') }}</div>
</el-form-item>
<el-form-item :label="$t('tls.mode')">
<el-select v-model="entry.mode" style="width:100%">
<el-option value="autocert" :label="$t('tls.goMode')" />
<el-option value="nginx" :label="$t('tls.nginxMode')" />
</el-select>
</el-form-item>
<el-button type="primary" :loading="tlsSaving" @click="savePublicEntry">{{ $t('tls.saveEntry') }}</el-button>
<el-button type="primary" :loading="tlsSaving" :disabled="legacyMode" @click="savePublicEntry">{{ $t('tls.saveEntry') }}</el-button>
</el-form>
<el-alert v-if="tlsStatus?.restart_required" type="warning" :closable="false" :title="$t('tls.restartRequired')" style="margin-top:12px" />
<el-alert v-else-if="entry.mode === 'nginx' && nginxSetup?.site_stage === 'none' && tlsStatus?.configured_domain" type="info" :closable="false" :title="$t('tls.siteActivationRequired')" style="margin-top:12px" />
<el-alert v-else-if="entry.mode === 'nginx' && tlsStatus?.public_base && tlsStatus?.configured_public_base !== tlsStatus?.public_base" type="warning" :closable="false" :title="$t('tls.pendingEntry', { address: tlsStatus.public_base })" style="margin-top:12px" />
<el-alert v-else-if="!legacyMode && nginxSetup?.site_stage === 'none' && tlsStatus?.configured_domain" type="info" :closable="false" :title="$t('tls.siteActivationRequired')" style="margin-top:12px" />
<el-alert v-else-if="!legacyMode && tlsStatus?.public_base && tlsStatus?.configured_public_base !== tlsStatus?.public_base" type="warning" :closable="false" :title="$t('tls.pendingEntry', { address: tlsStatus.public_base })" style="margin-top:12px" />
<el-alert v-if="tlsStatus?.management_direct_public" type="warning" :closable="false" :title="$t('tls.directPortWarning')" style="margin-top:12px" />
</el-card>
@@ -64,7 +59,7 @@
<template #header>
<div class="card-head">
<b>{{ $t('tls.certListTitle') }}</b>
<el-button type="primary" @click="openAddCert">{{ $t('tls.addCert') }}</el-button>
<el-button type="primary" :disabled="legacyMode" @click="openAddCert">{{ $t('tls.addCert') }}</el-button>
</div>
</template>
<el-table :data="certRows" size="default" v-loading="tlsLoading">
@@ -100,7 +95,7 @@
</el-card>
<!-- Nginx 准备(折叠) -->
<el-collapse v-if="entry.mode === 'nginx'">
<el-collapse v-if="!legacyMode">
<el-collapse-item :title="$t('tls.setupTitle')" name="setup">
<el-steps :active="nginxSetup?.site_stage === 'https' ? 3 : nginxSetup?.nginx_installed && nginxSetup?.certbot_installed && nginxSetup?.webroot_ready ? 2 : 1" finish-status="success" style="margin-bottom:16px">
<el-step :title="$t('tls.setupStepCheck')" />
@@ -229,12 +224,12 @@ const nginxActivateLog = ref('')
const nginxActivateLogView = ref(null)
const certDialog = ref(false)
const certSubmitting = ref(false)
const legacyMode = computed(() => tlsStatus.value?.mode === 'autocert' || tlsStatus.value?.configured_mode === 'autocert')
const entry = reactive({
scheme: 'http',
host: '',
port: 80,
mode: 'nginx',
})
const certForm = reactive({
@@ -270,7 +265,6 @@ const certRows = computed(() => {
function onSchemeChange() {
entry.port = defaultPort(entry.scheme)
if (entry.scheme === 'http') entry.mode = 'nginx'
}
function resetCertForm() {
@@ -374,7 +368,6 @@ async function loadTLS() {
entry.scheme = scheme === 'http' ? 'http' : 'https'
const port = Number(data.configured_port || data.port)
entry.port = port > 0 ? port : defaultPort(entry.scheme)
entry.mode = entry.host ? (data.configured_mode || data.mode || 'autocert') : 'nginx'
} catch (e) { ElMessage.error(e.response?.data?.error || t('tls.loadFailed')) }
finally { tlsLoading.value = false }
}
@@ -383,11 +376,6 @@ async function savePublicEntry() {
if (!entry.host) return ElMessage.warning(t('tls.hostRequired'))
tlsSaving.value = true
try {
let modeRes = null
if (entry.mode !== tlsStatus.value?.configured_mode) {
const result = await api.put('/system/tls/mode', { mode: entry.mode })
modeRes = result.data
}
const { data: domainRes } = await api.put('/system/tls/domain', {
domain: entry.host,
scheme: entry.scheme,
@@ -395,7 +383,7 @@ async function savePublicEntry() {
})
tlsStatus.value = domainRes.status
nginxPreview.value = null
if (domainRes.restart_required || modeRes?.restart_required) ElMessage.success(t('tls.restartRequired'))
if (domainRes.restart_required) ElMessage.success(t('tls.restartRequired'))
else if (domainRes.site_activation_required) ElMessage.success(t('tls.siteActivationRequired'))
else ElMessage.success(t(domainRes.applied ? 'tls.applied' : 'tls.saved'))
await refreshAll()
@@ -463,17 +451,13 @@ async function submitCert() {
await loadTLS()
return
}
// HTTP-01: ensure domain saved, nginx mode, then activate
// HTTP-01: save the public domain, then activate the Nginx site.
const host = (certForm.host || entry.host || '').trim()
if (!host) return ElMessage.warning(t('tls.hostRequired'))
entry.host = host.split(/[\s,]+/)[0]
await api.put('/system/tls/domain', {
domain: entry.host, scheme: entry.scheme, port: entry.port,
})
if (entry.mode !== 'nginx') {
await api.put('/system/tls/mode', { mode: 'nginx' })
entry.mode = 'nginx'
}
await streamActivate()
ElMessage.success(t('tls.siteReady'))
certDialog.value = false