The image gets a second, empty store slot. systemd-sysupdate (wrapped as router-update) installs a new version into the slot not in use: both store partitions, then the UKI with boot counting, verified against a signed SHA256SUMS. system.build.update holds a version's files. Counted boots must pass router-healthy (the router's units plus router.image.healthChecks, each checked on its own) to reach boot-complete.target; otherwise the box reboots, and once the tries are used up systemd-boot falls back to the previous version. checks.image now installs v2 into the empty slot, boots and blesses it, refuses a tampered update, and rolls a broken v3 back to v2. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
61 lines
1.7 KiB
Nix
61 lines
1.7 KiB
Nix
# A bootable appliance image for trying the verity/read-only layout on real
|
|
# hardware (`nix build .#image`, then write image.raw to a disk). Same network
|
|
# shape as examples/desktop: one NIC, LAN untagged, PPPoE on VLAN 1001.
|
|
#
|
|
# DEBUGGING ONLY: root has the console password `testtest`, readable in the
|
|
# Nix store and this repository. Remove it before any real use.
|
|
{ lib, ... }:
|
|
{
|
|
imports = [ ../../modules/image ];
|
|
|
|
networking.hostName = "router";
|
|
# Bump for every build that is meant to be installed as an update.
|
|
system.image.version = "1";
|
|
system.stateVersion = "26.11";
|
|
|
|
# Generic UEFI PC: storage, USB keyboard and NIC drivers in the initrd.
|
|
boot.initrd.availableKernelModules = [
|
|
"ahci"
|
|
"nvme"
|
|
"xhci_pci"
|
|
"usb_storage"
|
|
"sd_mod"
|
|
"virtio_blk"
|
|
"virtio_pci"
|
|
"virtio_scsi"
|
|
];
|
|
|
|
users.users.root.openssh.authorizedKeys.keys = [
|
|
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIHqyMLgAhEdnrRrd2CeYbphGDMPq/cBDjFJ4q4ItZusn nils@Nilss-Mac-mini.mch.stinnesbeck.com"
|
|
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIBFxbNNk87tvMxruuKvrryK7iAdf4xgS4xFqjKejNAI6 nils@nixtop"
|
|
];
|
|
users.users.root.password = "testtest";
|
|
warnings = [
|
|
"examples/image: root has the well-known debug console password `testtest`; remove it before production use."
|
|
];
|
|
|
|
router = {
|
|
enable = true;
|
|
wan = {
|
|
interface = "enp2s0";
|
|
ipv4 = {
|
|
type = "pppoe";
|
|
pppoe = {
|
|
vlan = 1001;
|
|
username = "CHANGE-ME@isp.example";
|
|
passwordFile = "/var/lib/router/pppoe-password";
|
|
};
|
|
};
|
|
};
|
|
lans.main = {
|
|
interface = "enp2s0";
|
|
internet = true;
|
|
ipv4.address = "192.168.10.1";
|
|
dhcp.pool = {
|
|
start = "192.168.10.100";
|
|
end = "192.168.10.199";
|
|
};
|
|
};
|
|
};
|
|
}
|