Skip to content

Commit cb67e51

Browse files
committed
feat: embed wireguard-go as a library and manage tunnels directly
Replace external wireguard-go/wg binaries and the Windows WireGuard MSI with wireguard-go embedded as a Go library. The helper now creates TUN devices, configures peers via wgctrl, and manages routes through native OS APIs (BSD routing sockets, netlink, winipcfg) instead of shelling out. Migrate key handling from custom crypto wrappers to wgtypes.Key with automatic legacy key migration. Add WireGuard public key validation at enrollment time, an iputil package for CIDR parsing, and cross- platform post-install smoke tests. Remove wireguard-go/wireguard-tools from all package dependencies (Homebrew, nix, deb).
1 parent 82e7b89 commit cb67e51

76 files changed

Lines changed: 2728 additions & 819 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/controlplane.yaml

Lines changed: 10 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ jobs:
3232
runs-on: ubuntu-latest
3333
steps:
3434
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # ratchet:actions/checkout@v6
35-
- uses: jdx/mise-action@1648a7812b9aeae629881980618f079932869151 # ratchet:jdx/mise-action@v3
35+
- uses: jdx/mise-action@1648a7812b9aeae629881980618f079932869151 # ratchet:jdx/mise-action@v4
3636
with:
3737
cache: false
3838
- run: mise run ${{ matrix.mise_task }}
@@ -44,7 +44,7 @@ jobs:
4444
runs-on: ubuntu-22.04
4545
steps:
4646
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # ratchet:actions/checkout@v6
47-
- uses: jdx/mise-action@1648a7812b9aeae629881980618f079932869151 # ratchet:jdx/mise-action@v3
47+
- uses: jdx/mise-action@1648a7812b9aeae629881980618f079932869151 # ratchet:jdx/mise-action@v4
4848

4949
- name: "Build controlplane"
5050
run: |
@@ -87,22 +87,18 @@ jobs:
8787

8888
- name: Set up Docker Buildx
8989
id: buildx
90-
uses: docker/setup-buildx-action@4d04d5d9486b7bd6fa91e7baf45bbb4f8b9deedd # ratchet:docker/setup-buildx-action@v4.0.0
90+
uses: docker/setup-buildx-action@4d04d5d9486b7bd6fa91e7baf45bbb4f8b9deedd # ratchet:docker/setup-buildx-action@v4
9191

9292
- name: Login to registry
93-
uses: docker/login-action@5e57cd118135c172c3672efd75eb46360885c0ef # ratchet:docker/login-action@v3
93+
uses: docker/login-action@b45d80f862d83dbcd57f89517bcf500b2ab88fb2 # ratchet:docker/login-action@v4
9494
with:
9595
registry: ${{ env.REGISTRY }}
9696
username: "oauth2accesstoken"
9797
password: "${{ steps.auth.outputs.access_token }}"
9898

99-
- name: Get Go version from go.mod
100-
id: go-version
101-
run: echo "version=$(awk '/^go /{print $2}' go.mod)" >> "$GITHUB_OUTPUT"
102-
10399
- name: Docker meta enroller
104100
id: metadata
105-
uses: docker/metadata-action@c299e40c65443455700f0fdfc63efafe5b349051 # ratchet:docker/metadata-action@v5
101+
uses: docker/metadata-action@030e881283bb7a6894de51c315a6bfe6a94e05cf # ratchet:docker/metadata-action@v6
106102
with:
107103
images: ${{ env.REGISTRY }}/naisdevice-enroller
108104
# Docker tags based on the following events/attributes
@@ -116,7 +112,7 @@ jobs:
116112
type=sha
117113
118114
- name: Build and push enroller
119-
uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83 # ratchet:docker/build-push-action@v6
115+
uses: docker/build-push-action@d08e5c354a6adb9ed34480a06d141179aa583294 # ratchet:docker/build-push-action@v7
120116
env:
121117
cache_ref: ${{ env.REGISTRY }}/naisdevice-enroller:main
122118
with:
@@ -125,8 +121,6 @@ jobs:
125121
push: true
126122
tags: ${{ steps.metadata.outputs.tags }}
127123
labels: ${{ steps.metadata.outputs.labels }}
128-
build-args: |
129-
GO_VERSION=${{ steps.go-version.outputs.version }}
130124
cache-from: type=registry,ref=${{ env.cache_ref }}
131125
cache-to: type=registry,ref=${{ env.cache_ref }},mode=max
132126

