mirror of
https://github.com/MHSanaei/3x-ui.git
synced 2026-11-02 19:25:05 +03:00
fix(amneziawg): bound what a handshake allocates and the tunnel MTU
Every handshake initiation builds Jc junk packets of Jmin..Jmax bytes and the I1-I5 signature packets, and the limits allowed the full uint32 range and lengths of any size, so one connection made the embedded device allocate without bound. The MTU reaches the device as an int32 and a wider value made it panic. Both ended the whole panel at the next connection, after every restart. Jc is now at most 128, Jmin/Jmax and each signature packet at most one 65535-byte datagram, and the MTU at most 65535. Saves refuse more, the device setup refuses rows stored before, and the stored MTU is capped where it is read. The form schemas carry the same limits.
This commit is contained in:
@@ -54,7 +54,7 @@ export const AmneziawgServerSchema = z.object({
|
||||
publicKey: z.string().optional(),
|
||||
subnetIp: z.string().default('10.8.1.0'),
|
||||
subnetCidr: clearedToDefault(z.number().int().min(1).max(32).default(24)),
|
||||
mtu: optionalClearedInt(z.number().int().min(1)),
|
||||
mtu: optionalClearedInt(z.number().int().min(1).max(65535)),
|
||||
primaryDns: z.string().default('8.8.8.8'),
|
||||
secondaryDns: z.string().default('8.8.4.4'),
|
||||
externalInterface: z.string().default(''),
|
||||
@@ -71,10 +71,10 @@ export const AmneziawgServerSchema = z.object({
|
||||
// embedded userspace stack -- no Xray routing, sniffing, IPv6 or port forwarding.
|
||||
kernelMode: z.boolean().default(false).optional(),
|
||||
// Upper bounds match amneziawg-go's own UAPI parsers (device/uapi.go):
|
||||
// jc/jmin/jmax are uint32, s1-s4 uint16. Wider values make IpcSet fail.
|
||||
jc: clearedToDefault(z.number().int().min(0).max(4294967295).default(5)),
|
||||
jmin: clearedToDefault(z.number().int().min(0).max(4294967295).default(10)),
|
||||
jmax: clearedToDefault(z.number().int().min(0).max(4294967295).default(50)),
|
||||
// Every handshake allocates jc packets of jmin..jmax bytes; s1-s4 are uint16.
|
||||
jc: clearedToDefault(z.number().int().min(0).max(128).default(5)),
|
||||
jmin: clearedToDefault(z.number().int().min(0).max(65535).default(10)),
|
||||
jmax: clearedToDefault(z.number().int().min(0).max(65535).default(50)),
|
||||
s1: clearedToDefault(z.number().int().min(0).max(1552).default(30)),
|
||||
s2: clearedToDefault(z.number().int().min(0).max(1608).default(45)),
|
||||
s3: clearedToDefault(z.number().int().min(0).max(1636).default(10)),
|
||||
|
||||
@@ -14,14 +14,14 @@ export type AmneziaWGOutboundPeer = z.infer<typeof AmneziaWGOutboundPeerSchema>;
|
||||
export const AmneziaWGOutboundSettingsSchema = z.object({
|
||||
// 0 = unset, so the backend derives MTU from S4 (amneziawg.EffectiveMTU);
|
||||
// a pinned 1420 fragments every full-size packet once S4 exceeds 20.
|
||||
mtu: z.number().int().min(0).default(0),
|
||||
mtu: z.number().int().min(0).max(65535).default(0),
|
||||
secretKey: z.string().default(''),
|
||||
address: z.array(z.string()).default([]),
|
||||
listenPort: z.number().int().min(0).max(65535).default(0),
|
||||
dns: z.string().default(''),
|
||||
jc: z.number().int().min(0).default(0),
|
||||
jmin: z.number().int().min(0).default(40),
|
||||
jmax: z.number().int().min(0).default(100),
|
||||
jc: z.number().int().min(0).max(128).default(0),
|
||||
jmin: z.number().int().min(0).max(65535).default(40),
|
||||
jmax: z.number().int().min(0).max(65535).default(100),
|
||||
// The remote server sets S1-S3; only amneziawg-go's uint16 UAPI width bounds them here.
|
||||
s1: z.number().int().min(0).max(65535).default(15),
|
||||
s2: z.number().int().min(0).max(65535).default(80),
|
||||
|
||||
@@ -42,9 +42,10 @@ describe('AmneziawgServerSchema obfuscation bounds', () => {
|
||||
['s2', 1609],
|
||||
['s3', 1637],
|
||||
['s4', 33],
|
||||
['jc', 4294967296],
|
||||
['jmin', 4294967296],
|
||||
['jmax', 5000000000],
|
||||
['jc', 129],
|
||||
['jmin', 65536],
|
||||
['jmax', 65536],
|
||||
['mtu', 65536],
|
||||
];
|
||||
|
||||
it.each(overWidth)('rejects %s past what amneziawg-go can apply or receive', (field, value) => {
|
||||
@@ -56,7 +57,9 @@ describe('AmneziawgServerSchema obfuscation bounds', () => {
|
||||
['s2', 1608],
|
||||
['s3', 1636],
|
||||
['s4', 32],
|
||||
['jc', 4294967295],
|
||||
['jc', 128],
|
||||
['jmax', 65535],
|
||||
['mtu', 65535],
|
||||
];
|
||||
|
||||
it.each(atLimit)('accepts %s exactly at its limit', (field, value) => {
|
||||
|
||||
Reference in New Issue
Block a user