Skip to content

Repository files navigation

dotfiles

Andrew McMahon's NixOS dotfiles built with nix

amcmahon NixOS configurations

NixOS/home-manager config files. Requires Nix flakes.

Shamelessly inspired/ripped-off from misterio77 and archer-65

Structure

  • flake.nix: Entrypoint for hosts and home configurations. Also exposes devshells for boostrapping (nix develop or nix-shell).
  • hosts: NixOS Configurations
    • common: 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 (see just 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 to pkgs.inputs.${flake}.
  • pkgs: Custom packages. Also accessible via nix build.
  • files: Committed static assets (e.g. wallpapers), referenced by path rather than fetched.

Just Commands

This repo includes a justfile with common maintenance tasks: Run these from inside nix develop (which provides just).

  • just fmt: Run formatting via treefmt.
  • just lint: Find dead code via deadnix. Skips the generated hardware-configuration.nix.
  • just check: Run just lint, then nix flake check.
  • just home-switch: Apply Home Manager config for amcmahon@rocinante.
  • just rebuild-switch: Apply NixOS config for rocinante.
  • just update: Update flake inputs, then format and check.
  • just clean: Run Nix garbage collection for the current user.
  • just clean-all: As just clean, then the same for the system profile.

How to bootstrap

Using rocinante as an example:

  1. 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;
  2. Run sudo nixos-rebuild switch

  3. Then:

    mkdir -p Sources
    cd Sources
    git clone git@github.com:McDamon/dotfiles.git
    cd dotfiles
    nix develop
  4. Clone the generated hardware configuration (we will modify this later):

    cp /etc/nixos/hardware-configuration.nix ~/Sources/dotfiles/hosts/rocinante/
  5. Add the following lines to hardware-configuration.nix:

    # Bootloader.
    boot.loader.systemd-boot.enable = true;
    boot.loader.efi.canTouchEfiVariables = true;
  6. Rebuild:

    sudo nixos-rebuild switch --flake .#rocinante
    home-manager switch --flake .#amcmahon@rocinante
  7. Set up Secure Boot, following nix-community/lanzaboote. hardware-configuration.nix already sets boot.lanzaboote.enable and forces boot.loader.systemd-boot.enable = false, so the remaining work is key material and firmware state.

    Generate keys (if /var/lib/sbctl does not already contain keys/), then rebuild so lanzaboote signs the boot files:

    sudo sbctl create-keys
    sudo nixos-rebuild switch --flake .#rocinante
    sudo sbctl verify

    sbctl verify must report the images on the EFI System Partition (/boot) as signed before going any further. /var/lib/sbctl/files.json stays empty under lanzaboote — it signs its own UKIs rather than registering them with sbctl — so verify is the only confirmation that the current generation will be accepted once the firmware starts enforcing. If it reports unsigned files, re-run nixos-rebuild switch to 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.

  8. Enroll the keys, which requires the firmware in Setup Mode. Check:

    sbctl status        # expect: Setup Mode: Enabled

    If 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. rocinante has 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. sbctl requires 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 status reports 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.

  9. 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 OS disables enforcement no matter what is enrolled). Then confirm:

    bootctl status        # expect: Secure Boot: enabled (user)
    sbctl status

    If 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 sets boot.initrd.luks — so there is nothing for systemd-cryptenroll to 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>

About

Andrew McMahon's NixOS dotfiles

Resources

Stars

Watchers

Forks

Releases

Packages

Used by

Contributors

Languages