diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 17c64c8b..a20866f1 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -140,7 +140,7 @@ jobs: - name: Set build tags run: | set -xeuo pipefail - TAGS='with_gvisor,with_quic,with_dhcp,with_wireguard,with_utls,with_reality_server,with_acme,with_clash_api,with_tailscale' + TAGS='with_gvisor,with_quic,with_dhcp,with_wireguard,with_utls,with_acme,with_clash_api,with_tailscale' echo "BUILD_TAGS=${TAGS}" >> "${GITHUB_ENV}" - name: Build if: matrix.os != 'android' diff --git a/.github/workflows/linux.yml b/.github/workflows/linux.yml index 7393e654..79b4d645 100644 --- a/.github/workflows/linux.yml +++ b/.github/workflows/linux.yml @@ -80,10 +80,7 @@ jobs: - name: Set build tags run: | set -xeuo pipefail - TAGS='with_gvisor,with_quic,with_dhcp,with_wireguard,with_utls,with_reality_server,with_acme,with_clash_api' - if [ ! '${{ matrix.legacy_go }}' = 'true' ]; then - TAGS="${TAGS},with_ech" - fi + TAGS='with_gvisor,with_quic,with_dhcp,with_wireguard,with_utls,with_acme,with_clash_api' echo "BUILD_TAGS=${TAGS}" >> "${GITHUB_ENV}" - name: Build run: | diff --git a/.golangci.yml b/.golangci.yml index 28b45337..9cb20ee8 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -28,7 +28,6 @@ run: - with_dhcp - with_wireguard - with_utls - - with_reality_server - with_acme - with_clash_api diff --git a/.goreleaser.fury.yaml b/.goreleaser.fury.yaml index c149b1f4..4237b075 100644 --- a/.goreleaser.fury.yaml +++ b/.goreleaser.fury.yaml @@ -15,7 +15,6 @@ builds: - with_dhcp - with_wireguard - with_utls - - with_reality_server - with_acme - with_clash_api - with_tailscale diff --git a/.goreleaser.yaml b/.goreleaser.yaml index 23e0771f..4c333d3b 100644 --- a/.goreleaser.yaml +++ b/.goreleaser.yaml @@ -17,7 +17,6 @@ builds: - with_dhcp - with_wireguard - with_utls - - with_reality_server - with_acme - with_clash_api - with_tailscale @@ -47,7 +46,6 @@ builds: - with_dhcp - with_wireguard - with_utls - - with_reality_server - with_acme - with_clash_api - with_tailscale diff --git a/Dockerfile b/Dockerfile index b2700b59..fecd98a6 100644 --- a/Dockerfile +++ b/Dockerfile @@ -13,7 +13,7 @@ RUN set -ex \ && export COMMIT=$(git rev-parse --short HEAD) \ && export VERSION=$(go run ./cmd/internal/read_tag) \ && go build -v -trimpath -tags \ - "with_gvisor,with_quic,with_dhcp,with_wireguard,with_utls,with_reality_server,with_acme,with_clash_api,with_tailscale" \ + "with_gvisor,with_quic,with_dhcp,with_wireguard,with_utls,with_acme,with_clash_api,with_tailscale" \ -o /go/bin/sing-box \ -ldflags "-X \"github.com/sagernet/sing-box/constant.Version=$VERSION\" -s -w -buildid=" \ ./cmd/sing-box diff --git a/Makefile b/Makefile index 0de2c8f9..3c8ef641 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ NAME = sing-box COMMIT = $(shell git rev-parse --short HEAD) -TAGS ?= with_gvisor,with_dhcp,with_wireguard,with_reality_server,with_clash_api,with_quic,with_utls,with_tailscale -TAGS_TEST ?= with_gvisor,with_quic,with_wireguard,with_grpc,with_utls,with_reality_server +TAGS ?= with_gvisor,with_dhcp,with_wireguard,with_clash_api,with_quic,with_utls,with_tailscale +TAGS_TEST ?= with_gvisor,with_quic,with_wireguard,with_grpc,with_utls GOHOSTOS = $(shell go env GOHOSTOS) GOHOSTARCH = $(shell go env GOHOSTARCH) diff --git a/common/badtls/read_wait_utls.go b/common/badtls/read_wait_utls.go index ebdb2251..bba016e4 100644 --- a/common/badtls/read_wait_utls.go +++ b/common/badtls/read_wait_utls.go @@ -7,7 +7,8 @@ import ( _ "unsafe" "github.com/sagernet/sing/common" - "github.com/sagernet/utls" + + "github.com/metacubex/utls" ) func init() { @@ -24,8 +25,8 @@ func init() { }) } -//go:linkname utlsReadRecord github.com/sagernet/utls.(*Conn).readRecord +//go:linkname utlsReadRecord github.com/metacubex/utls.(*Conn).readRecord func utlsReadRecord(c *tls.Conn) error -//go:linkname utlsHandlePostHandshakeMessage github.com/sagernet/utls.(*Conn).handlePostHandshakeMessage +//go:linkname utlsHandlePostHandshakeMessage github.com/metacubex/utls.(*Conn).handlePostHandshakeMessage func utlsHandlePostHandshakeMessage(c *tls.Conn) error diff --git a/common/tls/config.go b/common/tls/config.go index 52d88af0..72bbd194 100644 --- a/common/tls/config.go +++ b/common/tls/config.go @@ -18,6 +18,7 @@ type ( STDConfig = tls.Config STDConn = tls.Conn ConnectionState = tls.ConnectionState + CurveID = tls.CurveID ) func ParseTLSVersion(version string) (uint16, error) { diff --git a/common/tls/ech_tag_stub.go b/common/tls/ech_tag_stub.go new file mode 100644 index 00000000..1a9cbd56 --- /dev/null +++ b/common/tls/ech_tag_stub.go @@ -0,0 +1,5 @@ +//go:build with_ech + +package tls + +var _ int = "Due to the migration to stdlib, the separate `with_ech` build tag has been deprecated and is no longer needed, please update your build configuration." diff --git a/common/tls/reality_client.go b/common/tls/reality_client.go index 748567b5..823e8285 100644 --- a/common/tls/reality_client.go +++ b/common/tls/reality_client.go @@ -29,12 +29,13 @@ import ( "github.com/sagernet/sing-box/adapter" "github.com/sagernet/sing-box/option" + "github.com/sagernet/sing/common" "github.com/sagernet/sing/common/debug" E "github.com/sagernet/sing/common/exceptions" "github.com/sagernet/sing/common/ntp" aTLS "github.com/sagernet/sing/common/tls" - utls "github.com/sagernet/utls" + utls "github.com/metacubex/utls" "golang.org/x/crypto/hkdf" "golang.org/x/net/http2" ) @@ -114,6 +115,22 @@ func (e *RealityClientConfig) ClientHandshake(ctx context.Context, conn net.Conn if err != nil { return nil, err } + for _, extension := range uConn.Extensions { + if ce, ok := extension.(*utls.SupportedCurvesExtension); ok { + ce.Curves = common.Filter(ce.Curves, func(curveID utls.CurveID) bool { + return curveID != utls.X25519MLKEM768 + }) + } + if ks, ok := extension.(*utls.KeyShareExtension); ok { + ks.KeyShares = common.Filter(ks.KeyShares, func(share utls.KeyShare) bool { + return share.Group != utls.X25519MLKEM768 + }) + } + } + err = uConn.BuildHandshakeState() + if err != nil { + return nil, err + } if len(uConfig.NextProtos) > 0 { for _, extension := range uConn.Extensions { @@ -148,9 +165,13 @@ func (e *RealityClientConfig) ClientHandshake(ctx context.Context, conn net.Conn if err != nil { return nil, err } - ecdheKey := uConn.HandshakeState.State13.EcdheKey + keyShareKeys := uConn.HandshakeState.State13.KeyShareKeys + if keyShareKeys == nil { + return nil, E.New("nil KeyShareKeys") + } + ecdheKey := keyShareKeys.Ecdhe if ecdheKey == nil { - return nil, E.New("nil ecdhe_key") + return nil, E.New("nil ecdheKey") } authKey, err := ecdheKey.ECDH(publicKey) if err != nil { @@ -214,10 +235,6 @@ func realityClientFallback(ctx context.Context, uConn net.Conn, serverName strin response.Body.Close() } -func (e *RealityClientConfig) SetSessionIDGenerator(generator func(clientHello []byte, sessionID []byte) error) { - e.uClient.config.SessionIDGenerator = generator -} - func (e *RealityClientConfig) Clone() Config { return &RealityClientConfig{ e.ctx, diff --git a/common/tls/reality_server.go b/common/tls/reality_server.go index 84b0979d..27420248 100644 --- a/common/tls/reality_server.go +++ b/common/tls/reality_server.go @@ -1,4 +1,4 @@ -//go:build with_reality_server +//go:build with_utls package tls @@ -7,28 +7,29 @@ import ( "crypto/tls" "encoding/base64" "encoding/hex" + "fmt" "net" "time" - "github.com/sagernet/reality" "github.com/sagernet/sing-box/common/dialer" "github.com/sagernet/sing-box/log" "github.com/sagernet/sing-box/option" - "github.com/sagernet/sing/common/debug" E "github.com/sagernet/sing/common/exceptions" M "github.com/sagernet/sing/common/metadata" N "github.com/sagernet/sing/common/network" "github.com/sagernet/sing/common/ntp" + + utls "github.com/metacubex/utls" ) var _ ServerConfigCompat = (*RealityServerConfig)(nil) type RealityServerConfig struct { - config *reality.Config + config *utls.RealityConfig } func NewRealityServer(ctx context.Context, logger log.Logger, options option.InboundTLSOptions) (*RealityServerConfig, error) { - var tlsConfig reality.Config + var tlsConfig utls.RealityConfig if options.ACME != nil && len(options.ACME.Domain) > 0 { return nil, E.New("acme is unavailable in reality") @@ -74,6 +75,11 @@ func NewRealityServer(ctx context.Context, logger log.Logger, options option.Inb } tlsConfig.SessionTicketsDisabled = true + tlsConfig.Log = func(format string, v ...any) { + if logger != nil { + logger.Trace(fmt.Sprintf(format, v...)) + } + } tlsConfig.Type = N.NetworkTCP tlsConfig.Dest = options.Reality.Handshake.ServerOptions.Build().String() @@ -113,10 +119,6 @@ func NewRealityServer(ctx context.Context, logger log.Logger, options option.Inb return handshakeDialer.DialContext(ctx, network, M.ParseSocksaddr(addr)) } - if debug.Enabled { - tlsConfig.Show = true - } - return &RealityServerConfig{&tlsConfig}, nil } @@ -157,7 +159,7 @@ func (c *RealityServerConfig) Server(conn net.Conn) (Conn, error) { } func (c *RealityServerConfig) ServerHandshake(ctx context.Context, conn net.Conn) (Conn, error) { - tlsConn, err := reality.Server(ctx, conn, c.config) + tlsConn, err := utls.RealityServer(ctx, conn, c.config) if err != nil { return nil, err } @@ -173,7 +175,7 @@ func (c *RealityServerConfig) Clone() Config { var _ Conn = (*realityConnWrapper)(nil) type realityConnWrapper struct { - *reality.Conn + *utls.Conn } func (c *realityConnWrapper) ConnectionState() ConnectionState { diff --git a/common/tls/reality_stub.go b/common/tls/reality_stub.go index 8d394f7b..0feb2aac 100644 --- a/common/tls/reality_stub.go +++ b/common/tls/reality_stub.go @@ -1,15 +1,5 @@ -//go:build !with_reality_server +//go:build with_reality_server package tls -import ( - "context" - - "github.com/sagernet/sing-box/log" - "github.com/sagernet/sing-box/option" - E "github.com/sagernet/sing/common/exceptions" -) - -func NewRealityServer(ctx context.Context, logger log.Logger, options option.InboundTLSOptions) (ServerConfig, error) { - return nil, E.New(`reality server is not included in this build, rebuild with -tags with_reality_server`) -} +var _ int = "The separate `with_reality_server` build tag has been merged into `with_utls` and is no longer needed, please update your build configuration." diff --git a/common/tls/utls_client.go b/common/tls/utls_client.go index fe8e4296..5c0de6ad 100644 --- a/common/tls/utls_client.go +++ b/common/tls/utls_client.go @@ -16,8 +16,8 @@ import ( "github.com/sagernet/sing-box/option" E "github.com/sagernet/sing/common/exceptions" "github.com/sagernet/sing/common/ntp" - utls "github.com/sagernet/utls" + utls "github.com/metacubex/utls" "golang.org/x/net/http2" ) diff --git a/common/tls/utls_stub.go b/common/tls/utls_stub.go index d015611a..ea5da4a7 100644 --- a/common/tls/utls_stub.go +++ b/common/tls/utls_stub.go @@ -5,6 +5,7 @@ package tls import ( "context" + "github.com/sagernet/sing-box/log" "github.com/sagernet/sing-box/option" E "github.com/sagernet/sing/common/exceptions" ) @@ -14,5 +15,9 @@ func NewUTLSClient(ctx context.Context, serverAddress string, options option.Out } func NewRealityClient(ctx context.Context, serverAddress string, options option.OutboundTLSOptions) (Config, error) { - return nil, E.New(`uTLS, which is required by reality client is not included in this build, rebuild with -tags with_utls`) + return nil, E.New(`uTLS, which is required by reality is not included in this build, rebuild with -tags with_utls`) +} + +func NewRealityServer(ctx context.Context, logger log.Logger, options option.InboundTLSOptions) (ServerConfig, error) { + return nil, E.New(`uTLS, which is required by reality is not included in this build, rebuild with -tags with_utls`) } diff --git a/docs/installation/build-from-source.md b/docs/installation/build-from-source.md index c286c366..1f13e814 100644 --- a/docs/installation/build-from-source.md +++ b/docs/installation/build-from-source.md @@ -52,7 +52,6 @@ go build -tags "tag_a tag_b" ./cmd/sing-box | `with_dhcp` | :material-check: | Build with DHCP support, see [DHCP DNS transport](/configuration/dns/server/). | | `with_wireguard` | :material-check: | Build with WireGuard support, see [WireGuard outbound](/configuration/outbound/wireguard/). | | `with_utls` | :material-check: | Build with [uTLS](https://github.com/refraction-networking/utls) support for TLS outbound, see [TLS](/configuration/shared/tls#utls). | -| `with_reality_server` | :material-check: | Build with reality TLS server support, see [TLS](/configuration/shared/tls/). | | `with_acme` | :material-check: | Build with ACME TLS certificate issuer support, see [TLS](/configuration/shared/tls/). | | `with_clash_api` | :material-check: | Build with Clash API support, see [Experimental](/configuration/experimental#clash-api-fields). | | `with_v2ray_api` | :material-close:️ | Build with V2Ray API support, see [Experimental](/configuration/experimental#v2ray-api-fields). | diff --git a/docs/installation/build-from-source.zh.md b/docs/installation/build-from-source.zh.md index c0222929..512d2e24 100644 --- a/docs/installation/build-from-source.zh.md +++ b/docs/installation/build-from-source.zh.md @@ -56,7 +56,6 @@ go build -tags "tag_a tag_b" ./cmd/sing-box | `with_dhcp` | :material-check: | Build with DHCP support, see [DHCP DNS transport](/configuration/dns/server/). | | `with_wireguard` | :material-check: | Build with WireGuard support, see [WireGuard outbound](/configuration/outbound/wireguard/). | | `with_utls` | :material-check: | Build with [uTLS](https://github.com/refraction-networking/utls) support for TLS outbound, see [TLS](/configuration/shared/tls#utls). | -| `with_reality_server` | :material-check: | Build with reality TLS server support, see [TLS](/configuration/shared/tls/). | | `with_acme` | :material-check: | Build with ACME TLS certificate issuer support, see [TLS](/configuration/shared/tls/). | | `with_clash_api` | :material-check: | Build with Clash API support, see [Experimental](/configuration/experimental#clash-api-fields). | | `with_v2ray_api` | :material-close:️ | Build with V2Ray API support, see [Experimental](/configuration/experimental#v2ray-api-fields). | diff --git a/go.mod b/go.mod index b814bbcd..7e156b34 100644 --- a/go.mod +++ b/go.mod @@ -15,6 +15,7 @@ require ( github.com/libdns/cloudflare v0.1.1 github.com/logrusorgru/aurora v2.0.3+incompatible github.com/metacubex/tfo-go v0.0.0-20241231083714-66613d49c422 + github.com/metacubex/utls v1.7.0-alpha.3 github.com/mholt/acmez v1.2.0 github.com/miekg/dns v1.1.63 github.com/oschwald/maxminddb-golang v1.12.0 @@ -25,18 +26,16 @@ require ( github.com/sagernet/gomobile v0.1.6 github.com/sagernet/gvisor v0.0.0-20250325023245-7a9c0f5725fb github.com/sagernet/quic-go v0.49.0-beta.1 - github.com/sagernet/reality v0.0.0-20230406110435-ee17307e7691 github.com/sagernet/sing v0.6.11-0.20250521033217-30d675ea099b github.com/sagernet/sing-mux v0.3.2 github.com/sagernet/sing-quic v0.4.3 github.com/sagernet/sing-shadowsocks v0.2.8 github.com/sagernet/sing-shadowsocks2 v0.2.1 - github.com/sagernet/sing-shadowtls v0.2.1-0.20250316154757-6f9e732e5056 + github.com/sagernet/sing-shadowtls v0.2.1-0.20250503051639-fcd445d33c11 github.com/sagernet/sing-tun v0.6.6-0.20250428031943-0686f8c4f210 - github.com/sagernet/sing-vmess v0.2.3 + github.com/sagernet/sing-vmess v0.2.4-0.20250605032146-38cc72672c88 github.com/sagernet/smux v1.5.34-mod.2 github.com/sagernet/tailscale v1.80.3-mod.5 - github.com/sagernet/utls v1.6.7 github.com/sagernet/wireguard-go v0.0.1-beta.7 github.com/sagernet/ws v0.0.0-20231204124109-acfe8907c854 github.com/spf13/cobra v1.8.1 diff --git a/go.sum b/go.sum index 759add37..b8873a32 100644 --- a/go.sum +++ b/go.sum @@ -125,6 +125,8 @@ github.com/mdlayher/socket v0.5.0 h1:ilICZmJcQz70vrWVes1MFera4jGiWNocSkykwwoy3XI github.com/mdlayher/socket v0.5.0/go.mod h1:WkcBFfvyG8QENs5+hfQPl1X6Jpd2yeLIYgrGFmJiJxI= github.com/metacubex/tfo-go v0.0.0-20241231083714-66613d49c422 h1:zGeQt3UyNydIVrMRB97AA5WsYEau/TyCnRtTf1yUmJY= github.com/metacubex/tfo-go v0.0.0-20241231083714-66613d49c422/go.mod h1:l9oLnLoEXyGZ5RVLsh7QCC5XsouTUyKk4F2nLm2DHLw= +github.com/metacubex/utls v1.7.0-alpha.3 h1:cp1cEMUnoifiWrGHRzo+nCwPRveN9yPD8QaRFmfcYxA= +github.com/metacubex/utls v1.7.0-alpha.3/go.mod h1:oknYT0qTOwE4hjPmZOEpzVdefnW7bAdGLvZcqmk4TLU= github.com/mholt/acmez v1.2.0 h1:1hhLxSgY5FvH5HCnGUuwbKY2VQVo8IU7rxXKSnZ7F30= github.com/mholt/acmez v1.2.0/go.mod h1:VT9YwH1xgNX1kmYY89gY8xPJC84BFAisjo8Egigt4kE= github.com/miekg/dns v1.1.63 h1:8M5aAw6OMZfFXTT7K5V0Eu5YiiL8l7nUAkyN6C9YwaY= @@ -171,8 +173,6 @@ github.com/sagernet/nftables v0.3.0-beta.4 h1:kbULlAwAC3jvdGAC1P5Fa3GSxVwQJibNen github.com/sagernet/nftables v0.3.0-beta.4/go.mod h1:OQXAjvjNGGFxaTgVCSTRIhYB5/llyVDeapVoENYBDS8= github.com/sagernet/quic-go v0.49.0-beta.1 h1:3LdoCzVVfYRibZns1tYWSIoB65fpTmrwy+yfK8DQ8Jk= github.com/sagernet/quic-go v0.49.0-beta.1/go.mod h1:uesWD1Ihrldq1M3XtjuEvIUqi8WHNsRs71b3Lt1+p/U= -github.com/sagernet/reality v0.0.0-20230406110435-ee17307e7691 h1:5Th31OC6yj8byLGkEnIYp6grlXfo1QYUfiYFGjewIdc= -github.com/sagernet/reality v0.0.0-20230406110435-ee17307e7691/go.mod h1:B8lp4WkQ1PwNnrVMM6KyuFR20pU8jYBD+A4EhJovEXU= github.com/sagernet/sing v0.6.9/go.mod h1:ARkL0gM13/Iv5VCZmci/NuoOlePoIsW0m7BWfln/Hak= github.com/sagernet/sing v0.6.11-0.20250521033217-30d675ea099b h1:ZjTCYPb5f7aHdf1UpUvE22dVmf7BL8eQ/zLZhjgh7Wo= github.com/sagernet/sing v0.6.11-0.20250521033217-30d675ea099b/go.mod h1:ARkL0gM13/Iv5VCZmci/NuoOlePoIsW0m7BWfln/Hak= @@ -184,20 +184,16 @@ github.com/sagernet/sing-shadowsocks v0.2.8 h1:PURj5PRoAkqeHh2ZW205RWzN9E9RtKCVC github.com/sagernet/sing-shadowsocks v0.2.8/go.mod h1:lo7TWEMDcN5/h5B8S0ew+r78ZODn6SwVaFhvB6H+PTI= github.com/sagernet/sing-shadowsocks2 v0.2.1 h1:dWV9OXCeFPuYGHb6IRqlSptVnSzOelnqqs2gQ2/Qioo= github.com/sagernet/sing-shadowsocks2 v0.2.1/go.mod h1:RnXS0lExcDAovvDeniJ4IKa2IuChrdipolPYWBv9hWQ= -github.com/sagernet/sing-shadowtls v0.2.1-0.20250316154757-6f9e732e5056 h1:GFNJQAHhSXqAfxAw1wDG/QWbdpGH5Na3k8qUynqWnEA= -github.com/sagernet/sing-shadowtls v0.2.1-0.20250316154757-6f9e732e5056/go.mod h1:HyacBPIFiKihJQR8LQp56FM4hBtd/7MZXnRxxQIOPsc= +github.com/sagernet/sing-shadowtls v0.2.1-0.20250503051639-fcd445d33c11 h1:tK+75l64tm9WvEFrYRE1t0YxoFdWQqw/h7Uhzj0vJ+w= +github.com/sagernet/sing-shadowtls v0.2.1-0.20250503051639-fcd445d33c11/go.mod h1:sWqKnGlMipCHaGsw1sTTlimyUpgzP4WP3pjhCsYt9oA= github.com/sagernet/sing-tun v0.6.6-0.20250428031943-0686f8c4f210 h1:6H4BZaTqKI3YcDMyTV3E576LuJM4S4wY99xoq2T1ECw= github.com/sagernet/sing-tun v0.6.6-0.20250428031943-0686f8c4f210/go.mod h1:fisFCbC4Vfb6HqQNcwPJi2CDK2bf0Xapyz3j3t4cnHE= -github.com/sagernet/sing-vmess v0.2.3 h1:z6Ym8dnZG7k1fP3+54vz8G0tvRVJeOoTFFeUPwXTD44= -github.com/sagernet/sing-vmess v0.2.3/go.mod h1:jDAZ0A0St1zVRkyvhAPRySOFfhC+4SQtO5VYyeFotgA= +github.com/sagernet/sing-vmess v0.2.4-0.20250605032146-38cc72672c88 h1:0pVm8sPOel+BoiCddW3pV3cKDKEaSioVTYDdTSKjyFI= +github.com/sagernet/sing-vmess v0.2.4-0.20250605032146-38cc72672c88/go.mod h1:IL8Rr+EGwuqijszZkNrEFTQDKhilEpkqFqOlvdpS6/w= github.com/sagernet/smux v1.5.34-mod.2 h1:gkmBjIjlJ2zQKpLigOkFur5kBKdV6bNRoFu2WkltRQ4= github.com/sagernet/smux v1.5.34-mod.2/go.mod h1:0KW0+R+ycvA2INW4gbsd7BNyg+HEfLIAxa5N02/28Zc= -github.com/sagernet/tailscale v1.80.3-mod.4.0.20250512093633-e1bc1888c814 h1:B6ejgOuM1BrX4TzWvm1h/LQAOZW1T1jP4PSZe8b/49o= -github.com/sagernet/tailscale v1.80.3-mod.4.0.20250512093633-e1bc1888c814/go.mod h1:EBxXsWu4OH2ELbQLq32WoBeIubG8KgDrg4/Oaxjs6lI= github.com/sagernet/tailscale v1.80.3-mod.5 h1:7V7z+p2C//TGtff20pPnDCt3qP6uFyY62peJoKF9z/A= github.com/sagernet/tailscale v1.80.3-mod.5/go.mod h1:EBxXsWu4OH2ELbQLq32WoBeIubG8KgDrg4/Oaxjs6lI= -github.com/sagernet/utls v1.6.7 h1:Ep3+aJ8FUGGta+II2IEVNUc3EDhaRCZINWkj/LloIA8= -github.com/sagernet/utls v1.6.7/go.mod h1:Uua1TKO/FFuAhLr9rkaVnnrTmmiItzDjv1BUb2+ERwM= github.com/sagernet/wireguard-go v0.0.1-beta.7 h1:ltgBwYHfr+9Wz1eG59NiWnHrYEkDKHG7otNZvu85DXI= github.com/sagernet/wireguard-go v0.0.1-beta.7/go.mod h1:jGXij2Gn2wbrWuYNUmmNhf1dwcZtvyAvQoe8Xd8MbUo= github.com/sagernet/ws v0.0.0-20231204124109-acfe8907c854 h1:6uUiZcDRnZSAegryaUGwPC/Fj13JSHwiTftrXhMmYOc= diff --git a/test/reality_test.go b/test/reality_test.go new file mode 100644 index 00000000..220ccb6c --- /dev/null +++ b/test/reality_test.go @@ -0,0 +1,108 @@ +package main + +import ( + "net/netip" + "testing" + + C "github.com/sagernet/sing-box/constant" + "github.com/sagernet/sing-box/option" + "github.com/sagernet/sing/common" + "github.com/sagernet/sing/common/json/badoption" + + "github.com/gofrs/uuid/v5" +) + +func TestReality(t *testing.T) { + user, _ := uuid.NewV4() + startInstance(t, option.Options{ + Inbounds: []option.Inbound{ + { + Type: C.TypeMixed, + Tag: "mixed-in", + Options: &option.HTTPMixedInboundOptions{ + ListenOptions: option.ListenOptions{ + Listen: common.Ptr(badoption.Addr(netip.IPv4Unspecified())), + ListenPort: clientPort, + }, + }, + }, + { + Type: C.TypeVLESS, + Options: &option.VLESSInboundOptions{ + ListenOptions: option.ListenOptions{ + Listen: common.Ptr(badoption.Addr(netip.IPv4Unspecified())), + ListenPort: serverPort, + }, + Users: []option.VLESSUser{{UUID: user.String()}}, + InboundTLSOptionsContainer: option.InboundTLSOptionsContainer{ + TLS: &option.InboundTLSOptions{ + Enabled: true, + ServerName: "google.com", + Reality: &option.InboundRealityOptions{ + Enabled: true, + Handshake: option.InboundRealityHandshakeOptions{ + ServerOptions: option.ServerOptions{ + Server: "google.com", + ServerPort: 443, + }, + }, + ShortID: []string{"0123456789abcdef"}, + PrivateKey: "UuMBgl7MXTPx9inmQp2UC7Jcnwc6XYbwDNebonM-FCc", + }, + }, + }, + }, + }, + }, + Outbounds: []option.Outbound{ + { + Type: C.TypeDirect, + }, + { + Type: C.TypeVLESS, + Tag: "ss-out", + Options: &option.VLESSOutboundOptions{ + ServerOptions: option.ServerOptions{ + Server: "127.0.0.1", + ServerPort: serverPort, + }, + UUID: user.String(), + OutboundTLSOptionsContainer: option.OutboundTLSOptionsContainer{ + TLS: &option.OutboundTLSOptions{ + Enabled: true, + ServerName: "google.com", + Reality: &option.OutboundRealityOptions{ + Enabled: true, + ShortID: "0123456789abcdef", + PublicKey: "jNXHt1yRo0vDuchQlIP6Z0ZvjT3KtzVI-T4E7RoLJS0", + }, + UTLS: &option.OutboundUTLSOptions{ + Enabled: true, + }, + }, + }, + }, + }, + }, + Route: &option.RouteOptions{ + Rules: []option.Rule{ + { + Type: C.RuleTypeDefault, + DefaultOptions: option.DefaultRule{ + RawDefaultRule: option.RawDefaultRule{ + Inbound: []string{"mixed-in"}, + }, + RuleAction: option.RuleAction{ + Action: C.RuleActionTypeRoute, + + RouteOptions: option.RouteActionOptions{ + Outbound: "ss-out", + }, + }, + }, + }, + }, + }, + }) + testSuit(t, clientPort, testPort) +}