Files

20 KiB

🏗️ NixOS Infrastructure Project Canvas

Centralized NixOS configuration management project for Xavier Lagraula's infrastructure

📌 Context and Objectives

  • Scope: Centralized management of NixOS configurations for a complete infrastructure (hypervisors, workstations, LXC containers, services).
  • Environment:
    • One Proxmox hypervisor currently, a second one coming soon.
    • Several workstations (e.g., sting, gaia, PC-FRIDA).
    • LXC Containers (on Proxmox) VE for infrastructure services (DNS, Gitea, Bitwarden, etc.) and applications.
    • 2 main users (Xavier, Frida) + system users (root, admin, guest).
  • Hardware: ThinkCentre m710q (16 GB RAM, i3) with KDE 6.3.

Objectives

Objective Description Priority
Centralize configurations A single Git repository for all machines.
Modularity Reusable modules for services, machine types, and user profiles.
Automation Scripts to deploy configurations to machines and containers.
Security Secret management with sops-nix or agenix.
Portability Autonomous modules via callPackage.
Maintenance Clear documentation and simplified update processes.

🔍 Key Decisions

Decision Justification Impact
No flakes Simplify onboarding and avoid a steep learning curve. Configuration via configuration.nix + callPackage.
Modular structure Separate configurations by machine type and service. Clear and maintainable directory tree.
Servers named by service, not by application Indicate what the machine does (git01 = Git forge) rather than the software (Gitea). Allows changing the underlying app without renaming. Hosts under hosts/servers/<service>01 (e.g. git01, pass01, dns01).
Modules Make modules autonomous, portable, and reusable. Each module is an independent Nix package.
Separation of user-profiles/ and users/ Distinguish generic roles (e.g., admin) from concrete users (e.g., xavier). Flexibility to apply profiles to multiple users.
deploy.sh script Automate deployment on existing machines. Clone/update the repo + nixos-rebuild switch.
create-lxc-nixos.sh script Automate the creation of NixOS LXC containers on Proxmox. Ready-to-use container with initial configuration.
Initial configuration (initial-configuration.nix) Prepare an LXC container so it can update itself via Git. Self-sufficient containers.
Secret management with agenix Encrypt secrets (passwords, keys) for secure storage. Enhanced security for sensitive data.
Unprivileged LXC containers (--unprivileged 0) NixOS requires privileges to function correctly in LXC. Functional containers with NixOS.
Centralised network data A single declarative network data source (network/) consumed by NixOS configs and scripts. VLANs, subnets, host addresses defined once in network/hosts.nix.
IPv6-first with dual-stack Both ULA (fdb2:) and GUA (2a01:) prefixes defined per VLAN. Consistent internal addressing + global reachability for DMZ services.
DHCP-based IPv4 assignment LXC containers use useDHCP = true. Addresses are reserved in hosts.nix as source of truth. Centralised address management, no static IPs in per-host configs.

📂 File Structure

Git Repository Structure