@@ -152,22 +146,18 @@ jobs:
152146

153147
- name: Set up Docker Buildx
154148
id: buildx
155-
uses: docker/setup-buildx-action@4d04d5d9486b7bd6fa91e7baf45bbb4f8b9deedd # ratchet:docker/setup-buildx-action@v4.0.0
149+
uses: docker/setup-buildx-action@4d04d5d9486b7bd6fa91e7baf45bbb4f8b9deedd # ratchet:docker/setup-buildx-action@v4
156150

157151
- name: Login to registry
158-
uses: docker/login-action@5e57cd118135c172c3672efd75eb46360885c0ef # ratchet:docker/login-action@v3
152+
uses: docker/login-action@b45d80f862d83dbcd57f89517bcf500b2ab88fb2 # ratchet:docker/login-action@v4
159153
with:
160154
registry: ${{ env.REGISTRY }}
161155
username: "oauth2accesstoken"
162156
password: "${{ steps.auth.outputs.access_token }}"
163157

164-
- name: Get Go version from go.mod
165-
id: go-version
166-
run: echo "version=$(awk '/^go /{print $2}' go.mod)" >> "$GITHUB_OUTPUT"
167-
168158
- name: Docker meta auth-server
169159
id: metadata
170-
uses: docker/metadata-action@c299e40c65443455700f0fdfc63efafe5b349051 # ratchet:docker/metadata-action@v5
160+
uses: docker/metadata-action@030e881283bb7a6894de51c315a6bfe6a94e05cf # ratchet:docker/metadata-action@v6
171161
with:
172162
images: ${{ env.REGISTRY }}/naisdevice-auth-server
173163
# Docker tags based on the following events/attributes
@@ -181,7 +171,7 @@ jobs:
181171
type=sha
182172
183173
- name: Build and push auth-server
184-
uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83 # ratchet:docker/build-push-action@v6
174+
uses: docker/build-push-action@d08e5c354a6adb9ed34480a06d141179aa583294 # ratchet:docker/build-push-action@v7
185175
env:
186176
cache_ref: ${{ env.REGISTRY }}/naisdevice-auth-server:main
187177
with:
@@ -190,7 +180,5 @@ jobs:
190180
push: true
191181
tags: ${{ steps.metadata.outputs.tags }}
192182
labels: ${{ steps.metadata.outputs.labels }}
193-
build-args: |
194-
GO_VERSION=${{ steps.go-version.outputs.version }}
195183
cache-from: type=registry,ref=${{ env.cache_ref }}
196184
cache-to: type=gha,ref=${{ env.cache_ref }},mode=max

.github/workflows/naisdevice.yaml

Lines changed: 81 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ name: Naisdevice
22

33
on:
44
pull_request:
5-
types: [opened, reopened, synchronize]
5+
types: [opened, reopened, synchronize, labeled]
66
push:
77
branches: [main]
88
paths:
@@ -30,8 +30,9 @@ on:
3030
- "pkg/pb/**"
3131

3232
env:
33+
PRE_RELEASE: ${{ github.event_name == 'pull_request' && contains(github.event.pull_request.labels.*.name, 'pre-release') && 'true' || 'false' }}
3334
# some mise tasks use this to determine how they package/sign stuff.
34-
RELEASE: ${{ (github.ref == 'refs/heads/main' && github.actor != 'dependabot[bot]') && 'true' || 'false' }}
35+
RELEASE: ${{ ((github.ref == 'refs/heads/main' && github.actor != 'dependabot[bot]') || (github.event_name == 'pull_request' && contains(github.event.pull_request.labels.*.name, 'pre-release'))) && 'true' || 'false' }}
3536

