Skip to content

Commit bc18f6c

Browse files
authored
fix: add CODER_AGENT_TAILNET_LISTEN_PORT for specifying a static tailnet port (#6980)
Fixes #5175.
1 parent 4ee01dc commit bc18f6c

File tree

4 files changed

+35
-17
lines changed

4 files changed

+35
-17
lines changed

agent/agent.go

+13-9
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@ type Options struct {
8282
Logger slog.Logger
8383
AgentPorts map[int]string
8484
SSHMaxTimeout time.Duration
85+
TailnetListenPort uint16
8586
}
8687

8788
type Client interface {
@@ -118,6 +119,7 @@ func New(options Options) io.Closer {
118119
}
119120
ctx, cancelFunc := context.WithCancel(context.Background())
120121
a := &agent{
122+
tailnetListenPort: options.TailnetListenPort,
121123
reconnectingPTYTimeout: options.ReconnectingPTYTimeout,
122124
logger: options.Logger,
123125
closeCancel: cancelFunc,
@@ -139,12 +141,13 @@ func New(options Options) io.Closer {
139141
}
140142

141143
type agent struct {
142-
logger slog.Logger
143-
client Client
144-
exchangeToken func(ctx context.Context) (string, error)
145-
filesystem afero.Fs
146-
logDir string
147-
tempDir string
144+
logger slog.Logger
145+
client Client
146+
exchangeToken func(ctx context.Context) (string, error)
147+
tailnetListenPort uint16
148+
filesystem afero.Fs
149+
logDir string
150+
tempDir string
148151
// ignorePorts tells the api handler which ports to ignore when
149152
// listing all listening ports. This is helpful to hide ports that
150153
// are used by the agent, that the user does not care about.
@@ -606,9 +609,10 @@ func (a *agent) trackConnGoroutine(fn func()) error {
606609

607610
func (a *agent) createTailnet(ctx context.Context, derpMap *tailcfg.DERPMap) (_ *tailnet.Conn, err error) {
608611
network, err := tailnet.NewConn(&tailnet.Options{
609-
Addresses: []netip.Prefix{netip.PrefixFrom(codersdk.WorkspaceAgentIP, 128)},
610-
DERPMap: derpMap,
611-
Logger: a.logger.Named("tailnet"),
612+
Addresses: []netip.Prefix{netip.PrefixFrom(codersdk.WorkspaceAgentIP, 128)},
613+
DERPMap: derpMap,
614+
Logger: a.logger.Named("tailnet"),
615+
ListenPort: a.tailnetListenPort,
612616
})
613617
if err != nil {
614618
return nil, xerrors.Errorf("create tailnet: %w", err)

cli/agent.go

+17-8
Original file line numberDiff line numberDiff line change
@@ -30,11 +30,12 @@ import (
3030

3131
func (r *RootCmd) workspaceAgent() *clibase.Cmd {
3232
var (
33-
auth string
34-
logDir string
35-
pprofAddress string
36-
noReap bool
37-
sshMaxTimeout time.Duration
33+
auth string
34+
logDir string
35+
pprofAddress string
36+
noReap bool
37+
sshMaxTimeout time.Duration
38+
tailnetListenPort int64
3839
)
3940
cmd := &clibase.Cmd{
4041
Use: "agent",
@@ -187,9 +188,10 @@ func (r *RootCmd) workspaceAgent() *clibase.Cmd {
187188
}
188189

189190
closer := agent.New(agent.Options{
190-
Client: client,
191-
Logger: logger,
192-
LogDir: logDir,
191+
Client: client,
192+
Logger: logger,
193+
LogDir: logDir,
194+
TailnetListenPort: uint16(tailnetListenPort),
193195
ExchangeToken: func(ctx context.Context) (string, error) {
194196
if exchangeToken == nil {
195197
return client.SDK.SessionToken(), nil
@@ -248,6 +250,13 @@ func (r *RootCmd) workspaceAgent() *clibase.Cmd {
248250
Description: "Specify the max timeout for a SSH connection.",
249251
Value: clibase.DurationOf(&sshMaxTimeout),
250252
},
253+
{
254+
Flag: "tailnet-listen-port",
255+
Default: "0",
256+
Env: "CODER_AGENT_TAILNET_LISTEN_PORT",
257+
Description: "Specify a static port for Tailscale to use for listening.",
258+
Value: clibase.Int64Of(&tailnetListenPort),
259+
},
251260
}
252261

253262
return cmd

cli/testdata/coder_agent_--help.golden

+3
Original file line numberDiff line numberDiff line change
@@ -18,5 +18,8 @@ Starts the Coder workspace agent.
1818
--ssh-max-timeout duration, $CODER_AGENT_SSH_MAX_TIMEOUT (default: 0)
1919
Specify the max timeout for a SSH connection.
2020

21+
--tailnet-listen-port int, $CODER_AGENT_TAILNET_LISTEN_PORT (default: 0)
22+
Specify a static port for Tailscale to use for listening.
23+
2124
---
2225
Run `coder --help` for a list of global options.

tailnet/conn.go

+2
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ type Options struct {
5959
// If so, only DERPs can establish connections.
6060
BlockEndpoints bool
6161
Logger slog.Logger
62+
ListenPort uint16
6263
}
6364

6465
// NewConn constructs a new Wireguard server that will accept connections from the addresses provided.
@@ -137,6 +138,7 @@ func NewConn(options *Options) (conn *Conn, err error) {
137138
wireguardEngine, err := wgengine.NewUserspaceEngine(Logger(options.Logger.Named("wgengine")), wgengine.Config{
138139
LinkMonitor: wireguardMonitor,
139140
Dialer: dialer,
141+
ListenPort: options.ListenPort,
140142
})
141143
if err != nil {
142144
return nil, xerrors.Errorf("create wgengine: %w", err)

0 commit comments

Comments
 (0)