1204 lines
56 KiB
JSON
1204 lines
56 KiB
JSON
{
|
||
"common": {
|
||
"appName": "VPN Management Platform",
|
||
"confirm": "Confirm",
|
||
"cancel": "Cancel",
|
||
"save": "Save",
|
||
"delete": "Delete",
|
||
"edit": "Edit",
|
||
"add": "Add",
|
||
"create": "Create",
|
||
"close": "Close",
|
||
"search": "Search",
|
||
"refresh": "Refresh",
|
||
"back": "Back",
|
||
"submit": "Submit",
|
||
"yes": "Yes",
|
||
"no": "No",
|
||
"enabled": "Enabled",
|
||
"disabled": "Disabled",
|
||
"loading": "Loading",
|
||
"operation": "Actions",
|
||
"status": "Status",
|
||
"name": "Name",
|
||
"description": "Description",
|
||
"username": "Username",
|
||
"password": "Password",
|
||
"email": "Email",
|
||
"source": "Source",
|
||
"local": "Local",
|
||
"ldap": "LDAP",
|
||
"remark": "Remark",
|
||
"protocol": "Protocol",
|
||
"node": "Node",
|
||
"time": "Time",
|
||
"target": "Target",
|
||
"action": "Action",
|
||
"traffic": "Traffic ↓ / ↑",
|
||
"ipAddress": "IP Address",
|
||
"detail": "Detail",
|
||
"copy": "Copy",
|
||
"copied": "Copied",
|
||
"download": "Download",
|
||
"permanent": "Permanent",
|
||
"saveSuccess": "Saved",
|
||
"saveFailed": "Save failed",
|
||
"deleteSuccess": "Deleted",
|
||
"deleteFailed": "Delete failed",
|
||
"loadFailed": "Failed to load",
|
||
"operationFailed": "Operation failed",
|
||
"deleteConfirm": "Confirm Delete",
|
||
"noData": "No data",
|
||
"never": "Never",
|
||
"copiedToClipboard": "Copied to clipboard",
|
||
"logout": "Logout",
|
||
"batchOperation": "Batch Operation"
|
||
},
|
||
"login": {
|
||
"title": "VPN Management Platform",
|
||
"subtitle": "Unified multi-protocol VPN management — simple, secure, and controllable",
|
||
"protocols": "WireGuard · IPSec · IKEv2 · L2TP · GRE · FRP · OpenVPN",
|
||
"feature1Title": "Multi-Protocol Unified Management",
|
||
"feature1Desc": "WireGuard / IPSec / IKEv2 / L2TP / GRE / OpenVPN",
|
||
"feature2Title": "Enterprise-Grade Security",
|
||
"feature2Desc": "AES-GCM encrypted keys + Two-Factor Authentication",
|
||
"feature3Title": "One-Click Configuration",
|
||
"feature3Desc": "Wizard-driven generation, instant client config download",
|
||
"feature4Title": "Lightweight & Zero Dependencies",
|
||
"feature4Desc": "Single binary delivery, no Docker required",
|
||
"welcome": "Welcome Back",
|
||
"welcomeHint": "Please enter your credentials to sign in",
|
||
"usernameLabel": "Username",
|
||
"usernamePlaceholder": "Enter username",
|
||
"passwordLabel": "Password",
|
||
"passwordPlaceholder": "Enter password",
|
||
"loginButton": "Sign In",
|
||
"defaultAccount": "Default account: {account} — please change password after first login",
|
||
"errorEmpty": "Please enter username and password",
|
||
"loginSuccess": "Login successful",
|
||
"changePasswordFirst": "Please change your password first",
|
||
"loginFailed": "Login failed. Please check your network or contact the administrator."
|
||
},
|
||
"dashboard": {
|
||
"welcomeTitle": "Welcome to VPN Management Platform",
|
||
"welcomeDesc": "No tunnels yet — create your first one in 3 steps: Choose protocol → Fill parameters → Auto-generate config",
|
||
"createNow": "Create Tunnel Now",
|
||
"totalTunnels": "Total Tunnels",
|
||
"running": "Running",
|
||
"onlineUsers": "Online Users",
|
||
"totalTraffic": "Total Traffic ↓↑",
|
||
"protocolDistribution": "Protocol Distribution",
|
||
"protocolEngineStatus": "Protocol Engine Status",
|
||
"hostReadinessWarning": "Host prerequisites are incomplete. VPN forwarding or NAT may not work correctly.",
|
||
"readinessRoot": "Service is not running as root",
|
||
"readinessForwarding": "IPv4 forwarding is disabled",
|
||
"readinessRoute": "No default egress route detected",
|
||
"depCheckResult": "System dependency check results",
|
||
"depReady": "Ready",
|
||
"demoMode": "Demo Mode",
|
||
"deploy": "Deploy",
|
||
"installCmd": "Install Command",
|
||
"expiringTunnels": "Tunnels Expiring Soon (within 7 days)",
|
||
"expiryTime": "Expiry Time",
|
||
"noTunnels": "No tunnels yet",
|
||
"deploySuccess": "{name} {version} deployed successfully",
|
||
"deployFailed": "Failed to deploy {name}",
|
||
"contactAdmin": "Please contact the system administrator to install",
|
||
"recommendedCmd": "Recommended Command",
|
||
"otherDistros": "Other Distros",
|
||
"copyRecommended": "Copy Recommended",
|
||
"getInstallCmdFailed": "Failed to get install command",
|
||
"aptDefault": "apt default",
|
||
"oneClickInstall": "Install",
|
||
"oneClickFix": "Auto Fix",
|
||
"fixSuccess": "Fixed: {items}",
|
||
"fixFailed": "Fix failed: {items}",
|
||
"fixNeedRoot": "Root privileges required to modify system config",
|
||
"fixNothing": "Nothing to auto-fix"
|
||
},
|
||
"tunnels": {
|
||
"searchPlaceholder": "Search by name",
|
||
"allProtocols": "All Protocols",
|
||
"allStates": "All States",
|
||
"stateRunning": "Running",
|
||
"stateStopped": "Stopped",
|
||
"stateError": "Error",
|
||
"stateUndeployed": "Undeployed",
|
||
"createTunnel": "Create Tunnel",
|
||
"createFirst": "Create First Tunnel",
|
||
"noTunnels": "No tunnels yet",
|
||
"expireTime": "Expiry Time",
|
||
"localNode": "Local",
|
||
"authMethod": "Authentication",
|
||
"authUnknown": "Unspecified",
|
||
"wgAuthPassword": "Client account + device key",
|
||
"wgAuthHint": "The client account obtains device authorization; WireGuard authenticates using keys. Manually added static peers still connect by key.",
|
||
"start": "Start",
|
||
"stop": "Stop",
|
||
"started": "Started",
|
||
"startFailed": "Start failed",
|
||
"stopped": "Stopped",
|
||
"more": "More",
|
||
"viewLogs": "View Logs",
|
||
"downloadConfig": "Download Config",
|
||
"showQrCode": "Show QR Code",
|
||
"ipsecTest": "IPSec Test",
|
||
"delete": "Delete",
|
||
"detail": "Detail",
|
||
"protocol": "Protocol",
|
||
"createTime": "Created",
|
||
"autoStart": "Auto Start",
|
||
"runningParams": "Runtime Parameters",
|
||
"clientConfig": "Client Configuration",
|
||
"noClientConfig": "No client config available for this protocol",
|
||
"downloadClientConfig": "Download Client Config",
|
||
"ipsecParamCheck": "IPSec Parameter Check & Connectivity Test",
|
||
"trafficPolicy": "Traffic Policy",
|
||
"quotaGB": "Quota (GB)",
|
||
"quotaUnlimited": "0 = Unlimited. Used: {used}",
|
||
"rateLimitMbps": "Rate Limit (Mbps)",
|
||
"rateUnlimited": "0 = Unlimited",
|
||
"exceedAction": "Exceed Action",
|
||
"actionWarn": "Warn Only",
|
||
"actionBlock": "Auto Stop",
|
||
"actionThrottle": "Throttle to 1Mbps",
|
||
"resetCycle": "Reset Cycle",
|
||
"resetNone": "Never",
|
||
"resetDaily": "Daily",
|
||
"resetMonthly": "Monthly",
|
||
"savePolicy": "Save Policy",
|
||
"policySaved": "Traffic policy saved",
|
||
"peerList": "Peer List",
|
||
"addPeer": "Add Peer",
|
||
"peerId": "Peer ID",
|
||
"address": "Address",
|
||
"peerOnline": "Online",
|
||
"peerOffline": "Offline",
|
||
"config": "Config",
|
||
"qrCode": "QR Code",
|
||
"scanQrTitle": "Scan to Import WireGuard Client",
|
||
"scanQrHint": "Use WireGuard App's \"Add from QR code\"",
|
||
"addPeerTitle": "Add WireGuard Peer",
|
||
"autoGenId": "Leave empty for auto-generated client-N",
|
||
"peerNamePlaceholder": "Phone / Laptop",
|
||
"clientAddress": "Client Address",
|
||
"defaultAllowedIPs": "Leave empty for tunnel default",
|
||
"externalPublicKey": "External Public Key",
|
||
"externalKeyHint": "Leave empty for platform-managed key; fill in for external device",
|
||
"logTitle": "Instance Log — {name}",
|
||
"liveOutput": "● Live output",
|
||
"logStopped": "Stopped",
|
||
"pause": "Pause",
|
||
"resume": "Resume",
|
||
"clearScreen": "Clear",
|
||
"waitingLog": "Waiting for log output...",
|
||
"fillClientAddress": "Please enter client address",
|
||
"peerAdded": "Peer added",
|
||
"addFailed": "Add failed",
|
||
"deletePeerConfirm": "Delete peer \"{id}\"?",
|
||
"downloadFailed": "Download failed",
|
||
"qrFailed": "Failed to generate QR code",
|
||
"noClientConfigWarn": "No client config available",
|
||
"deleteTunnelConfirm": "Delete tunnel \"{name}\"? Configuration and keys will be permanently removed.",
|
||
"peerAlreadyAdded": "Peer already added",
|
||
"stopFailed": "Stop failed",
|
||
"selected": "{count} selected",
|
||
"batchStart": "Batch Start",
|
||
"batchStop": "Batch Stop",
|
||
"batchDelete": "Batch Delete",
|
||
"batchStartConfirm": "Confirm batch start {count} tunnels?",
|
||
"batchStopConfirm": "Confirm batch stop {count} tunnels?",
|
||
"batchDeleteConfirm": "Confirm batch delete {count} tunnels? This cannot be undone!",
|
||
"batchStarted": "Batch operation submitted, executing in background",
|
||
"taskProgress": "Task Progress",
|
||
"taskPending": "Pending",
|
||
"taskRunning": "Running",
|
||
"taskDone": "Done",
|
||
"taskFailed": "Failed",
|
||
"taskSuccess": "Success {count}/{total}",
|
||
"taskFailedCount": "Failed {count}",
|
||
"taskInProgress": "In progress ({done}/{total})",
|
||
"taskComplete": "All done",
|
||
"taskPartialFail": "Partial failure",
|
||
"viewTasks": "View Tasks",
|
||
"noTasks": "No task history",
|
||
"trafficTrend": "Traffic Trend",
|
||
"noTrafficData": "No traffic data yet (waiting for samples…)"
|
||
},
|
||
"oidcGuide": {
|
||
"title": "Feishu / OIDC browser authentication",
|
||
"externalService": "Requires openvpn-auth-oauth2",
|
||
"componentReady": "Authentication component installed v{version}",
|
||
"authEntryPending": "HTTPS is ready at {domain}; sync the authentication route in Settings → Feishu Identity after starting the tunnel.",
|
||
"app": "Create app",
|
||
"appShort": "Feishu developer console",
|
||
"identity": "Enter identity settings",
|
||
"identityShort": "OIDC and credentials",
|
||
"builtinIdentityShort": "Enter Feishu credentials in Settings",
|
||
"callback": "Set public callback",
|
||
"callbackShort": "HTTPS reverse proxy",
|
||
"test": "Test client",
|
||
"testShort": "Browser sign-in",
|
||
"appTip": "Ask a Feishu administrator to create and publish an app with the appropriate sign-in capability.",
|
||
"builtinAppTip": "Manage Feishu App ID and App Secret in Settings → Feishu Identity, not in each tunnel.",
|
||
"openConsole": "Open Feishu app console",
|
||
"appInstruction1": "Create an enterprise app, obtain its credentials, and enable the web sign-in capability.",
|
||
"appInstruction2": "Register a redirect URL under the app's security/redirect settings. If using a broker, use the broker's upstream callback here.",
|
||
"builtinAppInstruction2": "Register the Feishu app callback shown below in the app's redirect settings, not the VPN client callback.",
|
||
"appInstruction3": "Publish the app and restrict its available users to people allowed to access this VPN.",
|
||
"scopeTip": "Restrict who can use the Feishu app. LDAP dial-in users are not automatically linked to Feishu identities.",
|
||
"providerTip": "Use the built-in Feishu issuer configured in Settings, or provide an external issuer with OIDC discovery and ID tokens. A Feishu app URL alone is not an issuer.",
|
||
"source": "Identity source", "builtinSource": "Built-in Feishu", "externalSource": "External OIDC", "configureBuiltIn": "The built-in Feishu issuer is not enabled. Save app credentials and enable it in Settings first.", "manageFeishu": "Open Settings → Feishu Identity", "builtinSummary": "The Feishu App ID, App Secret, and tenant are managed in Settings; this tunnel references the issuer and its own public authentication entry.",
|
||
"useBuiltIn": "Use built-in Feishu issuer", "builtInSecret": "The server supplies the VPN Client Secret. Do not enter the Feishu App Secret here.", "builtInGatewayPending": "The public Nginx route for the built-in issuer is pending; sync it in Settings before testing.",
|
||
"issuer": "OIDC issuer URL",
|
||
"issuerTip": "Use an HTTPS issuer that provides standard discovery (/.well-known/openid-configuration) and ID tokens, not an authorization page URL.",
|
||
"clientId": "OIDC Client ID",
|
||
"clientIdTip": "Get the credentials from the provider named by the issuer. With a broker, create a VPN client in the broker; the Feishu App ID/Secret belong in its upstream Feishu configuration.",
|
||
"clientSecret": "OIDC Client Secret",
|
||
"copySecret": "Copy from the OIDC provider; hidden after saving",
|
||
"keepSecret": "Leave blank to retain current secret",
|
||
"secretTip": "Encrypted server-side and stored only in the auth service's 0600 configuration file.",
|
||
"baseUrl": "Public sign-in URL",
|
||
"baseTip": "Automatic filling reuses the domain and certificate only. The management site does not yet proxy OAuth2 paths to the auth component. Sign-in needs that Nginx route. Recheck saved tunnel callbacks if the domain changes.",
|
||
"builtinBaseTip": "Uses the system HTTPS domain automatically. The auth component listens locally; sync public routes in Settings after starting the tunnel.",
|
||
"reuseDomain": "Use current public domain", "linkedDomain": "Using the HTTPS domain from system settings; you can edit it.",
|
||
"listenPort": "Local auth service port",
|
||
"portTip": "Listens only on 127.0.0.1; no public access needed. New tunnels increment from 19090; +/- and manual entry skip configured and locally occupied ports.",
|
||
"portLookupFailed": "Could not find an available port. Retry or enter one manually.",
|
||
"callbackTitle": "Register this callback with the final OIDC provider",
|
||
"callbackTip": "With an identity broker, register this URL in the broker's OIDC client, and register the broker's upstream callback in Feishu. Reverse proxy the public endpoint to 127.0.0.1:{port}; :18080 does not handle this callback.",
|
||
"builtinCallbackTitle": "The VPN client and Feishu app use different callbacks", "builtinCallbackTip": "The VPN client callback above is handled by openvpn-auth-oauth2. Register only the Feishu app callback below in Feishu. After starting the tunnel, sync /oauth2/ to local port 127.0.0.1:{port} in Settings.", "feishuCallbackLabel": "Feishu app callback",
|
||
"testTip": "Install openvpn-auth-oauth2 and OpenVPN ≥ 2.6.2, then test with a WebAuth-capable client (e.g. OpenVPN Community for Windows or Tunnelblick/Viscosity for macOS). OpenVPN Connect v3 needs individual testing.",
|
||
"startFailed": "Configuration generated, but the tunnel did not start. Resolve the error below and retry from the tunnel list.",
|
||
"fillRequired": "Configure an identity source, OIDC issuer, VPN client credentials, and public sign-in URL"
|
||
},
|
||
"tunnelEditor": {
|
||
"title": "Edit Tunnel",
|
||
"backToList": "Back to List",
|
||
"sensitiveFieldHint": "Sensitive fields like passwords, PSK, and tokens are not displayed. Leave empty to keep the current value.",
|
||
"tunnelName": "Tunnel Name",
|
||
"protocolType": "Protocol Type",
|
||
"coreOptions": "Core Connection Settings",
|
||
"advancedOptions": "Detailed Settings",
|
||
"trafficMode": "Traffic Egress",
|
||
"trafficGateway": "All Traffic via VPN Gateway",
|
||
"trafficStatic": "Static Routes Only",
|
||
"trafficCustom": "Custom",
|
||
"trafficGatewayTip": "Routes all client traffic through the VPN gateway with NAT egress.",
|
||
"trafficStaticTip": "Pushes only the target networks below and preserves the client's default Internet route.",
|
||
"trafficCustomTip": "Control the default route, static routes, and NAT separately in detailed settings.",
|
||
"keepOriginal": "Leave empty to keep original",
|
||
"expireTime": "Expiry Time",
|
||
"expirePlaceholder": "Leave empty for permanent",
|
||
"autoStart": "Auto Start",
|
||
"saveConfig": "Save Configuration",
|
||
"loadFailed": "Failed to load tunnel",
|
||
"fillName": "Please enter tunnel name",
|
||
"configSaved": "Configuration saved"
|
||
},
|
||
"tunnelWizard": {
|
||
"step1": "Select Protocol",
|
||
"step2": "Fill Parameters",
|
||
"step3": "Generate Config",
|
||
"recommend": "Recommended",
|
||
"depReady": "✓ Dependencies Ready",
|
||
"notDeployed": "Not Deployed",
|
||
"oneClickInstall": "One-Click Install",
|
||
"onDemandHint": "Dependencies are checked without installing anything. Choose a protocol, then install only that protocol's missing dependencies from its card.",
|
||
"installCmd": "Install Command",
|
||
"customPlugin": "Custom Protocol Plugin",
|
||
"customScene": "Custom Integration",
|
||
"tunnelName": "Tunnel Name",
|
||
"namePlaceholder": "e.g., HQ-Branch Interconnect",
|
||
"protocolType": "Protocol Type",
|
||
"reselect": "Reselect",
|
||
"coreOptions": "Core Connection Settings",
|
||
"trafficMode": "Traffic Egress",
|
||
"trafficGateway": "All Traffic via VPN Gateway",
|
||
"trafficStatic": "Static Routes Only",
|
||
"trafficCustom": "Custom",
|
||
"trafficGatewayTip": "Routes all client traffic through the VPN gateway with NAT egress.",
|
||
"trafficStaticTip": "Pushes only the target networks below and preserves the client's default Internet route.",
|
||
"trafficCustomTip": "Control the default route, static routes, and NAT separately in detailed settings.",
|
||
"advancedOptions": "Advanced Options",
|
||
"expireTime": "Expiry Time",
|
||
"expirePlaceholder": "Leave empty for permanent",
|
||
"autoStartAfterCreate": "Auto-start after creation",
|
||
"previousStep": "Previous",
|
||
"generateConfig": "Generate Config",
|
||
"createSuccess": "Tunnel Created Successfully",
|
||
"configGenerated": "\"{name}\" configuration has been generated",
|
||
"clientConfig": "Client Configuration",
|
||
"downloadConfigFile": "Download Config File",
|
||
"showQrCode": "Show QR Code",
|
||
"goIpsecPeer": "Go to IPSec Peer Page",
|
||
"backToList": "Back to List",
|
||
"installCmdTitle": "{name} Install Command",
|
||
"pkgManagerDetected": "System package manager detected: {pm}. Recommended command below.",
|
||
"noPkgManager": "No system package manager detected. Install commands for various platforms below.",
|
||
"aptDefault": "apt (default)",
|
||
"recommended": "Recommended",
|
||
"copyThisCmd": "Copy This Command",
|
||
"otherDistros": "Other Distros",
|
||
"fillName": "Please enter tunnel name",
|
||
"fillRequired": "Please fill in required field: {label}",
|
||
"createFailed": "Creation failed",
|
||
"installSuccess": "{protocol} {version} installed successfully {method}",
|
||
"methodPackageManager": "(Package Manager)",
|
||
"methodDownload": "(One-Click Install)",
|
||
"installFailed": "Failed to install {protocol}"
|
||
},
|
||
"users": {
|
||
"title": "User Management",
|
||
"clientLoginHint": "These accounts sign in to the admin console. Desktop VPN clients use VPN dial-in users assigned to a WireGuard line.",
|
||
"batchImport": "Batch Import",
|
||
"ldapImport": "LDAP Import",
|
||
"addUser": "Add User",
|
||
"role": "Role",
|
||
"roleAdmin": "Admin",
|
||
"roleOperator": "Operator",
|
||
"roleViewer": "Viewer",
|
||
"noUsers": "No users yet",
|
||
"ldapTitle": "LDAP / Active Directory",
|
||
"ldapHint": "LDAP users can be auto-synced on first login, or pre-imported using the \"LDAP Import\" on the left.",
|
||
"ldapConfigHint": "Configure an LDAP server for centralized identity authentication",
|
||
"ldapEnabled": "Enable LDAP",
|
||
"ldapServerAddress": "LDAP Server Address",
|
||
"ldapServerAddressPlaceholder": "e.g. 8.217.205.92 or ldap.example.com",
|
||
"ldapPort": "Port",
|
||
"ldapProtocol": "Protocol",
|
||
"ldapProtocolLDAPS": "LDAPS (Recommended)",
|
||
"ldapProtocolLDAP": "LDAP",
|
||
"bindDn": "Administrator Bind DN",
|
||
"bindPassword": "Administrator Password",
|
||
"keepOriginal": "Leave empty to keep original",
|
||
"baseDn": "Base DN (User Search Base)",
|
||
"userFilter": "Search Filter (optional; %s is the username)",
|
||
"enableLdaps": "Enable LDAPS (SSL encryption)",
|
||
"usernameAttr": "Username Attribute",
|
||
"testConnection": "Test Connection",
|
||
"editUser": "Edit User",
|
||
"loginUsername": "Login username",
|
||
"keepUnchanged": "Leave empty to keep unchanged",
|
||
"min8Chars": "At least 8 characters",
|
||
"batchImportTitle": "Batch Import Users",
|
||
"batchHint": "One user per line: username,password or just username (auto-generates password). Password must be at least 8 characters.",
|
||
"batchPlaceholder": "One per line: username,password (e.g., user1,Pass1234); or username only for auto-generated password",
|
||
"defaultRole": "Default Role",
|
||
"startImport": "Start Import",
|
||
"ldapImportTitle": "Import Users from LDAP",
|
||
"ldapNotEnabled": "LDAP is not enabled. Please configure and test the connection on the right.",
|
||
"refreshUserList": "Refresh User List",
|
||
"userCount": "{count} users total, {selected} selected",
|
||
"fullName": "Name",
|
||
"imported": "Imported",
|
||
"pendingImport": "Pending",
|
||
"clickRefreshHint": "Click refresh above to load LDAP users",
|
||
"ldapDisabled": "LDAP is not enabled",
|
||
"importSelected": "Import Selected ({count})",
|
||
"updated": "Updated",
|
||
"fillUsername": "Please enter username",
|
||
"passwordMin8": "Password must be at least 8 characters",
|
||
"userCreated": "User created",
|
||
"deleteUserConfirm": "Delete user \"{username}\"?",
|
||
"enterAtLeastOne": "Please enter at least one line of user data",
|
||
"importResult": "Success: {success}, Skipped: {skipped}, Failed: {failed}",
|
||
"importResultTitle": "Import Result",
|
||
"importFailed": "Import failed",
|
||
"ldapLoadFailed": "LDAP load failed",
|
||
"ldapConfigSaved": "LDAP configuration saved",
|
||
"ldapConnected": "LDAP connection successful",
|
||
"ldapTestRequired": "Test the LDAP connection successfully before saving",
|
||
"ldapConnectFailed": "Connection failed",
|
||
"emptyUsername": "(empty)",
|
||
"errorDetails": "Error details:"
|
||
},
|
||
"clientDevices": {
|
||
"title": "Client Devices",
|
||
"hint": "Devices registered by desktop/mobile clients; revocation takes effect immediately",
|
||
"deviceName": "Device",
|
||
"platform": "Platform",
|
||
"tunnel": "Line",
|
||
"address": "Assigned IP",
|
||
"lastHandshake": "Last Handshake",
|
||
"revoked": "Revoked",
|
||
"revoke": "Revoke",
|
||
"revokeConfirm": "The device will be disconnected immediately and cannot reconnect. Continue?",
|
||
"revokeDone": "Device revoked",
|
||
"empty": "No client devices registered"
|
||
},
|
||
"vpnUsers": {
|
||
"title": "VPN Dial-in Users",
|
||
"mfaHint": "OpenVPN Two-Factor Auth (TOTP / Static Challenge / PIN+OTP)",
|
||
"addUser": "Add User",
|
||
"bulkImport": "Bulk Import",
|
||
"bulkImportTitle": "Import Platform Users",
|
||
"bulkImportHint": "Only OpenVPN supports platform local or LDAP account imports. Create dedicated accounts for L2TP/IKEv2.",
|
||
"importSelected": "Import Selected",
|
||
"importedCount": "Imported {count} users",
|
||
"importFailed": "Bulk import failed",
|
||
"selectOpenVPNTunnel": "Select OpenVPN Tunnel",
|
||
"selectTunnelAndUsers": "Select an OpenVPN tunnel and platform users",
|
||
"searchPlaceholder": "Search username, name, or email",
|
||
"allTunnels": "All Tunnels",
|
||
"selectedUsers": "{count} users selected",
|
||
"batchDelete": "Bulk Delete",
|
||
"batchDeleteConfirm": "Delete the selected {count} VPN dial-in users?",
|
||
"batchDeleteDone": "Selected VPN dial-in users deleted",
|
||
"displayName": "Name",
|
||
"tunnel": "Tunnel",
|
||
"otpMfa": "OTP / MFA",
|
||
"bound": "Bound",
|
||
"unbound": "Unbound",
|
||
"locked": "Locked",
|
||
"lastOnline": "Last Online",
|
||
"downloadConfig": "Download Config",
|
||
"otpManagement": "OTP Management",
|
||
"addVpnUserTitle": "Add VPN Dial-in User",
|
||
"dialTunnel": "Dial-in Tunnel",
|
||
"pickFromUsers": "Pick from Users",
|
||
"displayNameLabel": "Display Name",
|
||
"authSource": "Auth Source",
|
||
"min8Chars": "At least 8 characters",
|
||
"ldapDn": "LDAP DN",
|
||
"create": "Create",
|
||
"pickUserTitle": "Select Platform User",
|
||
"noPlatformUsers": "No platform users",
|
||
"clickRowHint": "Click a row to select and auto-fill",
|
||
"otpDialogTitle": "Two-Factor Auth — {username}",
|
||
"otpHint": "TOTP-based two-factor authentication (SHA1 / base32 / 30s / 6 digits), compatible with major Authenticator apps. Supports static challenge and PIN+OTP combo mode.",
|
||
"mfaNotEnabled": "Two-factor authentication is not enabled",
|
||
"mfaDisabledHint": "Bind an Authenticator app to require a one-time code when this user signs in to VPN.",
|
||
"mfaEnabledHint": "This user must provide both their password and a one-time code to sign in to VPN.",
|
||
"mfaSetupIntro": "Bind an Authenticator app to protect this user's VPN dial-in access.",
|
||
"manualSetup": "Can't scan? Use a manual key",
|
||
"verifySetup": "Confirm Binding",
|
||
"verifySetupHint": "After scanning in Authenticator, enter the current 6-digit code to verify the binding.",
|
||
"securityDetails": "Security Details",
|
||
"bindStatus": "Bind Status",
|
||
"boundTotp": "TOTP Bound",
|
||
"staticPin": "Static PIN",
|
||
"pinSet": "Set",
|
||
"pinNotSet": "Not Set",
|
||
"failCount": "Fail Count",
|
||
"lockStatus": "Lock",
|
||
"lockedUntil": "Yes (until {time})",
|
||
"lastOtpSuccess": "Last OTP Success",
|
||
"compatible": "Compatible",
|
||
"totpCompatible": "TOTP standard (compatible with Google/Microsoft Authenticator)",
|
||
"bindAuthenticator": "Bind Authenticator",
|
||
"disableMfa": "Disable MFA",
|
||
"regenBackupCodes": "Regenerate Backup Codes",
|
||
"setClearPin": "Set / Clear PIN",
|
||
"unlock": "Unlock",
|
||
"exportKeys": "Export Keys",
|
||
"scanHint": "Scan with Google Authenticator / Microsoft Authenticator / FreeOTP",
|
||
"base32Key": "Base32 key: {key}",
|
||
"input6DigitCode": "Enter 6-digit code to confirm binding",
|
||
"verifyAndEnable": "Verify & Enable",
|
||
"clientConnectHint": "Client connection: enter login password in the password field, enter 6-digit TOTP code as the second factor (if PIN is set, enter PIN+code, e.g., 1234123456). You can also append the 6-digit code directly to the password.",
|
||
"setPinTitle": "Set Static PIN",
|
||
"pinHint": "Second factor requires PIN + 6-digit TOTP code (concatenated without spaces). Leave empty to clear the PIN.",
|
||
"pinPlaceholder": "4-32 digit PIN, leave empty to clear",
|
||
"userFilled": "Filled user \"{username}\" info",
|
||
"vpnUserCreated": "VPN dial-in user created",
|
||
"createFailed": "Creation failed",
|
||
"downloadFailed": "Download failed",
|
||
"mfaSetupFailed": "Unable to start MFA setup",
|
||
"inputCode": "Please enter verification code",
|
||
"mfaEnabledMsg": "Two-factor authentication enabled.\n\nOne-time backup codes (save these — used when you lose your phone):\n{codes}\n\nClient connection: enter login password in the password field, enter 6-digit TOTP code as the second factor (if PIN is set, enter PIN+code).",
|
||
"bindSuccess": "Binding Successful",
|
||
"verifyFailed": "Verification failed",
|
||
"disableMfaConfirm": "Disable MFA for {username}?",
|
||
"mfaClosed": "MFA disabled",
|
||
"backupCodesTitle": "Backup Codes",
|
||
"newBackupCodes": "New backup codes (old codes invalidated):\n\n{codes}",
|
||
"generateFailed": "Generation failed",
|
||
"pinSetSuccess": "PIN set",
|
||
"pinCleared": "PIN cleared",
|
||
"unlocked": "Unlocked",
|
||
"unlockFailed": "Unlock failed",
|
||
"exportKeysTitle": "Export Keys",
|
||
"otpSecretsMsg": "TOTP key line (sensitive — do not share):\n\n{line}\n\nFormat: {format}",
|
||
"exportFailed": "Export failed",
|
||
"deleteVpnUserConfirm": "Delete VPN dial-in user {username}?"
|
||
},
|
||
"sessions": {
|
||
"title": "Online Sessions",
|
||
"onlineCount": "{count} online",
|
||
"publicAddress": "Public Address",
|
||
"vpnIp": "VPN IP",
|
||
"connectedDuration": "Duration",
|
||
"kickOffline": "Kick",
|
||
"noOnlineUsers": "No online users",
|
||
"identityUnknown": "Identity unknown",
|
||
"trafficAlert": "⚠ Abnormal Traffic Alert",
|
||
"userTunnel": "User/Tunnel",
|
||
"alertType": "Type",
|
||
"rateAlert": "Traffic Burst",
|
||
"quotaExceed": "Quota Exceeded",
|
||
"auditLog": "Connection Audit Log",
|
||
"event": "Event",
|
||
"eventConnect": "Connect",
|
||
"eventDisconnect": "Disconnect",
|
||
"eventAuthFail": "Auth Failed",
|
||
"eventQuotaExceed": "Quota Exceeded",
|
||
"eventRateAlert": "Traffic Burst",
|
||
"seconds": "{n}s",
|
||
"minutes": "{n}m",
|
||
"hoursMinutes": "{h}h {m}m",
|
||
"loadDataFailed": "Failed to load data",
|
||
"kickConfirm": "Kick user \"{username}\" offline?",
|
||
"kicked": "User kicked offline"
|
||
},
|
||
"logs": {
|
||
"auditTitle": "Audit Logs",
|
||
"connTitle": "Connection Logs",
|
||
"alertTitle": "Traffic Alerts",
|
||
"statsTitle": "Log Statistics",
|
||
"keywordPlaceholder": "Search target/detail",
|
||
"startDate": "Start Date",
|
||
"endDate": "End Date",
|
||
"exportCsv": "Export CSV",
|
||
"exportFailed": "Could not export logs. Please retry.",
|
||
"eventType": "Event Type",
|
||
"tunnelId": "Tunnel ID",
|
||
"auditCount": "Audit Logs",
|
||
"connCount": "Connection Logs",
|
||
"sessionCount": "Sessions",
|
||
"from": "From",
|
||
"cleanup": "Cleanup Logs",
|
||
"cleanupHint": "Delete log data older than specified days",
|
||
"cleanupPrompt": "Keep logs from the last how many days?",
|
||
"cleanupInputError": "Please enter a positive integer",
|
||
"cleanupDone": "Cleanup done: {audit} audit, {conn} connection, {session} session records deleted",
|
||
"loadFailed": "Failed to load logs",
|
||
"noAlerts": "No traffic alerts"
|
||
},
|
||
"identity": {
|
||
"tab": "Feishu identity", "title": "Built-in Feishu identity service", "description": "Issue OIDC identities for VPN using your existing HTTPS domain. Feishu app credentials stay upstream; this platform creates separate VPN client credentials.",
|
||
"guideTitle": "Feishu app setup", "guideApp": "Enter the enterprise app ID and secret; enable both permissions below.", "guidePermission": "", "guidePublish": "Publish the app and include VPN users in its availability scope.", "guideCallback": "Security Settings → Redirect URL:", "guideCallbackPending": "Configure an HTTPS domain first.", "guideVerify": "", "guideManual": "", "guideScope": "",
|
||
"tenantPermission": "tenant:tenant:readonly · enterprise", "userPermission": "contact:user.base:readonly · user", "checking": "Checking", "checked": "Verified", "checkFailed": "Check failed", "checkPending": "Not checked", "checkedByLogin": "Login verified", "loginPending": "Verify on first login",
|
||
"appId": "Feishu App ID", "appSecret": "Feishu App Secret", "secretPlaceholder": "Leave blank if saved; enter a new secret to rotate", "tenant": "Allowed Feishu tenant_key", "tenantPlaceholder": "Fetched automatically or enter manually", "fetchTenant": "Check again", "fetchingTenant": "Checking ({seconds}s)…", "tenantFetched": "Enterprise permission verified", "tenantFailed": "Enterprise permission check failed", "tenantNotEnabled": "", "enabled": "Enable built-in issuer", "httpsOnly": "Use HTTPS to enter app credentials.", "openHttps": "Open HTTPS management site",
|
||
"httpsRequired": "Configure and activate your public HTTPS site and certificate first.", "gatewayPending": "The identity provider is saved but Nginx does not yet route /id/; sync the gateway.",
|
||
"addresses": "Addresses and client credentials", "issuer": "OIDC issuer", "feishuCallback": "Callback registered in Feishu", "vpnCallback": "VPN client callback", "clientId": "VPN Client ID",
|
||
"oneTimeSecret": "New VPN Client Secret is displayed only once. Store it safely; rotation of active tunnel credentials requires separate planning.", "routeHint": "Sync identity routes first. After starting the one OpenVPN OIDC tunnel using this domain, sync again to route /oauth2/ to its local auth component.",
|
||
"syncGateway": "Sync identity gateway", "gatewaySynced": "Gateway routes updated", "gatewayFailed": "Gateway update failed", "loadFailed": "Could not load identity settings", "saved": "Identity settings saved", "saveFailed": "Could not save identity settings"
|
||
},
|
||
"settings": {
|
||
"pageDescription": "Manage account security, the public gateway, and server setup.",
|
||
"securityTab": "Account Security", "gatewayTab": "Public Gateway", "hostTab": "Server Setup",
|
||
"mustChangePassword": "First login or password has been reset by admin. You must change your password before using other features.",
|
||
"changePassword": "Change Password",
|
||
"oldPassword": "Current Password",
|
||
"newPassword": "New Password",
|
||
"min8Chars": "At least 8 characters",
|
||
"confirmNewPassword": "Confirm New Password",
|
||
"change": "Change",
|
||
"mfaTitle": "Two-Factor Authentication (MFA)",
|
||
"mfaHint": "Scan the QR code with Microsoft Authenticator, Google Authenticator, etc. Backup codes can be used to log in when you lose your phone.",
|
||
"setupMfa": "Set Up MFA",
|
||
"disableMfa": "Disable MFA",
|
||
"input6DigitCode": "Enter the 6-digit code from your app",
|
||
"verifyAndEnable": "Verify & Enable",
|
||
"deployTitle": "Deployment Info",
|
||
"deliveryForm": "Delivery",
|
||
"deliveryDesc": "Single binary (frontend embedded), no Docker required",
|
||
"dataDir": "Data Directory",
|
||
"dataDirDesc": "./data (override with VPN_DATA_DIR)",
|
||
"listenAddr": "Listen Address",
|
||
"listenAddrDesc": ":8080 (override with VPN_LISTEN_ADDR)",
|
||
"keyStorage": "Key Storage",
|
||
"keyStorageDesc": "PSK / Private keys encrypted with AES-GCM, config files with 0600 permissions",
|
||
"systemDeps": "System Dependencies",
|
||
"systemDepsDesc": "wireguard-tools / strongswan / xl2tpd / openvpn / frp",
|
||
"prodSuggestion": "Production Tip",
|
||
"prodSuggestionDesc": "Expose via Nginx/Caddy reverse proxy with TLS termination",
|
||
"auditTitle": "Audit Log (Latest 100)",
|
||
"auditMigrated": "Audit logs have been moved to Log Center with pagination, filtering, and CSV export",
|
||
"noAuditLogs": "No audit logs yet",
|
||
"mfaEnabledTitle": "MFA Enabled — Please Save Backup Codes",
|
||
"backupCodesHint": "These backup codes are shown only once. Use them to log in if you lose your phone. Copy and save them now!",
|
||
"copyAll": "Copy All",
|
||
"savedConfirm": "I've Saved Them",
|
||
"passwordMismatch": "New passwords do not match",
|
||
"passwordMin8": "New password must be at least 8 characters",
|
||
"passwordChanged": "Password changed",
|
||
"changeFailed": "Change failed",
|
||
"setupFailed": "Setup failed",
|
||
"verifyFailed": "Verification failed",
|
||
"mfaClosed": "MFA disabled",
|
||
"closeFailed": "Disable failed",
|
||
"mustChangeHint": "First login or password has been reset. Please change your password first.",
|
||
"confirmChange": "Confirm Change",
|
||
"strength": "Strength: {level}",
|
||
"strengthVeryWeak": "Very Weak",
|
||
"strengthWeak": "Weak",
|
||
"strengthFair": "Fair",
|
||
"strengthStrong": "Strong",
|
||
"strengthVeryStrong": "Very Strong"
|
||
},
|
||
"plugins": {
|
||
"title": "Custom Protocol Plugins",
|
||
"registerPlugin": "Register Plugin",
|
||
"commandHooks": "command hooks",
|
||
"pluginHint": "Plugins implement the unified protocol contract via {hooks}: the platform pipes tunnel config JSON to hook commands via stdin.",
|
||
"pluginContract": "Contract: {contract}; Status hook outputs {running} or {stopped} on stdout; Config hook outputs client config text.",
|
||
"protocolId": "Protocol ID",
|
||
"enabled": "Enabled",
|
||
"disabled": "Disabled",
|
||
"noPlugins": "No custom protocol plugins yet",
|
||
"editPlugin": "Edit Plugin",
|
||
"registerPluginTitle": "Register Protocol Plugin",
|
||
"protocolIdPlaceholder": "e.g., myproto (alphanumeric)",
|
||
"displayName": "Display Name",
|
||
"optional": "Optional",
|
||
"protocolIdRequired": "Protocol ID and Start hook are required"
|
||
},
|
||
"nodes": {
|
||
"title": "Node Management",
|
||
"addNode": "Add Node",
|
||
"nodeHint": "Nodes are used to deploy tunnels to relay servers. The local node is the built-in default; remote nodes support SSH credential verification (password/private key). Verified nodes show \"Verified\" status.",
|
||
"type": "Type",
|
||
"typeLocal": "Local",
|
||
"typeRemote": "Remote",
|
||
"sshUser": "SSH User",
|
||
"authMethod": "Auth Method",
|
||
"authPassword": "Password",
|
||
"authKey": "Private Key",
|
||
"statusReady": "Ready",
|
||
"statusVerified": "Verified",
|
||
"statusFailed": "Failed",
|
||
"statusUnverified": "Unverified",
|
||
"verify": "Verify",
|
||
"noNodes": "No remote nodes yet. Click the button above to add one.",
|
||
"editNode": "Edit Node",
|
||
"namePlaceholder": "e.g., Beijing Relay Node",
|
||
"addressPlaceholder": "IP or domain, e.g., 192.168.1.100",
|
||
"sshPort": "SSH Port",
|
||
"remoteNode": "Remote Node",
|
||
"localNode": "Local Node",
|
||
"defaultRoot": "Default: root",
|
||
"keepUnchanged": "Leave empty to keep unchanged",
|
||
"sshPasswordPlaceholder": "SSH login password",
|
||
"privateKeyPlaceholder": "Paste OpenSSH/PEM format private key",
|
||
"testConnection": "Test Connection",
|
||
"determine": "OK",
|
||
"fillAddressFirst": "Please enter the address first",
|
||
"requestFailed": "Request failed",
|
||
"fillNameAndAddress": "Please enter name and address",
|
||
"added": "Added",
|
||
"updated": "Updated",
|
||
"verifySuccess": "Verification successful: {msg}",
|
||
"verifyFailed": "Verification failed: {msg}",
|
||
"deleteNodeConfirm": "Delete node \"{name}\"? This action cannot be undone."
|
||
},
|
||
"notFound": {
|
||
"title": "404",
|
||
"subtitle": "The page you visited does not exist or has been removed",
|
||
"backHome": "Back to Home"
|
||
},
|
||
"mfaVerify": {
|
||
"title": "Two-Factor Authentication",
|
||
"hint": "Enter the 6-digit code from your Authenticator app",
|
||
"verifyAndLogin": "Verify & Login",
|
||
"backToLogin": "Back to Login",
|
||
"inputFullCode": "Please enter the full 6-digit code",
|
||
"sessionExpired": "Login session expired. Please log in again.",
|
||
"verifySuccess": "Verification successful",
|
||
"codeError": "Incorrect code. Please try again."
|
||
},
|
||
"ipsecPeer": {
|
||
"localParams": "Local IPSec Parameters",
|
||
"loadTemplate": "Load Device Template",
|
||
"localPublicIp": "Local Public IP",
|
||
"remoteGateway": "Remote Gateway",
|
||
"localSubnets": "Local Subnets",
|
||
"remoteSubnets": "Remote Subnets",
|
||
"psk": "Pre-Shared Key",
|
||
"phase1": "Phase 1 (IKE SA)",
|
||
"ikeVersion": "IKE Version",
|
||
"proposal": "Proposal",
|
||
"localId": "Local ID",
|
||
"remoteId": "Remote ID",
|
||
"phase2": "Phase 2 (IPSec SA)",
|
||
"espProposal": "ESP Proposal",
|
||
"pfsGroup": "PFS Group",
|
||
"dpdPolicy": "DPD Policy",
|
||
"dpdRestart": "restart (reconnect on disconnect)",
|
||
"dpdClear": "clear (remove SA)",
|
||
"dpdTrap": "trap (trigger on demand)",
|
||
"createIpsecTunnel": "Create IPSec Tunnel",
|
||
"paramConsistency": "Parameter Consistency Check",
|
||
"peerIkeVersion": "Peer IKE Version",
|
||
"peerPhase1": "Peer Phase 1",
|
||
"peerPhase2": "Peer Phase 2",
|
||
"peerPfsGroup": "Peer PFS Group",
|
||
"peerLocalSubnets": "Peer Local Subnets",
|
||
"peerIkePlaceholder": "Peer's IKE proposal",
|
||
"peerEspPlaceholder": "Peer's ESP proposal",
|
||
"peerSubnetsPlaceholder": "Peer's local (= your remote)",
|
||
"startCompare": "Start Comparison",
|
||
"paramsConsistent": "Parameters are consistent. Tunnel can be established.",
|
||
"paramsInconsistent": "Parameter inconsistencies found:",
|
||
"connectivityTest": "One-Click Connectivity Test",
|
||
"selectIpsecTunnel": "Select an existing IPSec tunnel",
|
||
"testConnectivity": "Test connectivity to remote gateway",
|
||
"reachable": "Reachable",
|
||
"unreachable": "Unreachable",
|
||
"latency": "Latency",
|
||
"templateLoaded": "Loaded \"{name}\" template: {note}",
|
||
"fillRequiredFields": "Please fill in all required fields (gateway/subnets/PSK)",
|
||
"ipsecCreated": "IPSec tunnel created and started",
|
||
"createFailed": "Creation failed",
|
||
"testFailed": "Test failed"
|
||
},
|
||
"router": {
|
||
"dashboard": "Dashboard",
|
||
"tunnels": "Tunnels",
|
||
"sessions": "Sessions",
|
||
"createTunnel": "Create Tunnel",
|
||
"editTunnel": "Edit Tunnel",
|
||
"ipsecPeer": "IPSec Peer Test",
|
||
"nodes": "Nodes",
|
||
"users": "Users",
|
||
"vpnUsers": "VPN Dial-in Users",
|
||
"clientDevices": "Client Devices",
|
||
"plugins": "Protocol Plugins",
|
||
"settings": "Settings",
|
||
"logs": "Log Center",
|
||
"notFound": "Page Not Found",
|
||
"sidebarOps": "Tunnel Ops",
|
||
"sidebarResource": "Identity & Devices",
|
||
"sidebarSystem": "System",
|
||
"sidebarWorkspace": "Workspace", "console": "Admin Console",
|
||
"navigation": "Main navigation", "openNavigation": "Open navigation", "closeNavigation": "Close navigation",
|
||
"collapseNavigation": "Collapse sidebar", "expandNavigation": "Expand sidebar"
|
||
},
|
||
"protocolIcon": {
|
||
"custom": "Custom Protocol"
|
||
},
|
||
"tls": {
|
||
"title": "Domain & certificate",
|
||
"description": "Configure a public domain and use Nginx / Certbot for HTTP-01 issuance and renewal.",
|
||
"domain": "Configured domain", "activeDomain": "Active domain", "saveDomain": "Save domain", "restartRequired": "Domain saved; restart OpsX VPN to enable ports 80/443 and automatic issuance", "saveFailed": "Could not save domain", "dns": "DNS", "certificate": "Certificate", "valid": "Valid", "pending": "Pending first HTTPS handshake",
|
||
"notConfigured": "Disabled", "saved": "Domain configuration saved", "issuer": "Issuer", "expires": "Expires", "renewal": "Renewal", "automatic": "Automatic (autocert)",
|
||
"ports": "HTTP / HTTPS ports", "externalPorts": "Managed by external Nginx; listener status not checked", "setupHint": "Restart to apply a saved domain or mode. Before switching to Nginx, follow the deployment guide to install it, issue a certificate, and validate the configuration. Go mode caches certificates in data/acme; saving settings alone does not issue 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",
|
||
"nginxHint": "Save the Nginx mode and domain, restart the service, then enable the site and request a certificate. Public ports 80/443 must be open.",
|
||
"externalRenewal": "Managed by Certbot", "previewNginx": "Preview Nginx configuration", "previewOnly": "Configuration preview; HTTP handles issuance and HTTPS starts after the certificate exists.", "httpSite": "HTTP-01 site", "httpsSite": "HTTPS management site",
|
||
"siteStage": "Site stage", "stage_none": "Inactive", "stage_http": "HTTP-01 ready; certificate pending", "stage_https": "HTTPS configuration enabled", "activateSite": "Enable site and issue certificate", "activateHint": "Checks existing sites and ports first. Certbot registration uses no email address, so renewal failures cannot be reported by email.", "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", "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.", "setupButton": "Prepare Nginx / Certbot", "setupComplete": "Dependencies are ready; configure the site and certificate next", "setupFailed": "Initialization failed; inspect the output", "setupInterrupted": "Log connection interrupted; refresh status. Installation may still be running on the server",
|
||
"commonSetupTitle": "First-time shared network setup", "commonSetupHint": "Check permissions, default route and IPv4 forwarding. Enable shared forwarding only when needed; install protocol-specific dependencies separately in Create Tunnel.", "hostRoot": "Privileges", "hostRoute": "Default route", "hostForward": "IPv4 forwarding", "enableForwarding": "Enable IPv4 forwarding", "forwardingEnabled": "IPv4 forwarding enabled"
|
||
},
|
||
"protocols": {
|
||
"wireguard": {
|
||
"name": "WireGuard",
|
||
"desc": "High-performance modern VPN with kernel-level implementation, roaming-friendly",
|
||
"scenes": "Internal Access / Mobile Office",
|
||
"fields": {
|
||
"address": {
|
||
"label": "Server VPN Subnet Address",
|
||
"tip": "Server's address within the VPN subnet (CIDR)"
|
||
},
|
||
"auth_mode": {
|
||
"label": "Client Authentication",
|
||
"tip": "Account login grants a device; the tunnel uses key authentication. Static peers still connect by key. Browser OIDC requires a client callback and explicit user grants.",
|
||
"options": {
|
||
"password": "Client account + device key",
|
||
"oidc": "Third-party OAuth2 / OIDC (not available yet)"
|
||
}
|
||
},
|
||
"listen_port": {
|
||
"label": "Listen Port"
|
||
},
|
||
"client_address": {
|
||
"label": "First Client Address",
|
||
"tip": "Add more peers in the detail page after creation"
|
||
},
|
||
"public_endpoint": {
|
||
"label": "Public Endpoint",
|
||
"tip": "For client connections — public IP:port"
|
||
},
|
||
"dns": {
|
||
"label": "DNS"
|
||
},
|
||
"allowed_ips": {
|
||
"label": "Client AllowedIPs",
|
||
"tip": "Use 0.0.0.0/0 for full tunnel; specify internal CIDRs for split tunnel"
|
||
},
|
||
"latency_probe": {
|
||
"label": "Tunnel probe target",
|
||
"tip": "Reachable IP:port through this line, e.g. 10.88.0.1:22; defaults to 223.5.5.5:443. Measures TCP setup time."
|
||
},
|
||
"keepalive": {
|
||
"label": "Keepalive (sec)",
|
||
"tip": "Recommended 15–25 for clients behind NAT"
|
||
},
|
||
"mtu": {
|
||
"label": "MTU",
|
||
"tip": "0 for default; common range 1280–1420 over public networks"
|
||
},
|
||
"enable_nat": {
|
||
"label": "Enable NAT Outbound",
|
||
"tip": "Enable when clients need internet or other subnet access"
|
||
},
|
||
"egress_interface": {
|
||
"label": "NAT Egress Interface",
|
||
"tip": "Leave empty to auto-detect the default route interface"
|
||
}
|
||
}
|
||
},
|
||
"ipsec": {
|
||
"name": "IPSec Site-to-Site",
|
||
"desc": "Site-to-site connectivity with third-party devices (Cisco/Huawei/FortiGate, etc.)",
|
||
"scenes": "Third-Party Integration / Site-to-Site",
|
||
"fields": {
|
||
"vendor_template": {
|
||
"label": "Vendor Template",
|
||
"tip": "Auto-fills Phase 1/Phase 2 proposals, still manually editable",
|
||
"options": {
|
||
"generic": "Generic Standard (Recommended)",
|
||
"cisco": "Cisco ISR/ASR",
|
||
"fortigate": "FortiGate",
|
||
"huawei": "Huawei USG/AR",
|
||
"h3c": "H3C"
|
||
}
|
||
},
|
||
"public_endpoint": {
|
||
"label": "Local Public IP"
|
||
},
|
||
"remote_gateway": {
|
||
"label": "Remote Gateway"
|
||
},
|
||
"local_subnets": {
|
||
"label": "Local Subnets",
|
||
"tip": "Separate multiple subnets with commas"
|
||
},
|
||
"remote_subnets": {
|
||
"label": "Remote Subnets"
|
||
},
|
||
"psk": {
|
||
"label": "Pre-Shared Key (PSK)"
|
||
},
|
||
"ike_version": {
|
||
"label": "IKE Version",
|
||
"options": {
|
||
"ikev2": "IKEv2",
|
||
"ikev1": "IKEv1"
|
||
}
|
||
},
|
||
"ike_proposal": {
|
||
"label": "Phase 1 Proposal",
|
||
"tip": "Encryption-Auth-DH group, must match remote side"
|
||
},
|
||
"esp_proposal": {
|
||
"label": "Phase 2 Proposal"
|
||
},
|
||
"pfs_group": {
|
||
"label": "PFS DH Group"
|
||
},
|
||
"ike_lifetime": {
|
||
"label": "IKE Lifetime (sec)"
|
||
},
|
||
"local_id": {
|
||
"label": "Local ID"
|
||
},
|
||
"remote_id": {
|
||
"label": "Remote ID"
|
||
}
|
||
}
|
||
},
|
||
"ikev2": {
|
||
"name": "IKEv2 Remote Access",
|
||
"desc": "Native VPN dial-in from phones and laptops, more modern than L2TP",
|
||
"scenes": "Remote Office / Native VPN",
|
||
"fields": {
|
||
"public_endpoint": {
|
||
"label": "Server Public Address"
|
||
},
|
||
"local_id": {
|
||
"label": "Server ID / Remote ID",
|
||
"tip": "Must match the client's Remote ID"
|
||
},
|
||
"psk": {
|
||
"label": "Machine Auth PSK",
|
||
"tip": "Leave empty to auto-generate; shared key for iOS/Android"
|
||
},
|
||
"address_pool": {
|
||
"label": "Client Address Pool"
|
||
},
|
||
"dns": {
|
||
"label": "Push DNS"
|
||
},
|
||
"local_ts": {
|
||
"label": "Allowed Subnets",
|
||
"tip": "0.0.0.0/0 for full tunnel; change to internal CIDR for split tunnel"
|
||
},
|
||
"ike_proposal": {
|
||
"label": "IKE Proposal"
|
||
},
|
||
"esp_proposal": {
|
||
"label": "ESP Proposal"
|
||
}
|
||
}
|
||
},
|
||
"l2tp": {
|
||
"name": "L2TP/IPSec",
|
||
"desc": "Best compatibility — natively supported by phones, legacy devices, and routers",
|
||
"scenes": "Mobile Devices / Legacy Compatibility",
|
||
"fields": {
|
||
"public_endpoint": {
|
||
"label": "Server Public IP"
|
||
},
|
||
"psk": {
|
||
"label": "IPSec Pre-Shared Key",
|
||
"tip": "Leave blank to generate a high-strength random key; retrieve it securely from client configuration after creation"
|
||
},
|
||
"ip_range": {
|
||
"label": "Client Address Pool"
|
||
},
|
||
"local_ip": {
|
||
"label": "Server Tunnel Address"
|
||
},
|
||
"dns": {
|
||
"label": "Push DNS"
|
||
}
|
||
}
|
||
},
|
||
"gre": {
|
||
"name": "GRE Tunnel",
|
||
"desc": "Standard IP protocol 47 tunnel for point-to-point Layer 3 connectivity between Linux, routers, and firewalls",
|
||
"scenes": "Network Device Interconnect / Site-to-Site Routing",
|
||
"fields": {
|
||
"local_endpoint": { "label": "Local Public IP" },
|
||
"remote_endpoint": { "label": "Remote Public IP" },
|
||
"local_tunnel_ip": { "label": "Local Tunnel IP", "tip": "Use a /30, for example 10.255.0.1/30" },
|
||
"remote_tunnel_ip": { "label": "Remote Tunnel IP", "tip": "Must share the local tunnel IP subnet" },
|
||
"remote_subnet": { "label": "Remote LAN Subnet", "tip": "Adds a static route through the GRE peer" },
|
||
"enable_nat": { "label": "NAT Remote Traffic", "tip": "Enable only when the remote subnet needs Internet egress via this host" },
|
||
"outbound_interface": { "label": "NAT Egress Interface" },
|
||
"ttl": { "label": "TTL" },
|
||
"mtu": { "label": "GRE MTU", "tip": "1476 is typical over public Internet GRE; lower it for additional encapsulation" }
|
||
}
|
||
},
|
||
"frp": {
|
||
"name": "FRP NAT Traversal",
|
||
"desc": "TCP/UDP/HTTP port forwarding and reverse proxy for NAT traversal",
|
||
"scenes": "NAT Traversal / Port Forwarding",
|
||
"fields": {
|
||
"mode": {
|
||
"label": "Mode",
|
||
"tip": "server = frps (public side), client = frpc (LAN side)",
|
||
"options": {
|
||
"server": "server (frps — public side)",
|
||
"client": "client (frpc — LAN side)"
|
||
}
|
||
},
|
||
"bind_port": {
|
||
"label": "Bind Port (server)"
|
||
},
|
||
"public_endpoint": {
|
||
"label": "Public Address (server)"
|
||
},
|
||
"dashboard_port": {
|
||
"label": "Dashboard Port (server)"
|
||
},
|
||
"dashboard_user": {
|
||
"label": "Dashboard User (server)"
|
||
},
|
||
"dashboard_password": {
|
||
"label": "Dashboard Password (server)",
|
||
"tip": "Auto-generates a strong password if left empty; keeps current password when editing"
|
||
},
|
||
"vhost_http_port": {
|
||
"label": "HTTP VHost Port",
|
||
"tip": "0 = disabled; must be >0 for HTTP proxying"
|
||
},
|
||
"vhost_https_port": {
|
||
"label": "HTTPS VHost Port",
|
||
"tip": "0 = disabled"
|
||
},
|
||
"allow_ports": {
|
||
"label": "Allowed Port Range",
|
||
"tip": "Restricts which remotePorts frpc can request"
|
||
},
|
||
"server_addr": {
|
||
"label": "frps Address (client)"
|
||
},
|
||
"server_port": {
|
||
"label": "frps Port (client)"
|
||
},
|
||
"token": {
|
||
"label": "Auth Token",
|
||
"tip": "Leave empty to auto-generate"
|
||
},
|
||
"proxy_name": {
|
||
"label": "Proxy Name"
|
||
},
|
||
"proxy_type": {
|
||
"label": "Proxy Type",
|
||
"options": {
|
||
"tcp": "TCP",
|
||
"udp": "UDP",
|
||
"http": "HTTP",
|
||
"https": "HTTPS",
|
||
"stcp": "STCP (Secure P2P)",
|
||
"xtcp": "XTCP (P2P)"
|
||
}
|
||
},
|
||
"local_ip": {
|
||
"label": "Local Target IP"
|
||
},
|
||
"local_port": {
|
||
"label": "Local Target Port"
|
||
},
|
||
"remote_port": {
|
||
"label": "Public Mapped Port"
|
||
},
|
||
"custom_domains": {
|
||
"label": "Custom Domains",
|
||
"tip": "Required for HTTP/HTTPS proxy"
|
||
},
|
||
"secret_key": {
|
||
"label": "STCP/XTCP Secret Key",
|
||
"tip": "Must match between visitor and server"
|
||
}
|
||
}
|
||
},
|
||
"openvpn": {
|
||
"name": "OpenVPN",
|
||
"desc": "Most mature open-source VPN, compatible with legacy systems and projects",
|
||
"scenes": "Legacy Compatibility / General Access",
|
||
"fields": {
|
||
"public_endpoint": {
|
||
"label": "Public Endpoint"
|
||
},
|
||
"port": {
|
||
"label": "Port"
|
||
},
|
||
"proto": {
|
||
"label": "Transport Protocol",
|
||
"tip": "Can be switched in edit mode; requires tunnel restart and client re-download",
|
||
"options": {
|
||
"udp": "UDP (Recommended, better performance)",
|
||
"tcp-server": "TCP (More stable through restrictive networks)"
|
||
}
|
||
},
|
||
"subnet": {
|
||
"label": "VPN Subnet",
|
||
"tip": "e.g., 10.8.0.0 255.255.240.0 for more clients (/20)"
|
||
},
|
||
"cipher": {
|
||
"label": "Cipher",
|
||
"options": {
|
||
"AES-256-GCM": "AES-256-GCM",
|
||
"AES-128-GCM": "AES-128-GCM",
|
||
"AES-256-CBC": "AES-256-CBC"
|
||
}
|
||
},
|
||
"auth_mode": {
|
||
"label": "Authentication Mode",
|
||
"tip": "Password mode aligns with verify-client-cert none + username-as-common-name",
|
||
"options": {
|
||
"certificate": "Certificate Only",
|
||
"password": "Username + Password",
|
||
"certificate+password": "Certificate + Password",
|
||
"oidc": "Third-party OAuth2 / OIDC (Feishu)"
|
||
}
|
||
},
|
||
"mfa_mode": {
|
||
"label": "Dial-in MFA (2FA)",
|
||
"tip": "static-challenge + TOTP; manage OTP in VPN Dial-in Users",
|
||
"options": {
|
||
"off": "Disabled",
|
||
"optional": "Optional (verified after user binds)",
|
||
"required": "Required (all dial-in users must use MFA)"
|
||
}
|
||
},
|
||
"otp_slop": {
|
||
"label": "OTP Clock Tolerance (sec)"
|
||
},
|
||
"otp_max_failures": {
|
||
"label": "OTP Lockout Threshold"
|
||
},
|
||
"otp_lockout_sec": {
|
||
"label": "OTP Lockout Duration (sec)"
|
||
},
|
||
"otp_disallow_reuse": {
|
||
"label": "Disallow OTP Reuse"
|
||
},
|
||
"dns": {
|
||
"label": "Push DNS"
|
||
},
|
||
"redirect_gateway": {
|
||
"label": "Full Tunnel",
|
||
"tip": "When off, only pushes internal routes below (common in production)"
|
||
},
|
||
"push_routes": {
|
||
"label": "Push Routes",
|
||
"tip": "One IP or CIDR per line; # comments are supported",
|
||
"placeholder": "# VPC networks\n172.16.0.0/16\n# Staging\n43.129.24.233",
|
||
"format_error": "Invalid route format: {route}"
|
||
},
|
||
"enable_nat": {
|
||
"label": "Enable NAT Outbound"
|
||
},
|
||
"max_clients": {
|
||
"label": "Max Clients",
|
||
"tip": "0 = unlimited; 1000 is common in production"
|
||
},
|
||
"keepalive_interval": {
|
||
"label": "Keepalive Interval",
|
||
"tip": "Production typical: keepalive 5 30"
|
||
},
|
||
"keepalive_timeout": {
|
||
"label": "Keepalive Timeout"
|
||
},
|
||
"tun_mtu": {
|
||
"label": "tun-mtu",
|
||
"tip": "Production typical: 1500"
|
||
},
|
||
"tun_mtu_extra": {
|
||
"label": "tun-mtu-extra"
|
||
},
|
||
"mssfix": {
|
||
"label": "mssfix",
|
||
"tip": "0 = unset; TCP production typical 1450; defaults to 1450 when TCP is selected"
|
||
},
|
||
"duplicate_cn": {
|
||
"label": "Allow duplicate-cn",
|
||
"tip": "Same username/cert on multiple devices simultaneously; auto-enabled in password mode"
|
||
},
|
||
"reneg_sec": {
|
||
"label": "reneg-sec",
|
||
"tip": "0 = disable TLS re-negotiation (recommended for production/MFA); cert-only default can be 3600"
|
||
},
|
||
"run_as_user": {
|
||
"label": "Drop Privileges User",
|
||
"tip": "Maps to 'user openvpn'; user must exist on the system; leave empty to run as root"
|
||
},
|
||
"run_as_group": {
|
||
"label": "Drop Privileges Group",
|
||
"tip": "Maps to 'group openvpn'"
|
||
}
|
||
}
|
||
},
|
||
"custom": {
|
||
"fields": {
|
||
"endpoint": {
|
||
"label": "Endpoint"
|
||
},
|
||
"token": {
|
||
"label": "Auth Credential"
|
||
},
|
||
"extra": {
|
||
"label": "Extra Parameters (JSON)"
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|