mirror of
https://github.com/coder/coder.git
synced 2025-07-13 21:36:50 +00:00
feat: add configurable DNS match domain for tailnet connections (#17336)
Use the hostname suffix to set the DNS match domain when creating a Tailnet as part of the vpn `Tunnel`. part of: #16828
This commit is contained in:
@ -36,7 +36,10 @@ const lostTimeout = 15 * time.Minute
|
|||||||
|
|
||||||
// CoderDNSSuffix is the default DNS suffix that we append to Coder DNS
|
// CoderDNSSuffix is the default DNS suffix that we append to Coder DNS
|
||||||
// records.
|
// records.
|
||||||
const CoderDNSSuffix = "coder."
|
const (
|
||||||
|
CoderDNSSuffix = "coder"
|
||||||
|
CoderDNSSuffixFQDN = dnsname.FQDN(CoderDNSSuffix + ".")
|
||||||
|
)
|
||||||
|
|
||||||
// engineConfigurable is the subset of wgengine.Engine that we use for configuration.
|
// engineConfigurable is the subset of wgengine.Engine that we use for configuration.
|
||||||
//
|
//
|
||||||
@ -71,18 +74,24 @@ type configMaps struct {
|
|||||||
|
|
||||||
engine engineConfigurable
|
engine engineConfigurable
|
||||||
static netmap.NetworkMap
|
static netmap.NetworkMap
|
||||||
|
|
||||||
hosts map[dnsname.FQDN][]netip.Addr
|
hosts map[dnsname.FQDN][]netip.Addr
|
||||||
peers map[uuid.UUID]*peerLifecycle
|
peers map[uuid.UUID]*peerLifecycle
|
||||||
addresses []netip.Prefix
|
addresses []netip.Prefix
|
||||||
derpMap *tailcfg.DERPMap
|
derpMap *tailcfg.DERPMap
|
||||||
logger slog.Logger
|
logger slog.Logger
|
||||||
blockEndpoints bool
|
blockEndpoints bool
|
||||||
|
matchDomain dnsname.FQDN
|
||||||
|
|
||||||
// for testing
|
// for testing
|
||||||
clock quartz.Clock
|
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()
|
pubKey := nodeKey.Public()
|
||||||
c := &configMaps{
|
c := &configMaps{
|
||||||
phased: phased{Cond: *(sync.NewCond(&sync.Mutex{}))},
|
phased: phased{Cond: *(sync.NewCond(&sync.Mutex{}))},
|
||||||
@ -126,6 +135,7 @@ func newConfigMaps(logger slog.Logger, engine engineConfigurable, nodeID tailcfg
|
|||||||
}},
|
}},
|
||||||
},
|
},
|
||||||
peers: make(map[uuid.UUID]*peerLifecycle),
|
peers: make(map[uuid.UUID]*peerLifecycle),
|
||||||
|
matchDomain: matchDomain,
|
||||||
clock: quartz.NewReal(),
|
clock: quartz.NewReal(),
|
||||||
}
|
}
|
||||||
go c.configLoop()
|
go c.configLoop()
|
||||||
@ -338,7 +348,7 @@ func (c *configMaps) reconfig(nm *netmap.NetworkMap, hosts map[dnsname.FQDN][]ne
|
|||||||
dnsCfg.Hosts = hosts
|
dnsCfg.Hosts = hosts
|
||||||
dnsCfg.OnlyIPv6 = true
|
dnsCfg.OnlyIPv6 = true
|
||||||
dnsCfg.Routes = map[dnsname.FQDN][]*dnstype.Resolver{
|
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, "")
|
cfg, err := nmcfg.WGCfg(nm, Logger(c.logger.Named("net.wgconfig")), netmap.AllowSingleHosts, "")
|
||||||
|
@ -34,7 +34,7 @@ func TestConfigMaps_setAddresses_different(t *testing.T) {
|
|||||||
nodePrivateKey := key.NewNode()
|
nodePrivateKey := key.NewNode()
|
||||||
nodeID := tailcfg.NodeID(5)
|
nodeID := tailcfg.NodeID(5)
|
||||||
discoKey := key.NewDisco()
|
discoKey := key.NewDisco()
|
||||||
uut := newConfigMaps(logger, fEng, nodeID, nodePrivateKey, discoKey.Public())
|
uut := newConfigMaps(logger, fEng, nodeID, nodePrivateKey, discoKey.Public(), CoderDNSSuffixFQDN)
|
||||||
defer uut.close()
|
defer uut.close()
|
||||||
|
|
||||||
addrs := []netip.Prefix{netip.MustParsePrefix("192.168.0.200/32")}
|
addrs := []netip.Prefix{netip.MustParsePrefix("192.168.0.200/32")}
|
||||||
@ -93,7 +93,7 @@ func TestConfigMaps_setAddresses_same(t *testing.T) {
|
|||||||
nodeID := tailcfg.NodeID(5)
|
nodeID := tailcfg.NodeID(5)
|
||||||
discoKey := key.NewDisco()
|
discoKey := key.NewDisco()
|
||||||
addrs := []netip.Prefix{netip.MustParsePrefix("192.168.0.200/32")}
|
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()
|
defer uut.close()
|
||||||
|
|
||||||
// Given: addresses already set
|
// Given: addresses already set
|
||||||
@ -123,7 +123,7 @@ func TestConfigMaps_updatePeers_new(t *testing.T) {
|
|||||||
nodePrivateKey := key.NewNode()
|
nodePrivateKey := key.NewNode()
|
||||||
nodeID := tailcfg.NodeID(5)
|
nodeID := tailcfg.NodeID(5)
|
||||||
discoKey := key.NewDisco()
|
discoKey := key.NewDisco()
|
||||||
uut := newConfigMaps(logger, fEng, nodeID, nodePrivateKey, discoKey.Public())
|
uut := newConfigMaps(logger, fEng, nodeID, nodePrivateKey, discoKey.Public(), CoderDNSSuffixFQDN)
|
||||||
defer uut.close()
|
defer uut.close()
|
||||||
|
|
||||||
p1ID := uuid.UUID{1}
|
p1ID := uuid.UUID{1}
|
||||||
@ -193,7 +193,7 @@ func TestConfigMaps_updatePeers_new_waitForHandshake_neverConfigures(t *testing.
|
|||||||
nodePrivateKey := key.NewNode()
|
nodePrivateKey := key.NewNode()
|
||||||
nodeID := tailcfg.NodeID(5)
|
nodeID := tailcfg.NodeID(5)
|
||||||
discoKey := key.NewDisco()
|
discoKey := key.NewDisco()
|
||||||
uut := newConfigMaps(logger, fEng, nodeID, nodePrivateKey, discoKey.Public())
|
uut := newConfigMaps(logger, fEng, nodeID, nodePrivateKey, discoKey.Public(), CoderDNSSuffixFQDN)
|
||||||
defer uut.close()
|
defer uut.close()
|
||||||
mClock := quartz.NewMock(t)
|
mClock := quartz.NewMock(t)
|
||||||
uut.clock = mClock
|
uut.clock = mClock
|
||||||
@ -237,7 +237,7 @@ func TestConfigMaps_updatePeers_new_waitForHandshake_outOfOrder(t *testing.T) {
|
|||||||
nodePrivateKey := key.NewNode()
|
nodePrivateKey := key.NewNode()
|
||||||
nodeID := tailcfg.NodeID(5)
|
nodeID := tailcfg.NodeID(5)
|
||||||
discoKey := key.NewDisco()
|
discoKey := key.NewDisco()
|
||||||
uut := newConfigMaps(logger, fEng, nodeID, nodePrivateKey, discoKey.Public())
|
uut := newConfigMaps(logger, fEng, nodeID, nodePrivateKey, discoKey.Public(), CoderDNSSuffixFQDN)
|
||||||
defer uut.close()
|
defer uut.close()
|
||||||
mClock := quartz.NewMock(t)
|
mClock := quartz.NewMock(t)
|
||||||
uut.clock = mClock
|
uut.clock = mClock
|
||||||
@ -308,7 +308,7 @@ func TestConfigMaps_updatePeers_new_waitForHandshake(t *testing.T) {
|
|||||||
nodePrivateKey := key.NewNode()
|
nodePrivateKey := key.NewNode()
|
||||||
nodeID := tailcfg.NodeID(5)
|
nodeID := tailcfg.NodeID(5)
|
||||||
discoKey := key.NewDisco()
|
discoKey := key.NewDisco()
|
||||||
uut := newConfigMaps(logger, fEng, nodeID, nodePrivateKey, discoKey.Public())
|
uut := newConfigMaps(logger, fEng, nodeID, nodePrivateKey, discoKey.Public(), CoderDNSSuffixFQDN)
|
||||||
defer uut.close()
|
defer uut.close()
|
||||||
mClock := quartz.NewMock(t)
|
mClock := quartz.NewMock(t)
|
||||||
uut.clock = mClock
|
uut.clock = mClock
|
||||||
@ -379,7 +379,7 @@ func TestConfigMaps_updatePeers_new_waitForHandshake_timeout(t *testing.T) {
|
|||||||
nodePrivateKey := key.NewNode()
|
nodePrivateKey := key.NewNode()
|
||||||
nodeID := tailcfg.NodeID(5)
|
nodeID := tailcfg.NodeID(5)
|
||||||
discoKey := key.NewDisco()
|
discoKey := key.NewDisco()
|
||||||
uut := newConfigMaps(logger, fEng, nodeID, nodePrivateKey, discoKey.Public())
|
uut := newConfigMaps(logger, fEng, nodeID, nodePrivateKey, discoKey.Public(), CoderDNSSuffixFQDN)
|
||||||
defer uut.close()
|
defer uut.close()
|
||||||
mClock := quartz.NewMock(t)
|
mClock := quartz.NewMock(t)
|
||||||
uut.clock = mClock
|
uut.clock = mClock
|
||||||
@ -437,7 +437,7 @@ func TestConfigMaps_updatePeers_same(t *testing.T) {
|
|||||||
nodePrivateKey := key.NewNode()
|
nodePrivateKey := key.NewNode()
|
||||||
nodeID := tailcfg.NodeID(5)
|
nodeID := tailcfg.NodeID(5)
|
||||||
discoKey := key.NewDisco()
|
discoKey := key.NewDisco()
|
||||||
uut := newConfigMaps(logger, fEng, nodeID, nodePrivateKey, discoKey.Public())
|
uut := newConfigMaps(logger, fEng, nodeID, nodePrivateKey, discoKey.Public(), CoderDNSSuffixFQDN)
|
||||||
defer uut.close()
|
defer uut.close()
|
||||||
|
|
||||||
// Then: we don't configure
|
// Then: we don't configure
|
||||||
@ -496,7 +496,7 @@ func TestConfigMaps_updatePeers_disconnect(t *testing.T) {
|
|||||||
nodePrivateKey := key.NewNode()
|
nodePrivateKey := key.NewNode()
|
||||||
nodeID := tailcfg.NodeID(5)
|
nodeID := tailcfg.NodeID(5)
|
||||||
discoKey := key.NewDisco()
|
discoKey := key.NewDisco()
|
||||||
uut := newConfigMaps(logger, fEng, nodeID, nodePrivateKey, discoKey.Public())
|
uut := newConfigMaps(logger, fEng, nodeID, nodePrivateKey, discoKey.Public(), CoderDNSSuffixFQDN)
|
||||||
defer uut.close()
|
defer uut.close()
|
||||||
|
|
||||||
p1ID := uuid.UUID{1}
|
p1ID := uuid.UUID{1}
|
||||||
@ -564,7 +564,7 @@ func TestConfigMaps_updatePeers_lost(t *testing.T) {
|
|||||||
nodePrivateKey := key.NewNode()
|
nodePrivateKey := key.NewNode()
|
||||||
nodeID := tailcfg.NodeID(5)
|
nodeID := tailcfg.NodeID(5)
|
||||||
discoKey := key.NewDisco()
|
discoKey := key.NewDisco()
|
||||||
uut := newConfigMaps(logger, fEng, nodeID, nodePrivateKey, discoKey.Public())
|
uut := newConfigMaps(logger, fEng, nodeID, nodePrivateKey, discoKey.Public(), CoderDNSSuffixFQDN)
|
||||||
defer uut.close()
|
defer uut.close()
|
||||||
mClock := quartz.NewMock(t)
|
mClock := quartz.NewMock(t)
|
||||||
start := mClock.Now()
|
start := mClock.Now()
|
||||||
@ -649,7 +649,7 @@ func TestConfigMaps_updatePeers_lost_and_found(t *testing.T) {
|
|||||||
nodePrivateKey := key.NewNode()
|
nodePrivateKey := key.NewNode()
|
||||||
nodeID := tailcfg.NodeID(5)
|
nodeID := tailcfg.NodeID(5)
|
||||||
discoKey := key.NewDisco()
|
discoKey := key.NewDisco()
|
||||||
uut := newConfigMaps(logger, fEng, nodeID, nodePrivateKey, discoKey.Public())
|
uut := newConfigMaps(logger, fEng, nodeID, nodePrivateKey, discoKey.Public(), CoderDNSSuffixFQDN)
|
||||||
defer uut.close()
|
defer uut.close()
|
||||||
mClock := quartz.NewMock(t)
|
mClock := quartz.NewMock(t)
|
||||||
start := mClock.Now()
|
start := mClock.Now()
|
||||||
@ -734,7 +734,7 @@ func TestConfigMaps_setAllPeersLost(t *testing.T) {
|
|||||||
nodePrivateKey := key.NewNode()
|
nodePrivateKey := key.NewNode()
|
||||||
nodeID := tailcfg.NodeID(5)
|
nodeID := tailcfg.NodeID(5)
|
||||||
discoKey := key.NewDisco()
|
discoKey := key.NewDisco()
|
||||||
uut := newConfigMaps(logger, fEng, nodeID, nodePrivateKey, discoKey.Public())
|
uut := newConfigMaps(logger, fEng, nodeID, nodePrivateKey, discoKey.Public(), CoderDNSSuffixFQDN)
|
||||||
defer uut.close()
|
defer uut.close()
|
||||||
mClock := quartz.NewMock(t)
|
mClock := quartz.NewMock(t)
|
||||||
start := mClock.Now()
|
start := mClock.Now()
|
||||||
@ -820,7 +820,7 @@ func TestConfigMaps_setBlockEndpoints_different(t *testing.T) {
|
|||||||
nodePrivateKey := key.NewNode()
|
nodePrivateKey := key.NewNode()
|
||||||
nodeID := tailcfg.NodeID(5)
|
nodeID := tailcfg.NodeID(5)
|
||||||
discoKey := key.NewDisco()
|
discoKey := key.NewDisco()
|
||||||
uut := newConfigMaps(logger, fEng, nodeID, nodePrivateKey, discoKey.Public())
|
uut := newConfigMaps(logger, fEng, nodeID, nodePrivateKey, discoKey.Public(), CoderDNSSuffixFQDN)
|
||||||
defer uut.close()
|
defer uut.close()
|
||||||
|
|
||||||
p1ID := uuid.MustParse("10000000-0000-0000-0000-000000000000")
|
p1ID := uuid.MustParse("10000000-0000-0000-0000-000000000000")
|
||||||
@ -864,7 +864,7 @@ func TestConfigMaps_setBlockEndpoints_same(t *testing.T) {
|
|||||||
nodePrivateKey := key.NewNode()
|
nodePrivateKey := key.NewNode()
|
||||||
nodeID := tailcfg.NodeID(5)
|
nodeID := tailcfg.NodeID(5)
|
||||||
discoKey := key.NewDisco()
|
discoKey := key.NewDisco()
|
||||||
uut := newConfigMaps(logger, fEng, nodeID, nodePrivateKey, discoKey.Public())
|
uut := newConfigMaps(logger, fEng, nodeID, nodePrivateKey, discoKey.Public(), CoderDNSSuffixFQDN)
|
||||||
defer uut.close()
|
defer uut.close()
|
||||||
|
|
||||||
p1ID := uuid.MustParse("10000000-0000-0000-0000-000000000000")
|
p1ID := uuid.MustParse("10000000-0000-0000-0000-000000000000")
|
||||||
@ -907,7 +907,7 @@ func TestConfigMaps_setDERPMap_different(t *testing.T) {
|
|||||||
nodePrivateKey := key.NewNode()
|
nodePrivateKey := key.NewNode()
|
||||||
nodeID := tailcfg.NodeID(5)
|
nodeID := tailcfg.NodeID(5)
|
||||||
discoKey := key.NewDisco()
|
discoKey := key.NewDisco()
|
||||||
uut := newConfigMaps(logger, fEng, nodeID, nodePrivateKey, discoKey.Public())
|
uut := newConfigMaps(logger, fEng, nodeID, nodePrivateKey, discoKey.Public(), CoderDNSSuffixFQDN)
|
||||||
defer uut.close()
|
defer uut.close()
|
||||||
|
|
||||||
derpMap := &tailcfg.DERPMap{
|
derpMap := &tailcfg.DERPMap{
|
||||||
@ -948,7 +948,7 @@ func TestConfigMaps_setDERPMap_same(t *testing.T) {
|
|||||||
nodePrivateKey := key.NewNode()
|
nodePrivateKey := key.NewNode()
|
||||||
nodeID := tailcfg.NodeID(5)
|
nodeID := tailcfg.NodeID(5)
|
||||||
discoKey := key.NewDisco()
|
discoKey := key.NewDisco()
|
||||||
uut := newConfigMaps(logger, fEng, nodeID, nodePrivateKey, discoKey.Public())
|
uut := newConfigMaps(logger, fEng, nodeID, nodePrivateKey, discoKey.Public(), CoderDNSSuffixFQDN)
|
||||||
defer uut.close()
|
defer uut.close()
|
||||||
|
|
||||||
// Given: DERP Map already set
|
// Given: DERP Map already set
|
||||||
@ -1017,7 +1017,7 @@ func TestConfigMaps_fillPeerDiagnostics(t *testing.T) {
|
|||||||
nodePrivateKey := key.NewNode()
|
nodePrivateKey := key.NewNode()
|
||||||
nodeID := tailcfg.NodeID(5)
|
nodeID := tailcfg.NodeID(5)
|
||||||
discoKey := key.NewDisco()
|
discoKey := key.NewDisco()
|
||||||
uut := newConfigMaps(logger, fEng, nodeID, nodePrivateKey, discoKey.Public())
|
uut := newConfigMaps(logger, fEng, nodeID, nodePrivateKey, discoKey.Public(), CoderDNSSuffixFQDN)
|
||||||
defer uut.close()
|
defer uut.close()
|
||||||
|
|
||||||
// Given: DERP Map and peer already set
|
// Given: DERP Map and peer already set
|
||||||
@ -1125,7 +1125,7 @@ func TestConfigMaps_updatePeers_nonexist(t *testing.T) {
|
|||||||
nodePrivateKey := key.NewNode()
|
nodePrivateKey := key.NewNode()
|
||||||
nodeID := tailcfg.NodeID(5)
|
nodeID := tailcfg.NodeID(5)
|
||||||
discoKey := key.NewDisco()
|
discoKey := key.NewDisco()
|
||||||
uut := newConfigMaps(logger, fEng, nodeID, nodePrivateKey, discoKey.Public())
|
uut := newConfigMaps(logger, fEng, nodeID, nodePrivateKey, discoKey.Public(), CoderDNSSuffixFQDN)
|
||||||
defer uut.close()
|
defer uut.close()
|
||||||
|
|
||||||
// Then: we don't configure
|
// Then: we don't configure
|
||||||
@ -1166,7 +1166,8 @@ func TestConfigMaps_addRemoveHosts(t *testing.T) {
|
|||||||
nodePrivateKey := key.NewNode()
|
nodePrivateKey := key.NewNode()
|
||||||
nodeID := tailcfg.NodeID(5)
|
nodeID := tailcfg.NodeID(5)
|
||||||
discoKey := key.NewDisco()
|
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()
|
defer uut.close()
|
||||||
|
|
||||||
addr1 := CoderServicePrefix.AddrFromUUID(uuid.New())
|
addr1 := CoderServicePrefix.AddrFromUUID(uuid.New())
|
||||||
@ -1190,8 +1191,10 @@ func TestConfigMaps_addRemoveHosts(t *testing.T) {
|
|||||||
req := testutil.RequireRecvCtx(ctx, t, fEng.reconfig)
|
req := testutil.RequireRecvCtx(ctx, t, fEng.reconfig)
|
||||||
require.Equal(t, req.dnsCfg, &dns.Config{
|
require.Equal(t, req.dnsCfg, &dns.Config{
|
||||||
Routes: map[dnsname.FQDN][]*dnstype.Resolver{
|
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{
|
Hosts: map[dnsname.FQDN][]netip.Addr{
|
||||||
"agent.myws.me.coder.": {
|
"agent.myws.me.coder.": {
|
||||||
addr1,
|
addr1,
|
||||||
@ -1219,7 +1222,7 @@ func TestConfigMaps_addRemoveHosts(t *testing.T) {
|
|||||||
req = testutil.RequireRecvCtx(ctx, t, fEng.reconfig)
|
req = testutil.RequireRecvCtx(ctx, t, fEng.reconfig)
|
||||||
require.Equal(t, req.dnsCfg, &dns.Config{
|
require.Equal(t, req.dnsCfg, &dns.Config{
|
||||||
Routes: map[dnsname.FQDN][]*dnstype.Resolver{
|
Routes: map[dnsname.FQDN][]*dnstype.Resolver{
|
||||||
CoderDNSSuffix: nil,
|
suffix: nil,
|
||||||
},
|
},
|
||||||
Hosts: map[dnsname.FQDN][]netip.Addr{
|
Hosts: map[dnsname.FQDN][]netip.Addr{
|
||||||
"newagent.myws.me.coder.": {
|
"newagent.myws.me.coder.": {
|
||||||
|
@ -120,6 +120,9 @@ type Options struct {
|
|||||||
// WireguardMonitor is optional, and is passed to the underlying wireguard
|
// WireguardMonitor is optional, and is passed to the underlying wireguard
|
||||||
// engine.
|
// engine.
|
||||||
WireguardMonitor *netmon.Monitor
|
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
|
// TelemetrySink allows tailnet.Conn to send network telemetry to the Coder
|
||||||
@ -267,12 +270,21 @@ func NewConn(options *Options) (conn *Conn, err error) {
|
|||||||
netStack.ProcessLocalIPs = true
|
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(
|
cfgMaps := newConfigMaps(
|
||||||
options.Logger,
|
options.Logger,
|
||||||
wireguardEngine,
|
wireguardEngine,
|
||||||
nodeID,
|
nodeID,
|
||||||
nodePrivateKey,
|
nodePrivateKey,
|
||||||
magicConn.DiscoPublicKey(),
|
magicConn.DiscoPublicKey(),
|
||||||
|
matchDomain,
|
||||||
)
|
)
|
||||||
cfgMaps.setAddresses(options.Addresses)
|
cfgMaps.setAddresses(options.Addresses)
|
||||||
if options.DERPMap != nil {
|
if options.DERPMap != nil {
|
||||||
|
@ -1309,7 +1309,7 @@ func NewTunnelAllWorkspaceUpdatesController(
|
|||||||
t := &TunnelAllWorkspaceUpdatesController{
|
t := &TunnelAllWorkspaceUpdatesController{
|
||||||
logger: logger,
|
logger: logger,
|
||||||
coordCtrl: c,
|
coordCtrl: c,
|
||||||
dnsNameOptions: DNSNameOptions{"coder"},
|
dnsNameOptions: DNSNameOptions{CoderDNSSuffix},
|
||||||
}
|
}
|
||||||
for _, opt := range opts {
|
for _, opt := range opts {
|
||||||
opt(t)
|
opt(t)
|
||||||
|
@ -1637,7 +1637,7 @@ func TestTunnelAllWorkspaceUpdatesController_DeleteAgent(t *testing.T) {
|
|||||||
fUH := newFakeUpdateHandler(ctx, t)
|
fUH := newFakeUpdateHandler(ctx, t)
|
||||||
fDNS := newFakeDNSSetter(ctx, t)
|
fDNS := newFakeDNSSetter(ctx, t)
|
||||||
coordC, updateC, updateCtrl := setupConnectedAllWorkspaceUpdatesController(ctx, t, logger,
|
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),
|
tailnet.WithHandler(fUH),
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -1664,7 +1664,8 @@ func TestTunnelAllWorkspaceUpdatesController_DeleteAgent(t *testing.T) {
|
|||||||
require.Equal(t, w1a1ID[:], coordCall.req.GetAddTunnel().GetId())
|
require.Equal(t, w1a1ID[:], coordCall.req.GetAddTunnel().GetId())
|
||||||
testutil.RequireSendCtx(ctx, t, coordCall.err, nil)
|
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)
|
require.NoError(t, err)
|
||||||
|
|
||||||
// DNS for w1a1
|
// DNS for w1a1
|
||||||
@ -1785,7 +1786,7 @@ func TestTunnelAllWorkspaceUpdatesController_DNSError(t *testing.T) {
|
|||||||
fConn := &fakeCoordinatee{}
|
fConn := &fakeCoordinatee{}
|
||||||
tsc := tailnet.NewTunnelSrcCoordController(logger, fConn)
|
tsc := tailnet.NewTunnelSrcCoordController(logger, fConn)
|
||||||
uut := tailnet.NewTunnelAllWorkspaceUpdatesController(logger, tsc,
|
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)
|
updateC := newFakeWorkspaceUpdateClient(ctx, t)
|
||||||
@ -1806,7 +1807,8 @@ func TestTunnelAllWorkspaceUpdatesController_DNSError(t *testing.T) {
|
|||||||
upRecvCall := testutil.RequireRecvCtx(ctx, t, updateC.recv)
|
upRecvCall := testutil.RequireRecvCtx(ctx, t, updateC.recv)
|
||||||
testutil.RequireSendCtx(ctx, t, upRecvCall.resp, initUp)
|
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)
|
require.NoError(t, err)
|
||||||
|
|
||||||
// DNS for w1a1
|
// DNS for w1a1
|
||||||
|
@ -7,6 +7,7 @@ import (
|
|||||||
"net/url"
|
"net/url"
|
||||||
|
|
||||||
"golang.org/x/xerrors"
|
"golang.org/x/xerrors"
|
||||||
|
|
||||||
"tailscale.com/net/dns"
|
"tailscale.com/net/dns"
|
||||||
"tailscale.com/net/netmon"
|
"tailscale.com/net/netmon"
|
||||||
"tailscale.com/wgengine/router"
|
"tailscale.com/wgengine/router"
|
||||||
@ -108,9 +109,11 @@ func (*client) NewConn(initCtx context.Context, serverURL *url.URL, token string
|
|||||||
return nil, xerrors.Errorf("get connection info: %w", err)
|
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).
|
// 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 != "" {
|
if connInfo.HostnameSuffix != "" {
|
||||||
dnsNameOptions.Suffix = connInfo.HostnameSuffix
|
dnsNameOptions.Suffix = connInfo.HostnameSuffix
|
||||||
|
dnsMatch = connInfo.HostnameSuffix
|
||||||
}
|
}
|
||||||
|
|
||||||
headers.Set(codersdk.SessionTokenHeader, token)
|
headers.Set(codersdk.SessionTokenHeader, token)
|
||||||
@ -134,6 +137,7 @@ func (*client) NewConn(initCtx context.Context, serverURL *url.URL, token string
|
|||||||
Router: options.Router,
|
Router: options.Router,
|
||||||
TUNDev: options.TUNDevice,
|
TUNDev: options.TUNDevice,
|
||||||
WireguardMonitor: options.WireguardMonitor,
|
WireguardMonitor: options.WireguardMonitor,
|
||||||
|
DNSMatchDomain: dnsMatch,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, xerrors.Errorf("create tailnet: %w", err)
|
return nil, xerrors.Errorf("create tailnet: %w", err)
|
||||||
|
Reference in New Issue
Block a user