mirror of
https://github.com/MHSanaei/3x-ui.git
synced 2026-10-08 23:22:09 +03:00
feat(amneziawg): make the Xray TPROXY bridge a per-inbound opt-in
Addresses Finding 10 from the automated PR review: an always-on TPROXY bridge makes every AmneziaWG tunnel hard-depend on Xray being up (all traffic, including DNS, drops whenever Xray restarts), and forces a full awg-quick down+up bounce on any client add/remove/re-IP, permanently losing the syncconf fast path. Adds ServerSettings.RouteThroughXray (off by default): - defaultPostUpDown only emits the TPROXY/policy-route rules when it's on; a plain AmneziaWG tunnel now has zero Xray dependency out of the box. - structuralFingerprint covers it (toggling it changes whether PostUp/ PostDown contain any TPROXY rules at all -- structural, not a per-peer host-rule). hostRulesFingerprint's IPv4 tracking is now itself conditional on RouteThroughXray (and IPv6 tracking on IPv6Enabled), so an instance that never uses either keeps the syncconf fast path for a plain peer re-IP. - injectAmneziawgEgress only creates a bridge for inbounds that opted in; checkAmneziawgEgressConflict (the Finding-7 fix) now parses each candidate through InstanceFromInbound so a non-routed inbound's port is correctly never treated as reserved. - New inbound-level Switch in the AmneziaWG form; the actual outbound decision is still made entirely through the panel's stock Routing page, same as before -- only whether the bridge exists at all is now a choice. Translation keys added to all 13 locales in the same commit this time, not backfilled later (see Finding 9's lesson). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -666,6 +666,7 @@ export const EXAMPLES: Record<string, unknown> = {
|
||||
"primaryDns": "",
|
||||
"privateKey": "",
|
||||
"publicKey": "",
|
||||
"routeThroughXray": false,
|
||||
"s1": 0,
|
||||
"s2": 0,
|
||||
"s3": 0,
|
||||
|
||||
@@ -2836,6 +2836,10 @@ export const SCHEMAS: Record<string, unknown> = {
|
||||
"publicKey": {
|
||||
"type": "string"
|
||||
},
|
||||
"routeThroughXray": {
|
||||
"description": "RouteThroughXray turns on this inbound's TPROXY-into-Xray bridge; see\nInstance.RouteThroughXray for what that means. Off by default.",
|
||||
"type": "boolean"
|
||||
},
|
||||
"s1": {
|
||||
"type": "integer"
|
||||
},
|
||||
|
||||
@@ -649,6 +649,7 @@ export interface ServerSettings {
|
||||
primaryDns?: string;
|
||||
privateKey: string;
|
||||
publicKey: string;
|
||||
routeThroughXray?: boolean;
|
||||
s1: number;
|
||||
s2: number;
|
||||
s3: number;
|
||||
|
||||
@@ -688,6 +688,7 @@ export const ServerSettingsSchema = z.object({
|
||||
primaryDns: z.string().optional(),
|
||||
privateKey: z.string(),
|
||||
publicKey: z.string(),
|
||||
routeThroughXray: z.boolean().optional(),
|
||||
s1: z.number().int(),
|
||||
s2: z.number().int(),
|
||||
s3: z.number().int(),
|
||||
|
||||
@@ -298,6 +298,7 @@ export function createDefaultAmneziawgInboundSettings(): AmneziawgInboundSetting
|
||||
ipv6Enabled: false,
|
||||
ipv6Subnet: '',
|
||||
ipv6ExternalInterface: '',
|
||||
routeThroughXray: false,
|
||||
jc: 5,
|
||||
jmin: 10,
|
||||
jmax: 50,
|
||||
|
||||
@@ -68,6 +68,14 @@ export default function AmneziawgFields({ awgPubKey, regenInboundAwg, regenInbou
|
||||
>
|
||||
<Input placeholder="eth0" />
|
||||
</FormField>
|
||||
<FormField
|
||||
name={['settings', 'server', 'routeThroughXray']}
|
||||
label={t('pages.xray.amneziawg.routeThroughXray')}
|
||||
extra={t('pages.xray.amneziawg.routeThroughXrayHint')}
|
||||
valueProp="checked"
|
||||
>
|
||||
<Switch />
|
||||
</FormField>
|
||||
<Form.Item label={t('pages.xray.amneziawg.obfuscation')}>
|
||||
<Button icon={<ReloadOutlined />} onClick={regenInboundAwgObfuscation}>
|
||||
{t('pages.xray.amneziawg.regenerateObfuscation')}
|
||||
|
||||
@@ -52,6 +52,7 @@ export const AmneziawgServerSchema = z.object({
|
||||
ipv6Enabled: z.boolean().default(false),
|
||||
ipv6Subnet: z.string().default(''),
|
||||
ipv6ExternalInterface: z.string().default(''),
|
||||
routeThroughXray: z.boolean().default(false),
|
||||
jc: z.number().int().min(0).default(5),
|
||||
jmin: z.number().int().min(0).default(10),
|
||||
jmax: z.number().int().min(0).default(50),
|
||||
|
||||
Reference in New Issue
Block a user