diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 4ec61a6..488f0d3 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -168,7 +168,7 @@ jobs: - name: Build s-ui run: | set -e - BUILD_TAGS="with_quic,with_grpc,with_utls,with_acme,with_gvisor,badlinkname,tfogo_checklinkname0" + BUILD_TAGS="with_quic,with_grpc,with_utls,with_acme,with_gvisor,badlinkname,tfogo_checklinkname0,with_tailscale" [ "${{ matrix.naive }}" = "true" ] && BUILD_TAGS="${BUILD_TAGS},with_naive_outbound,with_musl" go build -ldflags="-w -s -checklinkname=0 -linkmode external -extldflags '-static'" -tags "$BUILD_TAGS" -o sui main.go file sui diff --git a/.github/workflows/windows.yml b/.github/workflows/windows.yml index 4d653d3..3410eaf 100644 --- a/.github/workflows/windows.yml +++ b/.github/workflows/windows.yml @@ -19,7 +19,7 @@ on: env: NODE_VERSION: "24" - TAGS: "with_quic,with_grpc,with_utls,with_acme,with_gvisor,with_naive_outbound,with_purego,badlinkname,tfogo_checklinkname0" + TAGS: "with_quic,with_grpc,with_utls,with_acme,with_gvisor,with_naive_outbound,with_purego,badlinkname,tfogo_checklinkname0,with_tailscale" LIBCRONET_BASE_URL: "https://github.com/SagerNet/cronet-go/releases/latest/download" jobs: diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 3453d3c..45dd322 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -76,7 +76,7 @@ The **frontend** lives in a submodule. If you only work on the backend, you can mkdir -p web/html rm -rf web/html/* cp -R frontend/dist/* web/html/ - go build -ldflags "-w -s" -tags "with_quic,with_grpc,with_utls,with_acme,with_gvisor" -o sui main.go + go build -ldflags "-w -s" -tags "with_quic,with_grpc,with_utls,with_acme,with_gvisor,with_tailscale" -o sui main.go ``` 3. Run: @@ -89,7 +89,7 @@ The **frontend** lives in a submodule. If you only work on the backend, you can The backend is built with these tags for full functionality: -- `with_quic`, `with_grpc`, `with_utls`, `with_acme`, `with_gvisor` +- `with_quic`, `with_grpc`, `with_utls`, `with_acme`, `with_gvisor`, `with_tailscale` Use the same tags when building locally if you need feature parity with releases. @@ -167,7 +167,7 @@ When adding new features, place code in the appropriate layer (handler → servi 1. **Build verification**: Before submitting a PR, ensure the project builds: ```bash - go build -ldflags "-w -s" -tags "with_quic,with_grpc,with_utls,with_acme,with_gvisor" -o sui main.go + go build -ldflags "-w -s" -tags "with_quic,with_grpc,with_utls,with_acme,with_gvisor,with_tailscale" -o sui main.go ``` 2. **Manual testing**: Run with `./runSUI.sh`, test the changed area (panel, API, subscription, etc.). diff --git a/Dockerfile b/Dockerfile index c22447a..d180f1d 100644 --- a/Dockerfile +++ b/Dockerfile @@ -35,7 +35,7 @@ COPY --from=front-builder /app/dist/ /app/web/html/ RUN if [ "$TARGETARCH" = "arm" ]; then export GOARM=7; [ "$TARGETVARIANT" = "v6" ] && export GOARM=6; fi; \ go build -ldflags="-w -s" \ - -tags "with_quic,with_grpc,with_utls,with_acme,with_gvisor,with_naive_outbound,with_purego" \ + -tags "with_quic,with_grpc,with_utls,with_acme,with_gvisor,with_naive_outbound,with_purego,with_tailscale" \ -o sui main.go FROM alpine diff --git a/Dockerfile.frontend-artifact b/Dockerfile.frontend-artifact index 90f4cf1..d8a479c 100644 --- a/Dockerfile.frontend-artifact +++ b/Dockerfile.frontend-artifact @@ -30,7 +30,7 @@ COPY frontend_dist/ /app/web/html/ RUN if [ "$TARGETARCH" = "arm" ]; then export GOARM=7; [ "$TARGETVARIANT" = "v6" ] && export GOARM=6; fi; \ go build -ldflags="-w -s" \ - -tags "with_quic,with_grpc,with_utls,with_acme,with_gvisor,with_naive_outbound,with_purego" \ + -tags "with_quic,with_grpc,with_utls,with_acme,with_gvisor,with_naive_outbound,with_purego,with_tailscale" \ -o sui main.go FROM alpine diff --git a/build.sh b/build.sh index 2d8d0bf..3493462 100755 --- a/build.sh +++ b/build.sh @@ -11,5 +11,5 @@ mkdir -p web/html rm -fr web/html/* cp -R frontend/dist/* web/html/ -BUILD_TAGS="with_quic,with_grpc,with_utls,with_acme,with_gvisor,with_naive_outbound,with_musl,badlinkname,tfogo_checklinkname0" +BUILD_TAGS="with_quic,with_grpc,with_utls,with_acme,with_gvisor,with_naive_outbound,with_musl,badlinkname,tfogo_checklinkname0,with_tailscale" go build -ldflags '-w -s -checklinkname=0 -extldflags "-Wl,-no_warn_duplicate_libraries"' -tags "$BUILD_TAGS" -o sui main.go diff --git a/core/register.go b/core/register.go index ef5bdc3..ff9d4f6 100644 --- a/core/register.go +++ b/core/register.go @@ -27,7 +27,6 @@ import ( "github.com/sagernet/sing-box/protocol/shadowtls" "github.com/sagernet/sing-box/protocol/socks" "github.com/sagernet/sing-box/protocol/ssh" - "github.com/sagernet/sing-box/protocol/tailscale" "github.com/sagernet/sing-box/protocol/tor" "github.com/sagernet/sing-box/protocol/trojan" "github.com/sagernet/sing-box/protocol/tuic" @@ -36,7 +35,6 @@ import ( "github.com/sagernet/sing-box/protocol/vmess" "github.com/sagernet/sing-box/protocol/wireguard" "github.com/sagernet/sing-box/service/ccm" - "github.com/sagernet/sing-box/service/derp" "github.com/sagernet/sing-box/service/ocm" "github.com/sagernet/sing-box/service/resolved" "github.com/sagernet/sing-box/service/ssmapi" @@ -103,7 +101,7 @@ func EndpointRegistry() *endpoint.Registry { registry := endpoint.NewRegistry() wireguard.RegisterEndpoint(registry) - tailscale.RegisterEndpoint(registry) + registerTailscaleEndpoint(registry) return registry } @@ -122,7 +120,7 @@ func DNSTransportRegistry() *dns.TransportRegistry { quic.RegisterTransport(registry) quic.RegisterHTTP3Transport(registry) dhcp.RegisterTransport(registry) - tailscale.RegistryTransport(registry) + registerTailscaleTransport(registry) return registry } @@ -133,7 +131,7 @@ func ServiceRegistry() *service.Registry { resolved.RegisterService(registry) ssmapi.RegisterService(registry) - derp.Register(registry) + registerDERPService(registry) ccm.RegisterService(registry) ocm.RegisterService(registry) diff --git a/core/register_tailscale.go b/core/register_tailscale.go new file mode 100644 index 0000000..b85bb47 --- /dev/null +++ b/core/register_tailscale.go @@ -0,0 +1,23 @@ +//go:build with_tailscale + +package core + +import ( + "github.com/sagernet/sing-box/adapter/endpoint" + "github.com/sagernet/sing-box/adapter/service" + "github.com/sagernet/sing-box/dns" + "github.com/sagernet/sing-box/protocol/tailscale" + "github.com/sagernet/sing-box/service/derp" +) + +func registerTailscaleEndpoint(registry *endpoint.Registry) { + tailscale.RegisterEndpoint(registry) +} + +func registerTailscaleTransport(registry *dns.TransportRegistry) { + tailscale.RegistryTransport(registry) +} + +func registerDERPService(registry *service.Registry) { + derp.Register(registry) +} diff --git a/core/register_tailscale_stub.go b/core/register_tailscale_stub.go new file mode 100644 index 0000000..7a0b403 --- /dev/null +++ b/core/register_tailscale_stub.go @@ -0,0 +1,34 @@ +//go:build !with_tailscale + +package core + +import ( + "context" + + "github.com/sagernet/sing-box/adapter" + "github.com/sagernet/sing-box/adapter/endpoint" + "github.com/sagernet/sing-box/adapter/service" + C "github.com/sagernet/sing-box/constant" + "github.com/sagernet/sing-box/dns" + "github.com/sagernet/sing-box/log" + "github.com/sagernet/sing-box/option" + E "github.com/sagernet/sing/common/exceptions" +) + +func registerTailscaleEndpoint(registry *endpoint.Registry) { + endpoint.Register[option.TailscaleEndpointOptions](registry, C.TypeTailscale, func(ctx context.Context, router adapter.Router, logger log.ContextLogger, tag string, options option.TailscaleEndpointOptions) (adapter.Endpoint, error) { + return nil, E.New(`Tailscale is not included in this build, rebuild with -tags with_tailscale`) + }) +} + +func registerTailscaleTransport(registry *dns.TransportRegistry) { + dns.RegisterTransport[option.TailscaleDNSServerOptions](registry, C.DNSTypeTailscale, func(ctx context.Context, logger log.ContextLogger, tag string, options option.TailscaleDNSServerOptions) (adapter.DNSTransport, error) { + return nil, E.New(`Tailscale is not included in this build, rebuild with -tags with_tailscale`) + }) +} + +func registerDERPService(registry *service.Registry) { + service.Register[option.DERPServiceOptions](registry, C.TypeDERP, func(ctx context.Context, logger log.ContextLogger, tag string, options option.DERPServiceOptions) (adapter.Service, error) { + return nil, E.New(`DERP is not included in this build, rebuild with -tags with_tailscale`) + }) +} diff --git a/go.mod b/go.mod index cfa7f71..f1eb1ca 100644 --- a/go.mod +++ b/go.mod @@ -9,8 +9,8 @@ require ( github.com/gofrs/uuid/v5 v5.4.0 github.com/op/go-logging v0.0.0-20160315200505-970db520ece7 github.com/robfig/cron/v3 v3.0.1 - github.com/sagernet/sing v0.8.2 - github.com/sagernet/sing-box v1.13.3 + github.com/sagernet/sing v0.8.3-0.20260315153529-ed51f65fbfde + github.com/sagernet/sing-box v1.13.4 github.com/shirou/gopsutil/v4 v4.26.2 golang.zx2c4.com/wireguard/wgctrl v0.0.0-20241231184526-a9ab2273dd10 gopkg.in/yaml.v3 v3.0.1 @@ -144,10 +144,10 @@ require ( github.com/sagernet/sing-shadowsocks v0.2.8 // indirect github.com/sagernet/sing-shadowsocks2 v0.2.1 // indirect github.com/sagernet/sing-shadowtls v0.2.1-0.20250503051639-fcd445d33c11 // indirect - github.com/sagernet/sing-tun v0.8.3 // indirect + github.com/sagernet/sing-tun v0.8.6 // indirect github.com/sagernet/sing-vmess v0.2.8-0.20250909125414-3aed155119a1 // indirect github.com/sagernet/smux v1.5.50-sing-box-mod.1 // indirect - github.com/sagernet/tailscale v1.92.4-sing-box-1.13-mod.6.0.20260311131347-f88b27eeb76e // indirect + github.com/sagernet/tailscale v1.92.4-sing-box-1.13-mod.7 // indirect github.com/sagernet/wireguard-go v0.0.2-beta.1.0.20260224074747-506b7631853c // indirect github.com/sagernet/ws v0.0.0-20231204124109-acfe8907c854 // indirect github.com/tailscale/certstore v0.1.1-0.20231202035212-d3fa0460f47e // indirect diff --git a/go.sum b/go.sum index 3e1afde..253fd6d 100644 --- a/go.sum +++ b/go.sum @@ -296,8 +296,12 @@ github.com/sagernet/quic-go v0.59.0-sing-box-mod.4 h1:6qvrUW79S+CrPwWz6cMePXohgj github.com/sagernet/quic-go v0.59.0-sing-box-mod.4/go.mod h1:OqILvS182CyOol5zNNo6bguvOGgXzV459+chpRaUC+4= github.com/sagernet/sing v0.8.2 h1:kX1IH9SWJv4S0T9M8O+HNahWgbOuY1VauxbF7NU5lOg= github.com/sagernet/sing v0.8.2/go.mod h1:ARkL0gM13/Iv5VCZmci/NuoOlePoIsW0m7BWfln/Hak= +github.com/sagernet/sing v0.8.3-0.20260315153529-ed51f65fbfde h1:RNQzlpnsXIuu1HGts/fIzJ1PR7RhrzaNlU52MDyiX1c= +github.com/sagernet/sing v0.8.3-0.20260315153529-ed51f65fbfde/go.mod h1:ARkL0gM13/Iv5VCZmci/NuoOlePoIsW0m7BWfln/Hak= github.com/sagernet/sing-box v1.13.3 h1:aaJz3LxpqEO2oHsynSaD4947CtVHtj5B75ChQKeEM3U= github.com/sagernet/sing-box v1.13.3/go.mod h1:XxKnCcvh3OYE7KCqDoZ9D2U+wSh1GKm/O9TqqNkI1Hc= +github.com/sagernet/sing-box v1.13.4 h1:XfDZ4lvIFUuKS4SJDa2LjWnLxYwJfy5OF4jgI8lWUi4= +github.com/sagernet/sing-box v1.13.4/go.mod h1:ZlRKCQgJCu9ht00xse/BtsLPWYy+901l5clVvKEfJ+Y= github.com/sagernet/sing-mux v0.3.4 h1:ZQplKl8MNXutjzbMVtWvWG31fohhgOfCuUZR4dVQ8+s= github.com/sagernet/sing-mux v0.3.4/go.mod h1:QvlKMyNBNrQoyX4x+gq028uPbLM2XeRpWtDsWBJbFSk= github.com/sagernet/sing-quic v0.6.0 h1:dhrFnP45wgVKEOT1EvtsToxdzRnHIDIAgj6WHV9pLyM= @@ -310,12 +314,16 @@ github.com/sagernet/sing-shadowtls v0.2.1-0.20250503051639-fcd445d33c11 h1:tK+75 github.com/sagernet/sing-shadowtls v0.2.1-0.20250503051639-fcd445d33c11/go.mod h1:sWqKnGlMipCHaGsw1sTTlimyUpgzP4WP3pjhCsYt9oA= github.com/sagernet/sing-tun v0.8.3 h1:mozxmuIoRhFdVHnheenLpBaammVj7bZPcnkApaYKDPY= github.com/sagernet/sing-tun v0.8.3/go.mod h1:pLCo4o+LacXEzz0bhwhJkKBjLlKOGPBNOAZ97ZVZWzs= +github.com/sagernet/sing-tun v0.8.6 h1:NydXFikSXhiKqhahHKtuZ90HQPZFzlOFVRONmkr4C7I= +github.com/sagernet/sing-tun v0.8.6/go.mod h1:pLCo4o+LacXEzz0bhwhJkKBjLlKOGPBNOAZ97ZVZWzs= github.com/sagernet/sing-vmess v0.2.8-0.20250909125414-3aed155119a1 h1:aSwUNYUkVyVvdmBSufR8/nRFonwJeKSIROxHcm5br9o= github.com/sagernet/sing-vmess v0.2.8-0.20250909125414-3aed155119a1/go.mod h1:P11scgTxMxVVQ8dlM27yNm3Cro40mD0+gHbnqrNGDuY= github.com/sagernet/smux v1.5.50-sing-box-mod.1 h1:XkJcivBC9V4wBjiGXIXZ229aZCU1hzcbp6kSkkyQ478= github.com/sagernet/smux v1.5.50-sing-box-mod.1/go.mod h1:NjhsCEWedJm7eFLyhuBgIEzwfhRmytrUoiLluxs5Sk8= github.com/sagernet/tailscale v1.92.4-sing-box-1.13-mod.6.0.20260311131347-f88b27eeb76e h1:Sv1qUhJIidjSTc24XEknovDZnbmVSlAXj8wNVgIfgGo= github.com/sagernet/tailscale v1.92.4-sing-box-1.13-mod.6.0.20260311131347-f88b27eeb76e/go.mod h1:m87GAn4UcesHQF3leaPFEINZETO5za1LGn1GJdNDgNc= +github.com/sagernet/tailscale v1.92.4-sing-box-1.13-mod.7 h1:8zc1Aph1+ElqF9/7aSPkO0o4vTd+AfQC+CO324mLWGg= +github.com/sagernet/tailscale v1.92.4-sing-box-1.13-mod.7/go.mod h1:m87GAn4UcesHQF3leaPFEINZETO5za1LGn1GJdNDgNc= github.com/sagernet/wireguard-go v0.0.2-beta.1.0.20260224074747-506b7631853c h1:f9cXNB+IOOPnR8DOLMTpr42jf7naxh5Un5Y09BBf5Cg= github.com/sagernet/wireguard-go v0.0.2-beta.1.0.20260224074747-506b7631853c/go.mod h1:WUxgxUDZoCF2sxVmW+STSxatP02Qn3FcafTiI2BLtE0= github.com/sagernet/ws v0.0.0-20231204124109-acfe8907c854 h1:6uUiZcDRnZSAegryaUGwPC/Fj13JSHwiTftrXhMmYOc= diff --git a/windows/build-windows.bat b/windows/build-windows.bat index ba6817d..0ec64b5 100644 --- a/windows/build-windows.bat +++ b/windows/build-windows.bat @@ -53,11 +53,11 @@ set GOOS=windows set GOARCH=amd64 REM Try to build with CGO first -go build -ldflags "-w -s" -tags "with_quic,with_grpc,with_utls,with_acme,with_gvisor" -o sui.exe main.go +go build -ldflags "-w -s" -tags "with_quic,with_grpc,with_utls,with_acme,with_gvisor,with_tailscale" -o sui.exe main.go if errorlevel 1 ( echo Warning: CGO build failed, trying without CGO... set CGO_ENABLED=0 - go build -ldflags "-w -s" -tags "with_quic,with_grpc,with_utls,with_acme,with_gvisor" -o sui.exe main.go + go build -ldflags "-w -s" -tags "with_quic,with_grpc,with_utls,with_acme,with_gvisor,with_tailscale" -o sui.exe main.go if errorlevel 1 ( echo Error: Failed to build backend pause diff --git a/windows/build-windows.ps1 b/windows/build-windows.ps1 index dd6ed64..6435d41 100644 --- a/windows/build-windows.ps1 +++ b/windows/build-windows.ps1 @@ -96,7 +96,7 @@ if ($NoCGO) { } # Build command -$buildCmd = "go build -ldflags `"-w -s`" -tags `"with_quic,with_grpc,with_utls,with_acme,with_gvisor`" -o sui.exe main.go" +$buildCmd = "go build -ldflags `"-w -s`" -tags `"with_quic,with_grpc,with_utls,with_acme,with_gvisor,with_tailscale`" -o sui.exe main.go" try { Invoke-Expression $buildCmd