Files
tailscale/gokrazy/README.md
T
Kristoffer DalbyandKristoffer Dalby a7f3e08335 gokrazy/build: use AWS SDK instead of shelling out to aws CLI
Replace the four aws CLI shell-outs (s3 cp, ec2 import-snapshot,
describe-import-snapshot-tasks, register-image) with aws-sdk-go-v2 S3
and EC2 clients. Credentials come from the SDK default chain, so
existing aws sso login / aws configure / AWS_PROFILE / env / aws-vault
sessions keep working.

Verify auth via sts:GetCallerIdentity before the slow image build so a
logged-out user fails in seconds, not minutes. Upload via the S3
manager (concurrent multipart) with a native progress reader, log
[n/4] step lines, and bail on terminal import-snapshot failure states
instead of polling forever.

Updates #1866

Signed-off-by: Kristoffer Dalby <kristoffer@tailscale.com>
2026-07-15 15:15:17 +02:00

112 lines
3.9 KiB
Markdown

# Tailscale Appliance Gokrazy Image
This is (as of 2024-06-02) a **WORK IN PROGRESS** (pre-alpha) experiment to
package Tailscale as a [Gokrazy](https://gokrazy.org/) appliance image
for use on both VMs (AWS, GCP, Azure, Proxmox, ...) and Rasperry Pis.
See https://github.com/tailscale/tailscale/issues/1866
## Overview
It makes a ~70MB image (about the same size as
`tailscale-setup-full-1.66.4.exe` and smaller than the combined
Tailscale Android APK) that combines the Linux kernel and Tailscale
and that's it. Nothing written in C. (except optional busybox for
debugging) So no operating system to maintain. Gokrazy has three
partitions: two read-only ones (one active at a time, the other for
updates for the next boot) and one optional stateful, writable
partition that survives upgrades (`/perm/`)
Initial bootstrap configuration of this appliance will be over either
serial or configuration files (auth keys, subnet routes, etc) baked into
the image (for Raspberry Pis) or in cloud-init/user-data (for AWS, etc).
As of 2024-06-02, AWS user-data config files work.
## Quick start
Install dependencies:
```
$ brew install qemu e2fsprogs
```
Build + launch:
```
$ make qemu
```
That puts serial on stdio. To exit the serial console and escape to
the qemu monitor, type `Ctrl-a c`. Then type `quit` in the monitor to
quit.
## Building
`make image` to build just the image (`tsapp.img`), without uploading it.
## UTM
You can also use UTM, but the qemu path above is easier.
For UTM, see the [UTM instructions](UTM.md).
## AWS
### Build an AMI
`go run build.go --bucket=your-S3-temp-bucket` to build an AMI.
Credentials come from the AWS SDK's default chain, so authenticate any way it
recognizes: `aws sso login`, `aws configure`, an `AWS_PROFILE`,
`AWS_ACCESS_KEY_ID`/`AWS_SECRET_ACCESS_KEY` env vars, or
`aws-vault exec <profile> -- go run build.go --bucket=...` (aws-vault injects
temporary credentials as env vars). If no credentials are found the build stops
with a message telling you how to log in.
### Creating an instance
When creating an instance, you need a Nitro machine type to get a
virtual serial console. Notably, that means the `t2.*` instance types
that AWS pushes as a free option are not new enough. Use `t3.*` at least.
As of 2024-06-02 this builder tool only supports x86_64 (arm64 should
be trivial and will come soon), so don't use a Graviton machine type.
To connect to the serial console, you can either use the web console, or
use the CLI like:
```
$ aws ec2-instance-connect send-serial-console-ssh-public-key --instance-id i-0b4a0eabc43629f13 --serial-port 0 --ssh-public-key file:///your/home/.ssh/id_ed25519.pub --region us-west-2
{
"RequestId": "a93b0ea3-9ff9-45d5-b8ed-b1e70ccc0410",
"Success": true
}
$ ssh i-0b4a0eabc43629f13.port0@serial-console.ec2-instance-connect.us-west-2.aws
```
### Configuring the appliance
The appliance's `tailscaled` runs with `-config=optional:vm:user-data`, so a
single AMI supports two ways of joining a tailnet:
- **Declarative (user-data):** put a Tailscale config (the `alpha0` HuJSON
format) in the instance's user-data and the node configures itself on first
boot. The minimal config is just an auth key:
```json
{
"Version": "alpha0",
"AuthKey": "tskey-auth-..."
}
```
A config present in user-data locks the CLI (`tailscale set`/`up` are
rejected) unless it sets `"Locked": false`. Add `"RemoteConfig": true` to
hand full remote management of the node to the tailnet admin (see
`Prefs.RemoteConfig`) — appropriate for admin-owned fleet devices.
- **Interactive (serial console):** launch the AMI with *no* user-data. The
`optional:` prefix means the missing config is not an error, so `tailscaled`
boots unconfigured and you can enroll it over the serial console (connect as
above, then run `tailscale up` and open the printed login URL).
To require config instead (fail to boot if none is present), build an image
whose `tailscaled` uses `-config=vm:user-data` without the `optional:` prefix.