nixos-infra/
├── configuration.nix          # Main entry point
├── README.md
│
├── hosts/                      # Machine configurations
│   ├── servers/                # Servers (hypervisors, VMs, LXCs)
│   │   ├── hyper01/           # Hypervisor 1
│   │   │   └── configuration.nix
│   │   ├── hyper02/           # Hypervisor 2
│   │   │   └── configuration.nix
│   │   ├── dns01/              # LXC container for DNS (master)
│   │   │   └── configuration.nix
│   │   ├── dns02/              # LXC container for DNS (slave)
│   │   │   └── configuration.nix
│   │   ├── git01/              # LXC container for Git forge (e.g. Gitea)
│   │   │   └── configuration.nix
│   │   ├── pass01/             # LXC container for password manager (e.g. Vaultwarden)
│   │   │   └── configuration.nix
│   │   └── rp01/               # LXC container for reverse proxy
│   │       └── configuration.nix
│   │
│   └── workstations/           # Workstations
│       ├── sting/              # Xavier's station (admin, dev, audio)
│       │   └── configuration.nix
│       ├── PC-FRIDA/           # Frida's station (office)
│       │   └── configuration.nix
│       └── gaia/               # Xavier's laptop (audio)
│           └── configuration.nix
│
├── network/                    # Centralised network data (VLANs, subnets, hosts)
│   ├── default.nix             # Aggregator — imports vlans, subnets, hosts
│   ├── vlans.nix               # VLAN definitions
│   ├── subnets.nix             # Subnet prefix allocations
│   ├── hosts.nix               # Per-machine IP/address assignments
│   └── README.md               # Network architecture documentation
│
├── modules/                    # Autonomous modules
│   ├── machine-types/          # Machine types
│   │   ├── hypervisor/
│   │   │   └── default.nix     # Module for hypervisors
│   │   ├── vm/
│   │   │   └── default.nix     # Module for VMs
│   │   ├── lxc/
│   │   │   └── default.nix     # Module for LXC containers
│   │   └── workstation/
│   │       └── default.nix     # Module for workstations
│   │
│   ├── services/               # Services
│   │   ├── dns/
│   │   │   ├── default.nix     # Implementation
│   │   │   └── options.nix     # Exposed options
│   │   ├── git-forge/
│   │   │   └── default.nix
│   │   ├── password-manager/
│   │   │   └── default.nix
│   │   ├── reverse-proxy/
│   │   │   └── default.nix
│   │   └── ...
│   │
│   └── user-profiles/          # User profiles (roles)
│       ├── admin.nix           # Administrator profile
│       ├── dev.nix             # Developer profile
│       ├── cam.nix             # Audio production profile
│       └── standard.nix        # Standard profile
│
├── users/                      # Specific users
│   ├── root/
│   │   └── configuration.nix
│   ├── xavier/
│   │   └── configuration.nix
│   ├── frida/
│   │   └── configuration.nix
│   └── guest/
│       └── configuration.nix
│
├── scripts/                    # Utility scripts
│   ├── deploy.sh               # Deployment for existing machines
│   ├── create-lxc-nixos.sh     # LXC container creation on Proxmox
│   └── initial-configuration.nix # Initial configuration for new containers
│
├── secrets/                    # Secrets (excluded from Git)
│   └── .gitignore
│
└── overlays/                   # Overlays for custom packages
    └── custom-pkgs.nix


🖥️ Machine Profiles and Services

Machine Profiles

Profile Description File Usage
hypervisor Common configuration for hypervisors (KVM, libvirtd, etc.). modules/machine-types/hypervisor/default.nix Proxmox hypervisors.
vm Common configuration for virtual machines. modules/machine-types/vm/default.nix VMs under Proxmox.
lxc Common configuration for LXC containers. modules/machine-types/lxc/default.nix LXC containers under Proxmox.
workstation Common configuration for workstations. modules/machine-types/workstation/default.nix Development, audio production, office stations.
Profile Description File
admin Administrator access (sudo, service management). modules/user-profiles/admin.nix
dev Development environment (tools, permissions). modules/user-profiles/dev.nix
cam Computer-assisted music (CAM). modules/user-profiles/cam.nix
standard Standard user profile (basic access). modules/user-profiles/standard.nix

📋 Reference Tables

1. Machine List

Name Machine Type VLAN IPv4 IPv6 Token
hyper01 Hypervisor ADMIN 10.10.128.10/16 ::10
hyper02 Hypervisor ADMIN 10.10.128.11/16 ::11
dns01 LXC Container DMZ 10.40.128.10/16 ::10
dns02 LXC Container DMZ 10.40.128.11/16 ::11
git01 LXC Container DMZ 10.40.128.20/16 ::20
pass01 LXC Container DMZ 10.40.128.30/16 ::30
rp01 LXC Container DMZ 10.40.128.199/16 ::199
sting Workstation INTERNAL 10.50.128.10/16 ::10
PC-FRIDA Workstation INTERNAL 10.50.128.11/16 ::11
gaia Workstation INTERNAL 10.50.128.12/16 ::12

2. VLANs

VLAN ID Effective ID IPv4 Prefix IPv6 ULA IPv6 GUA
INET 1 1 Out of scope Out of scope Out of scope
ADMIN 90 100 10.10.0.0/16 fdb2:ae63:d45:d941::/64 2a01:e0a:2ea:d941::/64
IOT 200 200 10.20.0.0/16 fdb2:ae63:d45:d942::/64 2a01:e0a:2ea:d942::/64
GUEST 300 300 10.30.0.0/16 fdb2:ae63:d45:d943::/64 2a01:e0a:2ea:d943::/64
DMZ 400 400 10.40.0.0/16 fdb2:ae63:d45:d944::/64 2a01:e0a:2ea:d944::/64
INTERNAL 500 500 10.50.0.0/16 fdb2:ae63:d45:d945::/64 2a01:e0a:2ea:d945::/64