3637
concurrency:
3738
group: ${{ github.ref }}
@@ -50,14 +51,18 @@ jobs:
5051
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # ratchet:actions/checkout@v6
5152
with:
5253
fetch-depth: 0
53-
- uses: jdx/mise-action@1648a7812b9aeae629881980618f079932869151 # ratchet:jdx/mise-action@v3
54+
ref: ${{ github.event_name == 'pull_request' && github.event.pull_request.head.sha || github.sha }}
55+
- uses: jdx/mise-action@1648a7812b9aeae629881980618f079932869151 # ratchet:jdx/mise-action@v4
5456
- id: generate
5557
run: mise run ci:release-info
5658
env:
5759
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
60+
PRE_RELEASE: ${{ env.PRE_RELEASE }}
61+
PR_NUMBER: ${{ github.event.pull_request.number }}
5862
outputs:
5963
version: ${{ steps.generate.outputs.version }}
6064
changelog: ${{ steps.generate.outputs.changelog }}
65+
pre_release: ${{ env.PRE_RELEASE }}
6166

6267
checks:
6368
strategy:
@@ -76,7 +81,7 @@ jobs:
7681
contents: read
7782
steps:
7883
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # ratchet:actions/checkout@v6
79-
- uses: jdx/mise-action@1648a7812b9aeae629881980618f079932869151 # ratchet:jdx/mise-action@v3
84+
- uses: jdx/mise-action@1648a7812b9aeae629881980618f079932869151 # ratchet:jdx/mise-action@v4
8085
- run: mise run ${{ matrix.mise_task }}
8186

8287
builds:
@@ -109,7 +114,7 @@ jobs:
109114
OUTFILE: ./release_artifacts/naisdevice${{ matrix.gotags == 'tenant' && '-tenant' || '' }}_${{ matrix.platform.os }}_${{ matrix.arch }}.${{ matrix.platform.ext }}
110115
steps:
111116
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # ratchet:actions/checkout@v6
112-
- uses: jdx/mise-action@1648a7812b9aeae629881980618f079932869151 # ratchet:jdx/mise-action@v3
117+
- uses: jdx/mise-action@1648a7812b9aeae629881980618f079932869151 # ratchet:jdx/mise-action@v4
113118
- if: matrix.platform.os == 'windows'
114119
run: sudo apt-get update && sudo apt-get install --yes nsis osslsigncode
115120
- if: matrix.platform.os == 'macos'
@@ -129,34 +134,83 @@ jobs:
129134
run: |
130135
mkdir -p "$(dirname $OUTFILE)"
131136
mise run "package:${{ matrix.platform.os }}"
132-
- uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # ratchet:actions/upload-artifact@v5
137+
- uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # ratchet:actions/upload-artifact@v7
133138
with:
134139
name: installer-${{ matrix.platform.os }}-${{ matrix.arch }}-${{ matrix.gotags || 'nav' }}
135140
path: ${{ env.OUTFILE }}
136141

142+
smoke-tests:
143+
name: smoke test ${{ matrix.artifact }}
144+
needs: [builds]
145+
strategy:
146+
fail-fast: false
147+
matrix:
148+
include:
149+
- os: macos
150+
runner: macos-latest
151+
artifact: installer-macos-arm64-nav
152+
installer_glob: "*.pkg"
153+
- os: macos
154+
runner: macos-latest
155+
artifact: installer-macos-arm64-tenant
156+
installer_glob: "*.pkg"
157+
- os: linux
158+
runner: ubuntu-latest
159+
artifact: installer-linux-amd64-nav
160+
installer_glob: "*.deb"
161+
- os: linux
162+
runner: ubuntu-latest
163+
artifact: installer-linux-amd64-tenant
164+
installer_glob: "*.deb"
165+
- os: windows
166+
runner: windows-latest
167+
artifact: installer-windows-amd64-nav
168+
installer_glob: "*.exe"
169+
- os: windows
170+
runner: windows-latest
171+
artifact: installer-windows-amd64-tenant
172+
installer_glob: "*.exe"
173+
runs-on: ${{ matrix.runner }}
174+
steps:
175+
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # ratchet:actions/checkout@v6
176+
- uses: jdx/mise-action@1648a7812b9aeae629881980618f079932869151 # ratchet:jdx/mise-action@v4
177+
- uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # ratchet:actions/download-artifact@v8
178+
with:
179+
name: ${{ matrix.artifact }}
180+
path: ./downloaded-artifact/
181+
- name: run smoke test
182+
shell: bash
183+
run: mise run smoke-test:${{ matrix.os }} ./downloaded-artifact/${{ matrix.installer_glob }}
184+
137185
# Used by GitHub to determine if all checks/builds have passed
138186
branch-protection-checkpoint:
139-
needs: [checks, builds]
187+
needs: [checks, builds, smoke-tests]
140188
if: ${{ always() }}
141189
runs-on: ubuntu-latest
142190
steps:
143-
- if: ${{ needs.checks.result != 'success' || needs.builds.result != 'success' }}
191+
- if: ${{ needs.checks.result != 'success' || needs.builds.result != 'success' || needs.smoke-tests.result != 'success' }}
144192
run: exit 1
145-
- run: echo "All checks and builds passed."
193+
- run: echo "All checks, builds, and smoke tests passed."
146194

