A tunnel of its own (optional)

The stick comes up on WireGuard by itself, which is most of why installing a headless machine from your desk works at all. The machine you have just installed can do the same – and the moment to arrange it is now, before it reboots, because afterwards it is on its own.

Run this on the live system:
setup wireguard
Not the stick's key

Do not copy wg0.conf off the stick. That key is the stick’s identity to your server, and a second machine holding it would be a second peer claiming to be the same one – a confusing afternoon waiting to happen. The stick’s job is to install machines; this machine gets a key of its own.

Where the key comes from

The first question is how the key should come about, and the default is the careful answer.

  genkey -- make the key here, so your provider never sees it
  paste  -- you already have a wg0.conf, private key included
? Key: genkey

genkey makes the key pair on the live system and prints only the public half. You give that to your VPN provider, or add it as a [Peer] on your own server, and paste back the configuration it hands you. setup splices the private key into it – over a placeholder PrivateKey line if there is one, or under [Interface] if there is not. The secret never leaves the machine it belongs to.

paste is for when you already hold a complete wg0.conf, private key and all, because that is what you were given.

Either way the configuration is pasted at the terminal and ends with Ctrl-D, so there is no file to edit on a machine that is still being installed:

(stdout)
This machine's public key -- give this to your provider, or add it
as a peer on your own server. The private key stays here.

    IUpvRDOi8yIS4VER07dIOLXYJC9/9mo4OTJp2RMcqAM=

Now paste the configuration they give you back.
  (paste it, then press Ctrl-D on a line of its own)

What it writes

(stdout)
================ Review =================
Address:      10.9.0.7/32
Endpoint:     vpn.example.com:51820
AllowedIPs:   10.9.0.0/24
DNS:          10.9.0.1
Keepalive:    25
PrivateKey:   (not shown, and never written to the repo)
Writes:       /mnt/etc/wireguard/wg0.conf, 0600 root:root
=========================================

The key goes to the target’s /etc/wireguard/wg0.conf, owned by root and readable by nobody else, and aconfmgr/90-ignore.sh gains IgnorePath '/etc/wireguard/*' beside the rule that already ignores the SSH host keys. So admin diff does not report it as drift, and it is never committed.

What is configuration goes in the host repo, where the rest of the machine’s description lives: wireguard-tools in packages.txt and wg-quick@wg0 in units.txt. Either order works: if this step runs before Install the system the install picks both up, and if it runs after – where the step order puts it – it installs the package and enables the unit itself.

A DNS line needs one more package

If the configuration has a DNS = line, wg-quick hands it to resolvconf, which the installed system does not have: base does not bring it and the live system’s copy comes from the ISO. setup adds systemd-resolvconf to packages.txt when it sees one, which is the difference between a tunnel that comes up and a unit that fails on first boot.

Nothing is echoed back

The review names the address, the endpoint, the AllowedIPs, the DNS and the keepalive, and of the key says only that it is not shown. That is deliberate: everything setup prints is written to logs/000_SETUP.txt in the host repo and committed, so printing the configuration would commit a private key. What you paste is echoed by your terminal, not by setup, so it stays out of the log too.

The tunnel comes up on the next boot. Check it there with wg show.

// settings
theme:
fx: