Andrew McMahon's NixOS dotfiles
NixOS/home-manager config files. Requires Nix flakes.
Shamelessly inspired/ripped-off from misterio77 and archer-65
flake.nix: Entrypoint for hosts and home configurations. Also exposes devshells for boostrapping (nix developornix-shell).hosts: NixOS Configurationscommon: Configurations applied to all machines.optional: Opt-in configurations any machine can import.users: Per-user system-level accounts and groups.rocinante: AMD 9950X3D / RTX 5090 Workstation
home: Home-manager configuration. Applied standalone (seejust home-switch), not via the home-manager NixOS module.modules: Modules (with options).overlays: Patches and version overrides for some packages. Applied to both the NixOS and home-manager package sets. Also aliases every flake input topkgs.inputs.${flake}.pkgs: Custom packages. Also accessible vianix build.files: Committed static assets (e.g. wallpapers), referenced by path rather than fetched.
This repo includes a justfile with common maintenance tasks:
Run these from inside nix develop (which provides just).
just fmt: Run formatting viatreefmt.just lint: Find dead code viadeadnix. Skips the generatedhardware-configuration.nix.just check: Runjust lint, thennix flake check.just home-switch: Apply Home Manager config foramcmahon@rocinante.just rebuild-switch: Apply NixOS config forrocinante.just update: Update flake inputs, then format and check.just clean: Run Nix garbage collection for the current user.just clean-all: Asjust clean, then the same for the system profile.
Using rocinante as an example:
-
Add following to
/etc/nixos/configuration.nix:networking.hostName = "rocinante"; nix.settings.experimental-features = [ "nix-command" "flakes" ]; environment.systemPackages = with pkgs; [ vim wget git ]; services.openssh.enable = true;
-
Run
sudo nixos-rebuild switch -
Then:
mkdir -p Sources cd Sources git clone git@github.com:McDamon/dotfiles.git cd dotfiles nix develop
-
Clone the generated hardware configuration (we will modify this later):
cp /etc/nixos/hardware-configuration.nix ~/Sources/dotfiles/hosts/rocinante/ -
Add the following lines to
hardware-configuration.nix:# Bootloader. boot.loader.systemd-boot.enable = true; boot.loader.efi.canTouchEfiVariables = true;
-
Rebuild:
sudo nixos-rebuild switch --flake .#rocinante home-manager switch --flake .#amcmahon@rocinante
-
Set up Secure Boot, following nix-community/lanzaboote.
hardware-configuration.nixalready setsboot.lanzaboote.enableand forcesboot.loader.systemd-boot.enable = false, so the remaining work is key material and firmware state.Generate keys (if
/var/lib/sbctldoes not already containkeys/), then rebuild so lanzaboote signs the boot files:sudo sbctl create-keys sudo nixos-rebuild switch --flake .#rocinante sudo sbctl verifysbctl verifymust report the images on the EFI System Partition (/boot) as signed before going any further./var/lib/sbctl/files.jsonstays empty under lanzaboote — it signs its own UKIs rather than registering them withsbctl— soverifyis the only confirmation that the current generation will be accepted once the firmware starts enforcing. If it reports unsigned files, re-runnixos-rebuild switchto re-sign.Signing is a pure disk operation and does not care what state the firmware is in, so this step can be done before or after enrolling, and needs no reboot either side of it.
-
Enroll the keys, which requires the firmware in Setup Mode. Check:
sbctl status # expect: Setup Mode: EnabledIf it is disabled, the firmware is holding its factory keys and will reject a new PK. Reboot into BIOS, use Secure Boot → Key Management → Clear Secure Boot keys, leave Secure Boot itself off, and boot back into NixOS.
Then enroll. Use
--microsoft.rocinantehas a discrete NVIDIA GPU, and option ROMs are signed by Microsoft's 3rd-party UEFI CA — enrolling only our own keys risks the GPU failing to initialise, and some firmware also depends on MS-signed updates.sbctlrequires an explicitly alarming flag to skip them, which is the hint:sudo sbctl enroll-keys --microsoft
This writes to firmware variables and is not trivially reversible. Afterwards
sbctl statusreports Setup Mode disabled again — that is the success condition, not a failure. Installing a PK is exactly what moves the firmware from Setup Mode into User Mode. -
Reboot into BIOS and turn Secure Boot on. Enrolling keys does not enable enforcement — that is a separate firmware setting, and clearing the keys in step 8 typically switches it off as a side effect. On ASUS it lives under Boot → Secure Boot: set OS Type to
Windows UEFI mode(Other OSdisables enforcement no matter what is enrolled). Then confirm:bootctl status # expect: Secure Boot: enabled (user) sbctl statusIf the machine will not boot afterwards, turn Secure Boot back off in BIOS. The enrolled keys survive, so that returns you to the end of step 8 rather than to the beginning.
TPM-backed unlock does not apply to
rocinante. It has no encrypted volumes — root is plain ext4 and nothing setsboot.initrd.luks— so there is nothing forsystemd-cryptenrollto bind to. If a LUKS volume is ever added, enroll it against PCRs 0+7 after Secure Boot is on, since enabling Secure Boot changes PCR 7 and would invalidate an earlier enrollment:sudo systemd-cryptenroll --tpm2-device=auto --tpm2-pcrs=0+7 /dev/<luks-part>