Skip to content

Commit 17bc579

Browse files
authored
fix: direct embedded derp traffic directly to the server (#6595)
Prior to this change, DERP traffic would route from `coderd` to the `CODER_ACCESS_URL` to reach the internal DERP server, which may have resulted in slower connections due to proxying, or the failure of web traffic entirely. If your Coder deployment has a proxy in front of it, your traffic through web terminals, apps, and port-forwarding is about to get a lot faster!
1 parent e376849 commit 17bc579

File tree

5 files changed

+34
-38
lines changed

5 files changed

+34
-38
lines changed

coderd/coderdtest/coderdtest.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -258,7 +258,7 @@ func NewOptions(t *testing.T, options *Options) (func(http.Handler), context.Can
258258
stunAddr, stunCleanup := stuntest.ServeWithPacketListener(t, nettype.Std{})
259259
t.Cleanup(stunCleanup)
260260

261-
derpServer := derp.NewServer(key.NewNode(), tailnet.Logger(slogtest.Make(t, nil).Named("derp")))
261+
derpServer := derp.NewServer(key.NewNode(), tailnet.Logger(slogtest.Make(t, nil).Named("derp").Leveled(slog.LevelDebug)))
262262
derpServer.SetMeshKey("test-key")
263263

264264
// match default with cli default

coderd/workspaceagents.go

+15-36
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package coderd
22

33
import (
4+
"bufio"
45
"context"
56
"database/sql"
67
"encoding/json"
@@ -428,51 +429,29 @@ func (api *API) dialWorkspaceAgentTailnet(r *http.Request, agentID uuid.UUID) (*
428429
ctx := r.Context()
429430
clientConn, serverConn := net.Pipe()
430431

431-
derpMap := api.DERPMap.Clone()
432-
for _, region := range derpMap.Regions {
433-
if !region.EmbeddedRelay {
434-
continue
435-
}
436-
var node *tailcfg.DERPNode
437-
for _, n := range region.Nodes {
438-
if n.STUNOnly {
439-
continue
440-
}
441-
node = n
442-
break
443-
}
444-
if node == nil {
445-
continue
446-
}
447-
// TODO: This should dial directly to execute the
448-
// DERP server instead of contacting localhost.
449-
//
450-
// This requires modification of Tailscale internals
451-
// to pipe through a proxy function per-region, so
452-
// this is an easy and mostly reliable hack for now.
453-
cloned := node.Clone()
454-
// Add p for proxy.
455-
// This first node supports TLS.
456-
cloned.Name += "p"
457-
cloned.IPv4 = "127.0.0.1"
458-
cloned.InsecureForTests = true
459-
region.Nodes = append(region.Nodes, cloned.Clone())
460-
// This second node forces HTTP.
461-
cloned.Name += "-http"
462-
cloned.ForceHTTP = true
463-
region.Nodes = append(region.Nodes, cloned)
464-
}
465-
466432
conn, err := tailnet.NewConn(&tailnet.Options{
467433
Addresses: []netip.Prefix{netip.PrefixFrom(tailnet.IP(), 128)},
468-
DERPMap: derpMap,
434+
DERPMap: api.DERPMap,
469435
Logger: api.Logger.Named("tailnet"),
470436
})
471437
if err != nil {
472438
_ = clientConn.Close()
473439
_ = serverConn.Close()
474440
return nil, xerrors.Errorf("create tailnet conn: %w", err)
475441
}
442+
conn.SetDERPRegionDialer(func(_ context.Context, region *tailcfg.DERPRegion) net.Conn {
443+
if !region.EmbeddedRelay {
444+
return nil
445+
}
446+
left, right := net.Pipe()
447+
go func() {
448+
defer left.Close()
449+
defer right.Close()
450+
brw := bufio.NewReadWriter(bufio.NewReader(right), bufio.NewWriter(right))
451+
api.DERPServer.Accept(ctx, right, brw, r.RemoteAddr)
452+
}()
453+
return left
454+
})
476455

477456
sendNodes, _ := tailnet.ServeCoordinator(clientConn, func(node []*tailnet.Node) error {
478457
err = conn.UpdateNodes(node, true)

go.mod

+1-1
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ replace github.com/tcnksm/go-httpstat => github.com/kylecarbs/go-httpstat v0.0.0
4040

4141
// There are a few minor changes we make to Tailscale that we're slowly upstreaming. Compare here:
4242
// https://github.com/tailscale/tailscale/compare/main...coder:tailscale:main
43-
replace tailscale.com => github.com/coder/tailscale v1.1.1-0.20230307022319-1e5e724a3949
43+
replace tailscale.com => github.com/coder/tailscale v1.1.1-0.20230314023417-d9efcc0ac972
4444

4545
// Switch to our fork that imports fixes from http://github.com/tailscale/ssh.
4646
// See: https://github.com/coder/coder/issues/3371

go.sum

+12
Original file line numberDiff line numberDiff line change
@@ -378,6 +378,18 @@ github.com/coder/ssh v0.0.0-20220811105153-fcea99919338 h1:tN5GKFT68YLVzJoA8AHui
378378
github.com/coder/ssh v0.0.0-20220811105153-fcea99919338/go.mod h1:ZSS+CUoKHDrqVakTfTWUlKSr9MtMFkC4UvtQKD7O914=
379379
github.com/coder/tailscale v1.1.1-0.20230307022319-1e5e724a3949 h1:8WfMfRTDaEpnmhCJWfFQ7JHz19GyP+EgFgLGu5ngdek=
380380
github.com/coder/tailscale v1.1.1-0.20230307022319-1e5e724a3949/go.mod h1:jpg+77g19FpXL43U1VoIqoSg1K/Vh5CVxycGldQ8KhA=
381+
github.com/coder/tailscale v1.1.1-0.20230313184322-307d4b9ef4e1 h1:kOh+1rBcbahdodSiNBioO4g47m3Ef8CagNEX8U7/RyY=
382+
github.com/coder/tailscale v1.1.1-0.20230313184322-307d4b9ef4e1/go.mod h1:jpg+77g19FpXL43U1VoIqoSg1K/Vh5CVxycGldQ8KhA=
383+
github.com/coder/tailscale v1.1.1-0.20230313192237-8d691a009b20 h1:FFPv3xLsAT+n8chkePxB/VwqFwn4NL8GV8Lk97efUP0=
384+
github.com/coder/tailscale v1.1.1-0.20230313192237-8d691a009b20/go.mod h1:jpg+77g19FpXL43U1VoIqoSg1K/Vh5CVxycGldQ8KhA=
385+
github.com/coder/tailscale v1.1.1-0.20230313194848-e281f646c460 h1:WYnHzxQ1DsgDYyyS6i8tgdpjiwS1LrXJjwXcOVkU/3g=
386+
github.com/coder/tailscale v1.1.1-0.20230313194848-e281f646c460/go.mod h1:jpg+77g19FpXL43U1VoIqoSg1K/Vh5CVxycGldQ8KhA=
387+
github.com/coder/tailscale v1.1.1-0.20230313195101-c6534848756b h1:3xWbBCpQ+CqVP2Myh1YhCw8cJbMi6mjkDl4/x6YkiUw=
388+
github.com/coder/tailscale v1.1.1-0.20230313195101-c6534848756b/go.mod h1:jpg+77g19FpXL43U1VoIqoSg1K/Vh5CVxycGldQ8KhA=
389+
github.com/coder/tailscale v1.1.1-0.20230314021518-0cda9db154be h1:b0ZTDPpV/fAdkuS/V59cawnq+5vcXzkvXPMG/eZcRx0=
390+
github.com/coder/tailscale v1.1.1-0.20230314021518-0cda9db154be/go.mod h1:jpg+77g19FpXL43U1VoIqoSg1K/Vh5CVxycGldQ8KhA=
391+
github.com/coder/tailscale v1.1.1-0.20230314023417-d9efcc0ac972 h1:193YGsJz8hc4yxqAclE36paKl+9CQ6KGLgdleIguCVE=
392+
github.com/coder/tailscale v1.1.1-0.20230314023417-d9efcc0ac972/go.mod h1:jpg+77g19FpXL43U1VoIqoSg1K/Vh5CVxycGldQ8KhA=
381393
github.com/coder/terraform-provider-coder v0.6.15 h1:Llvh4RwxSQ/goy7ToTOeHf3tdEz+79qbyOh61hNnJs0=
382394
github.com/coder/terraform-provider-coder v0.6.15/go.mod h1:UIfU3bYNeSzJJvHyJ30tEKjD6Z9utloI+HUM/7n94CY=
383395
github.com/coder/terraform-provider-coder v0.6.17 h1:YvjM5nQx5RO+gXsYIv++CkiWCuJueQdJaPrsjnkZ4XQ=

tailnet/conn.go

+5
Original file line numberDiff line numberDiff line change
@@ -350,6 +350,11 @@ func (c *Conn) SetDERPMap(derpMap *tailcfg.DERPMap) {
350350
c.wireguardEngine.SetNetworkMap(&netMapCopy)
351351
}
352352

353+
// SetDERPRegionDialer updates the dialer to use for connecting to DERP regions.
354+
func (c *Conn) SetDERPRegionDialer(dialer func(ctx context.Context, region *tailcfg.DERPRegion) net.Conn) {
355+
c.magicConn.SetDERPRegionDialer(dialer)
356+
}
357+
353358
func (c *Conn) RemoveAllPeers() error {
354359
c.mutex.Lock()
355360
defer c.mutex.Unlock()

0 commit comments

Comments
 (0)