feat: add recovery-safe physical host and VPN tools
Keep kbot, Plasma/SDDM, NetworkManager, systemd-boot and the installed storage while adding dev/Hyprland as a separate physical host target. Keep EC2 integration and its updater isolated. Include WireGuard/OpenVPN clients, NetworkManager OpenVPN integration and network diagnostics; add recovery checks and activation instructions.
This commit is contained in:
@@ -3,6 +3,10 @@
|
||||
/result-*
|
||||
/.direnv/
|
||||
|
||||
# NixOS-generated files when the checkout lives at /etc/nix.
|
||||
/nix.conf
|
||||
/registry.json
|
||||
|
||||
# Local secrets must never be imported into Nix or committed.
|
||||
/.env
|
||||
/.env.*
|
||||
|
||||
@@ -1,12 +1,17 @@
|
||||
# Development host
|
||||
# Development hosts
|
||||
|
||||
Flat, explicit NixOS modules, with locked inputs. Required machine setup belongs in these configs—not a list of manual installs or dotfile copies.
|
||||
|
||||
**Choose the host, not the login name:** `nixosConfigurations.nixos` is this physical UEFI/NVMe machine; `nixosConfigurations.dev` is EC2 only. Both add the `dev` account. Never activate the EC2 closure on the physical machine.
|
||||
|
||||
| File | Owns |
|
||||
| --- | --- |
|
||||
| `flake.nix`, `flake.lock` | Host entry point and exact Nixpkgs/Home Manager/dotfile revisions and content hashes |
|
||||
| `configuration.nix` | EC2 base, platform, Nix features, compatibility version, imports |
|
||||
| `users.nix` | `dev`, SSH/sudo, Home Manager integration, workspace/repo ownership |
|
||||
| `configuration.nix` | EC2-only boot/storage/integration, updater and repo ownership |
|
||||
| `common.nix` | Shared dev environment, platform, Nix features and compatibility version |
|
||||
| `physical.nix`, `hardware-configuration.nix` | This physical host's systemd-boot/NVMe/Btrfs setup; retains `kbot`, Plasma/SDDM and NetworkManager while adding `dev` |
|
||||
| `physical-test.nix` | Regression checks for physical-host recovery access, storage, boot and VPN tools |
|
||||
| `users.nix` | `dev`, SSH/sudo, Home Manager integration and dev workspace ownership |
|
||||
| `dev-authorized-keys` | Public SSH keys for `dev`—never private keys |
|
||||
| `tools.nix`, `colors.nix` | Zsh, Kitty, Pi, Starship, fzf, Yazi, btop, Git policy and common CLI tools; shared readable palette |
|
||||
| `desktop.nix`, `hyprland.lua`, `anyrun.css`, `wallpaper.svg` | Hyprland/UWSM, bar, launcher, original wallpaper, notifications, lock/idle, PipeWire and desktop styling |
|
||||
@@ -14,23 +19,23 @@ Flat, explicit NixOS modules, with locked inputs. Required machine setup belongs
|
||||
| `workstation.nix`, `nvidia.nix` | Separately selected physical-workstation/greeter and NVIDIA integration; not enabled on EC2 |
|
||||
| `updates.nix`, `update-system.sh` | Daily stable-input updates in an isolated Git worktree; validated commits, no forced reboot or GC |
|
||||
| `desktop-test.nix`, `desktop-test.py`, `audit-desktop.sh`, `update-test.py` | Disposable graphical audit and updater failure/concurrency tests |
|
||||
| `network.nix` | systemd-resolved and network/WireGuard diagnostics; leaves interface management with the host |
|
||||
| `network.nix` | WireGuard/OpenVPN clients and network diagnostics; optional resolved, host-owned interface management |
|
||||
| `neovim.nix`, `neovim-test.lua` | Editor, unchanged upstream dotfile deployment and opt-in native runtime audit |
|
||||
| [DESKTOP.md](DESKTOP.md) | Historical component research; executable configuration is in the files above |
|
||||
|
||||
## Account
|
||||
|
||||
- Daily user: `dev`, UID 1001, home `/home/dev`, workspace `~/projects`.
|
||||
- Passwordless sudo is scoped to `dev`; existing SSM-user administration and root SSH recovery remain intact.
|
||||
- Passwordless sudo is scoped to `dev`; EC2's SSM-user administration and root SSH recovery remain intact. The physical host retains `kbot`'s existing wheel/sudo access.
|
||||
- `dev` is authorized by the public key in this repo. No private key or password is embedded.
|
||||
- `/etc/nixos` is writable by `dev` through a native tmpfiles ownership rule, which does not follow store symlinks.
|
||||
- On EC2 only, `/etc/nixos` is writable by `dev` through a native tmpfiles ownership rule, which does not follow store symlinks. The physical target leaves the original `/etc/nixos` recovery configs and `/home/kbot` untouched; `/etc/nix` remains administrator-managed.
|
||||
- Nix daemon access stays untrusted for ordinary use. Sudo is a separate, explicit administrative capability.
|
||||
- The declared daily shell is Zsh, with completion, suggestions, highlighting, Starship, fzf (`Ctrl-R`, `Ctrl-T`, `Alt-C`), and zoxide (`z`, `zi`). Root/SSM shells are not changed.
|
||||
- Kitty uses an opaque dark background, 13pt JetBrains Mono and generous padding. `Ctrl-Shift-+` / `Ctrl-Shift--` zoom its font; `Ctrl-Shift-Backspace` resets it. `y` opens Yazi with shell-directory integration.
|
||||
- Desktop keys: `Super-Enter` Kitty, `Super-Space` launcher, `Super-E` Yazi, `Super-B` Firefox, `Super-P` KeePassXC, `Super-Escape` lock, `Super-Q` close, `Super-1…0` workspaces, `Print` screenshot/annotation. Launch the **Hyprland (uwsm-managed)** session.
|
||||
- KeePassXC preferences are seeded once and remain writable. Open/create your own vault and pair its browser extension; no vault, account or VPN credentials are embedded. The physical-workstation module requires a securely provisioned `hashedPasswordFile`; EC2 gets no greeter or autologin.
|
||||
- KeePassXC preferences are seeded once and remain writable. Open/create your own vault and pair its browser extension; no vault, account or VPN credentials are embedded. The optional ReGreet module (`workstation.nix`, not used by either host here) requires a securely provisioned `hashedPasswordFile`; the physical host keeps SDDM and a locally set `dev` password. EC2 gets no greeter or autologin.
|
||||
- Element uses libsecret for encrypted local storage through KeePassXC. Before using it, create/open your own vault and select a dedicated application-token group in **Database Settings → Secret Service Integration**. Keep that vault unlocked when requested. Do not select Element's weaker/no-encryption fallback. Vault setup and application authentication are intentionally user-controlled.
|
||||
- `wg` and `wg-quick` are installed without any tunnels, peers, keys or added firewall ports. `resolvectl` is backed by resolved; DHCP remains under the existing host network manager.
|
||||
- `wg`, `wg-quick`, OpenVPN, `iperf3`, `nmap`, `traceroute`, `whois`, `mtr`, DNS tools, `tcpdump`, `ethtool`, `nc` and `socat` are installed without any tunnels, peers, keys or added firewall ports. The physical host also has NetworkManager's OpenVPN plugin and keeps its existing DNS setup. EC2 uses resolved; DHCP remains under each host's network manager.
|
||||
|
||||
Enter from an administrator session with `sudo -iu dev`.
|
||||
|
||||
@@ -38,7 +43,68 @@ Git author identity and remote destination are deliberately unset. `user.useConf
|
||||
|
||||
## Build and apply
|
||||
|
||||
As `dev`, from `/etc/nixos`:
|
||||
### Physical machine: keep kbot and add dev
|
||||
|
||||
`physical.nix` preserves `kbot` (UID 1000, `/home/kbot`, existing password, wheel/NetworkManager groups), KDE Plasma, SDDM, printing, locale/time zone, and the installed filesystems/boot loader. Home Manager manages **only `dev`**, UID 1001 with its own `/home/dev`. No autologin, password copying, or replacement greeter is enabled. The EC2 automatic updater is deliberately **not imported**.
|
||||
|
||||
The hardware file is a tracked copy of this machine's `/etc/nixos/hardware-configuration.nix`; do not use it unchanged on another machine. The original `/etc/nixos` files remain available as recovery configuration.
|
||||
|
||||
**Recovery from the earlier EC2 switch attempt:** that failure selected system-profile generation 2 even though generation 1 is still running and remains systemd-boot's default. Before testing the physical configuration, if the profile still points at the failed EC2 closure, restore its selection without activating anything:
|
||||
|
||||
```sh
|
||||
readlink -f /nix/var/nix/profiles/system
|
||||
sudo nix-env --profile /nix/var/nix/profiles/system --switch-generation 1
|
||||
```
|
||||
|
||||
This recovery command is specific to the observed generations on this machine; it is not a routine rebuild step.
|
||||
|
||||
From an administrator shell:
|
||||
|
||||
```sh
|
||||
cd /etc/nix
|
||||
nix --extra-experimental-features 'nix-command flakes' flake check --no-build --no-update-lock-file
|
||||
nix --extra-experimental-features 'nix-command flakes' build \
|
||||
.#checks.x86_64-linux.physical-config \
|
||||
.#checks.x86_64-linux.updates .#checks.x86_64-linux.desktop-config \
|
||||
--no-update-lock-file --no-link
|
||||
nix --extra-experimental-features 'nix-command flakes' build \
|
||||
.#nixosConfigurations.nixos.config.system.build.toplevel \
|
||||
--no-update-lock-file --out-link result-nixos
|
||||
built=$(readlink -f result-nixos)
|
||||
sudo "$built/sw/bin/nixos-rebuild" dry-activate --no-reexec --store-path "$built"
|
||||
```
|
||||
|
||||
Use **`result-nixos`**, not an old `result` pointing at the EC2 closure. The dry run must not remove `kbot`, SDDM, NetworkManager or the `/boot`, `/home`, `/nix` mounts. Existing services can still need a restart; keeping an account does not guarantee its current graphical session stays running.
|
||||
|
||||
Save your work, then activate from a text console (`Ctrl-Alt-F3`, log in as `kbot`, or use root). Keep that console available during testing:
|
||||
|
||||
```sh
|
||||
cd /etc/nix
|
||||
built=$(readlink -f result-nixos) # Re-establish this shell variable on the new console.
|
||||
# Activates users/services, but does NOT change the boot default. This is not a dry run.
|
||||
sudo "$built/sw/bin/nixos-rebuild" test --no-reexec --store-path "$built"
|
||||
# Choose a new password locally; mutable users preserve it across later rebuilds.
|
||||
sudo passwd dev
|
||||
```
|
||||
|
||||
At SDDM, choose **dev → Hyprland (uwsm-managed)** to try the new desktop, or **kbot → Plasma** for the existing environment. Once satisfied, persist the exact tested closure:
|
||||
|
||||
```sh
|
||||
sudo "$built/sw/bin/nixos-rebuild" switch --no-reexec --store-path "$built"
|
||||
```
|
||||
|
||||
If testing fails, use the retained text console to restore the booted system without changing the boot default:
|
||||
|
||||
```sh
|
||||
previous=$(readlink -f /run/booted-system)
|
||||
sudo "$previous/sw/bin/nixos-rebuild" test --no-reexec --store-path "$previous"
|
||||
```
|
||||
|
||||
If a later boot fails, select the original generation in systemd-boot (hold Space during startup). Keep recovery generations; do not garbage-collect them during migration. A working `kbot` account cannot recover an unbootable kernel/filesystem by itself.
|
||||
|
||||
### EC2 only
|
||||
|
||||
As `dev`, from `/etc/nixos` on the EC2 host:
|
||||
|
||||
```sh
|
||||
nixfmt --check ./*.nix
|
||||
@@ -93,9 +159,9 @@ Make focused changes, format/evaluate them, and commit regularly. Build and acti
|
||||
|
||||
## Updates and safety
|
||||
|
||||
- `nixos-update.timer` checks daily with up to one hour of jitter. Only the stable Nixpkgs/Home Manager branches advance; Neovim's source stays fixed. The updater skips a dirty repository, builds in a detached worktree, records a tested commit and applies it without rebooting. It attempts rollback if activation fails and retains recovery generations. Inspect `journalctl -u nixos-update` or trigger it with `sudo systemctl start nixos-update`.
|
||||
- **EC2 only:** `nixos-update.timer` checks daily with up to one hour of jitter. Only the stable Nixpkgs/Home Manager branches advance; Neovim's source stays fixed. The updater skips a dirty repository, builds in a detached worktree, records a tested commit and applies it without rebooting. It attempts rollback if activation fails and retains recovery generations. Inspect `journalctl -u nixos-update` or trigger it with `sudo systemctl start nixos-update`.
|
||||
- For a manual input refresh: `nix flake update nixpkgs home-manager`, review `flake.lock`, then check/build. The exact resolved revisions and hashes remain committed.
|
||||
- Keep the EC2 module, sandboxing, signature verification and recovery access intact.
|
||||
- Keep the EC2 module on the EC2 target only. Preserve sandboxing, signature verification and each host's recovery access.
|
||||
- `system.stateVersion` and `home.stateVersion` are both `26.05`; these preserve compatibility, not package versions.
|
||||
- `test` activates changes too; it is not a dry run. Keep the original system generation.
|
||||
- Rollbacks do not restore mutable user/application data, lockfile updates, backups, or this Git working tree.
|
||||
|
||||
+29
@@ -0,0 +1,29 @@
|
||||
# Shared dev environment; boot, storage, recovery users and updates are host-specific.
|
||||
{ config, inputs, ... }:
|
||||
{
|
||||
imports = [
|
||||
./users.nix
|
||||
./tools.nix
|
||||
./network.nix
|
||||
./desktop.nix
|
||||
./apps.nix
|
||||
./neovim.nix
|
||||
];
|
||||
|
||||
nixpkgs.hostPlatform = "x86_64-linux";
|
||||
|
||||
nix = {
|
||||
channel.enable = false;
|
||||
# Keep non-login environments on the same pin when NIX_PATH is unset.
|
||||
settings.nix-path = config.nix.nixPath;
|
||||
settings.experimental-features = [
|
||||
"nix-command"
|
||||
"flakes"
|
||||
];
|
||||
};
|
||||
|
||||
system.configurationRevision = inputs.self.rev or inputs.self.dirtyRev or null;
|
||||
|
||||
# Initial data/default compatibility, not the desired package release.
|
||||
system.stateVersion = "26.05";
|
||||
}
|
||||
+5
-29
@@ -1,37 +1,13 @@
|
||||
{
|
||||
config,
|
||||
inputs,
|
||||
modulesPath,
|
||||
...
|
||||
}:
|
||||
|
||||
# EC2 only. Physical machines must use the separate nixos host target.
|
||||
{ modulesPath, ... }:
|
||||
{
|
||||
imports = [
|
||||
# Keep the image's EC2 boot, storage, metadata, SSH and SSM integration.
|
||||
"${modulesPath}/virtualisation/amazon-image.nix"
|
||||
./users.nix
|
||||
./tools.nix
|
||||
./network.nix
|
||||
./desktop.nix
|
||||
./apps.nix
|
||||
./common.nix
|
||||
./updates.nix
|
||||
./neovim.nix
|
||||
];
|
||||
|
||||
nixpkgs.hostPlatform = "x86_64-linux";
|
||||
|
||||
nix = {
|
||||
channel.enable = false;
|
||||
# Keep non-login environments on the same pin when NIX_PATH is unset.
|
||||
settings.nix-path = config.nix.nixPath;
|
||||
settings.experimental-features = [
|
||||
"nix-command"
|
||||
"flakes"
|
||||
];
|
||||
};
|
||||
|
||||
system.configurationRevision = inputs.self.rev or inputs.self.dirtyRev or null;
|
||||
|
||||
# Initial data/default compatibility, not the desired package release.
|
||||
system.stateVersion = "26.05";
|
||||
# Only the EC2 host keeps its dev-owned configuration checkout here.
|
||||
systemd.tmpfiles.rules = [ "Z /etc/nixos - dev users -" ];
|
||||
}
|
||||
|
||||
@@ -27,6 +27,15 @@
|
||||
];
|
||||
};
|
||||
|
||||
# Physical host: adds dev/Hyprland without removing kbot/Plasma.
|
||||
nixosConfigurations.nixos = nixpkgs.lib.nixosSystem {
|
||||
specialArgs = { inherit inputs; };
|
||||
modules = [
|
||||
./physical.nix
|
||||
home-manager.nixosModules.home-manager
|
||||
];
|
||||
};
|
||||
|
||||
formatter.x86_64-linux = nixpkgs.legacyPackages.x86_64-linux.nixfmt;
|
||||
|
||||
nixosModules = {
|
||||
@@ -43,6 +52,10 @@
|
||||
in
|
||||
{
|
||||
desktop = import ./desktop-test.nix { inherit inputs pkgs; };
|
||||
physical-config = import ./physical-test.nix {
|
||||
inherit pkgs;
|
||||
config = inputs.self.nixosConfigurations.nixos.config;
|
||||
};
|
||||
desktop-config =
|
||||
pkgs.runCommand "hyprland-config-check" { nativeBuildInputs = [ pkgs.hyprland ]; }
|
||||
''
|
||||
|
||||
@@ -0,0 +1,60 @@
|
||||
# Do not modify this file! It was generated by ‘nixos-generate-config’
|
||||
# and may be overwritten by future invocations. Please make changes
|
||||
# to /etc/nixos/configuration.nix instead.
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
modulesPath,
|
||||
...
|
||||
}:
|
||||
|
||||
{
|
||||
imports = [
|
||||
(modulesPath + "/installer/scan/not-detected.nix")
|
||||
];
|
||||
|
||||
boot.initrd.availableKernelModules = [
|
||||
"xhci_pci"
|
||||
"thunderbolt"
|
||||
"nvme"
|
||||
"usb_storage"
|
||||
"sd_mod"
|
||||
"sdhci_pci"
|
||||
];
|
||||
boot.initrd.kernelModules = [ ];
|
||||
boot.kernelModules = [ "kvm-intel" ];
|
||||
boot.extraModulePackages = [ ];
|
||||
|
||||
fileSystems."/" = {
|
||||
device = "/dev/disk/by-uuid/8a16015f-d6f8-4f74-8558-6261b9112216";
|
||||
fsType = "btrfs";
|
||||
};
|
||||
|
||||
fileSystems."/home" = {
|
||||
device = "/dev/disk/by-uuid/8a16015f-d6f8-4f74-8558-6261b9112216";
|
||||
fsType = "btrfs";
|
||||
options = [ "subvol=home" ];
|
||||
};
|
||||
|
||||
fileSystems."/nix" = {
|
||||
device = "/dev/disk/by-uuid/8a16015f-d6f8-4f74-8558-6261b9112216";
|
||||
fsType = "btrfs";
|
||||
options = [ "subvol=nix" ];
|
||||
};
|
||||
|
||||
fileSystems."/boot" = {
|
||||
device = "/dev/disk/by-uuid/DEC5-51CB";
|
||||
fsType = "vfat";
|
||||
options = [
|
||||
"fmask=0077"
|
||||
"dmask=0077"
|
||||
];
|
||||
};
|
||||
|
||||
swapDevices = [ ];
|
||||
|
||||
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
|
||||
hardware.cpu.intel.npu.enable = true;
|
||||
hardware.cpu.intel.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware;
|
||||
}
|
||||
+10
-4
@@ -1,10 +1,11 @@
|
||||
{ pkgs, ... }:
|
||||
{ lib, pkgs, ... }:
|
||||
|
||||
{
|
||||
# Keep each host's existing interface/DHCP owner. On EC2 this is dhcpcd;
|
||||
# NixOS wires its resolvconf hook to resolved's compatibility interface.
|
||||
services.resolved = {
|
||||
enable = true;
|
||||
# Physical hosts can retain their existing DNS setup during migration.
|
||||
enable = lib.mkDefault true;
|
||||
settings.Resolve = {
|
||||
LLMNR = false;
|
||||
MulticastDNS = false;
|
||||
@@ -14,12 +15,17 @@
|
||||
|
||||
programs.mtr.enable = true;
|
||||
environment.systemPackages = with pkgs; [
|
||||
wireguard-tools
|
||||
wireguard-tools # wg and wg-quick; no interfaces or credentials are configured.
|
||||
openvpn
|
||||
iperf3
|
||||
nmap
|
||||
traceroute
|
||||
whois
|
||||
dnsutils
|
||||
tcpdump
|
||||
ethtool
|
||||
netcat-openbsd
|
||||
socat
|
||||
];
|
||||
# wg/wg-quick are available, but no invented peers, keys, routes or ports.
|
||||
# Client tools only: no VPN services, peers, keys, routes or firewall ports.
|
||||
}
|
||||
|
||||
@@ -0,0 +1,141 @@
|
||||
# Host configuration and built-file checks: no activation, VM or VPN connections.
|
||||
{ config, pkgs }:
|
||||
let
|
||||
inherit (pkgs) lib;
|
||||
kbot = config.users.users.kbot;
|
||||
dev = config.users.users.dev;
|
||||
btrfsDevice = "/dev/disk/by-uuid/8a16015f-d6f8-4f74-8558-6261b9112216";
|
||||
mounts = {
|
||||
"/" = {
|
||||
device = btrfsDevice;
|
||||
fsType = "btrfs";
|
||||
};
|
||||
"/home" = {
|
||||
device = btrfsDevice;
|
||||
fsType = "btrfs";
|
||||
options = [ "subvol=home" ];
|
||||
};
|
||||
"/nix" = {
|
||||
device = btrfsDevice;
|
||||
fsType = "btrfs";
|
||||
options = [ "subvol=nix" ];
|
||||
};
|
||||
"/boot" = {
|
||||
device = "/dev/disk/by-uuid/DEC5-51CB";
|
||||
fsType = "vfat";
|
||||
options = [
|
||||
"fmask=0077"
|
||||
"dmask=0077"
|
||||
];
|
||||
};
|
||||
};
|
||||
tests = [
|
||||
{
|
||||
assertion = config.boot.loader.systemd-boot.enable && !config.boot.loader.grub.enable;
|
||||
message = "The physical host must use systemd-boot, never EC2's GRUB disk.";
|
||||
}
|
||||
{
|
||||
assertion = lib.all (
|
||||
mount:
|
||||
let
|
||||
actual = config.fileSystems.${mount};
|
||||
expected = mounts.${mount};
|
||||
in
|
||||
actual.device == expected.device
|
||||
&& actual.fsType == expected.fsType
|
||||
&& lib.all (option: builtins.elem option actual.options) (expected.options or [ ])
|
||||
) (builtins.attrNames mounts);
|
||||
message = "Preserve the installed root/home/nix/EFI filesystems and Btrfs subvolumes.";
|
||||
}
|
||||
{
|
||||
assertion =
|
||||
config.users.mutableUsers
|
||||
&& kbot.isNormalUser
|
||||
&& kbot.uid == 1000
|
||||
&& kbot.home == "/home/kbot"
|
||||
&& builtins.elem "wheel" kbot.extraGroups
|
||||
&& builtins.elem "networkmanager" kbot.extraGroups
|
||||
&& kbot.password == null
|
||||
&& kbot.hashedPassword == null
|
||||
&& kbot.hashedPasswordFile == null;
|
||||
message = "Keep kbot's identity, local password and administrative/network access.";
|
||||
}
|
||||
{
|
||||
assertion =
|
||||
dev.isNormalUser
|
||||
&& dev.uid == 1001
|
||||
&& dev.home == "/home/dev"
|
||||
&& builtins.elem "wheel" dev.extraGroups
|
||||
&& builtins.elem "networkmanager" dev.extraGroups
|
||||
&& builtins.attrNames config.home-manager.users == [ "dev" ];
|
||||
message = "Add dev independently; Home Manager must not manage kbot's home.";
|
||||
}
|
||||
{
|
||||
assertion =
|
||||
config.services.displayManager.sddm.enable
|
||||
&& config.services.desktopManager.plasma6.enable
|
||||
&& config.programs.hyprland.enable
|
||||
&& config.programs.hyprland.withUWSM
|
||||
&& !config.services.greetd.enable
|
||||
&& !config.services.displayManager.autoLogin.enable;
|
||||
message = "Keep the Plasma/SDDM recovery login alongside Hyprland, without autologin.";
|
||||
}
|
||||
{
|
||||
assertion =
|
||||
config.networking.networkmanager.enable
|
||||
&& !config.services.resolved.enable
|
||||
&& builtins.elem (lib.getName pkgs.networkmanager-openvpn) (
|
||||
map lib.getName config.networking.networkmanager.plugins
|
||||
);
|
||||
message = "Keep NetworkManager/DNS and provide its OpenVPN integration.";
|
||||
}
|
||||
{
|
||||
assertion =
|
||||
!(config.systemd.services ? nixos-update)
|
||||
&& !(config.systemd.timers ? nixos-update)
|
||||
&& !(config.systemd.services ? amazon-ssm-agent)
|
||||
&& !(builtins.elem "Z /etc/nixos - dev users -" config.systemd.tmpfiles.rules);
|
||||
message = "The physical host must not inherit EC2 services, updater or repo ownership.";
|
||||
}
|
||||
{
|
||||
assertion =
|
||||
lib.all
|
||||
(package: builtins.elem (lib.getName package) (map lib.getName config.environment.systemPackages))
|
||||
(
|
||||
with pkgs;
|
||||
[
|
||||
wireguard-tools
|
||||
openvpn
|
||||
iperf3
|
||||
nmap
|
||||
traceroute
|
||||
whois
|
||||
dnsutils
|
||||
tcpdump
|
||||
ethtool
|
||||
netcat-openbsd
|
||||
socat
|
||||
]
|
||||
)
|
||||
&& config.programs.mtr.enable;
|
||||
message = "The VPN clients and network diagnostics must remain installed.";
|
||||
}
|
||||
{
|
||||
assertion =
|
||||
config.networking.wireguard.interfaces == { }
|
||||
&& config.networking.wg-quick.interfaces == { }
|
||||
&& config.services.openvpn.servers == { };
|
||||
message = "Installing VPN tools must not invent tunnels, peers or credentials.";
|
||||
}
|
||||
];
|
||||
in
|
||||
assert lib.all (test: lib.assertMsg test.assertion test.message) tests;
|
||||
pkgs.runCommand "physical-config-check" { } ''
|
||||
sessions=${config.services.displayManager.sessionData.desktops}/share
|
||||
test -f "$sessions/wayland-sessions/plasma.desktop"
|
||||
test -f "$sessions/wayland-sessions/hyprland-uwsm.desktop"
|
||||
for tool in wg wg-quick openvpn iperf3 nmap traceroute whois mtr dig tcpdump ethtool nc socat nm-connection-editor; do
|
||||
test -x "${config.system.path}/bin/$tool"
|
||||
done
|
||||
touch "$out"
|
||||
''
|
||||
@@ -0,0 +1,74 @@
|
||||
# This machine: retain the installed kbot/Plasma recovery environment and add dev.
|
||||
# Hardware settings were copied from /etc/nixos; those original files stay untouched.
|
||||
{ pkgs, ... }:
|
||||
{
|
||||
imports = [
|
||||
./hardware-configuration.nix
|
||||
./common.nix
|
||||
];
|
||||
|
||||
boot.loader = {
|
||||
systemd-boot.enable = true;
|
||||
efi.canTouchEfiVariables = true;
|
||||
};
|
||||
|
||||
networking.hostName = "nixos";
|
||||
networking.networkmanager = {
|
||||
enable = true;
|
||||
plugins = [ pkgs.networkmanager-openvpn ];
|
||||
};
|
||||
# Keep the installed DNS setup while testing the additional desktop.
|
||||
services.resolved.enable = false;
|
||||
|
||||
time.timeZone = "America/Chicago";
|
||||
i18n.defaultLocale = "en_US.UTF-8";
|
||||
i18n.extraLocaleSettings = {
|
||||
LC_ADDRESS = "en_US.UTF-8";
|
||||
LC_IDENTIFICATION = "en_US.UTF-8";
|
||||
LC_MEASUREMENT = "en_US.UTF-8";
|
||||
LC_MONETARY = "en_US.UTF-8";
|
||||
LC_NAME = "en_US.UTF-8";
|
||||
LC_NUMERIC = "en_US.UTF-8";
|
||||
LC_PAPER = "en_US.UTF-8";
|
||||
LC_TELEPHONE = "en_US.UTF-8";
|
||||
LC_TIME = "en_US.UTF-8";
|
||||
};
|
||||
|
||||
# SDDM offers both Plasma and Hyprland (uwsm-managed). Do not replace it with
|
||||
# workstation.nix's greetd/ReGreet or enable autologin during this migration.
|
||||
services.xserver = {
|
||||
enable = true;
|
||||
xkb = {
|
||||
layout = "us";
|
||||
variant = "";
|
||||
};
|
||||
};
|
||||
services.displayManager.sddm.enable = true;
|
||||
services.desktopManager.plasma6.enable = true;
|
||||
services.printing.enable = true;
|
||||
services.pulseaudio.enable = false;
|
||||
|
||||
# Preserve kbot's existing password and allow `sudo passwd dev` after activation.
|
||||
# No password hashes or credentials are copied into this repository/the store.
|
||||
users.mutableUsers = true;
|
||||
users.users.kbot = {
|
||||
isNormalUser = true;
|
||||
uid = 1000;
|
||||
home = "/home/kbot";
|
||||
description = "kbot";
|
||||
extraGroups = [
|
||||
"networkmanager"
|
||||
"wheel"
|
||||
];
|
||||
packages = [ pkgs.kdePackages.kate ];
|
||||
};
|
||||
users.users.dev.extraGroups = [ "networkmanager" ];
|
||||
environment.systemPackages = [ pkgs.networkmanagerapplet ];
|
||||
home-manager.users.dev.services.udiskie.enable = true;
|
||||
|
||||
# Retain the installed host's package policy.
|
||||
nixpkgs.config.allowUnfree = true;
|
||||
|
||||
# Intentionally no updates.nix: that updater builds the EC2 dev target.
|
||||
# Neither /etc/nixos nor /home/kbot is handed over to dev/Home Manager.
|
||||
}
|
||||
Reference in New Issue
Block a user