Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

feat: add configurable DNS match domain for tailnet connections#17336

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to ourterms of service andprivacy statement. We’ll occasionally send you account related emails.

Already on GitHub?Sign in to your account

Merged
spikecurtis merged 1 commit intomainfromspike/host-suffix/dns-match-domain
Apr 11, 2025
Merged
Show file tree
Hide file tree
Changes fromall commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 17 additions & 7 deletionstailnet/configmaps.go
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -36,7 +36,10 @@ const lostTimeout = 15 * time.Minute

// CoderDNSSuffix is the default DNS suffix that we append to Coder DNS
// records.
const CoderDNSSuffix = "coder."
const (
CoderDNSSuffix = "coder"
CoderDNSSuffixFQDN = dnsname.FQDN(CoderDNSSuffix + ".")
)

// engineConfigurable is the subset of wgengine.Engine that we use for configuration.
//
Expand DownExpand Up@@ -69,20 +72,26 @@ type configMaps struct {
filterDirty bool
closing bool

engine engineConfigurable
static netmap.NetworkMap
engine engineConfigurable
static netmap.NetworkMap

hosts map[dnsname.FQDN][]netip.Addr
peers map[uuid.UUID]*peerLifecycle
addresses []netip.Prefix
derpMap *tailcfg.DERPMap
logger slog.Logger
blockEndpoints bool
matchDomain dnsname.FQDN

// for testing
clock quartz.Clock
}

