# NixOS Configuration Repository This repository contains my personal NixOS configurations for multiple systems, managed using [Snowfall Lib](https://github.com/snowfallorg/lib) and the Nix Flakes system. ## Overview This repository provides a centralized, declarative configuration for all my systems, including: - Desktop PC (AMD) - NAS server - Steam Deck - Intel NUC - Raspberry Pi 4 - Raspberry Pi 5 - MacBook Pro (NixOS on Apple Silicon) - MacBook Pro (Darwin/macOS) ## Repository Structure ``` . ├── checks/ # Pre-commit hooks and other checks ├── flake.nix # Main flake configuration ├── homes/ # Home-manager configurations for users │ ├── aarch64-darwin/ # macOS home configurations │ ├── aarch64-linux/ # ARM Linux home configurations │ └── x86_64-linux/ # x86 Linux home configurations ├── modules/ # Reusable configuration modules │ ├── home/ # Home-manager modules │ └── nixos/ # NixOS system modules ├── overlays/ # Nixpkgs overlays ├── packages/ # Custom package definitions ├── secrets/ # Encrypted secrets (managed with sops-nix) └── systems/ # System-specific configurations ├── aarch64-darwin/ # macOS system configurations ├── aarch64-linux/ # ARM Linux system configurations └── x86_64-linux/ # x86 Linux system configurations ``` ## Key Features - **Modular Design**: Reusable modules for various system components - **Multi-System Support**: Configurations for different hardware platforms - **Home Manager Integration**: User environment management - **Secret Management**: Encrypted secrets with sops-nix - **Disk Management**: Declarative disk partitioning with disko - **State Management**: Persistent state management with impermanence - **Desktop Environments**: Support for GNOME, Hyprland, and COSMIC - **Hardware-Specific Optimizations**: Tailored configurations for different hardware ## Key Technologies - [Nix](https://nixos.org/) and [NixOS](https://nixos.org/) - [Nix Flakes](https://nixos.wiki/wiki/Flakes) - [Snowfall Lib](https://github.com/snowfallorg/lib) - [Home Manager](https://github.com/nix-community/home-manager) - [sops-nix](https://github.com/Mic92/sops-nix) - [disko](https://github.com/nix-community/disko) - [impermanence](https://github.com/nix-community/impermanence) - [lanzaboote](https://github.com/nix-community/lanzaboote) (Secure Boot) ## Notable System Configurations ### Desktop A powerful AMD-based desktop with gaming capabilities, featuring: - AMD CPU and GPU optimizations - Multiple desktop environment options (GNOME, Hyprland, COSMIC) - Gaming setup with Steam and related tools ### NAS A home server with various self-hosted services: - Media management (Jellyfin, seerr) - Download automation (Sonarr, Radarr, etc.) - Document management (Paperless) - File sharing (Samba, Nextcloud) - AI services (Ollama) ### Raspberry Pi Configurations for both Pi 4 and Pi 5: - Hardware-specific optimizations - Disk partitioning suitable for ARM devices - Bluetooth and wireless support ### Steam Deck Custom NixOS configuration for the Steam Deck: - Integration with Jovian for Steam Deck compatibility - Gaming optimizations - Steam ROM Manager ### MacBook Pro Configurations for both: - NixOS on Apple Silicon - nix-darwin for macOS ## Usage ### Building a System Configuration ```bash # Build and activate a system configuration sudo nixos-rebuild switch --flake .#hostname ``` ### Building a Home Configuration ```bash # Build and activate a home configuration home-manager switch --flake .#username@hostname ``` ## Secrets Management Secrets are managed with [sops-nix](https://github.com/Mic92/sops-nix). Each secret file is encrypted with [age](https://age-encryption.org/), using the SSH host key (`/etc/ssh/ssh_host_ed25519_key`) of each machine as a recipient, so that machine can decrypt its own secrets at boot without any passphrase. ### How age keys work sops-nix derives an age key from the machine's ed25519 SSH host key automatically. The corresponding age **public key** must be added to `.sops.yaml` before you can encrypt secrets for that machine. To get the age public key for a machine: ```bash # On the target machine (or from its host key file): nix-shell -p ssh-to-age --run \ 'ssh-keyscan localhost 2>/dev/null | ssh-to-age' # Or directly from the key file: nix-shell -p ssh-to-age --run \ 'ssh-to-age < /etc/ssh/ssh_host_ed25519_key.pub' ``` ### Adding a new machine 1. **Get the age public key** for the new machine using the command above. 2. **Add it to `.sops.yaml`**: ```yaml keys: - &new-machine age1 creation_rules: - path_regex: secrets/[^/]+\.(yaml|json|env|ini)$ key_groups: - age: - *new-machine # ... existing recipients ``` 3. **Re-encrypt all secret files** so the new machine becomes a recipient: ```bash find secrets/ -name '*.yaml' -exec sops updatekeys {} \; ``` ### Adding a new secret To add a secret to an existing file: ```bash # Edit the file interactively (sops decrypts, opens $EDITOR, re-encrypts on save) sops secrets/nas-secrets.yaml ``` To create a new secrets file: ```bash sops secrets/mymachine-secrets.yaml ``` The `.sops.yaml` `creation_rules` determine which keys encrypt the file based on its path. ### Generating Nebula VPN certificates The Nebula module (`mjallen.services.nebula`) expects three secrets per host under a configurable prefix: - `/ca-cert` — the CA certificate (shared across all nodes) - `/host-cert` — this node's signed certificate - `/host-key` — this node's private key **Step 1 — Create the CA** (once per network, on a trusted machine): ```bash nebula-cert ca -name "jallen-nebula" # Produces: ca.crt, ca.key ``` **Step 2 — Sign a certificate for each node**: ```bash # Lighthouse (assign an overlay IP, e.g. 10.1.1.1) nebula-cert sign -name "pi5" -ip "10.1.1.1/24" \ -ca-crt ca.crt -ca-key ca.key \ -out-crt lighthouse.crt -out-key lighthouse.key # Regular node (assign a unique overlay IP, e.g. 10.1.1.2) nebula-cert sign -name "nas" -ip "10.1.1.2/24" \ -ca-crt ca.crt -ca-key ca.key \ -out-crt nas.crt -out-key nas.key ``` **Step 3 — Add the secrets to SOPS**: ```bash # Edit the target host's secrets file sops secrets/pi5-secrets.yaml ``` Add the certificate contents under the configured prefix (e.g. `pi5/nebula`): ```yaml pi5: nebula: ca-cert: | lighthouse-cert: | lighthouse-key: | ``` The key name for the cert/key pair matches the `hostSecretName` option (e.g. `hostSecretName = "lighthouse"` → looks for `lighthouse-cert` / `lighthouse-key`). **Step 4 — Shred the plaintext key files** once they are in SOPS: ```bash shred -u ca.key lighthouse.key nas.key ``` > Keep `ca.crt` accessible if you need to sign more nodes later, but store `ca.key` only in SOPS. ## Documentation Comprehensive documentation is available in the [docs](./docs) directory: - [Getting Started](./docs/getting-started.md) - Instructions for setting up new systems - [Architecture](./docs/architecture.md) - Overview of the repository structure - [System Configurations](./docs/systems/README.md) - Details about each system - [Home Assistant](./docs/home-assistant/README.md) - Home Assistant setup and automations - [Custom Modules](./docs/modules/README.md) - Details about reusable configuration modules - [Troubleshooting](./docs/troubleshooting.md) - Common issues and solutions ## License This project is licensed under the MIT License - see the LICENSE file for details.