mirror of
https://github.com/MHSanaei/3x-ui.git
synced 2026-11-03 03:35:04 +03:00
fix(xray): keep legacy-private unencrypted outbounds on cores before 26.10.29
xray-core 26.10.29 (#7249) narrowed the "private" addresses an unencrypted vless/trojan outbound may reach to RFC 1918, loopback and link-local, so 100.64.0.0/10 (CGNAT, Tailscale), 198.18.0.0/15 and the other ranges of the old geoip:private list are now refused. The embedded validator follows the new core, which made the template save and outbound subscriptions refuse such an outbound even when the panel still runs an older core that accepts it. The legacy skip now also lets through, on a core from 26.7.11 up to 26.10.28, an outbound whose server address (flat, vnext or servers) is an IP in that core's wider private set. Unknown versions stay strict.
This commit is contained in:
@@ -11,26 +11,35 @@ import (
|
||||
|
||||
func TestShouldSkipLegacyUnencryptedOutboundRejection(t *testing.T) {
|
||||
prohibited := errors.New("vless without TLS or other encryption is prohibited unless the server address is a private IP or domain")
|
||||
public := []byte(`{"protocol":"vless","settings":{"address":"8.8.8.8","port":443}}`)
|
||||
cgnat := []byte(`{"protocol":"vless","settings":{"address":"100.64.1.2","port":443}}`)
|
||||
cgnatVnext := []byte(`{"protocol":"vless","settings":{"vnext":[{"address":"100.100.1.1","port":443}]}}`)
|
||||
benchmarkTrojan := []byte(`{"protocol":"trojan","settings":{"servers":[{"address":"198.18.0.9","port":443}]}}`)
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
version string
|
||||
err error
|
||||
want bool
|
||||
name string
|
||||
version string
|
||||
outbound []byte
|
||||
err error
|
||||
want bool
|
||||
}{
|
||||
{name: "older core", version: "26.4.25", err: prohibited, want: true},
|
||||
{name: "boundary version", version: "26.7.11", err: prohibited, want: false},
|
||||
{name: "newer core", version: "26.10.0", err: prohibited, want: false},
|
||||
{name: "unknown version", version: "Unknown", err: prohibited, want: false},
|
||||
{name: "unparseable version", version: "26.7", err: prohibited, want: false},
|
||||
{name: "empty version", version: "", err: prohibited, want: false},
|
||||
{name: "unrelated validation error", version: "26.4.25", err: errors.New("invalid outbound"), want: false},
|
||||
{name: "older core", version: "26.4.25", outbound: public, err: prohibited, want: true},
|
||||
{name: "boundary version", version: "26.7.11", outbound: public, err: prohibited, want: false},
|
||||
{name: "newer core", version: "26.10.0", outbound: public, err: prohibited, want: false},
|
||||
{name: "unknown version", version: "Unknown", outbound: public, err: prohibited, want: false},
|
||||
{name: "unparseable version", version: "26.7", outbound: public, err: prohibited, want: false},
|
||||
{name: "empty version", version: "", outbound: public, err: prohibited, want: false},
|
||||
{name: "unrelated validation error", version: "26.4.25", outbound: public, err: errors.New("invalid outbound"), want: false},
|
||||
{name: "cgnat on a core that still counts it private", version: "26.10.21", outbound: cgnat, err: prohibited, want: true},
|
||||
{name: "cgnat vnext on a core that still counts it private", version: "26.10.21", outbound: cgnatVnext, err: prohibited, want: true},
|
||||
{name: "benchmark range trojan on a core that still counts it private", version: "26.10.21", outbound: benchmarkTrojan, err: prohibited, want: true},
|
||||
{name: "cgnat on the core that narrowed private", version: "26.10.29", outbound: cgnat, err: prohibited, want: false},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
if got := shouldSkipLegacyUnencryptedOutboundRejection(tt.version, tt.err); got != tt.want {
|
||||
t.Fatalf("shouldSkipLegacyUnencryptedOutboundRejection(%q, %v) = %v, want %v", tt.version, tt.err, got, tt.want)
|
||||
if got := shouldSkipLegacyUnencryptedOutboundRejection(tt.version, tt.outbound, tt.err); got != tt.want {
|
||||
t.Fatalf("shouldSkipLegacyUnencryptedOutboundRejection(%q, %s, %v) = %v, want %v", tt.version, tt.outbound, tt.err, got, tt.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user