func newConfigMaps(logger slog.Logger, engine engineConfigurable, nodeID tailcfg.NodeID, nodeKey key.NodePrivate, discoKey key.DiscoPublic) *configMaps {
func newConfigMaps(
logger slog.Logger, engine engineConfigurable,
nodeID tailcfg.NodeID, nodeKey key.NodePrivate, discoKey key.DiscoPublic,
matchDomain dnsname.FQDN,
) *configMaps {
pubKey := nodeKey.Public()
c := &configMaps{
phased: phased{Cond: *(sync.NewCond(&sync.Mutex{}))},
Expand DownExpand Up@@ -125,8 +134,9 @@ func newConfigMaps(logger slog.Logger, engine engineConfigurable, nodeID tailcfg
Caps: []filter.CapMatch{},
}},
},
peers: make(map[uuid.UUID]*peerLifecycle),
clock: quartz.NewReal(),
peers: make(map[uuid.UUID]*peerLifecycle),
matchDomain: matchDomain,
clock: quartz.NewReal(),
}
go c.configLoop()
return c
Expand DownExpand Up@@ -338,7 +348,7 @@ func (c *configMaps) reconfig(nm *netmap.NetworkMap, hosts map[dnsname.FQDN][]ne
dnsCfg.Hosts = hosts
dnsCfg.OnlyIPv6 = true
dnsCfg.Routes = map[dnsname.FQDN][]*dnstype.Resolver{
CoderDNSSuffix: nil,
c.matchDomain: nil,
}
}
cfg, err := nmcfg.WGCfg(nm, Logger(c.logger.Named("net.wgconfig")), netmap.AllowSingleHosts, "")
Expand Down
45 changes: 24 additions & 21 deletionstailnet/configmaps_internal_test.go
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -34,7 +34,7 @@ func TestConfigMaps_setAddresses_different(t *testing.T) {
nodePrivateKey := key.NewNode()
nodeID := tailcfg.NodeID(5)
discoKey := key.NewDisco()
uut := newConfigMaps(logger, fEng, nodeID, nodePrivateKey, discoKey.Public())
uut := newConfigMaps(logger, fEng, nodeID, nodePrivateKey, discoKey.Public(), CoderDNSSuffixFQDN)
defer uut.close()

addrs := []netip.Prefix{netip.MustParsePrefix("192.168.0.200/32")}
Expand DownExpand Up@@ -93,7 +93,7 @@ func TestConfigMaps_setAddresses_same(t *testing.T) {
nodeID := tailcfg.NodeID(5)
discoKey := key.NewDisco()
addrs := []netip.Prefix{netip.MustParsePrefix("192.168.0.200/32")}
uut := newConfigMaps(logger, fEng, nodeID, nodePrivateKey, discoKey.Public())
uut := newConfigMaps(logger, fEng, nodeID, nodePrivateKey, discoKey.Public(), CoderDNSSuffixFQDN)
defer uut.close()

// Given: addresses already set
Expand DownExpand Up@@ -123,7 +123,7 @@ func TestConfigMaps_updatePeers_new(t *testing.T) {
nodePrivateKey := key.NewNode()
nodeID := tailcfg.NodeID(5)
discoKey := key.NewDisco()
uut := newConfigMaps(logger, fEng, nodeID, nodePrivateKey, discoKey.Public())
uut := newConfigMaps(logger, fEng, nodeID, nodePrivateKey, discoKey.Public(), CoderDNSSuffixFQDN)
defer uut.close()

p1ID := uuid.UUID{1}
Expand DownExpand Up@@ -193,7 +193,7 @@ func TestConfigMaps_updatePeers_new_waitForHandshake_neverConfigures(t *testing.
nodePrivateKey := key.NewNode()
nodeID := tailcfg.NodeID(5)
discoKey := key.NewDisco()
uut := newConfigMaps(logger, fEng, nodeID, nodePrivateKey, discoKey.Public())
uut := newConfigMaps(logger, fEng, nodeID, nodePrivateKey, discoKey.Public(), CoderDNSSuffixFQDN)
defer uut.close()
mClock := quartz.NewMock(t)
uut.clock = mClock
Expand DownExpand Up@@ -237,7 +237,7 @@ func TestConfigMaps_updatePeers_new_waitForHandshake_outOfOrder(t *testing.T) {
nodePrivateKey := key.NewNode()
nodeID := tailcfg.NodeID(5)
discoKey := key.NewDisco()
uut := newConfigMaps(logger, fEng, nodeID, nodePrivateKey, discoKey.Public())
uut := newConfigMaps(logger, fEng, nodeID, nodePrivateKey, discoKey.Public(), CoderDNSSuffixFQDN)
defer uut.close()
mClock := quartz.NewMock(t)
uut.clock = mClock
Expand DownExpand Up@@ -308,7 +308,7 @@ func TestConfigMaps_updatePeers_new_waitForHandshake(t *testing.T) {
nodePrivateKey := key.NewNode()
nodeID := tailcfg.NodeID(5)
discoKey := key.NewDisco()
uut := newConfigMaps(logger, fEng, nodeID, nodePrivateKey, discoKey.Public())
uut := newConfigMaps(logger, fEng, nodeID, nodePrivateKey, discoKey.Public(), CoderDNSSuffixFQDN)
defer uut.close()
mClock := quartz.NewMock(t)
uut.clock = mClock
Expand DownExpand Up@@ -379,7 +379,7 @@ func TestConfigMaps_updatePeers_new_waitForHandshake_timeout(t *testing.T) {
nodePrivateKey := key.NewNode()
nodeID := tailcfg.NodeID(5)
discoKey := key.NewDisco()
uut := newConfigMaps(logger, fEng, nodeID, nodePrivateKey, discoKey.Public())
uut := newConfigMaps(logger, fEng, nodeID, nodePrivateKey, discoKey.Public(), CoderDNSSuffixFQDN)
defer uut.close()
mClock := quartz.NewMock(t)
uut.clock = mClock
Expand DownExpand Up@@ -437,7 +437,7 @@ func TestConfigMaps_updatePeers_same(t *testing.T) {
nodePrivateKey := key.NewNode()
nodeID := tailcfg.NodeID(5)
discoKey := key.NewDisco()
uut := newConfigMaps(logger, fEng, nodeID, nodePrivateKey, discoKey.Public())
uut := newConfigMaps(logger, fEng, nodeID, nodePrivateKey, discoKey.Public(), CoderDNSSuffixFQDN)
defer uut.close()

// Then: we don't configure
Expand DownExpand Up@@ -496,7 +496,7 @@ func TestConfigMaps_updatePeers_disconnect(t *testing.T) {
nodePrivateKey := key.NewNode()
nodeID := tailcfg.NodeID(5)
discoKey := key.NewDisco()
uut := newConfigMaps(logger, fEng, nodeID, nodePrivateKey, discoKey.Public())
uut := newConfigMaps(logger, fEng, nodeID, nodePrivateKey, discoKey.Public(), CoderDNSSuffixFQDN)
defer uut.close()

p1ID := uuid.UUID{1}
Expand DownExpand Up@@ -564,7 +564,7 @@ func TestConfigMaps_updatePeers_lost(t *testing.T) {
nodePrivateKey := key.NewNode()
nodeID := tailcfg.NodeID(5)
discoKey := key.NewDisco()
uut := newConfigMaps(logger, fEng, nodeID, nodePrivateKey, discoKey.Public())
uut := newConfigMaps(logger, fEng, nodeID, nodePrivateKey, discoKey.Public(), CoderDNSSuffixFQDN)
defer uut.close()
mClock := quartz.NewMock(t)
start := mClock.Now()
Expand DownExpand Up@@ -649,7 +649,7 @@ func TestConfigMaps_updatePeers_lost_and_found(t *testing.T) {
nodePrivateKey := key.NewNode()
nodeID := tailcfg.NodeID(5)
discoKey := key.NewDisco()
uut := newConfigMaps(logger, fEng, nodeID, nodePrivateKey, discoKey.Public())
uut := newConfigMaps(logger, fEng, nodeID, nodePrivateKey, discoKey.Public(), CoderDNSSuffixFQDN)
defer uut.close()
mClock := quartz.NewMock(t)
start := mClock.Now()
Expand DownExpand Up@@ -734,7 +734,7 @@ func TestConfigMaps_setAllPeersLost(t *testing.T) {
nodePrivateKey := key.NewNode()
nodeID := tailcfg.NodeID(5)
discoKey := key.NewDisco()
uut := newConfigMaps(logger, fEng, nodeID, nodePrivateKey, discoKey.Public())
uut := newConfigMaps(logger, fEng, nodeID, nodePrivateKey, discoKey.Public(), CoderDNSSuffixFQDN)
defer uut.close()
mClock := quartz.NewMock(t)
start := mClock.Now()
Expand DownExpand Up@@ -820,7 +820,7 @@ func TestConfigMaps_setBlockEndpoints_different(t *testing.T) {
nodePrivateKey := key.NewNode()
nodeID := tailcfg.NodeID(5)
discoKey := key.NewDisco()
uut := newConfigMaps(logger, fEng, nodeID, nodePrivateKey, discoKey.Public())
uut := newConfigMaps(logger, fEng, nodeID, nodePrivateKey, discoKey.Public(), CoderDNSSuffixFQDN)
defer uut.close()

p1ID := uuid.MustParse("10000000-0000-0000-0000-000000000000")
Expand DownExpand Up@@ -864,7 +864,7 @@ func TestConfigMaps_setBlockEndpoints_same(t *testing.T) {
nodePrivateKey := key.NewNode()
nodeID := tailcfg.NodeID(5)
discoKey := key.NewDisco()
uut := newConfigMaps(logger, fEng, nodeID, nodePrivateKey, discoKey.Public())
uut := newConfigMaps(logger, fEng, nodeID, nodePrivateKey, discoKey.Public(), CoderDNSSuffixFQDN)
defer uut.close()

p1ID := uuid.MustParse("10000000-0000-0000-0000-000000000000")
Expand DownExpand Up@@ -907,7 +907,7 @@ func TestConfigMaps_setDERPMap_different(t *testing.T) {
nodePrivateKey := key.NewNode()
nodeID := tailcfg.NodeID(5)
discoKey := key.NewDisco()
uut := newConfigMaps(logger, fEng, nodeID, nodePrivateKey, discoKey.Public())
uut := newConfigMaps(logger, fEng, nodeID, nodePrivateKey, discoKey.Public(), CoderDNSSuffixFQDN)
defer uut.close()

derpMap := &tailcfg.DERPMap{
Expand DownExpand Up@@ -948,7 +948,7 @@ func TestConfigMaps_setDERPMap_same(t *testing.T) {
nodePrivateKey := key.NewNode()
nodeID := tailcfg.NodeID(5)
discoKey := key.NewDisco()
uut := newConfigMaps(logger, fEng, nodeID, nodePrivateKey, discoKey.Public())
uut := newConfigMaps(logger, fEng, nodeID, nodePrivateKey, discoKey.Public(), CoderDNSSuffixFQDN)
defer uut.close()

// Given: DERP Map already set
Expand DownExpand Up@@ -1017,7 +1017,7 @@ func TestConfigMaps_fillPeerDiagnostics(t *testing.T) {
nodePrivateKey := key.NewNode()
nodeID := tailcfg.NodeID(5)
discoKey := key.NewDisco()
uut := newConfigMaps(logger, fEng, nodeID, nodePrivateKey, discoKey.Public())
uut := newConfigMaps(logger, fEng, nodeID, nodePrivateKey, discoKey.Public(), CoderDNSSuffixFQDN)
defer uut.close()

// Given: DERP Map and peer already set
Expand DownExpand Up@@ -1125,7 +1125,7 @@ func TestConfigMaps_updatePeers_nonexist(t *testing.T) {
nodePrivateKey := key.NewNode()
nodeID := tailcfg.NodeID(5)
discoKey := key.NewDisco()
uut := newConfigMaps(logger, fEng, nodeID, nodePrivateKey, discoKey.Public())
uut := newConfigMaps(logger, fEng, nodeID, nodePrivateKey, discoKey.Public(), CoderDNSSuffixFQDN)
defer uut.close()

// Then: we don't configure
Expand DownExpand Up@@ -1166,7 +1166,8 @@ func TestConfigMaps_addRemoveHosts(t *testing.T) {
nodePrivateKey := key.NewNode()
nodeID := tailcfg.NodeID(5)
discoKey := key.NewDisco()
uut := newConfigMaps(logger, fEng, nodeID, nodePrivateKey, discoKey.Public())
suffix := dnsname.FQDN("test.")
uut := newConfigMaps(logger, fEng, nodeID, nodePrivateKey, discoKey.Public(), suffix)
defer uut.close()

addr1 := CoderServicePrefix.AddrFromUUID(uuid.New())
Expand All@@ -1190,8 +1191,10 @@ func TestConfigMaps_addRemoveHosts(t *testing.T) {
req := testutil.RequireRecvCtx(ctx, t, fEng.reconfig)
require.Equal(t, req.dnsCfg, &dns.Config{
Routes: map[dnsname.FQDN][]*dnstype.Resolver{
CoderDNSSuffix: nil,
suffix: nil,
},
// Note that host names and Routes are independent --- so we faithfully reproduce the hosts, even though
// they don't match the route.
Hosts: map[dnsname.FQDN][]netip.Addr{
"agent.myws.me.coder.": {
addr1,
Expand DownExpand Up@@ -1219,7 +1222,7 @@ func TestConfigMaps_addRemoveHosts(t *testing.T) {
req = testutil.RequireRecvCtx(ctx, t, fEng.reconfig)
require.Equal(t, req.dnsCfg, &dns.Config{
Routes: map[dnsname.FQDN][]*dnstype.Resolver{
CoderDNSSuffix: nil,
suffix: nil,
},
Hosts: map[dnsname.FQDN][]netip.Addr{
"newagent.myws.me.coder.": {
Expand Down
12 changes: 12 additions & 0 deletionstailnet/conn.go
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -120,6 +120,9 @@ type Options struct {
// WireguardMonitor is optional, and is passed to the underlying wireguard
// engine.
WireguardMonitor *netmon.Monitor
// DNSMatchDomain is the DNS suffix to use as a match domain. Only relevant for TUN connections that configure the
// OS DNS resolver.
DNSMatchDomain string
}

// TelemetrySink allows tailnet.Conn to send network telemetry to the Coder
Expand DownExpand Up@@ -267,12 +270,21 @@ func NewConn(options *Options) (conn *Conn, err error) {
netStack.ProcessLocalIPs = true
}

if options.DNSMatchDomain == "" {
options.DNSMatchDomain = CoderDNSSuffix
}
matchDomain, err := dnsname.ToFQDN(options.DNSMatchDomain + ".")
if err != nil {
return nil, xerrors.Errorf("convert hostname suffix (%s) to fully-qualified domain: %w",
options.DNSMatchDomain, err)
}
cfgMaps := newConfigMaps(
options.Logger,
wireguardEngine,
nodeID,
nodePrivateKey,
magicConn.DiscoPublicKey(),
matchDomain,
)
cfgMaps.setAddresses(options.Addresses)
if options.DERPMap != nil {
Expand Down
2 changes: 1 addition & 1 deletiontailnet/controllers.go
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -1309,7 +1309,7 @@ func NewTunnelAllWorkspaceUpdatesController(
t := &TunnelAllWorkspaceUpdatesController{
logger: logger,
coordCtrl: c,
dnsNameOptions: DNSNameOptions{"coder"},
dnsNameOptions: DNSNameOptions{CoderDNSSuffix},
}
for _, opt := range opts {
opt(t)
Expand Down
10 changes: 6 additions & 4 deletionstailnet/controllers_test.go
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -1637,7 +1637,7 @@ func TestTunnelAllWorkspaceUpdatesController_DeleteAgent(t *testing.T) {
fUH := newFakeUpdateHandler(ctx, t)
fDNS := newFakeDNSSetter(ctx, t)
coordC, updateC, updateCtrl := setupConnectedAllWorkspaceUpdatesController(ctx, t, logger,
tailnet.WithDNS(fDNS, "testy", tailnet.DNSNameOptions{Suffix:"coder"}),
tailnet.WithDNS(fDNS, "testy", tailnet.DNSNameOptions{Suffix:tailnet.CoderDNSSuffix}),
tailnet.WithHandler(fUH),
)

Expand All@@ -1664,7 +1664,8 @@ func TestTunnelAllWorkspaceUpdatesController_DeleteAgent(t *testing.T) {
require.Equal(t, w1a1ID[:], coordCall.req.GetAddTunnel().GetId())
testutil.RequireSendCtx(ctx, t, coordCall.err, nil)

expectedCoderConnectFQDN, err := dnsname.ToFQDN(fmt.Sprintf(tailnet.IsCoderConnectEnabledFmtString, "coder"))
expectedCoderConnectFQDN, err := dnsname.ToFQDN(
fmt.Sprintf(tailnet.IsCoderConnectEnabledFmtString, tailnet.CoderDNSSuffix))
require.NoError(t, err)

// DNS for w1a1
Expand DownExpand Up@@ -1785,7 +1786,7 @@ func TestTunnelAllWorkspaceUpdatesController_DNSError(t *testing.T) {
fConn := &fakeCoordinatee{}
tsc := tailnet.NewTunnelSrcCoordController(logger, fConn)
uut := tailnet.NewTunnelAllWorkspaceUpdatesController(logger, tsc,
tailnet.WithDNS(fDNS, "testy", tailnet.DNSNameOptions{Suffix:"coder"}),
tailnet.WithDNS(fDNS, "testy", tailnet.DNSNameOptions{Suffix:tailnet.CoderDNSSuffix}),
)

updateC := newFakeWorkspaceUpdateClient(ctx, t)
Expand All@@ -1806,7 +1807,8 @@ func TestTunnelAllWorkspaceUpdatesController_DNSError(t *testing.T) {
upRecvCall := testutil.RequireRecvCtx(ctx, t, updateC.recv)
testutil.RequireSendCtx(ctx, t, upRecvCall.resp, initUp)

expectedCoderConnectFQDN, err := dnsname.ToFQDN(fmt.Sprintf(tailnet.IsCoderConnectEnabledFmtString, "coder"))
expectedCoderConnectFQDN, err := dnsname.ToFQDN(
fmt.Sprintf(tailnet.IsCoderConnectEnabledFmtString, tailnet.CoderDNSSuffix))
require.NoError(t, err)

// DNS for w1a1
Expand Down
6 changes: 5 additions & 1 deletionvpn/client.go
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -7,6 +7,7 @@ import (
"net/url"

"golang.org/x/xerrors"

"tailscale.com/net/dns"
"tailscale.com/net/netmon"
"tailscale.com/wgengine/router"
Expand DownExpand Up@@ -108,9 +109,11 @@ func (*client) NewConn(initCtx context.Context, serverURL *url.URL, token string
return nil, xerrors.Errorf("get connection info: %w", err)
}
// default to DNS suffix of "coder" if the server hasn't set it (might be too old).
dnsNameOptions := tailnet.DNSNameOptions{Suffix: "coder"}
dnsNameOptions := tailnet.DNSNameOptions{Suffix: tailnet.CoderDNSSuffix}
dnsMatch := tailnet.CoderDNSSuffix
if connInfo.HostnameSuffix != "" {
dnsNameOptions.Suffix = connInfo.HostnameSuffix
dnsMatch = connInfo.HostnameSuffix
}

headers.Set(codersdk.SessionTokenHeader, token)
Expand All@@ -134,6 +137,7 @@ func (*client) NewConn(initCtx context.Context, serverURL *url.URL, token string
Router: options.Router,
TUNDev: options.TUNDevice,
WireguardMonitor: options.WireguardMonitor,
DNSMatchDomain: dnsMatch,
})
if err != nil {
return nil, xerrors.Errorf("create tailnet: %w", err)
Expand Down
Loading

[8]ページ先頭

©2009-2025 Movatter.jp