mirror of
https://github.com/coder/coder.git
synced 2026-06-02 20:48:20 +00:00
chore: add Coder service prefix to tailnet (#14943)
re: #14715 This PR introduces the Coder service prefix: `fd60:627a:a42b::/48` and refactors our existing code as calling the Tailscale service prefix explicitly (rather than implicitly). Removes the unused `Addresses` agent option. All clients today assume they can compute the Agent's IP address based on its UUID, so an agent started with a custom address would break things.
This commit is contained in:
+4
-11
@@ -82,7 +82,6 @@ type Options struct {
|
|||||||
SSHMaxTimeout time.Duration
|
SSHMaxTimeout time.Duration
|
||||||
TailnetListenPort uint16
|
TailnetListenPort uint16
|
||||||
Subsystems []codersdk.AgentSubsystem
|
Subsystems []codersdk.AgentSubsystem
|
||||||
Addresses []netip.Prefix
|
|
||||||
PrometheusRegistry *prometheus.Registry
|
PrometheusRegistry *prometheus.Registry
|
||||||
ReportMetadataInterval time.Duration
|
ReportMetadataInterval time.Duration
|
||||||
ServiceBannerRefreshInterval time.Duration
|
ServiceBannerRefreshInterval time.Duration
|
||||||
@@ -180,7 +179,6 @@ func New(options Options) Agent {
|
|||||||
announcementBannersRefreshInterval: options.ServiceBannerRefreshInterval,
|
announcementBannersRefreshInterval: options.ServiceBannerRefreshInterval,
|
||||||
sshMaxTimeout: options.SSHMaxTimeout,
|
sshMaxTimeout: options.SSHMaxTimeout,
|
||||||
subsystems: options.Subsystems,
|
subsystems: options.Subsystems,
|
||||||
addresses: options.Addresses,
|
|
||||||
syscaller: options.Syscaller,
|
syscaller: options.Syscaller,
|
||||||
modifiedProcs: options.ModifiedProcesses,
|
modifiedProcs: options.ModifiedProcesses,
|
||||||
processManagementTick: options.ProcessManagementTick,
|
processManagementTick: options.ProcessManagementTick,
|
||||||
@@ -250,7 +248,6 @@ type agent struct {
|
|||||||
lifecycleLastReportedIndex int // Keeps track of the last lifecycle state we successfully reported.
|
lifecycleLastReportedIndex int // Keeps track of the last lifecycle state we successfully reported.
|
||||||
|
|
||||||
network *tailnet.Conn
|
network *tailnet.Conn
|
||||||
addresses []netip.Prefix
|
|
||||||
statsReporter *statsReporter
|
statsReporter *statsReporter
|
||||||
logSender *agentsdk.LogSender
|
logSender *agentsdk.LogSender
|
||||||
|
|
||||||
@@ -1112,15 +1109,11 @@ func (a *agent) updateCommandEnv(current []string) (updated []string, err error)
|
|||||||
return updated, nil
|
return updated, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *agent) wireguardAddresses(agentID uuid.UUID) []netip.Prefix {
|
func (*agent) wireguardAddresses(agentID uuid.UUID) []netip.Prefix {
|
||||||
if len(a.addresses) == 0 {
|
return []netip.Prefix{
|
||||||
return []netip.Prefix{
|
// This is the IP that should be used primarily.
|
||||||
// This is the IP that should be used primarily.
|
tailnet.TailscaleServicePrefix.PrefixFromUUID(agentID),
|
||||||
netip.PrefixFrom(tailnet.IPFromUUID(agentID), 128),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return a.addresses
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *agent) trackGoroutine(fn func()) error {
|
func (a *agent) trackGoroutine(fn func()) error {
|
||||||
|
|||||||
+2
-2
@@ -1880,7 +1880,7 @@ func TestAgent_UpdatedDERP(t *testing.T) {
|
|||||||
// Setup a client connection.
|
// Setup a client connection.
|
||||||
newClientConn := func(derpMap *tailcfg.DERPMap, name string) *workspacesdk.AgentConn {
|
newClientConn := func(derpMap *tailcfg.DERPMap, name string) *workspacesdk.AgentConn {
|
||||||
conn, err := tailnet.NewConn(&tailnet.Options{
|
conn, err := tailnet.NewConn(&tailnet.Options{
|
||||||
Addresses: []netip.Prefix{netip.PrefixFrom(tailnet.IP(), 128)},
|
Addresses: []netip.Prefix{tailnet.TailscaleServicePrefix.RandomPrefix()},
|
||||||
DERPMap: derpMap,
|
DERPMap: derpMap,
|
||||||
Logger: logger.Named(name),
|
Logger: logger.Named(name),
|
||||||
})
|
})
|
||||||
@@ -2372,7 +2372,7 @@ func setupAgent(t *testing.T, metadata agentsdk.Manifest, ptyTimeout time.Durati
|
|||||||
_ = agnt.Close()
|
_ = agnt.Close()
|
||||||
})
|
})
|
||||||
conn, err := tailnet.NewConn(&tailnet.Options{
|
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,
|
DERPMap: metadata.DERPMap,
|
||||||
Logger: logger.Named("client"),
|
Logger: logger.Named("client"),
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -83,7 +83,7 @@ func TestDERP(t *testing.T) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
w1IP := tailnet.IP()
|
w1IP := tailnet.TailscaleServicePrefix.RandomAddr()
|
||||||
w1, err := tailnet.NewConn(&tailnet.Options{
|
w1, err := tailnet.NewConn(&tailnet.Options{
|
||||||
Addresses: []netip.Prefix{netip.PrefixFrom(w1IP, 128)},
|
Addresses: []netip.Prefix{netip.PrefixFrom(w1IP, 128)},
|
||||||
Logger: logger.Named("w1"),
|
Logger: logger.Named("w1"),
|
||||||
@@ -92,7 +92,7 @@ func TestDERP(t *testing.T) {
|
|||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
w2, err := tailnet.NewConn(&tailnet.Options{
|
w2, err := tailnet.NewConn(&tailnet.Options{
|
||||||
Addresses: []netip.Prefix{netip.PrefixFrom(tailnet.IP(), 128)},
|
Addresses: []netip.Prefix{tailnet.TailscaleServicePrefix.RandomPrefix()},
|
||||||
Logger: logger.Named("w2"),
|
Logger: logger.Named("w2"),
|
||||||
DERPMap: derpMap,
|
DERPMap: derpMap,
|
||||||
})
|
})
|
||||||
|
|||||||
+2
-2
@@ -61,7 +61,7 @@ func NewServerTailnet(
|
|||||||
) (*ServerTailnet, error) {
|
) (*ServerTailnet, error) {
|
||||||
logger = logger.Named("servertailnet")
|
logger = logger.Named("servertailnet")
|
||||||
conn, err := tailnet.NewConn(&tailnet.Options{
|
conn, err := tailnet.NewConn(&tailnet.Options{
|
||||||
Addresses: []netip.Prefix{netip.PrefixFrom(tailnet.IP(), 128)},
|
Addresses: []netip.Prefix{tailnet.TailscaleServicePrefix.RandomPrefix()},
|
||||||
DERPForceWebSockets: derpForceWebSockets,
|
DERPForceWebSockets: derpForceWebSockets,
|
||||||
Logger: logger,
|
Logger: logger,
|
||||||
BlockEndpoints: blockEndpoints,
|
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.
|
// "localhost:port", causing connections to be shared across agents.
|
||||||
tgt := *targetURL
|
tgt := *targetURL
|
||||||
_, port, _ := net.SplitHostPort(tgt.Host)
|
_, 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 := httputil.NewSingleHostReverseProxy(&tgt)
|
||||||
proxy.ErrorHandler = func(w http.ResponseWriter, r *http.Request, theErr error) {
|
proxy.ErrorHandler = func(w http.ResponseWriter, r *http.Request, theErr error) {
|
||||||
|
|||||||
@@ -186,7 +186,9 @@ func TestServerTailnet_ReverseProxy(t *testing.T) {
|
|||||||
// Ensure the reverse proxy director rewrites the url host to the agent's IP.
|
// Ensure the reverse proxy director rewrites the url host to the agent's IP.
|
||||||
rp.Director(req)
|
rp.Director(req)
|
||||||
assert.Equal(t,
|
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,
|
req.URL.Host,
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -51,7 +51,7 @@ type AgentConnOptions struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *AgentConn) agentAddress() netip.Addr {
|
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.
|
// AwaitReachable waits for the agent to be reachable.
|
||||||
|
|||||||
@@ -236,7 +236,7 @@ func (c *Client) DialAgent(dialCtx context.Context, agentID uuid.UUID, options *
|
|||||||
CompressionMode: websocket.CompressionDisabled,
|
CompressionMode: websocket.CompressionDisabled,
|
||||||
})
|
})
|
||||||
|
|
||||||
ip := tailnet.IP()
|
ip := tailnet.TailscaleServicePrefix.RandomAddr()
|
||||||
var header http.Header
|
var header http.Header
|
||||||
if headerTransport, ok := c.client.HTTPClient.Transport.(*codersdk.HeaderTransport); ok {
|
if headerTransport, ok := c.client.HTTPClient.Transport.(*codersdk.HeaderTransport); ok {
|
||||||
header = headerTransport.Header
|
header = headerTransport.Header
|
||||||
|
|||||||
@@ -120,7 +120,7 @@ func TestPGCoordinatorSingle_AgentInvalidIP(t *testing.T) {
|
|||||||
defer agent.Close(ctx)
|
defer agent.Close(ctx)
|
||||||
agent.UpdateNode(&proto.Node{
|
agent.UpdateNode(&proto.Node{
|
||||||
Addresses: []string{
|
Addresses: []string{
|
||||||
netip.PrefixFrom(agpl.IP(), 128).String(),
|
agpl.TailscaleServicePrefix.RandomPrefix().String(),
|
||||||
},
|
},
|
||||||
PreferredDerp: 10,
|
PreferredDerp: 10,
|
||||||
})
|
})
|
||||||
@@ -147,7 +147,7 @@ func TestPGCoordinatorSingle_AgentInvalidIPBits(t *testing.T) {
|
|||||||
defer agent.Close(ctx)
|
defer agent.Close(ctx)
|
||||||
agent.UpdateNode(&proto.Node{
|
agent.UpdateNode(&proto.Node{
|
||||||
Addresses: []string{
|
Addresses: []string{
|
||||||
netip.PrefixFrom(agpl.IPFromUUID(agent.ID), 64).String(),
|
netip.PrefixFrom(agpl.TailscaleServicePrefix.AddrFromUUID(agent.ID), 64).String(),
|
||||||
},
|
},
|
||||||
PreferredDerp: 10,
|
PreferredDerp: 10,
|
||||||
})
|
})
|
||||||
@@ -174,7 +174,7 @@ func TestPGCoordinatorSingle_AgentValidIP(t *testing.T) {
|
|||||||
defer agent.Close(ctx)
|
defer agent.Close(ctx)
|
||||||
agent.UpdateNode(&proto.Node{
|
agent.UpdateNode(&proto.Node{
|
||||||
Addresses: []string{
|
Addresses: []string{
|
||||||
netip.PrefixFrom(agpl.IPFromUUID(agent.ID), 128).String(),
|
agpl.TailscaleServicePrefix.PrefixFromUUID(agent.ID).String(),
|
||||||
},
|
},
|
||||||
PreferredDerp: 10,
|
PreferredDerp: 10,
|
||||||
})
|
})
|
||||||
|
|||||||
+37
-17
@@ -327,28 +327,48 @@ func NewConn(options *Options) (conn *Conn, err error) {
|
|||||||
return server, nil
|
return server, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func maskUUID(uid uuid.UUID) uuid.UUID {
|
type ServicePrefix [6]byte
|
||||||
// This is Tailscale's ephemeral service prefix. This can be changed easily
|
|
||||||
// later-on, because all of our nodes are ephemeral.
|
var (
|
||||||
// fd7a:115c:a1e0
|
// TailscaleServicePrefix is the IPv6 prefix for all tailnet nodes since it was first added to
|
||||||
uid[0] = 0xfd
|
// Coder. It is identical to the service prefix Tailscale.com uses. With the introduction of
|
||||||
uid[1] = 0x7a
|
// CoderVPN, we would like to stop using the Tailscale prefix so that we don't conflict with
|
||||||
uid[2] = 0x11
|
// Tailscale if both are installed at the same time. However, there are a large number of agents
|
||||||
uid[3] = 0x5c
|
// and clients using this prefix, so we need to carefully manage deprecation and eventual
|
||||||
uid[4] = 0xa1
|
// removal.
|
||||||
uid[5] = 0xe0
|
// 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
|
return uid
|
||||||
}
|
}
|
||||||
|
|
||||||
// IP generates a random IP with a static service prefix.
|
// RandomAddr returns a random IP address in the service prefix.
|
||||||
func IP() netip.Addr {
|
func (p ServicePrefix) RandomAddr() netip.Addr {
|
||||||
uid := maskUUID(uuid.New())
|
return netip.AddrFrom16(p.maskUUID(uuid.New()))
|
||||||
return netip.AddrFrom16(uid)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// IP generates a new IP from a UUID.
|
// AddrFromUUID returns an IPv6 address corresponding to the given UUID in the service prefix.
|
||||||
func IPFromUUID(uid uuid.UUID) netip.Addr {
|
func (p ServicePrefix) AddrFromUUID(uid uuid.UUID) netip.Addr {
|
||||||
return netip.AddrFrom16(maskUUID(uid))
|
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.
|
// Conn is an actively listening Wireguard connection.
|
||||||
|
|||||||
+44
-15
@@ -3,6 +3,7 @@ package tailnet_test
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"net/netip"
|
"net/netip"
|
||||||
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
@@ -30,7 +31,7 @@ func TestTailnet(t *testing.T) {
|
|||||||
t.Parallel()
|
t.Parallel()
|
||||||
logger := slogtest.Make(t, nil).Leveled(slog.LevelDebug)
|
logger := slogtest.Make(t, nil).Leveled(slog.LevelDebug)
|
||||||
conn, err := tailnet.NewConn(&tailnet.Options{
|
conn, err := tailnet.NewConn(&tailnet.Options{
|
||||||
Addresses: []netip.Prefix{netip.PrefixFrom(tailnet.IP(), 128)},
|
Addresses: []netip.Prefix{tailnet.TailscaleServicePrefix.RandomPrefix()},
|
||||||
Logger: logger.Named("w1"),
|
Logger: logger.Named("w1"),
|
||||||
DERPMap: derpMap,
|
DERPMap: derpMap,
|
||||||
})
|
})
|
||||||
@@ -42,7 +43,7 @@ func TestTailnet(t *testing.T) {
|
|||||||
t.Parallel()
|
t.Parallel()
|
||||||
logger := slogtest.Make(t, nil).Leveled(slog.LevelDebug)
|
logger := slogtest.Make(t, nil).Leveled(slog.LevelDebug)
|
||||||
ctx := testutil.Context(t, testutil.WaitLong)
|
ctx := testutil.Context(t, testutil.WaitLong)
|
||||||
w1IP := tailnet.IP()
|
w1IP := tailnet.TailscaleServicePrefix.RandomAddr()
|
||||||
w1, err := tailnet.NewConn(&tailnet.Options{
|
w1, err := tailnet.NewConn(&tailnet.Options{
|
||||||
Addresses: []netip.Prefix{netip.PrefixFrom(w1IP, 128)},
|
Addresses: []netip.Prefix{netip.PrefixFrom(w1IP, 128)},
|
||||||
Logger: logger.Named("w1"),
|
Logger: logger.Named("w1"),
|
||||||
@@ -51,7 +52,7 @@ func TestTailnet(t *testing.T) {
|
|||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
w2, err := tailnet.NewConn(&tailnet.Options{
|
w2, err := tailnet.NewConn(&tailnet.Options{
|
||||||
Addresses: []netip.Prefix{netip.PrefixFrom(tailnet.IP(), 128)},
|
Addresses: []netip.Prefix{tailnet.TailscaleServicePrefix.RandomPrefix()},
|
||||||
Logger: logger.Named("w2"),
|
Logger: logger.Named("w2"),
|
||||||
DERPMap: derpMap,
|
DERPMap: derpMap,
|
||||||
})
|
})
|
||||||
@@ -106,7 +107,7 @@ func TestTailnet(t *testing.T) {
|
|||||||
logger := slogtest.Make(t, nil).Leveled(slog.LevelDebug)
|
logger := slogtest.Make(t, nil).Leveled(slog.LevelDebug)
|
||||||
ctx := testutil.Context(t, testutil.WaitMedium)
|
ctx := testutil.Context(t, testutil.WaitMedium)
|
||||||
|
|
||||||
w1IP := tailnet.IP()
|
w1IP := tailnet.TailscaleServicePrefix.RandomAddr()
|
||||||
derpMap := tailnettest.RunDERPOnlyWebSockets(t)
|
derpMap := tailnettest.RunDERPOnlyWebSockets(t)
|
||||||
w1, err := tailnet.NewConn(&tailnet.Options{
|
w1, err := tailnet.NewConn(&tailnet.Options{
|
||||||
Addresses: []netip.Prefix{netip.PrefixFrom(w1IP, 128)},
|
Addresses: []netip.Prefix{netip.PrefixFrom(w1IP, 128)},
|
||||||
@@ -117,7 +118,7 @@ func TestTailnet(t *testing.T) {
|
|||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
w2, err := tailnet.NewConn(&tailnet.Options{
|
w2, err := tailnet.NewConn(&tailnet.Options{
|
||||||
Addresses: []netip.Prefix{netip.PrefixFrom(tailnet.IP(), 128)},
|
Addresses: []netip.Prefix{tailnet.TailscaleServicePrefix.RandomPrefix()},
|
||||||
Logger: logger.Named("w2"),
|
Logger: logger.Named("w2"),
|
||||||
DERPMap: derpMap,
|
DERPMap: derpMap,
|
||||||
BlockEndpoints: true,
|
BlockEndpoints: true,
|
||||||
@@ -168,7 +169,7 @@ func TestTailnet(t *testing.T) {
|
|||||||
t.Parallel()
|
t.Parallel()
|
||||||
logger := slogtest.Make(t, nil).Leveled(slog.LevelDebug)
|
logger := slogtest.Make(t, nil).Leveled(slog.LevelDebug)
|
||||||
ctx := testutil.Context(t, testutil.WaitLong)
|
ctx := testutil.Context(t, testutil.WaitLong)
|
||||||
w1IP := tailnet.IP()
|
w1IP := tailnet.TailscaleServicePrefix.RandomAddr()
|
||||||
w1, err := tailnet.NewConn(&tailnet.Options{
|
w1, err := tailnet.NewConn(&tailnet.Options{
|
||||||
Addresses: []netip.Prefix{netip.PrefixFrom(w1IP, 128)},
|
Addresses: []netip.Prefix{netip.PrefixFrom(w1IP, 128)},
|
||||||
Logger: logger.Named("w1"),
|
Logger: logger.Named("w1"),
|
||||||
@@ -177,7 +178,7 @@ func TestTailnet(t *testing.T) {
|
|||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
w2, err := tailnet.NewConn(&tailnet.Options{
|
w2, err := tailnet.NewConn(&tailnet.Options{
|
||||||
Addresses: []netip.Prefix{netip.PrefixFrom(tailnet.IP(), 128)},
|
Addresses: []netip.Prefix{tailnet.TailscaleServicePrefix.RandomPrefix()},
|
||||||
Logger: logger.Named("w2"),
|
Logger: logger.Named("w2"),
|
||||||
DERPMap: derpMap,
|
DERPMap: derpMap,
|
||||||
})
|
})
|
||||||
@@ -211,7 +212,7 @@ func TestTailnet(t *testing.T) {
|
|||||||
t.Parallel()
|
t.Parallel()
|
||||||
logger := slogtest.Make(t, nil).Leveled(slog.LevelDebug)
|
logger := slogtest.Make(t, nil).Leveled(slog.LevelDebug)
|
||||||
ctx := testutil.Context(t, testutil.WaitLong)
|
ctx := testutil.Context(t, testutil.WaitLong)
|
||||||
w1IP := tailnet.IP()
|
w1IP := tailnet.TailscaleServicePrefix.RandomAddr()
|
||||||
w1, err := tailnet.NewConn(&tailnet.Options{
|
w1, err := tailnet.NewConn(&tailnet.Options{
|
||||||
Addresses: []netip.Prefix{netip.PrefixFrom(w1IP, 128)},
|
Addresses: []netip.Prefix{netip.PrefixFrom(w1IP, 128)},
|
||||||
Logger: logger.Named("w1"),
|
Logger: logger.Named("w1"),
|
||||||
@@ -221,7 +222,7 @@ func TestTailnet(t *testing.T) {
|
|||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
w2, err := tailnet.NewConn(&tailnet.Options{
|
w2, err := tailnet.NewConn(&tailnet.Options{
|
||||||
Addresses: []netip.Prefix{netip.PrefixFrom(tailnet.IP(), 128)},
|
Addresses: []netip.Prefix{tailnet.TailscaleServicePrefix.RandomPrefix()},
|
||||||
Logger: logger.Named("w2"),
|
Logger: logger.Named("w2"),
|
||||||
DERPMap: derpMap,
|
DERPMap: derpMap,
|
||||||
BlockEndpoints: true,
|
BlockEndpoints: true,
|
||||||
@@ -261,7 +262,7 @@ func TestConn_PreferredDERP(t *testing.T) {
|
|||||||
logger := slogtest.Make(t, nil).Leveled(slog.LevelDebug)
|
logger := slogtest.Make(t, nil).Leveled(slog.LevelDebug)
|
||||||
derpMap, _ := tailnettest.RunDERPAndSTUN(t)
|
derpMap, _ := tailnettest.RunDERPAndSTUN(t)
|
||||||
conn, err := tailnet.NewConn(&tailnet.Options{
|
conn, err := tailnet.NewConn(&tailnet.Options{
|
||||||
Addresses: []netip.Prefix{netip.PrefixFrom(tailnet.IP(), 128)},
|
Addresses: []netip.Prefix{tailnet.TailscaleServicePrefix.RandomPrefix()},
|
||||||
Logger: logger.Named("w1"),
|
Logger: logger.Named("w1"),
|
||||||
DERPMap: derpMap,
|
DERPMap: derpMap,
|
||||||
})
|
})
|
||||||
@@ -290,7 +291,7 @@ func TestConn_UpdateDERP(t *testing.T) {
|
|||||||
logger := slogtest.Make(t, nil).Leveled(slog.LevelDebug)
|
logger := slogtest.Make(t, nil).Leveled(slog.LevelDebug)
|
||||||
|
|
||||||
derpMap1, _ := tailnettest.RunDERPAndSTUN(t)
|
derpMap1, _ := tailnettest.RunDERPAndSTUN(t)
|
||||||
ip := tailnet.IP()
|
ip := tailnet.TailscaleServicePrefix.RandomAddr()
|
||||||
conn, err := tailnet.NewConn(&tailnet.Options{
|
conn, err := tailnet.NewConn(&tailnet.Options{
|
||||||
Addresses: []netip.Prefix{netip.PrefixFrom(ip, 128)},
|
Addresses: []netip.Prefix{netip.PrefixFrom(ip, 128)},
|
||||||
Logger: logger.Named("w1"),
|
Logger: logger.Named("w1"),
|
||||||
@@ -320,7 +321,7 @@ func TestConn_UpdateDERP(t *testing.T) {
|
|||||||
|
|
||||||
// Connect from a different client.
|
// Connect from a different client.
|
||||||
client1, err := tailnet.NewConn(&tailnet.Options{
|
client1, err := tailnet.NewConn(&tailnet.Options{
|
||||||
Addresses: []netip.Prefix{netip.PrefixFrom(tailnet.IP(), 128)},
|
Addresses: []netip.Prefix{tailnet.TailscaleServicePrefix.RandomPrefix()},
|
||||||
Logger: logger.Named("client1"),
|
Logger: logger.Named("client1"),
|
||||||
DERPMap: derpMap1,
|
DERPMap: derpMap1,
|
||||||
BlockEndpoints: true,
|
BlockEndpoints: true,
|
||||||
@@ -394,7 +395,7 @@ parentLoop:
|
|||||||
// Connect from a different different client with up-to-date derp map and
|
// Connect from a different different client with up-to-date derp map and
|
||||||
// nodes.
|
// nodes.
|
||||||
client2, err := tailnet.NewConn(&tailnet.Options{
|
client2, err := tailnet.NewConn(&tailnet.Options{
|
||||||
Addresses: []netip.Prefix{netip.PrefixFrom(tailnet.IP(), 128)},
|
Addresses: []netip.Prefix{tailnet.TailscaleServicePrefix.RandomPrefix()},
|
||||||
Logger: logger.Named("client2"),
|
Logger: logger.Named("client2"),
|
||||||
DERPMap: derpMap2,
|
DERPMap: derpMap2,
|
||||||
BlockEndpoints: true,
|
BlockEndpoints: true,
|
||||||
@@ -425,7 +426,7 @@ func TestConn_BlockEndpoints(t *testing.T) {
|
|||||||
derpMap, _ := tailnettest.RunDERPAndSTUN(t)
|
derpMap, _ := tailnettest.RunDERPAndSTUN(t)
|
||||||
|
|
||||||
// Setup conn 1.
|
// Setup conn 1.
|
||||||
ip1 := tailnet.IP()
|
ip1 := tailnet.TailscaleServicePrefix.RandomAddr()
|
||||||
conn1, err := tailnet.NewConn(&tailnet.Options{
|
conn1, err := tailnet.NewConn(&tailnet.Options{
|
||||||
Addresses: []netip.Prefix{netip.PrefixFrom(ip1, 128)},
|
Addresses: []netip.Prefix{netip.PrefixFrom(ip1, 128)},
|
||||||
Logger: logger.Named("w1"),
|
Logger: logger.Named("w1"),
|
||||||
@@ -439,7 +440,7 @@ func TestConn_BlockEndpoints(t *testing.T) {
|
|||||||
}()
|
}()
|
||||||
|
|
||||||
// Setup conn 2.
|
// Setup conn 2.
|
||||||
ip2 := tailnet.IP()
|
ip2 := tailnet.TailscaleServicePrefix.RandomAddr()
|
||||||
conn2, err := tailnet.NewConn(&tailnet.Options{
|
conn2, err := tailnet.NewConn(&tailnet.Options{
|
||||||
Addresses: []netip.Prefix{netip.PrefixFrom(ip2, 128)},
|
Addresses: []netip.Prefix{netip.PrefixFrom(ip2, 128)},
|
||||||
Logger: logger.Named("w2"),
|
Logger: logger.Named("w2"),
|
||||||
@@ -492,3 +493,31 @@ func stitch(t *testing.T, dst, src *tailnet.Conn) {
|
|||||||
assert.NoError(t, err)
|
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())
|
||||||
|
}
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ func TestCoordinator(t *testing.T) {
|
|||||||
client := test.NewClient(ctx, t, coordinator, "client", uuid.New())
|
client := test.NewClient(ctx, t, coordinator, "client", uuid.New())
|
||||||
defer client.Close(ctx)
|
defer client.Close(ctx)
|
||||||
client.UpdateNode(&proto.Node{
|
client.UpdateNode(&proto.Node{
|
||||||
Addresses: []string{netip.PrefixFrom(tailnet.IP(), 128).String()},
|
Addresses: []string{tailnet.TailscaleServicePrefix.RandomPrefix().String()},
|
||||||
PreferredDerp: 10,
|
PreferredDerp: 10,
|
||||||
})
|
})
|
||||||
require.Eventually(t, func() bool {
|
require.Eventually(t, func() bool {
|
||||||
@@ -63,7 +63,7 @@ func TestCoordinator(t *testing.T) {
|
|||||||
|
|
||||||
client.UpdateNode(&proto.Node{
|
client.UpdateNode(&proto.Node{
|
||||||
Addresses: []string{
|
Addresses: []string{
|
||||||
netip.PrefixFrom(tailnet.IP(), 64).String(),
|
netip.PrefixFrom(tailnet.TailscaleServicePrefix.RandomAddr(), 64).String(),
|
||||||
},
|
},
|
||||||
PreferredDerp: 10,
|
PreferredDerp: 10,
|
||||||
})
|
})
|
||||||
@@ -84,7 +84,7 @@ func TestCoordinator(t *testing.T) {
|
|||||||
defer agent.Close(ctx)
|
defer agent.Close(ctx)
|
||||||
agent.UpdateNode(&proto.Node{
|
agent.UpdateNode(&proto.Node{
|
||||||
Addresses: []string{
|
Addresses: []string{
|
||||||
netip.PrefixFrom(tailnet.IPFromUUID(agent.ID), 128).String(),
|
tailnet.TailscaleServicePrefix.PrefixFromUUID(agent.ID).String(),
|
||||||
},
|
},
|
||||||
PreferredDerp: 10,
|
PreferredDerp: 10,
|
||||||
})
|
})
|
||||||
@@ -106,7 +106,7 @@ func TestCoordinator(t *testing.T) {
|
|||||||
defer agent.Close(ctx)
|
defer agent.Close(ctx)
|
||||||
agent.UpdateNode(&proto.Node{
|
agent.UpdateNode(&proto.Node{
|
||||||
Addresses: []string{
|
Addresses: []string{
|
||||||
netip.PrefixFrom(tailnet.IP(), 128).String(),
|
tailnet.TailscaleServicePrefix.RandomPrefix().String(),
|
||||||
},
|
},
|
||||||
PreferredDerp: 10,
|
PreferredDerp: 10,
|
||||||
})
|
})
|
||||||
@@ -126,7 +126,8 @@ func TestCoordinator(t *testing.T) {
|
|||||||
defer agent.Close(ctx)
|
defer agent.Close(ctx)
|
||||||
agent.UpdateNode(&proto.Node{
|
agent.UpdateNode(&proto.Node{
|
||||||
Addresses: []string{
|
Addresses: []string{
|
||||||
netip.PrefixFrom(tailnet.IPFromUUID(agent.ID), 64).String(),
|
netip.PrefixFrom(
|
||||||
|
tailnet.TailscaleServicePrefix.AddrFromUUID(agent.ID), 64).String(),
|
||||||
},
|
},
|
||||||
PreferredDerp: 10,
|
PreferredDerp: 10,
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ func TestTelemetryStore(t *testing.T) {
|
|||||||
t.Run("CreateEvent", func(t *testing.T) {
|
t.Run("CreateEvent", func(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
remotePrefix := netip.PrefixFrom(IP(), 128)
|
remotePrefix := TailscaleServicePrefix.RandomPrefix()
|
||||||
remoteIP := remotePrefix.Addr()
|
remoteIP := remotePrefix.Addr()
|
||||||
application := "test"
|
application := "test"
|
||||||
|
|
||||||
@@ -31,16 +31,16 @@ func TestTelemetryStore(t *testing.T) {
|
|||||||
{
|
{
|
||||||
ID: 1,
|
ID: 1,
|
||||||
Addresses: []netip.Prefix{
|
Addresses: []netip.Prefix{
|
||||||
netip.PrefixFrom(IP(), 128),
|
TailscaleServicePrefix.RandomPrefix(),
|
||||||
netip.PrefixFrom(IP(), 128),
|
TailscaleServicePrefix.RandomPrefix(),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
ID: 2,
|
ID: 2,
|
||||||
Addresses: []netip.Prefix{
|
Addresses: []netip.Prefix{
|
||||||
remotePrefix,
|
remotePrefix,
|
||||||
netip.PrefixFrom(IP(), 128),
|
TailscaleServicePrefix.RandomPrefix(),
|
||||||
netip.PrefixFrom(IP(), 128),
|
TailscaleServicePrefix.RandomPrefix(),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -373,7 +373,7 @@ http {
|
|||||||
// and creates a tailnet.Conn which will only use DERP to connect to the peer.
|
// 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 {
|
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{
|
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,
|
DERPMap: derpMap,
|
||||||
BlockEndpoints: true,
|
BlockEndpoints: true,
|
||||||
Logger: logger,
|
Logger: logger,
|
||||||
@@ -389,7 +389,7 @@ func StartClientDERP(t *testing.T, logger slog.Logger, serverURL *url.URL, derpM
|
|||||||
// only use DERP WebSocket fallback.
|
// only use DERP WebSocket fallback.
|
||||||
func StartClientDERPWebSockets(t *testing.T, logger slog.Logger, serverURL *url.URL, derpMap *tailcfg.DERPMap, me, peer Client) *tailnet.Conn {
|
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{
|
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,
|
DERPMap: derpMap,
|
||||||
BlockEndpoints: true,
|
BlockEndpoints: true,
|
||||||
Logger: logger,
|
Logger: logger,
|
||||||
@@ -406,7 +406,7 @@ func StartClientDERPWebSockets(t *testing.T, logger slog.Logger, serverURL *url.
|
|||||||
// connection to be established between the two peers.
|
// 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 {
|
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{
|
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,
|
DERPMap: derpMap,
|
||||||
BlockEndpoints: false,
|
BlockEndpoints: false,
|
||||||
Logger: logger,
|
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.
|
// Wait for direct connection to be established.
|
||||||
peerIP := tailnet.IPFromUUID(peer.ID)
|
peerIP := tailnet.TailscaleServicePrefix.AddrFromUUID(peer.ID)
|
||||||
require.Eventually(t, func() bool {
|
require.Eventually(t, func() bool {
|
||||||
t.Log("attempting ping to peer to judge direct connection")
|
t.Log("attempting ping to peer to judge direct connection")
|
||||||
ctx := testutil.Context(t, testutil.WaitShort)
|
ctx := testutil.Context(t, testutil.WaitShort)
|
||||||
|
|||||||
@@ -267,7 +267,7 @@ func handleTestSubprocess(t *testing.T) {
|
|||||||
|
|
||||||
if me.ShouldRunTests {
|
if me.ShouldRunTests {
|
||||||
// Wait for connectivity.
|
// Wait for connectivity.
|
||||||
peerIP := tailnet.IPFromUUID(peer.ID)
|
peerIP := tailnet.TailscaleServicePrefix.AddrFromUUID(peer.ID)
|
||||||
if !conn.AwaitReachable(testutil.Context(t, testutil.WaitLong), peerIP) {
|
if !conn.AwaitReachable(testutil.Context(t, testutil.WaitLong), peerIP) {
|
||||||
t.Fatalf("peer %v did not become reachable", peerIP)
|
t.Fatalf("peer %v did not become reachable", peerIP)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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.Run("Connectivity", func(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
peerIP := tailnet.IPFromUUID(peer.ID)
|
peerIP := tailnet.TailscaleServicePrefix.AddrFromUUID(peer.ID)
|
||||||
_, _, _, err := conn.Ping(testutil.Context(t, testutil.WaitLong), peerIP)
|
_, _, _, err := conn.Ping(testutil.Context(t, testutil.WaitLong), peerIP)
|
||||||
require.NoError(t, err, "ping peer")
|
require.NoError(t, err, "ping peer")
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("RestartDERP", func(t *testing.T) {
|
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)
|
_, _, _, err := conn.Ping(testutil.Context(t, testutil.WaitLong), peerIP)
|
||||||
require.NoError(t, err, "ping peer")
|
require.NoError(t, err, "ping peer")
|
||||||
sendRestart(t, serverURL, true, false)
|
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) {
|
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)
|
_, _, _, err := conn.Ping(testutil.Context(t, testutil.WaitLong), peerIP)
|
||||||
require.NoError(t, err, "ping peer")
|
require.NoError(t, err, "ping peer")
|
||||||
sendRestart(t, serverURL, false, true)
|
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) {
|
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)
|
_, _, _, err := conn.Ping(testutil.Context(t, testutil.WaitLong), peerIP)
|
||||||
require.NoError(t, err, "ping peer")
|
require.NoError(t, err, "ping peer")
|
||||||
sendRestart(t, serverURL, true, true)
|
sendRestart(t, serverURL, true, true)
|
||||||
|
|||||||
+1
-1
@@ -80,7 +80,7 @@ func (a AgentCoordinateeAuth) Authorize(req *proto.CoordinateRequest) error {
|
|||||||
return xerrors.Errorf("invalid address bits, expected 128, got %d", pre.Bits())
|
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 {
|
legacyWorkspaceAgentIP.Compare(pre.Addr()) != 0 {
|
||||||
return xerrors.Errorf("invalid node address, got %s", pre.Addr().String())
|
return xerrors.Errorf("invalid node address, got %s", pre.Addr().String())
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user