mirror of
https://github.com/MHSanaei/3x-ui.git
synced 2026-11-15 01:25:00 +03:00
5eec178483
Add a per-inbound "Route through Xray" toggle (off by default) plus an optional outbound picker on MTProto inbounds. mtg only supports a SOCKS5 upstream, so when enabled the panel injects a loopback SOCKS bridge into the generated Xray config — tagged with the inbound's own tag — and mtg dials Telegram through it via a [network] proxies upstream. The router then governs Telegram egress: matchable in the Routing tab, or forced to a chosen outbound/balancer via the picker. - mtproto: Instance carries RouteThroughXray + XrayRoutePort (in the fingerprint); InstanceFromInbound parses them; renderConfig emits the socks5 [network] upstream; freeLocalPort exported as FreeLocalPort. - xray.go: injectMtprotoEgress appends the loopback SOCKS bridge and prepends an optional inboundTag->outbound/balancer rule, hot-appliable like injectPanelEgress. - inbound.go: backend-owned egress port persisted in settings, allocated once and carried across edits (stored value wins); stripped with the inert outboundTag when routing is off; allocation failure fails the save; routed add/update/del force a config regen. - mtproto_job: skip folding mtg metrics for routed inbounds (the bridge, carrying the inbound tag, is metered by xray_traffic_job) to avoid double-counting. - frontend: toggle + outbound/balancer Select (useOutboundTags) on the MTProto form; i18n keys for all locales.
34 lines
1.8 KiB
TypeScript
34 lines
1.8 KiB
TypeScript
import { z } from 'zod';
|
|
|
|
// mtg's [domain-fronting] section: where the sidecar forwards non-Telegram
|
|
// traffic (e.g. an NGINX fake site). All optional — omitted keys fall back to
|
|
// mtg's defaults (DNS-resolve the FakeTLS host, port 443, no proxy protocol).
|
|
export const MtprotoDomainFrontingSchema = z.object({
|
|
ip: z.string().optional(),
|
|
port: z.number().int().min(0).max(65535).optional(),
|
|
proxyProtocol: z.boolean().optional(),
|
|
});
|
|
export type MtprotoDomainFronting = z.infer<typeof MtprotoDomainFrontingSchema>;
|
|
|
|
// MTProto (Telegram) inbound. Served by an mtg sidecar process, not Xray, so
|
|
// it has no clients and no stream settings. `secret` is the FakeTLS secret
|
|
// (ee-prefixed); the backend rebuilds it to match `fakeTlsDomain` on save.
|
|
// The remaining fields map to optional mtg config knobs and are written to the
|
|
// generated mtg.toml only when set.
|
|
export const MtprotoInboundSettingsSchema = z.object({
|
|
fakeTlsDomain: z.string().default('www.cloudflare.com'),
|
|
secret: z.string().default(''),
|
|
proxyProtocolListener: z.boolean().optional(),
|
|
preferIp: z.enum(['prefer-ipv6', 'prefer-ipv4', 'only-ipv6', 'only-ipv4']).optional(),
|
|
debug: z.boolean().optional(),
|
|
domainFronting: MtprotoDomainFrontingSchema.optional(),
|
|
// When set, the mtg sidecar dials Telegram through a loopback SOCKS bridge in
|
|
// the Xray config so the egress obeys routing rules. `outboundTag` optionally
|
|
// forces that traffic out a specific outbound/balancer. `routeXrayPort` is the
|
|
// bridge port; it is allocated and owned by the backend (never edited here).
|
|
routeThroughXray: z.boolean().optional(),
|
|
outboundTag: z.string().optional(),
|
|
routeXrayPort: z.number().int().min(0).max(65535).optional(),
|
|
});
|
|
export type MtprotoInboundSettings = z.infer<typeof MtprotoInboundSettingsSchema>;
|