🏗️ 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


S
Description
No description provided
Readme MIT 210 KiB
Languages
Nix 63.6%
Shell 36.4%