mirror of
https://github.com/MHSanaei/3x-ui.git
synced 2026-11-15 01:25:00 +03:00
fix(panel): default TLS ALPN to http/1.1 for WebSocket transport (#6787)
* fix(panel): default TLS ALPN to http/1.1 for WebSocket transport WebSocket bootstraps over HTTP/1.1: leaving ALPN at the schema default ['h2','http/1.1'] makes the server negotiate h2 and the WS handshake fails. See issue #6782. * style(frontend): keep comments within the two-line limit * style(frontend): keep comments within the two-line limit
This commit is contained in:
@@ -14,7 +14,7 @@ function defaultCertificate(): Record<string, unknown> {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export function createTlsSettingsWithDefaultCert(): Record<string, unknown> {
|
export function createTlsSettingsWithDefaultCert(network?: string): Record<string, unknown> {
|
||||||
const tls = TlsStreamSettingsSchema.parse({}) as Record<string, unknown>;
|
const tls = TlsStreamSettingsSchema.parse({}) as Record<string, unknown>;
|
||||||
tls.certificates = [defaultCertificate()];
|
tls.certificates = [defaultCertificate()];
|
||||||
const settings =
|
const settings =
|
||||||
@@ -23,6 +23,11 @@ export function createTlsSettingsWithDefaultCert(): Record<string, unknown> {
|
|||||||
: {};
|
: {};
|
||||||
settings.fingerprint = 'chrome';
|
settings.fingerprint = 'chrome';
|
||||||
tls.settings = settings;
|
tls.settings = settings;
|
||||||
|
/* WebSocket bootstraps over HTTP/1.1: the schema default ALPN
|
||||||
|
* ['h2','http/1.1'] makes the server negotiate h2 (see issue #6782). */
|
||||||
|
if (network === 'ws') {
|
||||||
|
tls.alpn = ['http/1.1'];
|
||||||
|
}
|
||||||
return tls;
|
return tls;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -894,6 +894,12 @@ export default function InboundFormModal({
|
|||||||
cleaned.finalmask = { ...fm, udp };
|
cleaned.finalmask = { ...fm, udp };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
/* WebSocket needs HTTP/1.1 for its handshake; the TLS default
|
||||||
|
* ALPN ['h2','http/1.1'] makes the server negotiate h2 (see #6782). */
|
||||||
|
if (next === 'ws' && cleaned.security === 'tls') {
|
||||||
|
const tls = (cleaned.tlsSettings as Record<string, unknown> | undefined) ?? {};
|
||||||
|
cleaned.tlsSettings = { ...tls, alpn: ['http/1.1'] };
|
||||||
|
}
|
||||||
setV('streamSettings', cleaned);
|
setV('streamSettings', cleaned);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -344,7 +344,8 @@ export function useSecurityActions({
|
|||||||
delete cleaned.tlsSettings;
|
delete cleaned.tlsSettings;
|
||||||
delete cleaned.realitySettings;
|
delete cleaned.realitySettings;
|
||||||
if (next === 'tls') {
|
if (next === 'tls') {
|
||||||
cleaned.tlsSettings = createTlsSettingsWithDefaultCert();
|
const network = (current.network as string | undefined) ?? '';
|
||||||
|
cleaned.tlsSettings = createTlsSettingsWithDefaultCert(network);
|
||||||
}
|
}
|
||||||
if (next === 'reality') {
|
if (next === 'reality') {
|
||||||
const reality = RealityStreamSettingsSchema.parse({}) as Record<string, unknown>;
|
const reality = RealityStreamSettingsSchema.parse({}) as Record<string, unknown>;
|
||||||
|
|||||||
@@ -18,12 +18,16 @@ import {
|
|||||||
createDefaultVmessInboundSettings,
|
createDefaultVmessInboundSettings,
|
||||||
createDefaultWireguardInboundSettings,
|
createDefaultWireguardInboundSettings,
|
||||||
} from '@/lib/xray/inbound-defaults';
|
} from '@/lib/xray/inbound-defaults';
|
||||||
import { createHysteriaTlsSettingsWithDefaultCert } from '@/lib/xray/inbound-tls-defaults';
|
import {
|
||||||
|
createHysteriaTlsSettingsWithDefaultCert,
|
||||||
|
createTlsSettingsWithDefaultCert,
|
||||||
|
} from '@/lib/xray/inbound-tls-defaults';
|
||||||
import { HttpInboundSettingsSchema } from '@/schemas/protocols/inbound/http';
|
import { HttpInboundSettingsSchema } from '@/schemas/protocols/inbound/http';
|
||||||
import {
|
import {
|
||||||
HysteriaClientSchema,
|
HysteriaClientSchema,
|
||||||
HysteriaInboundSettingsSchema,
|
HysteriaInboundSettingsSchema,
|
||||||
} from '@/schemas/protocols/inbound/hysteria';
|
} from '@/schemas/protocols/inbound/hysteria';
|
||||||
|
import { TlsStreamSettingsSchema } from '@/schemas/protocols/security/tls';
|
||||||
import { MixedInboundSettingsSchema } from '@/schemas/protocols/inbound/mixed';
|
import { MixedInboundSettingsSchema } from '@/schemas/protocols/inbound/mixed';
|
||||||
import {
|
import {
|
||||||
ShadowsocksClientSchema,
|
ShadowsocksClientSchema,
|
||||||
@@ -234,3 +238,19 @@ describe('createHysteriaTlsSettingsWithDefaultCert', () => {
|
|||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('createTlsSettingsWithDefaultCert', () => {
|
||||||
|
it('keeps the schema ALPN default for non-WebSocket transports', () => {
|
||||||
|
for (const network of [undefined, '', 'tcp', 'kcp', 'grpc', 'httpupgrade', 'xhttp']) {
|
||||||
|
const tls = createTlsSettingsWithDefaultCert(network);
|
||||||
|
expect(tls.alpn).toEqual(['h2', 'http/1.1']);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
it("defaults ALPN to http/1.1 for WebSocket (issue #6782)", () => {
|
||||||
|
const tls = createTlsSettingsWithDefaultCert('ws');
|
||||||
|
expect(tls.alpn).toEqual(['http/1.1']);
|
||||||
|
// The overridden value must still satisfy the TLS settings schema.
|
||||||
|
expect(TlsStreamSettingsSchema.parse(tls).alpn).toEqual(['http/1.1']);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user