3. List of User Profiles

Name Role
admin Superuser
dev Developer
standard Web & Office
guest Guest

4. User List

Name Role SSH Access
root Superuser
xavier Main user
frida User
guest Guest

5. User/Machine/Profile Mappings

User Machine Applied Profiles Role
root All - Superuser
xavier All admin Development + administration
xavier sting admin, dev Hypervisor management
frida PC-FRIDA standard Development
guest None guest Guest user
xavier sting admin, dev Hypervisor management
frida PC-FRIDA standard Development
guest None guest Guest user


🌐 Network Architecture

The network topology and addressing are defined declaratively in network/, the single source of truth for:

  • VLANs (network/vlans.nix)
  • Subnet prefixes (network/subnets.nix)
  • Host address assignments (network/hosts.nix)

Prefix rules

Type Formula Example (DMZ, effectiveId=400)
IPv4 10.<effectiveId>.0.0/16 — hosts in 10.<v>.128.0/17 10.40.0.0/16
IPv6 ULA fdb2:ae63:d45:d94<N>::/64 where N = effectiveId/100 fdb2:ae63:d45:d944::/64
IPv6 GUA 2a01:e0a:2ea:d94<N>::/64 where N = effectiveId/100 2a01:e0a:2ea:d944::/64

ADMIN exception: VLAN ID is 90 but treated as effective ID 100 for prefix computation. This avoids a risky production renumbering.

Consumption

From a NixOS configuration:

let network = import ../../network { };
in {
  networking.hostName = "dns01";
  networking.useDHCP = true;
}

From a shell script:

nix eval --json -f network/default.nix hosts | jq '.dns01.ipv4'
# → "10.40.128.10"

🔄 Deployment Workflow

For LXC containers (Proxmox)

  1. Create the container :
  • Use create-lxc-nixos.sh to create a container from the NixOS template.
  • The script installs the initial configuration (initial-configuration.nix).
  1. Deploy the final configuration :
  • The deploy.sh script is executed automatically to apply the specific configuration to the container (e.g., hosts/servers/dns01/configuration.nix).
  1. Update :
  • git pull in /etc/nixos-infra + nixos-rebuild switch.

For workstations and hypervisors

  1. Clone the repository :
     git clone https://github.com/xlagraula/nixos-infra.git /etc/nixos-infra
    
  2. Link the configuration :
     ln -s /etc/nixos-infra/hosts/workstations/dev-xavier/configuration.nix /etc/nixos/configuration.nix
    
  3. Apply the configuration :
     sudo nixos-rebuild switch
    


🔐 Secret Management

  • Tool : agenix.
  • Process :
    1. Encrypt secrets with age :
     echo "my-secret" | age -r age1... -o secrets/bitwarden/password.age
    
    1. Integrate into the configuration :
     age.secrets.bitwarden-password = {
       path = ./secrets/bitwarden/password.age;
       mode = "600";
     };
    
    1. Never commit secrets in plain text (add secrets/ to .gitignore).


📅 Roadmap

Step Description Status Priority
Test the NixOS LXC template Verify that the template works under Proxmox.
Finalize create-lxc-nixos.sh Test the creation of an LXC container.
Write the DNS module Module for the DNS service (Bind).
Configure agenix Encrypt the first secrets.
Document the process README.md to explain deployment.
DHCP service module Kea or ISC DHCP consuming network/hosts.nix
Automate with Ansible Playbook to create multiple containers.
Integrate CI/CD Test configurations before deployment.


💡 Notes and Best Practices

  • Naming :
    • Servers: Name by service, not by application (e.g., git01, pass01, dns01).
    • Workstations: Use descriptive hostnames (e.g., sting, gaia).
    • Hypervisors: Prefix with hyper (e.g., hyper01, hyper02).
  • Security :
    • Disable root SSH access once deployment is complete.
    • Use SSH keys for authentication.
  • Network :
    • IPv4 addresses are allocated from the upper half of each VLAN (10.<v>.128.0/17).
    • Addresses are assigned via DHCP reservations — network/hosts.nix is the source of truth.
    • See network/README.md for the complete architecture documentation.
  • Maintenance :
    • Update nixpkgs regularly (nix-channel --update).
    • Document changes in the CHANGELOG.md.
  • Backups :
    • Backup configurations (/etc/nixos-infra) and secrets (secrets/).
    • For LXC containers under Proxmox, use Proxmox backups.


📚 Useful Resources