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

Commit1917ec0

Browse files
committed
feat: vpn uses WorkspaceHostnameSuffix for DNS names
1 parent76cb7a7 commit1917ec0

File tree

6 files changed

+247
-171
lines changed

6 files changed

+247
-171
lines changed

‎codersdk/workspacesdk/workspacesdk.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,7 @@ type AgentConnectionInfo struct {
143143
DERPMap*tailcfg.DERPMap`json:"derp_map"`
144144
DERPForceWebSocketsbool`json:"derp_force_websockets"`
145145
DisableDirectConnectionsbool`json:"disable_direct_connections"`
146-
HostnameSuffixstring`json:"hostname_suffix"`
146+
HostnameSuffixstring`json:"hostname_suffix,omitempty"`
147147
}
148148

149149
func (c*Client)AgentConnectionInfoGeneric(ctx context.Context) (AgentConnectionInfo,error) {

‎tailnet/conn.go

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -357,9 +357,7 @@ func NewConn(options *Options) (conn *Conn, err error) {
357357
// A FQDN to be mapped to `tsaddr.CoderServiceIPv6`. This address can be used
358358
// when you want to know if Coder Connect is running, but are not trying to
359359
// connect to a specific known workspace.
360-
constIsCoderConnectEnabledFQDNString="is.coder--connect--enabled--right--now.coder."
361-
362-
varIsCoderConnectEnabledFQDN,_=dnsname.ToFQDN(IsCoderConnectEnabledFQDNString)
360+
constIsCoderConnectEnabledFmtString="is.coder--connect--enabled--right--now.%s."
363361

364362
typeServicePrefix [6]byte
365363

‎tailnet/controllers.go

Lines changed: 33 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -864,11 +864,12 @@ func (r *basicResumeTokenRefresher) refresh() {
864864
}
865865

866866
typeTunnelAllWorkspaceUpdatesControllerstruct {
867-
coordCtrl*TunnelSrcCoordController
868-
dnsHostSetterDNSHostsSetter
869-
updateHandlerUpdatesHandler
870-
ownerUsernamestring
871-
logger slog.Logger
867+
coordCtrl*TunnelSrcCoordController
868+
dnsHostSetterDNSHostsSetter
869+
dnsNameOptionsDNSNameOptions
870+
updateHandlerUpdatesHandler
871+
ownerUsernamestring
872+
logger slog.Logger
872873

873874
mu sync.Mutex
874875
updater*tunnelUpdater
@@ -883,37 +884,39 @@ type Workspace struct {
883884
agentsmap[uuid.UUID]*Agent
884885
}
885886

887+
typeDNSNameOptionsstruct {
888+
Suffixstring
889+
}
890+
886891
// updateDNSNames updates the DNS names for all agents in the workspace.
887892
// DNS hosts must be all lowercase, or the resolver won't be able to find them.
888893
// Usernames are globally unique & case-insensitive.
889894
// Workspace names are unique per-user & case-insensitive.
890895
// Agent names are unique per-workspace & case-insensitive.
891-
func (w*Workspace)updateDNSNames()error {
896+
func (w*Workspace)updateDNSNames(optionsDNSNameOptions)error {
892897
wsName:=strings.ToLower(w.Name)
893898
username:=strings.ToLower(w.ownerUsername)
894899
forid,a:=rangew.agents {
895900
agentName:=strings.ToLower(a.Name)
896901
names:=make(map[dnsname.FQDN][]netip.Addr)
897902
// TODO: technically, DNS labels cannot start with numbers, but the rules are often not
898903
// strictly enforced.
899-
fqdn,err:=dnsname.ToFQDN(fmt.Sprintf("%s.%s.me.coder.",agentName,wsName))
904+
fqdn,err:=dnsname.ToFQDN(fmt.Sprintf("%s.%s.me.%s.",agentName,wsName,options.Suffix))
900905
iferr!=nil {
901906
returnerr
902907
}
903908
names[fqdn]= []netip.Addr{CoderServicePrefix.AddrFromUUID(a.ID)}
904-
fqdn,err=dnsname.ToFQDN(fmt.Sprintf("%s.%s.%s.coder.",agentName,wsName,username))
909+
fqdn,err=dnsname.ToFQDN(fmt.Sprintf("%s.%s.%s.%s.",agentName,wsName,username,options.Suffix))
905910
iferr!=nil {
906911
returnerr
907912
}
908913
names[fqdn]= []netip.Addr{CoderServicePrefix.AddrFromUUID(a.ID)}
909914
iflen(w.agents)==1 {
910-
fqdn,err:=dnsname.ToFQDN(fmt.Sprintf("%s.coder.",wsName))
915+
fqdn,err=dnsname.ToFQDN(fmt.Sprintf("%s.%s.",wsName,options.Suffix))
911916
iferr!=nil {
912917
returnerr
913918
}
914-
for_,a:=rangew.agents {
915-
names[fqdn]= []netip.Addr{CoderServicePrefix.AddrFromUUID(a.ID)}
916-
}
919+
names[fqdn]= []netip.Addr{CoderServicePrefix.AddrFromUUID(a.ID)}
917920
}
918921
a.Hosts=names
919922
w.agents[id]=a
@@ -950,6 +953,7 @@ func (t *TunnelAllWorkspaceUpdatesController) New(client WorkspaceUpdatesClient)
950953
logger:t.logger,
951954
coordCtrl:t.coordCtrl,
952955
dnsHostsSetter:t.dnsHostSetter,
956+
dnsNameOptions:t.dnsNameOptions,
953957
updateHandler:t.updateHandler,
954958
ownerUsername:t.ownerUsername,
955959
recvLoopDone:make(chanstruct{}),
@@ -996,6 +1000,7 @@ type tunnelUpdater struct {
9961000
updateHandlerUpdatesHandler
9971001
ownerUsernamestring
9981002
recvLoopDonechanstruct{}
1003+
dnsNameOptionsDNSNameOptions
9991004

10001005
sync.Mutex
10011006
workspacesmap[uuid.UUID]*Workspace
@@ -1250,14 +1255,15 @@ func (t *tunnelUpdater) allAgentIDsLocked() []uuid.UUID {
12501255
func (t*tunnelUpdater)updateDNSNamesLocked()map[dnsname.FQDN][]netip.Addr {
12511256
names:=make(map[dnsname.FQDN][]netip.Addr)
12521257
for_,w:=ranget.workspaces {
1253-
err:=w.updateDNSNames()
1258+
err:=w.updateDNSNames(t.dnsNameOptions)
12541259
iferr!=nil {
12551260
// This should never happen in production, because converting the FQDN only fails
12561261
// if names are too long, and we put strict length limits on agent, workspace, and user
12571262
// names.
12581263
t.logger.Critical(context.Background(),
12591264
"failed to include DNS name(s)",
12601265
slog.F("workspace_id",w.ID),
1266+
slog.F("suffix",t.dnsNameOptions.Suffix),
12611267
slog.Error(err))
12621268
}
12631269
for_,a:=rangew.agents {
@@ -1266,18 +1272,25 @@ func (t *tunnelUpdater) updateDNSNamesLocked() map[dnsname.FQDN][]netip.Addr {
12661272
}
12671273
}
12681274
}
1269-
names[IsCoderConnectEnabledFQDN]= []netip.Addr{tsaddr.CoderServiceIPv6()}
1275+
isCoderConnectEnabledFQDN,err:=dnsname.ToFQDN(fmt.Sprintf(IsCoderConnectEnabledFmtString,t.dnsNameOptions.Suffix))
1276+
iferr!=nil {
1277+
t.logger.Critical(context.Background(),
1278+
"failed to include Coder Connect enabled DNS name",slog.F("suffix",t.dnsNameOptions.Suffix))
1279+
}else {
1280+
names[isCoderConnectEnabledFQDN]= []netip.Addr{tsaddr.CoderServiceIPv6()}
1281+
}
12701282
returnnames
12711283
}
12721284

12731285
typeTunnelAllOptionfunc(t*TunnelAllWorkspaceUpdatesController)
12741286

12751287
// WithDNS configures the tunnelAllWorkspaceUpdatesController to set DNS names for all workspaces
12761288
// and agents it learns about.
1277-
funcWithDNS(dDNSHostsSetter,ownerUsernamestring)TunnelAllOption {
1289+
funcWithDNS(dDNSHostsSetter,ownerUsernamestring,optionsDNSNameOptions)TunnelAllOption {
12781290
returnfunc(t*TunnelAllWorkspaceUpdatesController) {
12791291
t.dnsHostSetter=d
12801292
t.ownerUsername=ownerUsername
1293+
t.dnsNameOptions=options
12811294
}
12821295
}
12831296

@@ -1293,7 +1306,11 @@ func WithHandler(h UpdatesHandler) TunnelAllOption {
12931306
funcNewTunnelAllWorkspaceUpdatesController(
12941307
logger slog.Logger,c*TunnelSrcCoordController,opts...TunnelAllOption,
12951308
)*TunnelAllWorkspaceUpdatesController {
1296-
t:=&TunnelAllWorkspaceUpdatesController{logger:logger,coordCtrl:c}
1309+
t:=&TunnelAllWorkspaceUpdatesController{
1310+
logger:logger,
1311+
coordCtrl:c,
1312+
dnsNameOptions:DNSNameOptions{"coder"},
1313+
}
12971314
for_,opt:=rangeopts {
12981315
opt(t)
12991316
}

‎tailnet/controllers_test.go

Lines changed: 40 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1522,7 +1522,7 @@ func TestTunnelAllWorkspaceUpdatesController_Initial(t *testing.T) {
15221522
fUH:=newFakeUpdateHandler(ctx,t)
15231523
fDNS:=newFakeDNSSetter(ctx,t)
15241524
coordC,updateC,updateCtrl:=setupConnectedAllWorkspaceUpdatesController(ctx,t,logger,
1525-
tailnet.WithDNS(fDNS,"testy"),
1525+
tailnet.WithDNS(fDNS,"testy", tailnet.DNSNameOptions{Suffix:"mctest"}),
15261526
tailnet.WithHandler(fUH),
15271527
)
15281528

@@ -1562,16 +1562,19 @@ func TestTunnelAllWorkspaceUpdatesController_Initial(t *testing.T) {
15621562
w2a1IP:=netip.MustParseAddr("fd60:627a:a42b:0201::")
15631563
w2a2IP:=netip.MustParseAddr("fd60:627a:a42b:0202::")
15641564

1565+
expectedCoderConnectFQDN,err:=dnsname.ToFQDN(fmt.Sprintf(tailnet.IsCoderConnectEnabledFmtString,"mctest"))
1566+
require.NoError(t,err)
1567+
15651568
// Also triggers setting DNS hosts
15661569
expectedDNS:=map[dnsname.FQDN][]netip.Addr{
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()},
1570+
"w1a1.w1.me.mctest.": {ws1a1IP},
1571+
"w2a1.w2.me.mctest.": {w2a1IP},
1572+
"w2a2.w2.me.mctest.": {w2a2IP},
1573+
"w1a1.w1.testy.mctest.": {ws1a1IP},
1574+
"w2a1.w2.testy.mctest.": {w2a1IP},
1575+
"w2a2.w2.testy.mctest.": {w2a2IP},
1576+
"w1.mctest.": {ws1a1IP},
1577+
expectedCoderConnectFQDN: {tsaddr.CoderServiceIPv6()},
15751578
}
15761579
dnsCall:=testutil.RequireRecvCtx(ctx,t,fDNS.calls)
15771580
require.Equal(t,expectedDNS,dnsCall.hosts)
@@ -1586,23 +1589,23 @@ func TestTunnelAllWorkspaceUpdatesController_Initial(t *testing.T) {
15861589
{
15871590
ID:w1a1ID,Name:"w1a1",WorkspaceID:w1ID,
15881591
Hosts:map[dnsname.FQDN][]netip.Addr{
1589-
"w1.coder.": {ws1a1IP},
1590-
"w1a1.w1.me.coder.": {ws1a1IP},
1591-
"w1a1.w1.testy.coder.": {ws1a1IP},
1592+
"w1.mctest.": {ws1a1IP},
1593+
"w1a1.w1.me.mctest.": {ws1a1IP},
1594+
"w1a1.w1.testy.mctest.": {ws1a1IP},
15921595
},
15931596
},
15941597
{
15951598
ID:w2a1ID,Name:"w2a1",WorkspaceID:w2ID,
15961599
Hosts:map[dnsname.FQDN][]netip.Addr{
1597-
"w2a1.w2.me.coder.": {w2a1IP},
1598-
"w2a1.w2.testy.coder.": {w2a1IP},
1600+
"w2a1.w2.me.mctest.": {w2a1IP},
1601+
"w2a1.w2.testy.mctest.": {w2a1IP},
15991602
},
16001603
},
16011604
{
16021605
ID:w2a2ID,Name:"w2a2",WorkspaceID:w2ID,
16031606
Hosts:map[dnsname.FQDN][]netip.Addr{
1604-
"w2a2.w2.me.coder.": {w2a2IP},
1605-
"w2a2.w2.testy.coder.": {w2a2IP},
1607+
"w2a2.w2.me.mctest.": {w2a2IP},
1608+
"w2a2.w2.testy.mctest.": {w2a2IP},
16061609
},
16071610
},
16081611
},
@@ -1634,7 +1637,7 @@ func TestTunnelAllWorkspaceUpdatesController_DeleteAgent(t *testing.T) {
16341637
fUH:=newFakeUpdateHandler(ctx,t)
16351638
fDNS:=newFakeDNSSetter(ctx,t)
16361639
coordC,updateC,updateCtrl:=setupConnectedAllWorkspaceUpdatesController(ctx,t,logger,
1637-
tailnet.WithDNS(fDNS,"testy"),
1640+
tailnet.WithDNS(fDNS,"testy", tailnet.DNSNameOptions{Suffix:"coder"}),
16381641
tailnet.WithHandler(fUH),
16391642
)
16401643

@@ -1661,12 +1664,15 @@ func TestTunnelAllWorkspaceUpdatesController_DeleteAgent(t *testing.T) {
16611664
require.Equal(t,w1a1ID[:],coordCall.req.GetAddTunnel().GetId())
16621665
testutil.RequireSendCtx(ctx,t,coordCall.err,nil)
16631666

1667+
expectedCoderConnectFQDN,err:=dnsname.ToFQDN(fmt.Sprintf(tailnet.IsCoderConnectEnabledFmtString,"coder"))
1668+
require.NoError(t,err)
1669+
16641670
// DNS for w1a1
16651671
expectedDNS:=map[dnsname.FQDN][]netip.Addr{
1666-
"w1a1.w1.testy.coder.":{ws1a1IP},
1667-
"w1a1.w1.me.coder.":{ws1a1IP},
1668-
"w1.coder.":{ws1a1IP},
1669-
tailnet.IsCoderConnectEnabledFQDNString: {tsaddr.CoderServiceIPv6()},
1672+
"w1a1.w1.testy.coder.": {ws1a1IP},
1673+
"w1a1.w1.me.coder.": {ws1a1IP},
1674+
"w1.coder.": {ws1a1IP},
1675+
expectedCoderConnectFQDN: {tsaddr.CoderServiceIPv6()},
16701676
}
16711677
dnsCall:=testutil.RequireRecvCtx(ctx,t,fDNS.calls)
16721678
require.Equal(t,expectedDNS,dnsCall.hosts)
@@ -1719,10 +1725,10 @@ func TestTunnelAllWorkspaceUpdatesController_DeleteAgent(t *testing.T) {
17191725

17201726
// DNS contains only w1a2
17211727
expectedDNS=map[dnsname.FQDN][]netip.Addr{
1722-
"w1a2.w1.testy.coder.":{ws1a2IP},
1723-
"w1a2.w1.me.coder.":{ws1a2IP},
1724-
"w1.coder.":{ws1a2IP},
1725-
tailnet.IsCoderConnectEnabledFQDNString: {tsaddr.CoderServiceIPv6()},
1728+
"w1a2.w1.testy.coder.": {ws1a2IP},
1729+
"w1a2.w1.me.coder.": {ws1a2IP},
1730+
"w1.coder.": {ws1a2IP},
1731+
expectedCoderConnectFQDN: {tsaddr.CoderServiceIPv6()},
17261732
}
17271733
dnsCall=testutil.RequireRecvCtx(ctx,t,fDNS.calls)
17281734
require.Equal(t,expectedDNS,dnsCall.hosts)
@@ -1779,7 +1785,7 @@ func TestTunnelAllWorkspaceUpdatesController_DNSError(t *testing.T) {
17791785
fConn:=&fakeCoordinatee{}
17801786
tsc:=tailnet.NewTunnelSrcCoordController(logger,fConn)
17811787
uut:=tailnet.NewTunnelAllWorkspaceUpdatesController(logger,tsc,
1782-
tailnet.WithDNS(fDNS,"testy"),
1788+
tailnet.WithDNS(fDNS,"testy", tailnet.DNSNameOptions{Suffix:"coder"}),
17831789
)
17841790

17851791
updateC:=newFakeWorkspaceUpdateClient(ctx,t)
@@ -1800,12 +1806,15 @@ func TestTunnelAllWorkspaceUpdatesController_DNSError(t *testing.T) {
18001806
upRecvCall:=testutil.RequireRecvCtx(ctx,t,updateC.recv)
18011807
testutil.RequireSendCtx(ctx,t,upRecvCall.resp,initUp)
18021808

1809+
expectedCoderConnectFQDN,err:=dnsname.ToFQDN(fmt.Sprintf(tailnet.IsCoderConnectEnabledFmtString,"coder"))
1810+
require.NoError(t,err)
1811+
18031812
// DNS for w1a1
18041813
expectedDNS:=map[dnsname.FQDN][]netip.Addr{
1805-
"w1a1.w1.me.coder.":{ws1a1IP},
1806-
"w1a1.w1.testy.coder.":{ws1a1IP},
1807-
"w1.coder.":{ws1a1IP},
1808-
tailnet.IsCoderConnectEnabledFQDNString: {tsaddr.CoderServiceIPv6()},
1814+
"w1a1.w1.me.coder.": {ws1a1IP},
1815+
"w1a1.w1.testy.coder.": {ws1a1IP},
1816+
"w1.coder.": {ws1a1IP},
1817+
expectedCoderConnectFQDN: {tsaddr.CoderServiceIPv6()},
18091818
}
18101819
dnsCall:=testutil.RequireRecvCtx(ctx,t,fDNS.calls)
18111820
require.Equal(t,expectedDNS,dnsCall.hosts)
@@ -1816,7 +1825,7 @@ func TestTunnelAllWorkspaceUpdatesController_DNSError(t *testing.T) {
18161825
testutil.RequireSendCtx(ctx,t,closeCall,io.EOF)
18171826

18181827
// error should be our initial DNS error
1819-
err:=testutil.RequireRecvCtx(ctx,t,updateCW.Wait())
1828+
err=testutil.RequireRecvCtx(ctx,t,updateCW.Wait())
18201829
require.ErrorIs(t,err,dnsError)
18211830
}
18221831

‎vpn/client.go

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,11 @@ func (*client) NewConn(initCtx context.Context, serverURL *url.URL, token string
107107
iferr!=nil {
108108
returnnil,xerrors.Errorf("get connection info: %w",err)
109109
}
110+
// default to DNS suffix of "coder" if the server hasn't set it (might be too old).
111+
dnsNameOptions:= tailnet.DNSNameOptions{Suffix:"coder"}
112+
ifconnInfo.HostnameSuffix!="" {
113+
dnsNameOptions.Suffix=connInfo.HostnameSuffix
114+
}
110115

111116
headers.Set(codersdk.SessionTokenHeader,token)
112117
dialer:=workspacesdk.NewWebsocketDialer(options.Logger,rpcURL,&websocket.DialOptions{
@@ -148,7 +153,7 @@ func (*client) NewConn(initCtx context.Context, serverURL *url.URL, token string
148153
updatesCtrl:=tailnet.NewTunnelAllWorkspaceUpdatesController(
149154
options.Logger,
150155
coordCtrl,
151-
tailnet.WithDNS(conn,me.Username),
156+
tailnet.WithDNS(conn,me.Username,dnsNameOptions),
152157
tailnet.WithHandler(options.UpdateHandler),
153158
)
154159
controller.WorkspaceUpdatesCtrl=updatesCtrl

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp