Commit Graph

51 Commits

Author SHA1 Message Date
Ethan e738ff5299 ci: remove dylib build pipeline (#22592)
## Summary

The macOS `.dylib` is only used by Coder Desktop macOS v0.7.2 or older.
v0.7.2 was released in August 2025. v0.8.0 of Coder Desktop macOS, also
released in August 2025, uses a signed Coder slim binary from the
deployment instead.

It's unlikely customers will be using Coder Desktop macOS v0.7.2 and the
next release of Coder simultaneously, so I think we can safely remove
this process, given it slows down CI & release processes.

## Changes

- **Makefile**: Remove `DYLIB_ARCHES`, `CODER_DYLIBS` variables and
`build/coder-dylib` target
- **scripts/build_go.sh**: Remove `--dylib` flag and all dylib-specific
logic (c-shared buildmode, CGO, plist embedding, vpn/dylib entrypoint)
- **scripts/sign_darwin.sh**: Remove dylib-specific comment
- **CI (ci.yaml)**: Remove `build-dylib` job, artifact download/insert
steps, and `build-dylib` dependency from `build` job
- **Release (release.yaml)**: Remove `build-dylib` job, artifact
download/insert steps, and `build-dylib` dependency from `release` job
- **vpn/dylib/**: Delete entire directory (`lib.go` + `info.plist.tmpl`)
- **vpn/router.go, vpn/dns.go**: Clean up comments referencing dylib

The slim and fat binary builds are completely unaffected — the dylib was
an independent build target with its own CI job.

_Generated by mux but reviewed by a human_
2026-03-05 01:50:50 +11:00
Michael Suchacz adc7775405 feat(vpn): add Linux support for vpn-daemon and OS networking stack (#22051)
This change adds Linux support for Desktop VPN by aligning Linux
behavior with the existing Windows daemon implementation and adding a
Linux networking stack implementation.

### What changed
- Consolidated the daemon command implementation into a shared file:
  - `cli/vpndaemon_windows_linux.go` (`//go:build windows || linux`)
- Consolidated daemon tests into a shared file:
- `cli/vpndaemon_windows_linux_test.go` (`//go:build windows || linux`)
- Removed Linux-only duplicate daemon files:
  - `cli/vpndaemon_linux.go`
  - `cli/vpndaemon_linux_test.go`
- Removed unsupported-platform stubs per current supported OS targets:
  - `cli/vpndaemon_other.go`
  - `vpn/tun.go`
- Kept Linux networking stack implementation in:
  - `vpn/tun_linux.go`

### Notes
- Linux now uses the same `rpc-read-handle` / `rpc-write-handle` flags
and env vars as Windows.
- The daemon logs to stderr (via CLI logger sinks), and does not forward
logs over the RPC pipe.
2026-02-12 12:14:56 +01:00
Spike Curtis bddb808b25 chore: arrange imports in a standard way (#21452)
Fixes all our Go file imports to match the preferred spec that we've _mostly_ been using. For example:

```
import (
	"context"
	"time"

	"github.com/prometheus/client_golang/prometheus"
	"golang.org/x/xerrors"
	"gopkg.in/natefinch/lumberjack.v2"

	"cdr.dev/slog/v3"
	"github.com/coder/coder/v2/codersdk/agentsdk"
	"github.com/coder/serpent"
)
```

3 groups: standard library, 3rd partly libs, Coder libs.

This PR makes the change across the codebase. The PR in the stack above modifies our formatting to maintain this state of affairs, and is a separate PR so it's possible to review that one in detail.
2026-01-08 15:24:11 +04:00
Spike Curtis 49b34a716a fix: fix slog to always use array of Fields (#21426)
Upgrades to slog v3 which includes a small, but backward incompatible API change to the acceptible call arguments when logging. This change allows us to verify via compile time type checking that arguments are correct and won't cause a panic, as was possible in slog v1, which this replaces (v2 was tagged but never used in coder/coder).

It also updates dependencies that also use slog and were updated.

I've left the `aibridge` dependency as a commit SHA, under the assumption that the team there (cc @pawbana @dannykopping ) will tag and update the dependency soon and on their own schedule.

Other dependencies, I pushed new tags.
2026-01-08 10:29:41 +04:00
Dean Sheather 69c2c40512 chore: add user details to aibridge interception list endpoint (#20397)
- Adds FK from `aibridge_interceptions.initiator_id` to `users.id`
- This is enforced by deleting any rows that don't have any users. Since
this is an experimental feature AND coder never deletes user rows I
think this is acceptable.
- Adds `name` as a property on `codersdk.MinimalUser`
- This matches the `visible_users` view in the database. I'm unsure why
`name` wasn't already included given that `username` is.
- Adds a new `initiator` field to `codersdk.AIBridgeInterception` which
contains `codersdk.MinimalUser` (ID, username, name, avatar URL)
- Removes `initiator_id` from `codersdk.AIBridgeInterception`
    - Should be fine since we're still in early access
2025-10-22 16:18:31 +11:00
Dean Sheather bf78966256 chore: remove soft isolation configurability (#19069)
Undoes a lot of the changes in 5319d47dfa

Keeps the `netns.SetCoderSoftIsolation()` call, but always sets it to
`true` when using a TUN device.
2025-07-29 22:30:17 +10:00
Dean Sheather 2a430ab435 fix: avoid duplicating logs on Coder Connect Windows (#19052)
The sinks are already added to the logger above, so they're just getting duplicated
2025-07-28 14:02:00 +10:00
Dean Sheather 5319d47dfa chore: add support for tailscale soft isolation in VPN (#19023) 2025-07-24 04:18:29 +00:00
Dean Sheather a1b87a67c6 fix: use client preferred URL for the default DERP (#18911)
The agentsdk currently does a remap of the DERP map to change the
EmbeddedRelay node's URL to match the agent's access URL.

This PR makes changes to the `workspacesdk` (used by clients like the
CLI) and `vpn` (used by Coder Desktop) to match this behavior.

This enables us the ability to try Coder clients in dogfood over a VPN
without changing the global access URL.
2025-07-17 20:17:44 +10:00
Ethan 79c666bf08 fix(vpn): avoid setting session token header twice (#18524)
`coderd` currently does not handle a session token header value of the form `token1, token2`. However, it does handle multiple instances of the token header by simply taking the first. This is the default behaviour of `http.Header.Get`.

So, setting the token header twice causes issues when Coder is behind a proxy that merges duplicate headers, such as [Apache](https://httpd.apache.org/docs/2.4/mod/mod_headers.html#:~:text=list%20of%20values.-,When%20a%20new%20value%20is%20merged%20onto%20an%20existing%20header,format%20specifiers%20have%20been%20processed).


This PR ensures we don't set it twice by not sharing one slice between the `HTTPClient` and the `websocket.DialerOptions`. It also adds a regression test.
2025-06-25 11:27:35 +10:00
Michael Suchacz b091b996af chore: update VPN proto to match additional types used by Coder Desktop (#18504)
Extends vpn.proto with DownloadProgress messages used by Coder Desktop
on Windows.
2025-06-24 11:48:17 +00:00
ケイラ fae30a00fd chore: remove unnecessary redeclarations in for loops (#18440) 2025-06-20 13:16:55 -06:00
Ethan 628b81c334 chore(vpn): send info, debug logs over tunnel (#18240)
Closes https://github.com/coder/internal/issues/397
2025-06-06 14:31:27 +10:00
Ethan 0076e8479f chore(vpn): send ping results over tunnel (#18200)
Closes #17982.

The purpose of this PR is to expose network latency via the API used by Coder Desktop.

This PR has the tunnel ping all known agents every 5 seconds, in order to produce an instance of:
```proto
message LastPing {
	// latency is the RTT of the ping to the agent.
	google.protobuf.Duration latency = 1;
	// did_p2p indicates whether the ping was sent P2P, or over DERP.
	bool did_p2p = 2;
	// preferred_derp is the human readable name of the preferred DERP region,
	// or the region used for the last ping, if it was sent over DERP.
	string preferred_derp = 3;
	// preferred_derp_latency is the last known latency to the preferred DERP
	// region. Unset if the region does not appear in the DERP map.
	optional google.protobuf.Duration preferred_derp_latency = 4;
}
```
The contents of this message are stored and included on all subsequent upsertions of the agent. 
Note that we upsert existing agents every 5 seconds to update the `last_handshake` value.

On the desktop apps, this message will be used to produce a tooltip similar to that of the VS Code extension:
<img width="495" alt="image" src="https://github.com/user-attachments/assets/d8b65f3d-f536-4c64-9af9-35c1a42c92d2" />
(wording not final)

Unlike the VS Code extension, we omit:
- The Latency of *all* available DERP regions. It seems not ideal to send a copy of this entire map for every online agent, and it certainly doesn't make sense for it to be on the `Agent` or `LastPing` message. 
If we do want to expose this info on Coder Desktop, we should consider how best to do so; maybe we want to include it on a more generic `Netcheck` message.
- The current throughput (Bytes up/down). This is out of scope of the linked issue, and is non-trivial to implement. I'm also not sure of the value given the frequency we're doing these status updates (every 5 seconds).
If we want to expose it, it'll be in a separate PR.

<img width="343" alt="image" src="https://github.com/user-attachments/assets/8447d03b-9721-4111-8ac1-332d70a1e8f1" />
2025-06-06 14:18:57 +10:00
Spike Curtis 6c0bed0f53 chore: update to coder/quartz v0.2.0 (#18007)
Upgrade to coder/quartz v0.2.0 including fixing up a minor API breaking change.
2025-05-27 16:05:03 +04:00
Michael Suchacz 2696926003 fix: fixed flaking VPN tunnel tests & bump coder/quartz to 0.1.3 (#17737)
Closes: https://github.com/coder/internal/issues/624
2025-05-09 12:27:47 +02:00
Michael Suchacz 5f516ed135 feat: improve coder connect tunnel handling on reconnect (#17598)
Closes https://github.com/coder/internal/issues/563

The [Coder Connect
tunnel](https://github.com/coder/coder/blob/main/vpn/tunnel.go) receives
workspace state from the Coder server over a [dRPC
stream.](https://github.com/coder/coder/blob/114ba4593b2a82dfd41cdcb7fd6eb70d866e7b86/tailnet/controllers.go#L1029)
When first connecting to this stream, the current state of the user's
workspaces is received, with subsequent messages being diffs on top of
that state.

However, if the client disconnects from this stream, such as when the
user's device is suspended, and then reconnects later, no mechanism
exists for the tunnel to differentiate that message containing the
entire initial state from another diff, and so that state is incorrectly
applied as a diff.

In practice:
- Tunnel connects, receives a workspace update containing all the
existing workspaces & agents.
- Tunnel loses connection, but isn't completely stopped.
- All the user's workspaces are restarted, producing a new set of
agents.
- Tunnel regains connection, and receives a workspace update containing
all the existing workspaces & agents.
- This initial update is incorrectly applied as a diff, with the
Tunnel's state containing both the old & new agents.

This PR introduces a solution in which tunnelUpdater, when created,
sends a FreshState flag with the WorkspaceUpdate type. This flag is
handled in the vpn tunnel in the following fashion:
- Preserve existing Agents
- Remove current Agents in the tunnel that are not present in the
WorkspaceUpdate
- Remove unreferenced Workspaces
2025-05-06 16:00:16 +02:00
ケイラ f670bc31f5 chore: update testutil chan helpers (#17408) 2025-04-16 10:37:09 -06:00
Spike Curtis 9e2af3e127 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
2025-04-11 15:00:48 +04:00
Spike Curtis 2c573dc023 feat: vpn uses WorkspaceHostnameSuffix for DNS names (#17335)
Use the hostname suffix to set DNS names as programmed into the DNS service and returned by the vpn `Tunnel`.

part of: #16828
2025-04-11 13:24:20 +04:00
Spike Curtis f6a10eeb7f chore: sync vpn.proto with coder/coder-desktop-windows (#17106)
Syncs `vpn.proto` with https://github.com/coder/coder-desktop-windows/blob/main/Vpn.Proto/vpn.proto
2025-03-26 13:38:39 +04:00
Jon Ayers 17ddee05e5 chore: update golang to 1.24.1 (#17035)
- Update go.mod to use Go 1.24.1
- Update GitHub Actions setup-go action to use Go 1.24.1
- Fix linting issues with golangci-lint by:
  - Updating to golangci-lint v1.57.1 (more compatible with Go 1.24.1)

🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>

---------

Co-authored-by: Claude <claude@anthropic.com>
2025-03-26 01:56:39 -05:00
Spike Curtis 117e4c2fe7 feat: adds device_id, device_os, and coder_desktop_version to telemetry (#17086)
Records the Device ID, Device OS and Coder Desktop version to telemetry.

These values are provided by the Coder Desktop client in the StartRequest method of the VPN protocol. We render them as an HTTP header to transmit to Coderd, where they are decoded and added to telemetry.
2025-03-25 15:26:05 +04:00
Dean Sheather b23e05b1fe fix(vpn): fail early if wintun.dll is not present (#16707)
Prevents the VPN startup from hanging for 5 minutes due to a startup
backoff if `wintun.dll` cannot be loaded.

Because the `wintun` package doesn't expose an easy `Load() error`
method for us, the only way for us to force it to load (without unwanted
side effects) is through `wintun.Version()` which doesn't return an
error message.

So, we call that function so the `wintun` package loads the DLL and
configures the logging properly, then we try to load the DLL ourselves.
`LoadLibraryEx` will not load the library multiple times and returns a
reference to the existing library.

Closes https://github.com/coder/coder-desktop-windows/issues/24
2025-02-28 15:20:00 +11:00
Ethan 2a248b171c fix(vpn/tunnel): cancel updater ticks on tunnel stop (#16598)
Closes https://github.com/coder/coder-desktop-macos/issues/51.
2025-02-19 13:13:55 +11:00
Ethan edd982e852 fix(vpn/tunnel): fix panic when starting tunnel with headers (#16565)
`http.Header` is a map so it needs to be initialized ..
2025-02-14 03:11:51 +00:00
Ethan 0e728a7a9b chore(vpn/tunnel): sort outgoing fqdns by length (#16520)
On the Mac app, we want to display the shortest FQDN - we might as well
do the sorting as they leave the tunnel.
Right now it's coming from a map, so it's they arrive in a random order
each peer update.
2025-02-11 22:36:13 +11:00
Dean Sheather 584503180b chore: initialize COM in vpn-daemon on Windows (#16476) 2025-02-07 13:01:56 +10:00
Ethan 49a2412206 fix(vpn): configure dns hosts with username (#16352)
Previously we were configuring using the display name of the user, which
may contain spaces, special characters, and isn't unique. This was
always supposed to be the username.
2025-01-31 03:08:57 +00:00
Mathias Fredriksson 9520da338e fix: conform to stricter printf usage in Go 1.24 (#16330) 2025-01-29 18:06:22 +02:00
Dean Sheather 28088165a1 chore: get TUN/DNS working on Windows for CoderVPN (#16310) 2025-01-29 08:09:36 +00:00
Ethan a658ccf362 fix(vpn): send subnet masks and prefix lengths from router (#16317)
These were somehow missed when I wrote the router..

Also updates `coder/tailscale` to bring in the DNS changes
https://github.com/coder/tailscale/pull/64
2025-01-29 15:11:08 +11:00
Thomas Kosiewski 1336925c9f feat(flake.nix): switch dogfood dev image to buildNixShellImage from dockerTools (#16223)
Replace Depot build action with Nix for Nix dogfood image builds

The dogfood Nix image is now built using Nix's native container tooling instead of Depot. This change:

- Adds Nix setup steps to the GitHub Actions workflow
- Removes the Dockerfile.nix in favor of a Nix-native container build
- Updates the flake.nix to support building Docker images
- Introduces a hash file to track Nix-related changes
- Updates the vendorHash for Go dependencies

Change-Id: I4e011fe3a19d9a1375fbfd5223c910e59d66a5d9
Signed-off-by: Thomas Kosiewski <tk@coder.com>
2025-01-28 16:38:37 +01:00
Ethan ab92306d01 fix(vpn): handle sending nil router config (#16267)
Previously, a `nil` Router config would cause a panic in the dylib.
Normally, a nil Router config would indicate a shutdown of the service,
and that settings should be reset. However, for Coder Desktop macOS the
network configuration will be reset by the disconnecting of the system
VPN, so we'll instead do nothing.
2025-01-28 20:47:21 +11:00
Ethan 4872d14e55 fix(vpn): pass dup'd FDs to tunnel (#16249)
We were duping the passed FDs and then not using the result.
2025-01-24 02:29:20 +00:00
Cian Johnston 7b88776403 chore(testutil): add testutil.GoleakOptions (#16070)
- Adds `testutil.GoleakOptions` and consolidates existing options to
this location
- Pre-emptively adds required ignore for this Dependabot PR to pass CI
https://github.com/coder/coder/pull/16066
2025-01-08 15:38:37 +00:00
Spike Curtis 2c7f8ac65f chore: migrate to coder/websocket 1.8.12 (#15898)
Migrates us to `coder/websocket` v1.8.12 rather than `nhooyr/websocket` on an older version.

Works around https://github.com/coder/websocket/issues/504 by adding an explicit test for `xerrors.Is(err, io.EOF)` where we were previously getting `io.EOF` from the netConn.
2024-12-19 00:51:30 +04:00
Ethan 01f2ac0a09 chore: embed Info.plist in dylib (#15907)
Relates to https://github.com/coder/coder-desktop-macos/issues/2
2024-12-18 11:08:33 +00:00
Ethan 67fdbe5f49 fix(vpn): use unbuffered channel in speaker (#15863)
Closes https://github.com/coder/internal/issues/253.
2024-12-16 19:48:00 +11:00
Ethan a0a5683430 chore(vpn): upsert agents with their network status (#15659)
Closes #14734.
- Each outgoing agent upsertion also includes the timestamp of the last wireguard handshake.
- Agent upsertions will be created, for existing agents, with an updated last handshake time on a regular, fixed, interval of 10 seconds.
2024-12-05 14:22:39 +11:00
Ethan ba48069325 chore: implement CoderVPN client & tunnel (#15612)
Addresses #14734.

This PR wires up `tunnel.go` to a `tailnet.Conn` via the new `/tailnet` endpoint, with all the necessary controllers such that a VPN connection can be started, stopped and inspected via the CoderVPN protocol.
2024-12-05 13:30:22 +11:00
Dean Sheather 14a60303ac chore: rework RPC version negotiation (#15687)
Changes the RPC header format from `codervpn <version> <role>` to
`codervpn <role> <version1,version2,...>`.

The versions list is a list of the maximum supported minor version for
each major version, sorted by major versions.

E.g. `1.0,2.3,3.1` means `1.0, 2.0, 2.1, 2.2, 2.3, 3.0, 3.1` are
supported.

When we eventually support multiple versions, the peer's version list
will be compared against the current supported versions list to
determine the maximum major and minor version supported by both peers.

Closes #15601
2024-12-04 09:38:24 +00:00
Dean Sheather 06c99793f4 chore: add csharp_namespace to vpn.proto (#15634) 2024-11-26 19:58:18 +10:00
Ethan 32fc844b47 chore: support building Coder Desktop .dylib (#15512)
Relates to #14734.
2024-11-20 14:13:03 +11:00
Dean Sheather d63bd213f7 chore: add vpn-daemon run subcommand for windows (#15526)
`coder vpn-daemon run` will instantiate a RPC connection with the
specified pipe handles and communicate with the (yet to be implemented)
parent process.

The tests don't ensure that the tunnel is actually usable yet as the
tunnel functionality isn't implemented, but it does make sure that the
tunnel tries to read from the RPC pipe.

Closes #14735
2024-11-18 21:10:01 +10:00
Spike Curtis 5861e516b9 chore: add standard test logger ignoring db canceled (#15556)
Refactors our use of `slogtest` to instantiate a "standard logger" across most of our tests.  This standard logger incorporates https://github.com/coder/slog/pull/217 to also ignore database query canceled errors by default, which are a source of low-severity flakes.

Any test that has set non-default `slogtest.Options` is left alone. In particular, `coderdtest` defaults to ignoring all errors. We might consider revisiting that decision now that we have better tools to target the really common flaky Error logs on shutdown.
2024-11-18 14:09:22 +04:00
Spike Curtis 40802958e9 fix: use explicit api versions for agent and tailnet (#15508)
Bumps the Tailnet and Agent API version 2.3, and creates some extra controls and machinery around these versions.

What happened is that we accidentally shipped two new API features without bumping the version.  `ScriptCompleted` on the Agent API in Coder v2.16 and `RefreshResumeToken` on the Tailnet API in Coder v2.15.

Since we can't easily retroactively bump the versions, we'll roll these changes into API version 2.3 along with the new WorkspaceUpdates RPC, which hasn't been released yet.  That means there is some ambiguity in Coder v2.15-v2.17 about exactly what methods are supported on the Tailnet and Agent APIs.  This isn't great, but hasn't caused us major issues because 

1. RefreshResumeToken is considered optional, and clients just log and move on if the RPC isn't supported. 
2. Agents basically never get started talking to a Coderd that is older than they are, since the agent binary is normally downloaded from Coderd at workspace start.

Still it's good to get things squared away in terms of versions for SDK users and possible edge cases around client and server versions.

To mitigate against this thing happening again, this PR also:

1. adds a CODEOWNERS for the API proto packages, so I'll review changes
2. defines interface types for different API versions, and has the agent explicitly use a specific version.  That way, if you add a new method, and try to use it in the agent without thinking explicitly about versions, it won't compile.

With the protocol controllers stuff, we've sort of already abstracted the Tailnet API such that the interface type strategy won't work, but I'll work on getting the Controller to be version aware, such that it can check the API version it's getting against the controllers it has -- in a later PR.
2024-11-15 11:16:28 +04:00
Ethan 098728138f chore: add a tailscale router that uses the CoderVPN protocol (#15391)
Closes #14732.
2024-11-07 22:45:17 +11:00
Ethan 871cc05e99 chore: add a dns.OSConfigurator implementation that uses the CoderVPN protocol (#15342)
Closes #14733.
2024-11-05 19:23:16 +11:00
Spike Curtis 3565227d02 chore: disable erroneous linting of function names in vpn (#15055)
Disables bogus linting e.g. https://github.com/coder/coder/actions/runs/11305350065/job/31444754200?pr=15011
2024-10-15 11:45:56 +04:00