diff --git a/agent/agent.go b/agent/agent.go index 3a01605639..4e8c81ff97 100644 --- a/agent/agent.go +++ b/agent/agent.go @@ -82,7 +82,6 @@ type Options struct { SSHMaxTimeout time.Duration TailnetListenPort uint16 Subsystems []codersdk.AgentSubsystem - Addresses []netip.Prefix PrometheusRegistry *prometheus.Registry ReportMetadataInterval time.Duration ServiceBannerRefreshInterval time.Duration @@ -180,7 +179,6 @@ func New(options Options) Agent { announcementBannersRefreshInterval: options.ServiceBannerRefreshInterval, sshMaxTimeout: options.SSHMaxTimeout, subsystems: options.Subsystems, - addresses: options.Addresses, syscaller: options.Syscaller, modifiedProcs: options.ModifiedProcesses, processManagementTick: options.ProcessManagementTick, @@ -250,7 +248,6 @@ type agent struct { lifecycleLastReportedIndex int // Keeps track of the last lifecycle state we successfully reported. network *tailnet.Conn - addresses []netip.Prefix statsReporter *statsReporter logSender *agentsdk.LogSender @@ -1112,15 +1109,11 @@ func (a *agent) updateCommandEnv(current []string) (updated []string, err error) return updated, nil } -func (a *agent) wireguardAddresses(agentID uuid.UUID) []netip.Prefix { - if len(a.addresses) == 0 { - return []netip.Prefix{ - // This is the IP that should be used primarily. - netip.PrefixFrom(tailnet.IPFromUUID(agentID), 128), - } +func (*agent) wireguardAddresses(agentID uuid.UUID) []netip.Prefix { + return []netip.Prefix{ + // This is the IP that should be used primarily. + tailnet.TailscaleServicePrefix.PrefixFromUUID(agentID), } - - return a.addresses } func (a *agent) trackGoroutine(fn func()) error { diff --git a/agent/agent_test.go b/agent/agent_test.go index 5ef7afdb0e..5cfacb1093 100644 --- a/agent/agent_test.go +++ b/agent/agent_test.go @@ -1880,7 +1880,7 @@ func TestAgent_UpdatedDERP(t *testing.T) { // Setup a client connection. newClientConn := func(derpMap *tailcfg.DERPMap, name string) *workspacesdk.AgentConn { conn, err := tailnet.NewConn(&tailnet.Options{ - Addresses: []netip.Prefix{netip.PrefixFrom(tailnet.IP(), 128)}, + Addresses: []netip.Prefix{tailnet.TailscaleServicePrefix.RandomPrefix()}, DERPMap: derpMap, Logger: logger.Named(name), }) @@ -2372,7 +2372,7 @@ func setupAgent(t *testing.T, metadata agentsdk.Manifest, ptyTimeout time.Durati _ = agnt.Close() }) conn, err := tailnet.NewConn(&tailnet.Options{ - Addresses: []netip.Prefix{netip.PrefixFrom(tailnet.IP(), 128)}, + Addresses: []netip.Prefix{netip.PrefixFrom(tailnet.TailscaleServicePrefix.RandomAddr(), 128)}, DERPMap: metadata.DERPMap, Logger: logger.Named("client"), }) diff --git a/coderd/coderd_test.go b/coderd/coderd_test.go index ffbeec4591..f19c8d4c53 100644 --- a/coderd/coderd_test.go +++ b/coderd/coderd_test.go @@ -83,7 +83,7 @@ func TestDERP(t *testing.T) { }, }, } - w1IP := tailnet.IP() + w1IP := tailnet.TailscaleServicePrefix.RandomAddr() w1, err := tailnet.NewConn(&tailnet.Options{ Addresses: []netip.Prefix{netip.PrefixFrom(w1IP, 128)}, Logger: logger.Named("w1"), @@ -92,7 +92,7 @@ func TestDERP(t *testing.T) { require.NoError(t, err) w2, err := tailnet.NewConn(&tailnet.Options{ - Addresses: []netip.Prefix{netip.PrefixFrom(tailnet.IP(), 128)}, + Addresses: []netip.Prefix{tailnet.TailscaleServicePrefix.RandomPrefix()}, Logger: logger.Named("w2"), DERPMap: derpMap, }) diff --git a/coderd/tailnet.go b/coderd/tailnet.go index e995f92fe6..e489f571a0 100644 --- a/coderd/tailnet.go +++ b/coderd/tailnet.go @@ -61,7 +61,7 @@ func NewServerTailnet( ) (*ServerTailnet, error) { logger = logger.Named("servertailnet") conn, err := tailnet.NewConn(&tailnet.Options{ - Addresses: []netip.Prefix{netip.PrefixFrom(tailnet.IP(), 128)}, + Addresses: []netip.Prefix{tailnet.TailscaleServicePrefix.RandomPrefix()}, DERPForceWebSockets: derpForceWebSockets, Logger: logger, BlockEndpoints: blockEndpoints, @@ -352,7 +352,7 @@ func (s *ServerTailnet) ReverseProxy(targetURL, dashboardURL *url.URL, agentID u // "localhost:port", causing connections to be shared across agents. tgt := *targetURL _, port, _ := net.SplitHostPort(tgt.Host) - tgt.Host = net.JoinHostPort(tailnet.IPFromUUID(agentID).String(), port) + tgt.Host = net.JoinHostPort(tailnet.TailscaleServicePrefix.AddrFromUUID(agentID).String(), port) proxy := httputil.NewSingleHostReverseProxy(&tgt) proxy.ErrorHandler = func(w http.ResponseWriter, r *http.Request, theErr error) { diff --git a/coderd/tailnet_test.go b/coderd/tailnet_test.go index d4dac9b94c..f004fc06cd 100644 --- a/coderd/tailnet_test.go +++ b/coderd/tailnet_test.go @@ -186,7 +186,9 @@ func TestServerTailnet_ReverseProxy(t *testing.T) { // Ensure the reverse proxy director rewrites the url host to the agent's IP. rp.Director(req) assert.Equal(t, - fmt.Sprintf("[%s]:%d", tailnet.IPFromUUID(a.id).String(), workspacesdk.AgentHTTPAPIServerPort), + fmt.Sprintf("[%s]:%d", + tailnet.TailscaleServicePrefix.AddrFromUUID(a.id).String(), + workspacesdk.AgentHTTPAPIServerPort), req.URL.Host, ) }) diff --git a/codersdk/workspacesdk/agentconn.go b/codersdk/workspacesdk/agentconn.go index c7cbf31f8c..4c3a9539bb 100644 --- a/codersdk/workspacesdk/agentconn.go +++ b/codersdk/workspacesdk/agentconn.go @@ -51,7 +51,7 @@ type AgentConnOptions struct { } func (c *AgentConn) agentAddress() netip.Addr { - return tailnet.IPFromUUID(c.opts.AgentID) + return tailnet.TailscaleServicePrefix.AddrFromUUID(c.opts.AgentID) } // AwaitReachable waits for the agent to be reachable. diff --git a/codersdk/workspacesdk/workspacesdk.go b/codersdk/workspacesdk/workspacesdk.go index b273d69712..d0983d8159 100644 --- a/codersdk/workspacesdk/workspacesdk.go +++ b/codersdk/workspacesdk/workspacesdk.go @@ -236,7 +236,7 @@ func (c *Client) DialAgent(dialCtx context.Context, agentID uuid.UUID, options * CompressionMode: websocket.CompressionDisabled, }) - ip := tailnet.IP() + ip := tailnet.TailscaleServicePrefix.RandomAddr() var header http.Header if headerTransport, ok := c.client.HTTPClient.Transport.(*codersdk.HeaderTransport); ok { header = headerTransport.Header diff --git a/enterprise/tailnet/pgcoord_test.go b/enterprise/tailnet/pgcoord_test.go index dc9b4e2806..08c0017a2d 100644 --- a/enterprise/tailnet/pgcoord_test.go +++ b/enterprise/tailnet/pgcoord_test.go @@ -120,7 +120,7 @@ func TestPGCoordinatorSingle_AgentInvalidIP(t *testing.T) { defer agent.Close(ctx) agent.UpdateNode(&proto.Node{ Addresses: []string{ - netip.PrefixFrom(agpl.IP(), 128).String(), + agpl.TailscaleServicePrefix.RandomPrefix().String(), }, PreferredDerp: 10, }) @@ -147,7 +147,7 @@ func TestPGCoordinatorSingle_AgentInvalidIPBits(t *testing.T) { defer agent.Close(ctx) agent.UpdateNode(&proto.Node{ Addresses: []string{ - netip.PrefixFrom(agpl.IPFromUUID(agent.ID), 64).String(), + netip.PrefixFrom(agpl.TailscaleServicePrefix.AddrFromUUID(agent.ID), 64).String(), }, PreferredDerp: 10, }) @@ -174,7 +174,7 @@ func TestPGCoordinatorSingle_AgentValidIP(t *testing.T) { defer agent.Close(ctx) agent.UpdateNode(&proto.Node{ Addresses: []string{ - netip.PrefixFrom(agpl.IPFromUUID(agent.ID), 128).String(), + agpl.TailscaleServicePrefix.PrefixFromUUID(agent.ID).String(), }, PreferredDerp: 10, }) diff --git a/tailnet/conn.go b/tailnet/conn.go index 7726525e7b..1217bdeb6f 100644 --- a/tailnet/conn.go +++ b/tailnet/conn.go @@ -327,28 +327,48 @@ func NewConn(options *Options) (conn *Conn, err error) { return server, nil } -func maskUUID(uid uuid.UUID) uuid.UUID { - // This is Tailscale's ephemeral service prefix. This can be changed easily - // later-on, because all of our nodes are ephemeral. - // fd7a:115c:a1e0 - uid[0] = 0xfd - uid[1] = 0x7a - uid[2] = 0x11 - uid[3] = 0x5c - uid[4] = 0xa1 - uid[5] = 0xe0 +type ServicePrefix [6]byte + +var ( + // TailscaleServicePrefix is the IPv6 prefix for all tailnet nodes since it was first added to + // Coder. It is identical to the service prefix Tailscale.com uses. With the introduction of + // CoderVPN, we would like to stop using the Tailscale prefix so that we don't conflict with + // Tailscale if both are installed at the same time. However, there are a large number of agents + // and clients using this prefix, so we need to carefully manage deprecation and eventual + // removal. + // fd7a:115c:a1e0:://48 + TailscaleServicePrefix ServicePrefix = [6]byte{0xfd, 0x7a, 0x11, 0x5c, 0xa1, 0xe0} + // CoderServicePrefix is the Coder-specific IPv6 prefix for tailnet nodes, which we are in the + // process of migrating to. It allows Coder to run alongside Tailscale without conflicts even + // if both are set up as TUN interfaces into the OS (e.g. CoderVPN). + // fd60:627a:a42b::/48 + CoderServicePrefix ServicePrefix = [6]byte{0xfd, 0x60, 0x62, 0x7a, 0xa4, 0x2b} +) + +// maskUUID returns a new UUID with the first 6 bytes changed to the ServicePrefix +func (p ServicePrefix) maskUUID(uid uuid.UUID) uuid.UUID { + copy(uid[:], p[:]) return uid } -// IP generates a random IP with a static service prefix. -func IP() netip.Addr { - uid := maskUUID(uuid.New()) - return netip.AddrFrom16(uid) +// RandomAddr returns a random IP address in the service prefix. +func (p ServicePrefix) RandomAddr() netip.Addr { + return netip.AddrFrom16(p.maskUUID(uuid.New())) } -// IP generates a new IP from a UUID. -func IPFromUUID(uid uuid.UUID) netip.Addr { - return netip.AddrFrom16(maskUUID(uid)) +// AddrFromUUID returns an IPv6 address corresponding to the given UUID in the service prefix. +func (p ServicePrefix) AddrFromUUID(uid uuid.UUID) netip.Addr { + return netip.AddrFrom16(p.maskUUID(uid)) +} + +// PrefixFromUUID returns a single IPv6 /128 prefix corresponding to the given UUID. +func (p ServicePrefix) PrefixFromUUID(uid uuid.UUID) netip.Prefix { + return netip.PrefixFrom(p.AddrFromUUID(uid), 128) +} + +// RandomPrefix returns a single IPv6 /128 prefix within the service prefix. +func (p ServicePrefix) RandomPrefix() netip.Prefix { + return netip.PrefixFrom(p.RandomAddr(), 128) } // Conn is an actively listening Wireguard connection. diff --git a/tailnet/conn_test.go b/tailnet/conn_test.go index 5eaaf28755..c7938afd27 100644 --- a/tailnet/conn_test.go +++ b/tailnet/conn_test.go @@ -3,6 +3,7 @@ package tailnet_test import ( "context" "net/netip" + "strings" "testing" "time" @@ -30,7 +31,7 @@ func TestTailnet(t *testing.T) { t.Parallel() logger := slogtest.Make(t, nil).Leveled(slog.LevelDebug) conn, err := tailnet.NewConn(&tailnet.Options{ - Addresses: []netip.Prefix{netip.PrefixFrom(tailnet.IP(), 128)}, + Addresses: []netip.Prefix{tailnet.TailscaleServicePrefix.RandomPrefix()}, Logger: logger.Named("w1"), DERPMap: derpMap, }) @@ -42,7 +43,7 @@ func TestTailnet(t *testing.T) { t.Parallel() logger := slogtest.Make(t, nil).Leveled(slog.LevelDebug) ctx := testutil.Context(t, testutil.WaitLong) - w1IP := tailnet.IP() + w1IP := tailnet.TailscaleServicePrefix.RandomAddr() w1, err := tailnet.NewConn(&tailnet.Options{ Addresses: []netip.Prefix{netip.PrefixFrom(w1IP, 128)}, Logger: logger.Named("w1"), @@ -51,7 +52,7 @@ func TestTailnet(t *testing.T) { require.NoError(t, err) w2, err := tailnet.NewConn(&tailnet.Options{ - Addresses: []netip.Prefix{netip.PrefixFrom(tailnet.IP(), 128)}, + Addresses: []netip.Prefix{tailnet.TailscaleServicePrefix.RandomPrefix()}, Logger: logger.Named("w2"), DERPMap: derpMap, }) @@ -106,7 +107,7 @@ func TestTailnet(t *testing.T) { logger := slogtest.Make(t, nil).Leveled(slog.LevelDebug) ctx := testutil.Context(t, testutil.WaitMedium) - w1IP := tailnet.IP() + w1IP := tailnet.TailscaleServicePrefix.RandomAddr() derpMap := tailnettest.RunDERPOnlyWebSockets(t) w1, err := tailnet.NewConn(&tailnet.Options{ Addresses: []netip.Prefix{netip.PrefixFrom(w1IP, 128)}, @@ -117,7 +118,7 @@ func TestTailnet(t *testing.T) { require.NoError(t, err) w2, err := tailnet.NewConn(&tailnet.Options{ - Addresses: []netip.Prefix{netip.PrefixFrom(tailnet.IP(), 128)}, + Addresses: []netip.Prefix{tailnet.TailscaleServicePrefix.RandomPrefix()}, Logger: logger.Named("w2"), DERPMap: derpMap, BlockEndpoints: true, @@ -168,7 +169,7 @@ func TestTailnet(t *testing.T) { t.Parallel() logger := slogtest.Make(t, nil).Leveled(slog.LevelDebug) ctx := testutil.Context(t, testutil.WaitLong) - w1IP := tailnet.IP() + w1IP := tailnet.TailscaleServicePrefix.RandomAddr() w1, err := tailnet.NewConn(&tailnet.Options{ Addresses: []netip.Prefix{netip.PrefixFrom(w1IP, 128)}, Logger: logger.Named("w1"), @@ -177,7 +178,7 @@ func TestTailnet(t *testing.T) { require.NoError(t, err) w2, err := tailnet.NewConn(&tailnet.Options{ - Addresses: []netip.Prefix{netip.PrefixFrom(tailnet.IP(), 128)}, + Addresses: []netip.Prefix{tailnet.TailscaleServicePrefix.RandomPrefix()}, Logger: logger.Named("w2"), DERPMap: derpMap, }) @@ -211,7 +212,7 @@ func TestTailnet(t *testing.T) { t.Parallel() logger := slogtest.Make(t, nil).Leveled(slog.LevelDebug) ctx := testutil.Context(t, testutil.WaitLong) - w1IP := tailnet.IP() + w1IP := tailnet.TailscaleServicePrefix.RandomAddr() w1, err := tailnet.NewConn(&tailnet.Options{ Addresses: []netip.Prefix{netip.PrefixFrom(w1IP, 128)}, Logger: logger.Named("w1"), @@ -221,7 +222,7 @@ func TestTailnet(t *testing.T) { require.NoError(t, err) w2, err := tailnet.NewConn(&tailnet.Options{ - Addresses: []netip.Prefix{netip.PrefixFrom(tailnet.IP(), 128)}, + Addresses: []netip.Prefix{tailnet.TailscaleServicePrefix.RandomPrefix()}, Logger: logger.Named("w2"), DERPMap: derpMap, BlockEndpoints: true, @@ -261,7 +262,7 @@ func TestConn_PreferredDERP(t *testing.T) { logger := slogtest.Make(t, nil).Leveled(slog.LevelDebug) derpMap, _ := tailnettest.RunDERPAndSTUN(t) conn, err := tailnet.NewConn(&tailnet.Options{ - Addresses: []netip.Prefix{netip.PrefixFrom(tailnet.IP(), 128)}, + Addresses: []netip.Prefix{tailnet.TailscaleServicePrefix.RandomPrefix()}, Logger: logger.Named("w1"), DERPMap: derpMap, }) @@ -290,7 +291,7 @@ func TestConn_UpdateDERP(t *testing.T) { logger := slogtest.Make(t, nil).Leveled(slog.LevelDebug) derpMap1, _ := tailnettest.RunDERPAndSTUN(t) - ip := tailnet.IP() + ip := tailnet.TailscaleServicePrefix.RandomAddr() conn, err := tailnet.NewConn(&tailnet.Options{ Addresses: []netip.Prefix{netip.PrefixFrom(ip, 128)}, Logger: logger.Named("w1"), @@ -320,7 +321,7 @@ func TestConn_UpdateDERP(t *testing.T) { // Connect from a different client. client1, err := tailnet.NewConn(&tailnet.Options{ - Addresses: []netip.Prefix{netip.PrefixFrom(tailnet.IP(), 128)}, + Addresses: []netip.Prefix{tailnet.TailscaleServicePrefix.RandomPrefix()}, Logger: logger.Named("client1"), DERPMap: derpMap1, BlockEndpoints: true, @@ -394,7 +395,7 @@ parentLoop: // Connect from a different different client with up-to-date derp map and // nodes. client2, err := tailnet.NewConn(&tailnet.Options{ - Addresses: []netip.Prefix{netip.PrefixFrom(tailnet.IP(), 128)}, + Addresses: []netip.Prefix{tailnet.TailscaleServicePrefix.RandomPrefix()}, Logger: logger.Named("client2"), DERPMap: derpMap2, BlockEndpoints: true, @@ -425,7 +426,7 @@ func TestConn_BlockEndpoints(t *testing.T) { derpMap, _ := tailnettest.RunDERPAndSTUN(t) // Setup conn 1. - ip1 := tailnet.IP() + ip1 := tailnet.TailscaleServicePrefix.RandomAddr() conn1, err := tailnet.NewConn(&tailnet.Options{ Addresses: []netip.Prefix{netip.PrefixFrom(ip1, 128)}, Logger: logger.Named("w1"), @@ -439,7 +440,7 @@ func TestConn_BlockEndpoints(t *testing.T) { }() // Setup conn 2. - ip2 := tailnet.IP() + ip2 := tailnet.TailscaleServicePrefix.RandomAddr() conn2, err := tailnet.NewConn(&tailnet.Options{ Addresses: []netip.Prefix{netip.PrefixFrom(ip2, 128)}, Logger: logger.Named("w2"), @@ -492,3 +493,31 @@ func stitch(t *testing.T, dst, src *tailnet.Conn) { assert.NoError(t, err) }) } + +func TestTailscaleServicePrefix(t *testing.T) { + t.Parallel() + a := tailnet.TailscaleServicePrefix.RandomAddr() + require.True(t, strings.HasPrefix(a.String(), "fd7a:115c:a1e0")) + p := tailnet.TailscaleServicePrefix.RandomPrefix() + require.True(t, strings.HasPrefix(p.String(), "fd7a:115c:a1e0")) + require.True(t, strings.HasSuffix(p.String(), "/128")) + u := uuid.MustParse("aaaaaaaa-aaaa-aaaa-aaaa-123456789abc") + a = tailnet.TailscaleServicePrefix.AddrFromUUID(u) + require.Equal(t, "fd7a:115c:a1e0:aaaa:aaaa:1234:5678:9abc", a.String()) + p = tailnet.TailscaleServicePrefix.PrefixFromUUID(u) + require.Equal(t, "fd7a:115c:a1e0:aaaa:aaaa:1234:5678:9abc/128", p.String()) +} + +func TestCoderServicePrefix(t *testing.T) { + t.Parallel() + a := tailnet.CoderServicePrefix.RandomAddr() + require.True(t, strings.HasPrefix(a.String(), "fd60:627a:a42b")) + p := tailnet.CoderServicePrefix.RandomPrefix() + require.True(t, strings.HasPrefix(p.String(), "fd60:627a:a42b")) + require.True(t, strings.HasSuffix(p.String(), "/128")) + u := uuid.MustParse("aaaaaaaa-aaaa-aaaa-aaaa-123456789abc") + a = tailnet.CoderServicePrefix.AddrFromUUID(u) + require.Equal(t, "fd60:627a:a42b:aaaa:aaaa:1234:5678:9abc", a.String()) + p = tailnet.CoderServicePrefix.PrefixFromUUID(u) + require.Equal(t, "fd60:627a:a42b:aaaa:aaaa:1234:5678:9abc/128", p.String()) +} diff --git a/tailnet/coordinator_test.go b/tailnet/coordinator_test.go index 99b4724e35..5ffffde824 100644 --- a/tailnet/coordinator_test.go +++ b/tailnet/coordinator_test.go @@ -40,7 +40,7 @@ func TestCoordinator(t *testing.T) { client := test.NewClient(ctx, t, coordinator, "client", uuid.New()) defer client.Close(ctx) client.UpdateNode(&proto.Node{ - Addresses: []string{netip.PrefixFrom(tailnet.IP(), 128).String()}, + Addresses: []string{tailnet.TailscaleServicePrefix.RandomPrefix().String()}, PreferredDerp: 10, }) require.Eventually(t, func() bool { @@ -63,7 +63,7 @@ func TestCoordinator(t *testing.T) { client.UpdateNode(&proto.Node{ Addresses: []string{ - netip.PrefixFrom(tailnet.IP(), 64).String(), + netip.PrefixFrom(tailnet.TailscaleServicePrefix.RandomAddr(), 64).String(), }, PreferredDerp: 10, }) @@ -84,7 +84,7 @@ func TestCoordinator(t *testing.T) { defer agent.Close(ctx) agent.UpdateNode(&proto.Node{ Addresses: []string{ - netip.PrefixFrom(tailnet.IPFromUUID(agent.ID), 128).String(), + tailnet.TailscaleServicePrefix.PrefixFromUUID(agent.ID).String(), }, PreferredDerp: 10, }) @@ -106,7 +106,7 @@ func TestCoordinator(t *testing.T) { defer agent.Close(ctx) agent.UpdateNode(&proto.Node{ Addresses: []string{ - netip.PrefixFrom(tailnet.IP(), 128).String(), + tailnet.TailscaleServicePrefix.RandomPrefix().String(), }, PreferredDerp: 10, }) @@ -126,7 +126,8 @@ func TestCoordinator(t *testing.T) { defer agent.Close(ctx) agent.UpdateNode(&proto.Node{ Addresses: []string{ - netip.PrefixFrom(tailnet.IPFromUUID(agent.ID), 64).String(), + netip.PrefixFrom( + tailnet.TailscaleServicePrefix.AddrFromUUID(agent.ID), 64).String(), }, PreferredDerp: 10, }) diff --git a/tailnet/telemetry_internal_test.go b/tailnet/telemetry_internal_test.go index 9b3e4d8820..8e4234f66c 100644 --- a/tailnet/telemetry_internal_test.go +++ b/tailnet/telemetry_internal_test.go @@ -18,7 +18,7 @@ func TestTelemetryStore(t *testing.T) { t.Run("CreateEvent", func(t *testing.T) { t.Parallel() - remotePrefix := netip.PrefixFrom(IP(), 128) + remotePrefix := TailscaleServicePrefix.RandomPrefix() remoteIP := remotePrefix.Addr() application := "test" @@ -31,16 +31,16 @@ func TestTelemetryStore(t *testing.T) { { ID: 1, Addresses: []netip.Prefix{ - netip.PrefixFrom(IP(), 128), - netip.PrefixFrom(IP(), 128), + TailscaleServicePrefix.RandomPrefix(), + TailscaleServicePrefix.RandomPrefix(), }, }, { ID: 2, Addresses: []netip.Prefix{ remotePrefix, - netip.PrefixFrom(IP(), 128), - netip.PrefixFrom(IP(), 128), + TailscaleServicePrefix.RandomPrefix(), + TailscaleServicePrefix.RandomPrefix(), }, }, }, diff --git a/tailnet/test/integration/integration.go b/tailnet/test/integration/integration.go index 0d3956cf44..ff38aec98b 100644 --- a/tailnet/test/integration/integration.go +++ b/tailnet/test/integration/integration.go @@ -373,7 +373,7 @@ http { // and creates a tailnet.Conn which will only use DERP to connect to the peer. func StartClientDERP(t *testing.T, logger slog.Logger, serverURL *url.URL, derpMap *tailcfg.DERPMap, me, peer Client) *tailnet.Conn { return startClientOptions(t, logger, serverURL, me, peer, &tailnet.Options{ - Addresses: []netip.Prefix{netip.PrefixFrom(tailnet.IPFromUUID(me.ID), 128)}, + Addresses: []netip.Prefix{tailnet.TailscaleServicePrefix.PrefixFromUUID(me.ID)}, DERPMap: derpMap, BlockEndpoints: true, Logger: logger, @@ -389,7 +389,7 @@ func StartClientDERP(t *testing.T, logger slog.Logger, serverURL *url.URL, derpM // only use DERP WebSocket fallback. func StartClientDERPWebSockets(t *testing.T, logger slog.Logger, serverURL *url.URL, derpMap *tailcfg.DERPMap, me, peer Client) *tailnet.Conn { return startClientOptions(t, logger, serverURL, me, peer, &tailnet.Options{ - Addresses: []netip.Prefix{netip.PrefixFrom(tailnet.IPFromUUID(me.ID), 128)}, + Addresses: []netip.Prefix{tailnet.TailscaleServicePrefix.PrefixFromUUID(me.ID)}, DERPMap: derpMap, BlockEndpoints: true, Logger: logger, @@ -406,7 +406,7 @@ func StartClientDERPWebSockets(t *testing.T, logger slog.Logger, serverURL *url. // connection to be established between the two peers. func StartClientDirect(t *testing.T, logger slog.Logger, serverURL *url.URL, derpMap *tailcfg.DERPMap, me, peer Client) *tailnet.Conn { conn := startClientOptions(t, logger, serverURL, me, peer, &tailnet.Options{ - Addresses: []netip.Prefix{netip.PrefixFrom(tailnet.IPFromUUID(me.ID), 128)}, + Addresses: []netip.Prefix{tailnet.TailscaleServicePrefix.PrefixFromUUID(me.ID)}, DERPMap: derpMap, BlockEndpoints: false, Logger: logger, @@ -418,7 +418,7 @@ func StartClientDirect(t *testing.T, logger slog.Logger, serverURL *url.URL, der }) // Wait for direct connection to be established. - peerIP := tailnet.IPFromUUID(peer.ID) + peerIP := tailnet.TailscaleServicePrefix.AddrFromUUID(peer.ID) require.Eventually(t, func() bool { t.Log("attempting ping to peer to judge direct connection") ctx := testutil.Context(t, testutil.WaitShort) diff --git a/tailnet/test/integration/integration_test.go b/tailnet/test/integration/integration_test.go index 142df60db0..c52aeca3c0 100644 --- a/tailnet/test/integration/integration_test.go +++ b/tailnet/test/integration/integration_test.go @@ -267,7 +267,7 @@ func handleTestSubprocess(t *testing.T) { if me.ShouldRunTests { // Wait for connectivity. - peerIP := tailnet.IPFromUUID(peer.ID) + peerIP := tailnet.TailscaleServicePrefix.AddrFromUUID(peer.ID) if !conn.AwaitReachable(testutil.Context(t, testutil.WaitLong), peerIP) { t.Fatalf("peer %v did not become reachable", peerIP) } diff --git a/tailnet/test/integration/suite.go b/tailnet/test/integration/suite.go index e3403da32b..eefba0eaf2 100644 --- a/tailnet/test/integration/suite.go +++ b/tailnet/test/integration/suite.go @@ -48,13 +48,13 @@ func TestSuite(t *testing.T, _ slog.Logger, serverURL *url.URL, conn *tailnet.Co t.Run("Connectivity", func(t *testing.T) { t.Parallel() - peerIP := tailnet.IPFromUUID(peer.ID) + peerIP := tailnet.TailscaleServicePrefix.AddrFromUUID(peer.ID) _, _, _, err := conn.Ping(testutil.Context(t, testutil.WaitLong), peerIP) require.NoError(t, err, "ping peer") }) t.Run("RestartDERP", func(t *testing.T) { - peerIP := tailnet.IPFromUUID(peer.ID) + peerIP := tailnet.TailscaleServicePrefix.AddrFromUUID(peer.ID) _, _, _, err := conn.Ping(testutil.Context(t, testutil.WaitLong), peerIP) require.NoError(t, err, "ping peer") sendRestart(t, serverURL, true, false) @@ -63,7 +63,7 @@ func TestSuite(t *testing.T, _ slog.Logger, serverURL *url.URL, conn *tailnet.Co }) t.Run("RestartCoordinator", func(t *testing.T) { - peerIP := tailnet.IPFromUUID(peer.ID) + peerIP := tailnet.TailscaleServicePrefix.AddrFromUUID(peer.ID) _, _, _, err := conn.Ping(testutil.Context(t, testutil.WaitLong), peerIP) require.NoError(t, err, "ping peer") sendRestart(t, serverURL, false, true) @@ -72,7 +72,7 @@ func TestSuite(t *testing.T, _ slog.Logger, serverURL *url.URL, conn *tailnet.Co }) t.Run("RestartBoth", func(t *testing.T) { - peerIP := tailnet.IPFromUUID(peer.ID) + peerIP := tailnet.TailscaleServicePrefix.AddrFromUUID(peer.ID) _, _, _, err := conn.Ping(testutil.Context(t, testutil.WaitLong), peerIP) require.NoError(t, err, "ping peer") sendRestart(t, serverURL, true, true) diff --git a/tailnet/tunnel.go b/tailnet/tunnel.go index 68b78d4f92..e5bd3c7875 100644 --- a/tailnet/tunnel.go +++ b/tailnet/tunnel.go @@ -80,7 +80,7 @@ func (a AgentCoordinateeAuth) Authorize(req *proto.CoordinateRequest) error { return xerrors.Errorf("invalid address bits, expected 128, got %d", pre.Bits()) } - if IPFromUUID(a.ID).Compare(pre.Addr()) != 0 && + if TailscaleServicePrefix.AddrFromUUID(a.ID).Compare(pre.Addr()) != 0 && legacyWorkspaceAgentIP.Compare(pre.Addr()) != 0 { return xerrors.Errorf("invalid node address, got %s", pre.Addr().String()) }