147195
release-github:
148-
if: github.ref == 'refs/heads/main' && github.actor != 'dependabot[bot]' && needs.release-info.outputs.changelog != '' && needs.release-info.outputs.version != ''
196+
if: >-
197+
needs.release-info.outputs.changelog != '' && needs.release-info.outputs.version != '' &&
198+
(
199+
(github.ref == 'refs/heads/main' && github.actor != 'dependabot[bot]') ||
200+
needs.release-info.outputs.pre_release == 'true'
201+
)
149202
needs: [release-info, branch-protection-checkpoint]
150203
runs-on: ubuntu-latest
151204
permissions:
152205
contents: write
206+
env:
207+
RELEASE_TARGET_COMMIT: ${{ github.event_name == 'pull_request' && github.event.pull_request.head.sha || github.sha }}
153208
steps:
154209
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # ratchet:actions/checkout@v6
155210
with:
156-
fetch-depth: 0
157-
- uses: jdx/mise-action@1648a7812b9aeae629881980618f079932869151 # ratchet:jdx/mise-action@v3
158-
- run: git tag ${{ needs.release-info.outputs.version }}
159-
- uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # ratchet:actions/download-artifact@v6
211+
ref: ${{ env.RELEASE_TARGET_COMMIT }}
212+
- uses: jdx/mise-action@1648a7812b9aeae629881980618f079932869151 # ratchet:jdx/mise-action@v4
213+
- uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # ratchet:actions/download-artifact@v8
160214
with:
161215
merge-multiple: true
162216
path: release_artifacts
@@ -165,15 +219,18 @@ jobs:
165219
id: release
166220
with:
167221
tag_name: ${{ needs.release-info.outputs.version }}
222+
target_commitish: ${{ env.RELEASE_TARGET_COMMIT }}
168223
body: ${{ needs.release-info.outputs.changelog }}
169-
prerelease: false
224+
prerelease: ${{ needs.release-info.outputs.pre_release == 'true' }}
170225
files: ./release_artifacts/*
171226
env:
172227
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
173-
- env:
228+
- if: needs.release-info.outputs.pre_release != 'true'
229+
env:
174230
VERSION: ${{ needs.release-info.outputs.version }}
175231
run: mise run ci:prepare-template-vars ./release_artifacts/checksums.txt -v > template.vars
176-
- uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # ratchet:actions/upload-artifact@v5
232+
- if: needs.release-info.outputs.pre_release != 'true'
233+
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # ratchet:actions/upload-artifact@v7
177234
with:
178235
name: template-vars
179236
path: ./template.vars
@@ -182,12 +239,13 @@ jobs:
182239
echo "A new release is available over at https://github.com/${{ github.repository }}/releases/tag/${{ needs.release-info.outputs.version }}." >> $GITHUB_STEP_SUMMARY
183240
184241
release-gar:
242+
if: needs.release-info.outputs.pre_release != 'true'
185243
strategy:
186244
fail-fast: false
187245
matrix:
188246
arch: [arm64, amd64]
189247
suffix: [nav, tenant]
190-
needs: [release-github]
248+
needs: [release-info, release-github]
191249
runs-on: ubuntu-latest
192250
permissions:
193251
contents: read
@@ -201,15 +259,16 @@ jobs:
201259
service_account: gh-naisdevice@nais-io.iam.gserviceaccount.com
202260
token_format: access_token
203261
- uses: google-github-actions/setup-gcloud@aa5489c8933f4cc7a4f7d45035b3b1440c9c10db # ratchet:google-github-actions/setup-gcloud@v3
204-
- uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # ratchet:actions/download-artifact@v6
262+
- uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # ratchet:actions/download-artifact@v8
205263
with:
206264
name: installer-linux-${{ matrix.arch }}-${{ matrix.suffix }}
207265
path: ./downloaded-artifact/
208266
- run: |
209267
gcloud artifacts apt upload nais-ppa --project nais-io --quiet --location europe-north1 --source ./downloaded-artifact/*
210268
211269
release-external-repos:
212-
needs: [release-github]
270+
if: needs.release-info.outputs.pre_release != 'true'
271+
needs: [release-info, release-github]
213272
strategy:
214273
fail-fast: false
215274
matrix:
@@ -234,8 +293,8 @@ jobs:
234293
private-key: ${{ secrets.NAIS_APP_PRIVATE_KEY }}
235294
app-id: ${{ secrets.NAIS_APP_ID }}
236295
repo: ${{ matrix.target.repo }}
237-
- uses: jdx/mise-action@1648a7812b9aeae629881980618f079932869151 # ratchet:jdx/mise-action@v3
238-
- uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # ratchet:actions/download-artifact@v6
296+
- uses: jdx/mise-action@1648a7812b9aeae629881980618f079932869151 # ratchet:jdx/mise-action@v4
297+
- uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # ratchet:actions/download-artifact@v8
239298
with:
240299
name: template-vars
241300
- name: update ${{ matrix.target.repo }}

.github/workflows/templates/naisdevice-tenant.rb

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,6 @@
55
desc "naisdevice is a mechanism enabling developers to connect to internal resources in a secure and friendly manner."
66
homepage "https://docs.nais.io/operate/naisdevice/how-to/install/"
77

8-
depends_on formula: [
9-
"wireguard-go",
10-
"wireguard-tools",
11-
]
12-
138
if Hardware::CPU.intel?
149
url "https://github.com/nais/device/releases/download/#{version}/$NAISDEVICE_TENANT_MACOS_AMD64_FILENAME", verified: "github.com/nais/device/"
1510
sha256 "$NAISDEVICE_TENANT_MACOS_AMD64_HASH_BASE16"

.github/workflows/templates/naisdevice.rb

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,6 @@
55
desc "naisdevice is a mechanism enabling developers to connect to internal resources in a secure and friendly manner."
66
homepage "https://docs.nais.io/operate/naisdevice/how-to/install/"
77

8-
depends_on formula: [
9-
"wireguard-go",
10-
"wireguard-tools",
11-
]
12-
138
if Hardware::CPU.intel?
149
url "https://github.com/nais/device/releases/download/#{version}/$NAISDEVICE_MACOS_AMD64_FILENAME", verified: "github.com/nais/device/"
1510
sha256 "$NAISDEVICE_MACOS_AMD64_HASH_BASE16"

.gitignore

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,6 @@ bin
55
.DS_Store
66
*.pkg
77
*.app
8-
wireguard-go-*
9-
wireguard-tools-*
108
cmd/device-agent/main_windows.syso
119
cmd/helper/main_windows.syso
1210
packaging/windows/obj

AGENTS.md

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
# Project instructions for AI coding agents
2+
3+
## Commands
4+
5+
### After all changes are made, run
6+
7+
- `mise run test`
8+
- `mise run check`
9+
- `go fix [changed_files]...`
10+
11+
## Tech stack
12+
13+
- go (look at go.mod for version)
14+
- gRPC
15+
- protobuf
16+
- wireguard
17+
- sqlite
18+
19+
## Code style
20+
21+
- Write obvious code instead of clever code.
22+
- Favor self-explanatory code over code comments.
23+
- If you really have to add a comment, make sure it's short and concise.
24+
- Wrap errors with context: `fmt.Errorf("short description: %w", err)`.
25+
- Use `testify/require` and `testify/assert` for tests. Prefer table-driven tests.
26+
- Platform-specific code goes in files with build-tag suffixes (`_darwin.go`, `_linux.go`, `_windows.go`).
27+
28+
## Git
29+
30+
- Use [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/) for all commit messages.
31+
- Never commit unless explicitly told to.
32+
- Never push unless explicitly told to.

assets/linux/nfpm.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ license: "MIT"
1313
depends:
1414
- "jq"
1515
- "sed"
16-
- "wireguard"
16+
- "wireguard | wireguard-tools"
1717
scripts:
1818
postinstall: "./assets/linux/postinstall"
1919
postremove: "./assets/linux/postrm"

0 commit comments

Comments
 (0)