-
Notifications
You must be signed in to change notification settings - Fork 2
appliance
Pre-Alpha. This page describes behavior that may change.
Ze ships a bootable VM appliance image: a minimal Linux system built with gokrazy that runs Ze as its only application. No package manager, no shell (except an emergency serial console), atomic A/B updates, automatic process supervision. The result is a 2 GB disk image suitable for N100-class mini PCs, Proxmox VMs, or QEMU testing. The default target is x86_64; set GOKRAZY_ARCH=arm64 for a native Apple Silicon QEMU image.
If you just want to run Ze on an existing Linux host, use the binary or container builds from the install page instead. The appliance is for when you want a locked-down, single-purpose networking box.
| Component | Purpose |
|---|---|
| Linux kernel (x86_64) | Boot and hardware drivers. |
| Gokrazy init | Process supervisor, DHCP client, NTP, web status UI. |
| Ze | BGP daemon with all internal plugins compiled in. |
| serial-busybox | Emergency shell on the serial console (not started by default). |
The root filesystem is a read-only SquashFS. Persistent data lives on a separate ext4 partition mounted at /perm.
Install once on the build machine. macOS:
brew install e2fsprogs # ext4 filesystem tools
brew install qemu # VM runtime (testing only)The gokrazy build tooling is vendored in the repo at gokrazy/tools/vendor/ and invoked directly via go run (it replaced the earlier bin/gok shell-out). A vendored gokrazy updater handles OTA pushes. No separate install is needed.
After cloning the repo, download gokrazy system packages (Linux kernel, init, serial console) into the Go module cache. This is a one-time ~42 MB download. The exact versions are pinned in gokrazy/ze/builddir/*/go.mod (tracked in git, verified by go.sum):
make ze-gokrazy-depsAfter this, subsequent builds work offline.
The first build creates SSH credentials and a TLS certificate for the web UI:
make ze-gokrazy USER=admin PASS=secretSubsequent rebuilds reuse the existing database (same credentials, same TLS cert):
make ze-gokrazyTo use a database from a running instance or from another machine:
make ze-gokrazy ZEFS=/path/to/database.zefsThe first build does six things:
- Builds
bin/zefor the host. - Runs
ze initwith the supplied credentials and generates a self-signed TLS certificate (the--web-certflag wires this up). - Cross-compiles Ze for
linux/amd64. - Builds a 2 GB disk image.
- Formats the persistent
/permpartition. - Injects
database.zefs(credentials plus TLS cert) into/perm/ze/.
The database is kept at tmp/gokrazy/init/database.zefs between builds, so browsers that trust the certificate on first use will not prompt again after image rebuilds. The final image lands at tmp/gokrazy/ze.img.
make ze-gokrazy-runThis boots the image with the ports you care about forwarded to localhost:
| Host port | Guest service | How to use it |
|---|---|---|
| 18080 | Gokrazy web UI (port 80) | http://localhost:18080/ |
| 28080 | Ze web UI (port 8080) | http://localhost:28080/ |
| 2222 | Ze SSH CLI (port 22) | ssh -p 2222 admin@localhost |
Quit QEMU with Ctrl-A X.
The gokrazy web UI (:18080) shows process status, stdout/stderr ring buffers, and resource usage. Default credentials for it live in gokrazy/ze/config.json under Update.HTTPPassword.
Write the image to a USB drive or internal disk on your target machine:
# Linux
sudo dd if=tmp/gokrazy/ze.img of=/dev/sdX bs=4M status=progress
# macOS
sudo dd if=tmp/gokrazy/ze.img of=/dev/rdiskN bs=4mOr import into Proxmox:
qm importdisk <vmid> tmp/gokrazy/ze.img <storage>The machine boots to a serial console (115200 baud). Ze starts automatically, gets a DHCP address, and begins listening for BGP connections according to the baked-in /etc/ze/ze.conf.
The initial Ze config is embedded in the read-only root filesystem at /etc/ze/ze.conf. It is baked in at build time from the ExtraFileContents field of gokrazy/ze/config.json. The shipped seed enables the web UI on :8080 and SSH on :22, with logging at info level:
environment {
log {
level info
}
web {
enabled true
server default {
ip 0.0.0.0
port 8080
}
}
ssh {
enabled true
server default {
ip 0.0.0.0
port 22
}
}
}
To change the seed config, edit ExtraFileContents in gokrazy/ze/config.json and rebuild.
Once booted, use ze config edit over SSH to modify the running configuration. Changes are stored in /perm/ze/database.zefs and persist across reboots and image updates.
Ze's environment is set in gokrazy/ze/config.json under PackageConfig:
| Variable | Value | Purpose |
|---|---|---|
ze.config.dir |
/perm/ze |
Persistent storage for database.zefs. |
ze.bgp.api.socketpath |
/tmp/ze.socket |
Unix socket for the local API. |
ze.bgp.daemon.drop |
false |
No privilege dropping (no zeuser on gokrazy). |
ze.log |
info |
Log level. |
ze.log.backend |
stderr |
Logs land in the gokrazy ring buffer. |
Gokrazy supports atomic A/B partition updates over the network. Push the most recent image to the running instance:
ze install appliance push <name>This pushes the new root filesystem without touching /perm. The machine reboots into the new version. If the update fails mid-flight, the previous root partition is still intact, so you cannot brick the box with a bad update.
For full image rebuilds (when you also want to update the kernel or partition layout), run ze install appliance build <name> again and re-flash.
Gokrazy has no shell and no PATH. Ze's external plugin mechanism uses /bin/sh -c to fork processes, so it does not work here. Instead, every Ze plugin (bgp-rib, bgp-gr, bgp-adj-rib-in, …) is compiled into the ze binary as an internal plugin and runs as a goroutine. This is the default build and covers all standard BGP functionality. If you need an external plugin, the gokrazy appliance is the wrong target.
Gokrazy's init restarts Ze if it exits with a non-zero status, except exit code 125 which means "don't restart". Ze handles SIGTERM for graceful shutdown. Logs (stdout/stderr) are captured in ring buffers visible through the gokrazy web UI.
The /perm partition (ext4) survives image updates. Ze stores its database (database.zefs), TLS certificates, and config state there. The pointer is ze.config.dir=/perm/ze.
gokrazy/
.gitignore # excludes *.img
tools/
tools.go # blank import pinning the gok version
go.mod, go.sum # gok dependency pins
vendor/ # vendored gok source (~16 MB, committed)
ze/
config.json # gokrazy instance config (what to build, how to start)
builddir/
codeberg.org/thomas-mangin/ze/
go.mod # ze dependency pins + relative replace directive
go.sum
github.com/rtr7/kernel/
go.mod, go.sum # Linux kernel version pin
github.com/gokrazy/gokrazy/
go.mod, go.sum # gokrazy init version pin
cmd/dhcp/ # DHCP client
cmd/ntp/ # NTP client
cmd/heartbeat/ # watchdog heartbeat
cmd/randomd/ # entropy seeder
github.com/gokrazy/serial-busybox/
go.mod, go.sum # emergency serial shell
The tools/vendor/ directory holds the gok tool source, committed to git. The builddir/ files are small text (go.mod + go.sum, ~27 KB). System packages (kernel, init) live in the Go module cache after make ze-gokrazy-deps.
The ze install appliance command provides a structured workflow for managing appliance fleets from a bastion host. (ze appliance is a deprecated alias that prints a warning.)
| Command | Purpose |
|---|---|
ze install appliance init <name> |
Interactive wizard: set target IP, SSH user, passphrase. Creates encrypted appliance directory at ~/.config/ze/appliances/<name>/. |
ze install appliance build <name> |
Build a full disk image for the named appliance. |
ze install appliance run <name> |
Boot the image in QEMU for local testing. |
ze install appliance push <name> |
OTA update to the running appliance (A/B partition swap). |
ze install appliance config-push <name> |
Push config to a running device. The device auto-reverts after 30s if BGP does not stabilize. |
ze install appliance config-push --all --parallel 4 |
Push config to all appliances in parallel. |
ze install appliance list |
List all configured appliances. |
ze install appliance show <name> |
Show appliance details. |
ze install appliance export <name> |
Export encrypted archive for disaster recovery. |
ze install appliance import <archive> |
Restore appliance from encrypted archive. |
Appliance secrets are encrypted at rest using Argon2id + XChaCha20-Poly1305 when a passphrase is set.
When config is pushed to a device (config-push), the device:
- Validates the new config against YANG schemas.
- Applies the config atomically.
- Waits 30 seconds for BGP sessions to stabilize.
- If BGP does not stabilize, automatically reverts to the previous config.
This prevents a bad config push from leaving a device unreachable.
ze appliance iso builds a bootable UEFI installer ISO around an existing appliance image. The ISO contains a compressed disk image and a minimal initrd that writes it to the target disk on boot.
ze appliance iso <name>
ze appliance iso <name> --arch arm64The ISO verifies the embedded image checksum before writing. After installation, the system powers off so removable media can be removed before the next boot.
The appliance kernel build supports named kernel profiles that customize the kernel configuration for specific hardware targets.
| Profile | Purpose |
|---|---|
| (default) | Generic server, headless operation. |
hardware-kms |
Intel iGPU KMS support for hardware with integrated graphics. |
Specify a profile with --kernel-profile:
ze appliance build <name> --kernel-profile hardware-kmsThe kernel profile is included in the ISO and doctor cache keys.
The appliance kernel has been updated from 6.6.58 to 7.0.11.
The ze.wait kernel command-line parameter adds a delay before the installer begins, useful for slow NIC carrier detection or debugging PXE boot sequences.
The appliance uses QEMU-based kernel builds (replacing the previous Docker-based approach). Features include multi-threaded TCG, ccache for incremental builds, and architecture-aware cross-compilation. The kernel source is extracted to a separate directory for cache efficiency.
- Install for non-appliance builds (binary, container, from source).
- Zero-Touch Provisioning for PXE-based bare-metal provisioning.
- Building for host builds and toolchain setup.
- CLI for editing the running config over SSH.
- Web UI for the browser interface reachable on port 8080 of the appliance.
Adapted from main/docs/guide/appliance.md.
Unreviewed draft. This wiki was authored in bulk and has not been reviewed. File corrections on the issue tracker.
- Overview
- YANG Model
- Editor Workflow
- Archive and Rollback
- System
- Interfaces
- VRRP
- BFD
- FIB
- OSPF
- IS-IS
- MPLS / LDP / RSVP-TE
- RSVP-TE
- SRv6
- Static Routes
- Policy Routing
- Firewall
- Traffic Control
- Class of Service
- L2TP/PPP
- PPPoE
- VPP Data Plane
- RPKI
- IPsec VPN
- TACACS+ AAA
- RADIUS AAA
- AS112 DNS
- Authorization
- Fleet
- BGP
- Starting and Stopping
- Show Commands
- Monitoring
- Flow Export
- DDoS Mitigation
- Anomaly Detection
- Health Checks
- Audit Trail
- Production Diagnostics
- Logging
- Operational Reports
- Healthcheck
- Self-Update
- Zero-Touch Provisioning
- MRT Analysis
- Upgrade and Restart
- Storage
- Policy
- Core
- Resilience
- Validation
- Capabilities
- Address Families
- Protocol
- Subsystems
- Infrastructure
- Route Server at an IXP
- Transit Edge with RPKI
- Public Looking Glass
- ExaBGP Migration Walkthrough
- FlowSpec Injection
- Chaos-Tested Peering
- AS Path Topology