Skip to content

Commit 3c1cb5d

Browse files
chore: add generic DNS record for checking if Coder Connect is running (#17298)
Closes coder/internal#466 ``` $ dig -6 @fD60:627a:a42b::53 is.coder--connect--enabled--right--now.coder AAAA ; <<>> DiG 9.10.6 <<>> -6 @fD60:627a:a42b::53 is.coder--connect--enabled--right--now.coder AAAA ; (1 server found) ;; global options: +cmd ;; Got answer: ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 62390 ;; flags: qr aa rd ra ad; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0 ;; QUESTION SECTION: ;is.coder--connect--enabled--right--now.coder. IN AAAA ;; ANSWER SECTION: is.coder--connect--enabled--right--now.coder. 2 IN AAAA fd60:627a:a42b::53 ;; Query time: 3 msec ;; SERVER: fd60:627a:a42b::53#53(fd60:627a:a42b::53) ;; WHEN: Wed Apr 09 16:59:18 AEST 2025 ;; MSG SIZE rcvd: 134 ``` Hostname considerations: - Workspace names, usernames, and agent names can't have double hyphens, so this name can't conflict with a real Coder Connect hostname. - Components can't start or end with hyphens according to [RFC 952](https://www.rfc-editor.org/rfc/rfc952.html) - DNS records can't have hyphens in the 3rd and 4th positions, as to not conflict with IDNs https://datatracker.ietf.org/doc/html/rfc5891
1 parent e7e4753 commit 3c1cb5d

File tree

3 files changed

+30
-16
lines changed

3 files changed

+30
-16
lines changed

tailnet/conn.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -354,6 +354,13 @@ func NewConn(options *Options) (conn *Conn, err error) {
354354
return server, nil
355355
}
356356

357+
// A FQDN to be mapped to `tsaddr.CoderServiceIPv6`. This address can be used
358+
// when you want to know if Coder Connect is running, but are not trying to
359+
// connect to a specific known workspace.
360+
const IsCoderConnectEnabledFQDNString = "is.coder--connect--enabled--right--now.coder."
361+
362+
var IsCoderConnectEnabledFQDN, _ = dnsname.ToFQDN(IsCoderConnectEnabledFQDNString)
363+
357364
type ServicePrefix [6]byte
358365

359366
var (

tailnet/controllers.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import (
1616
"golang.org/x/xerrors"
1717
"storj.io/drpc"
1818
"storj.io/drpc/drpcerr"
19+
"tailscale.com/net/tsaddr"
1920
"tailscale.com/tailcfg"
2021
"tailscale.com/util/dnsname"
2122

@@ -1265,6 +1266,7 @@ func (t *tunnelUpdater) updateDNSNamesLocked() map[dnsname.FQDN][]netip.Addr {
12651266
}
12661267
}
12671268
}
1269+
names[IsCoderConnectEnabledFQDN] = []netip.Addr{tsaddr.CoderServiceIPv6()}
12681270
return names
12691271
}
12701272

tailnet/controllers_test.go

Lines changed: 21 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import (
2222
"google.golang.org/protobuf/types/known/timestamppb"
2323
"storj.io/drpc"
2424
"storj.io/drpc/drpcerr"
25+
"tailscale.com/net/tsaddr"
2526
"tailscale.com/tailcfg"
2627
"tailscale.com/types/key"
2728
"tailscale.com/util/dnsname"
@@ -1563,13 +1564,14 @@ func TestTunnelAllWorkspaceUpdatesController_Initial(t *testing.T) {
15631564

15641565
// Also triggers setting DNS hosts
15651566
expectedDNS := map[dnsname.FQDN][]netip.Addr{
1566-
"w1a1.w1.me.coder.": {ws1a1IP},
1567-
"w2a1.w2.me.coder.": {w2a1IP},
1568-
"w2a2.w2.me.coder.": {w2a2IP},
1569-
"w1a1.w1.testy.coder.": {ws1a1IP},
1570-
"w2a1.w2.testy.coder.": {w2a1IP},
1571-
"w2a2.w2.testy.coder.": {w2a2IP},
1572-
"w1.coder.": {ws1a1IP},
1567+
"w1a1.w1.me.coder.": {ws1a1IP},
1568+
"w2a1.w2.me.coder.": {w2a1IP},
1569+
"w2a2.w2.me.coder.": {w2a2IP},
1570+
"w1a1.w1.testy.coder.": {ws1a1IP},
1571+
"w2a1.w2.testy.coder.": {w2a1IP},
1572+
"w2a2.w2.testy.coder.": {w2a2IP},
1573+
"w1.coder.": {ws1a1IP},
1574+
tailnet.IsCoderConnectEnabledFQDNString: {tsaddr.CoderServiceIPv6()},
15731575
}
15741576
dnsCall := testutil.RequireRecvCtx(ctx, t, fDNS.calls)
15751577
require.Equal(t, expectedDNS, dnsCall.hosts)
@@ -1661,9 +1663,10 @@ func TestTunnelAllWorkspaceUpdatesController_DeleteAgent(t *testing.T) {
16611663

16621664
// DNS for w1a1
16631665
expectedDNS := map[dnsname.FQDN][]netip.Addr{
1664-
"w1a1.w1.testy.coder.": {ws1a1IP},
1665-
"w1a1.w1.me.coder.": {ws1a1IP},
1666-
"w1.coder.": {ws1a1IP},
1666+
"w1a1.w1.testy.coder.": {ws1a1IP},
1667+
"w1a1.w1.me.coder.": {ws1a1IP},
1668+
"w1.coder.": {ws1a1IP},
1669+
tailnet.IsCoderConnectEnabledFQDNString: {tsaddr.CoderServiceIPv6()},
16671670
}
16681671
dnsCall := testutil.RequireRecvCtx(ctx, t, fDNS.calls)
16691672
require.Equal(t, expectedDNS, dnsCall.hosts)
@@ -1716,9 +1719,10 @@ func TestTunnelAllWorkspaceUpdatesController_DeleteAgent(t *testing.T) {
17161719

17171720
// DNS contains only w1a2
17181721
expectedDNS = map[dnsname.FQDN][]netip.Addr{
1719-
"w1a2.w1.testy.coder.": {ws1a2IP},
1720-
"w1a2.w1.me.coder.": {ws1a2IP},
1721-
"w1.coder.": {ws1a2IP},
1722+
"w1a2.w1.testy.coder.": {ws1a2IP},
1723+
"w1a2.w1.me.coder.": {ws1a2IP},
1724+
"w1.coder.": {ws1a2IP},
1725+
tailnet.IsCoderConnectEnabledFQDNString: {tsaddr.CoderServiceIPv6()},
17221726
}
17231727
dnsCall = testutil.RequireRecvCtx(ctx, t, fDNS.calls)
17241728
require.Equal(t, expectedDNS, dnsCall.hosts)
@@ -1798,9 +1802,10 @@ func TestTunnelAllWorkspaceUpdatesController_DNSError(t *testing.T) {
17981802

17991803
// DNS for w1a1
18001804
expectedDNS := map[dnsname.FQDN][]netip.Addr{
1801-
"w1a1.w1.me.coder.": {ws1a1IP},
1802-
"w1a1.w1.testy.coder.": {ws1a1IP},
1803-
"w1.coder.": {ws1a1IP},
1805+
"w1a1.w1.me.coder.": {ws1a1IP},
1806+
"w1a1.w1.testy.coder.": {ws1a1IP},
1807+
"w1.coder.": {ws1a1IP},
1808+
tailnet.IsCoderConnectEnabledFQDNString: {tsaddr.CoderServiceIPv6()},
18041809
}
18051810
dnsCall := testutil.RequireRecvCtx(ctx, t, fDNS.calls)
18061811
require.Equal(t, expectedDNS, dnsCall.hosts)

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy