From 498b28fac0d8092f4b37441260a977bfff354cd5 Mon Sep 17 00:00:00 2001 From: Menno van Leeuwen Date: Tue, 4 Mar 2025 11:22:51 +0100 Subject: [PATCH] refactor: add NixOS configuration files for server and workstation setups --- bin/actions/update.sh | 9 +- config/nixos/common/server.nix | 46 ++++++ config/nixos/common/workstation.nix | 75 +++++++++ config/nixos/configuration.nix | 70 +++++++++ config/nixos/flake.lock | 113 ++++++++++++++ config/nixos/flake.nix | 81 ++++++++++ config/nixos/hardware/mennos-gamingpc.nix | 57 +++++++ config/nixos/hardware/mennos-laptop.nix | 84 ++++++++++ config/nixos/hardware/mennos-server.nix | 64 ++++++++ config/nixos/hardware/mennos-server/zfs.nix | 147 ++++++++++++++++++ config/nixos/hosts.nix | 11 ++ config/nixos/packages/common/default.nix | 12 ++ .../nixos/packages/common/virtualisation.nix | 39 +++++ config/nixos/packages/server/default.nix | 6 + .../nixos/packages/workstation/1password.nix | 25 +++ config/nixos/packages/workstation/default.nix | 8 + config/nixos/packages/workstation/flatpak.nix | 11 ++ config/nixos/users.nix | 21 +++ config/nixos/yubikey.nix | 109 +++++++++++++ 19 files changed, 981 insertions(+), 7 deletions(-) create mode 100644 config/nixos/common/server.nix create mode 100644 config/nixos/common/workstation.nix create mode 100644 config/nixos/configuration.nix create mode 100644 config/nixos/flake.lock create mode 100644 config/nixos/flake.nix create mode 100644 config/nixos/hardware/mennos-gamingpc.nix create mode 100644 config/nixos/hardware/mennos-laptop.nix create mode 100644 config/nixos/hardware/mennos-server.nix create mode 100644 config/nixos/hardware/mennos-server/zfs.nix create mode 100644 config/nixos/hosts.nix create mode 100644 config/nixos/packages/common/default.nix create mode 100644 config/nixos/packages/common/virtualisation.nix create mode 100644 config/nixos/packages/server/default.nix create mode 100644 config/nixos/packages/workstation/1password.nix create mode 100644 config/nixos/packages/workstation/default.nix create mode 100644 config/nixos/packages/workstation/flatpak.nix create mode 100644 config/nixos/users.nix create mode 100644 config/nixos/yubikey.nix diff --git a/bin/actions/update.sh b/bin/actions/update.sh index a9e1add..04f25dd 100755 --- a/bin/actions/update.sh +++ b/bin/actions/update.sh @@ -7,7 +7,6 @@ help() { printfe "%s\n" "green" " --ha, -H Upgrade Home Manager packages." printfe "%s\n" "green" " --ansible, -A Upgrade Ansible packages." printfe "%s\n" "green" " --ansible-verbose Upgrade Ansible packages with verbose output. (-vvv)" - printfe "%s\n" "green" " --nix, -X Update Home Manager flake." printfe "%s\n" "green" " --full-speed, -F Upgrade packages and use all available cores for compilation. (Default: 8 cores)" printfe "%s\n" "green" " --help, -h Display this help message." exit 0 @@ -16,7 +15,6 @@ help() { while [[ "$#" -gt 0 ]]; do case $1 in --ha|-H) RUN_HA=true ;; - --nix|-X) RUN_NIX=true ;; --ansible|-A) RUN_ANSIBLE=true ;; --ansible-verbose) RUN_ANSIBLE=true @@ -29,9 +27,8 @@ while [[ "$#" -gt 0 ]]; do shift done -if [[ -z "$RUN_HA" && -z "$RUN_NIX" && -z "$RUN_ANSIBLE" ]]; then +if [[ -z "$RUN_HA" && -z "$RUN_ANSIBLE" ]]; then RUN_HA=true - RUN_NIX=true RUN_ANSIBLE=true fi @@ -46,12 +43,10 @@ fi printfe "%s\n" "cyan" "Limiting to $CORES cores with $JOBS jobs." -if [[ "$RUN_NIX" == true ]]; then +if [[ "$RUN_HA" == true ]]; then printfe "%s\n" "cyan" "Updating Home Manager flake..." cd $HOME/dotfiles/config/home-manager && nix --extra-experimental-features nix-command --extra-experimental-features flakes flake update -fi -if [[ "$RUN_HA" == true ]]; then if command -v home-manager &> /dev/null; then printfe "%s\n" "cyan" "Cleaning old backup files..." rm -rf $HOME/.config/mimeapps.list.backup diff --git a/config/nixos/common/server.nix b/config/nixos/common/server.nix new file mode 100644 index 0000000..b41d0a8 --- /dev/null +++ b/config/nixos/common/server.nix @@ -0,0 +1,46 @@ +{ config, pkgs, ... }: +{ + # Install xanmod kernel + # boot.kernelPackages = pkgs.linuxKernel.packages.linux_xanmod_stable.zfs; + + services.openssh = { + enable = true; + ports = [ 400 ]; + settings = { + PasswordAuthentication = false; + AllowUsers = [ "menno" ]; + X11Forwarding = false; + PermitRootLogin = "prohibit-password"; + AllowTCPForwarding = true; + AllowAgentForwarding = true; + PermitEmptyPasswords = false; + PubkeyAuthentication = true; + }; + }; + + networking = { + firewall = { + enable = true; + + # External ports + allowedTCPPorts = [ + ## Portforwarded + 80 # HTTP + 443 # HTTPS + 22 # Git over SSH + 25565 # Minecraft + 24454 # Minecraft (Voice Chat) + 32400 # Plex + 51820 # WireGuard + + ## Internal services / TailScale + 400 # SSH + ]; + + allowedUDPPorts = [ + 51820 # WireGuard + 25565 # Minecraft + ]; + }; + }; +} diff --git a/config/nixos/common/workstation.nix b/config/nixos/common/workstation.nix new file mode 100644 index 0000000..2837194 --- /dev/null +++ b/config/nixos/common/workstation.nix @@ -0,0 +1,75 @@ +{ pkgs, ... }: +{ + # Enable the X11 windowing system. + services.xserver.enable = true; + + # Enable the GNOME Desktop Environment. + services.xserver.displayManager.gdm.enable = true; + services.xserver.desktopManager.gnome.enable = true; + + # Enable the Cosmic Desktop Environment. + # services.desktopManager.cosmic.enable = true; + # services.displayManager.cosmic-greeter.enable = true; + + # Install xanmod kernel + boot.kernelPackages = pkgs.linuxKernel.packages.linux_xanmod_stable; + + environment.systemPackages = with pkgs; [ + gnome-session + xdg-desktop-portal + xdg-desktop-portal-gnome + xdg-desktop-portal-gtk + ]; + + # Configure keymap in X11 + services.xserver.xkb = { + layout = "us"; + variant = "euro"; + }; + + # Enable sound with pipewire. + hardware.pulseaudio.enable = false; + security.rtkit.enable = true; + services.pipewire = { + enable = true; + alsa.enable = true; + alsa.support32Bit = true; + pulse.enable = true; + }; + + # Open ports in the firewall + networking.firewall = { + enable = true; + allowedTCPPorts = [ + # RDP (Gnome Remote Desktop) + 3389 + 3390 + 3391 + + # SSH + 400 + ]; + allowedUDPPorts = [ + # RDP (Gnome Remote Desktop) + 3389 + 3390 + 3391 + ]; + }; + + # OpenSSH server + services.openssh = { + enable = true; + ports = [ 400 ]; + settings = { + PasswordAuthentication = false; + AllowUsers = [ "menno" ]; + X11Forwarding = true; + PermitRootLogin = "prohibit-password"; + AllowTCPForwarding = true; + AllowAgentForwarding = true; + PermitEmptyPasswords = false; + PubkeyAuthentication = true; + }; + }; +} diff --git a/config/nixos/configuration.nix b/config/nixos/configuration.nix new file mode 100644 index 0000000..dd71ed8 --- /dev/null +++ b/config/nixos/configuration.nix @@ -0,0 +1,70 @@ +{ + config, + pkgs, + lib, + isServer ? false, + isWorkstation ? false, + ... +}: +{ + imports = + [ + ./packages/common/default.nix + ./users.nix + ./hosts.nix + ./yubikey.nix + ] + # Include packages based on whether this is a server or workstation. + ++ lib.optional isServer ./packages/server/default.nix + ++ lib.optional isWorkstation ./packages/workstation/default.nix; + + # Enable networking + networking.networkmanager.enable = true; + + # Allow unfree packages + nixpkgs.config.allowUnfree = true; + + # Enable experimental nix-command flakes + nix = { + package = pkgs.nixVersions.stable; + extraOptions = '' + experimental-features = nix-command flakes + ''; + }; + + # Set your time zone. + time.timeZone = "Europe/Amsterdam"; + + # Select internationalisation properties. + i18n.defaultLocale = "en_US.UTF-8"; + + i18n.extraLocaleSettings = { + LC_ADDRESS = "nl_NL.UTF-8"; + LC_IDENTIFICATION = "nl_NL.UTF-8"; + LC_MEASUREMENT = "nl_NL.UTF-8"; + LC_MONETARY = "nl_NL.UTF-8"; + LC_NAME = "nl_NL.UTF-8"; + LC_NUMERIC = "nl_NL.UTF-8"; + LC_PAPER = "nl_NL.UTF-8"; + LC_TELEPHONE = "nl_NL.UTF-8"; + LC_TIME = "nl_NL.UTF-8"; + }; + + environment.systemPackages = with pkgs; [ + tailscale + pciutils + ]; + + services.tailscale.enable = true; + security.sudo.extraConfig = '' + Defaults env_reset,pwfeedback + ''; + + # This value determines the NixOS release from which the default + # settings for stateful data, like file locations and database versions + # on your system were taken. It‘s perfectly fine and recommended to leave + # this value at the release version of the first install of this system. + # Before changing this value read the documentation for this option + # (e.g. man configuration.nix or on https://nixos.org/nixos/options.html). + system.stateVersion = "24.11"; # Did you read the comment? +} diff --git a/config/nixos/flake.lock b/config/nixos/flake.lock new file mode 100644 index 0000000..91efe2e --- /dev/null +++ b/config/nixos/flake.lock @@ -0,0 +1,113 @@ +{ + "nodes": { + "flake-compat": { + "flake": false, + "locked": { + "lastModified": 1717312683, + "narHash": "sha256-FrlieJH50AuvagamEvWMIE6D2OAnERuDboFDYAED/dE=", + "owner": "nix-community", + "repo": "flake-compat", + "rev": "38fd3954cf65ce6faf3d0d45cd26059e059f07ea", + "type": "github" + }, + "original": { + "owner": "nix-community", + "repo": "flake-compat", + "type": "github" + } + }, + "nixos-cosmic": { + "inputs": { + "flake-compat": "flake-compat", + "nixpkgs": "nixpkgs", + "nixpkgs-stable": "nixpkgs-stable" + }, + "locked": { + "lastModified": 1736944949, + "narHash": "sha256-rZJtjYBZe5vmanJ/yh5GoZgdISm+EU4iUhG6WD1SwBs=", + "owner": "lilyinstarlight", + "repo": "nixos-cosmic", + "rev": "0dc33f0eb391a1a942a358a01b47f763703d7097", + "type": "github" + }, + "original": { + "owner": "lilyinstarlight", + "repo": "nixos-cosmic", + "type": "github" + } + }, + "nixpkgs": { + "locked": { + "lastModified": 1736798957, + "narHash": "sha256-qwpCtZhSsSNQtK4xYGzMiyEDhkNzOCz/Vfu4oL2ETsQ=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "9abb87b552b7f55ac8916b6fc9e5cb486656a2f3", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixos-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs-stable": { + "locked": { + "lastModified": 1736867362, + "narHash": "sha256-i/UJ5I7HoqmFMwZEH6vAvBxOrjjOJNU739lnZnhUln8=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "9c6b49aeac36e2ed73a8c472f1546f6d9cf1addc", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixos-24.11", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs-unstable": { + "locked": { + "lastModified": 1736798957, + "narHash": "sha256-qwpCtZhSsSNQtK4xYGzMiyEDhkNzOCz/Vfu4oL2ETsQ=", + "owner": "nixos", + "repo": "nixpkgs", + "rev": "9abb87b552b7f55ac8916b6fc9e5cb486656a2f3", + "type": "github" + }, + "original": { + "owner": "nixos", + "ref": "nixos-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs_2": { + "locked": { + "lastModified": 1736867362, + "narHash": "sha256-i/UJ5I7HoqmFMwZEH6vAvBxOrjjOJNU739lnZnhUln8=", + "owner": "nixos", + "repo": "nixpkgs", + "rev": "9c6b49aeac36e2ed73a8c472f1546f6d9cf1addc", + "type": "github" + }, + "original": { + "owner": "nixos", + "ref": "nixos-24.11", + "repo": "nixpkgs", + "type": "github" + } + }, + "root": { + "inputs": { + "nixos-cosmic": "nixos-cosmic", + "nixpkgs": "nixpkgs_2", + "nixpkgs-unstable": "nixpkgs-unstable" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/config/nixos/flake.nix b/config/nixos/flake.nix new file mode 100644 index 0000000..50fa9e4 --- /dev/null +++ b/config/nixos/flake.nix @@ -0,0 +1,81 @@ +{ + description = "menno's dotfiles"; + + inputs = { + nixpkgs.url = "github:nixos/nixpkgs?ref=nixos-24.11"; + nixpkgs-unstable.url = "github:nixos/nixpkgs/nixos-unstable"; + nixos-cosmic.url = "github:lilyinstarlight/nixos-cosmic"; + }; + + outputs = + { + self, + nixpkgs, + nixpkgs-unstable, + nixos-cosmic, + }: + let + system = "x86_64-linux"; + + pkgs = import nixpkgs { + inherit system; + config.allowUnfree = true; + }; + + pkgs-unstable = import nixpkgs-unstable { + inherit system; + config.allowUnfree = true; + }; + in + { + nixosConfigurations = { + "mennos-laptop" = nixpkgs.lib.nixosSystem { + inherit system; + modules = [ + ./hardware/mennos-laptop.nix + ./common/workstation.nix + ./configuration.nix + ]; + specialArgs = { + inherit + pkgs-unstable + nixos-cosmic + ; + isWorkstation = true; + isServer = false; + }; + }; + + "mennos-gamingpc" = nixpkgs.lib.nixosSystem { + inherit system; + modules = [ + ./hardware/mennos-gamingpc.nix + ./common/workstation.nix + ./configuration.nix + ]; + specialArgs = { + inherit + pkgs-unstable + nixos-cosmic + ; + isWorkstation = true; + isServer = false; + }; + }; + + "mennos-server" = nixpkgs.lib.nixosSystem { + inherit system; + modules = [ + ./hardware/mennos-server.nix + ./common/server.nix + ./configuration.nix + ]; + specialArgs = { + inherit pkgs-unstable; + isWorkstation = false; + isServer = true; + }; + }; + }; + }; +} diff --git a/config/nixos/hardware/mennos-gamingpc.nix b/config/nixos/hardware/mennos-gamingpc.nix new file mode 100644 index 0000000..b080924 --- /dev/null +++ b/config/nixos/hardware/mennos-gamingpc.nix @@ -0,0 +1,57 @@ +{ + config, + lib, + pkgs, + modulesPath, + ... +}: +{ + imports = [ /etc/nixos/hardware-configuration.nix ]; + networking.hostName = "mennos-gamingpc"; + + fileSystems."/" = { + device = "/dev/disk/by-uuid/ac5a70cf-4b12-4d02-b5b4-a6eddf4c40b5"; + fsType = "ext4"; + options = [ "noatime" ]; + }; + + networking.interfaces.enp8s0.wakeOnLan = { + enable = true; + }; + + # Bootloader. + boot.loader.systemd-boot.enable = true; + boot.loader.efi.canTouchEfiVariables = true; + + # Enable Vulkan support for AMD graphics cards + hardware.graphics.extraPackages32 = with pkgs.pkgsi686Linux; [ amdvlk ]; + + # Swap file (Desktop PC has 48GB of RAM so 8GB swap should be enough) + swapDevices = [ + { + device = "/swapfile"; + size = 8192; + } + ]; + + # Enable graphics + hardware.graphics = { + enable = true; + + # Enable the latest AMDGPU drivers + extraPackages = with pkgs; [ + amdvlk + rocmPackages.clr + ]; + }; + + # Add ROCm packages and nvtop + environment.systemPackages = with pkgs; [ + rocmPackages.rocm-smi + rocmPackages.clr + rocmPackages.rocm-core + rocmPackages.hipcc + rocmPackages.rocm-device-libs + nvtopPackages.amd + ]; +} diff --git a/config/nixos/hardware/mennos-laptop.nix b/config/nixos/hardware/mennos-laptop.nix new file mode 100644 index 0000000..9b423f1 --- /dev/null +++ b/config/nixos/hardware/mennos-laptop.nix @@ -0,0 +1,84 @@ +{ + config, + lib, + pkgs, + modulesPath, + ... +}: +{ + imports = [ /etc/nixos/hardware-configuration.nix ]; + networking.hostName = "mennos-laptop"; + + fileSystems."/" = { + device = "/dev/disk/by-uuid/1356cd09-5c55-45b5-8b06-6aadc84cee37"; + fsType = "ext4"; + options = [ "noatime" ]; + }; + + # Bootloader + boot.loader.systemd-boot.enable = true; + boot.loader.efi.canTouchEfiVariables = true; + + # Enable graphics + hardware.graphics = { + enable = true; + extraPackages = with pkgs; [ + amdvlk + rocmPackages.clr + ]; + }; + + # Swap file (Laptop has 32GB of RAM so 8GB swap should be enough) + swapDevices = [ + { + device = "/swapfile"; + size = 8192; + } + ]; + + # Load AMD and NVIDIA drivers for Xorg and Wayland + services.xserver.videoDrivers = [ + "nvidia" + "amdgpu" + ]; + + # Monitoring tools + environment.systemPackages = with pkgs; [ + nvtopPackages.nvidia + nvtopPackages.amd + glxinfo + vulkan-tools + ]; + + hardware.nvidia = { + # Enable modesetting + modesetting.enable = true; + + # Power management configuration + powerManagement = { + enable = true; + finegrained = false; # Disabled as it requires offload mode + }; + + # Prime configuration for hybrid graphics + prime = { + offload = { + enable = true; + enableOffloadCmd = true; + }; + + # AMD GPU as primary + amdgpuBusId = "PCI:5:0:0"; + nvidiaBusId = "PCI:1:0:0"; + }; + + open = false; + nvidiaSettings = true; + package = config.boot.kernelPackages.nvidiaPackages.stable; + }; + + boot.kernelParams = [ + "amdgpu.sg_display=0" + "nvidia-drm.modeset=1" + ]; +} diff --git a/config/nixos/hardware/mennos-server.nix b/config/nixos/hardware/mennos-server.nix new file mode 100644 index 0000000..3cb86f7 --- /dev/null +++ b/config/nixos/hardware/mennos-server.nix @@ -0,0 +1,64 @@ +{ + config, + lib, + pkgs, + modulesPath, + ... +}: +{ + imports = [ + /etc/nixos/hardware-configuration.nix + ./mennos-server/zfs.nix + ]; + + fileSystems."/" = { + device = "/dev/disk/by-uuid/dd3fa13c-a1bd-4dc9-bcb4-aee17c7f12d1"; + fsType = "ext4"; + options = [ "noatime" ]; + }; + + networking.hostName = "mennos-server"; + networking.hostId = "64519940"; + + # Bootloader. + boot.loader.systemd-boot.enable = true; + boot.loader.efi.canTouchEfiVariables = true; + + # Allow unfree packages + nixpkgs.config.allowUnfree = true; + + # Load nvidia driver for Xorg and Wayland + services.xserver.videoDrivers = [ "nvidia" ]; + + # Enable graphics + hardware.graphics.enable = true; + + # nvtop, a system monitor for GPUs + environment.systemPackages = with pkgs; [ nvtopPackages.nvidia ]; + + # Enable NVIDIA Docker support + # test with: $ docker run --rm -it --device=nvidia.com/gpu=all ubuntu:latest nvidia-smi + hardware.nvidia-container-toolkit.enable = true; + virtualisation.docker = { + enable = true; + }; + + # Swap file (Laptop has 64GB of RAM so 16GB swap should be enough) + swapDevices = [ + { + device = "/swapfile"; + size = 16384; + } + ]; + + hardware.nvidia = { + modesetting.enable = true; + powerManagement.enable = false; + powerManagement.finegrained = false; + open = false; + nvidiaSettings = true; + + # Use the latest driver from the unstable channel + package = config.boot.kernelPackages.nvidiaPackages.stable; + }; +} diff --git a/config/nixos/hardware/mennos-server/zfs.nix b/config/nixos/hardware/mennos-server/zfs.nix new file mode 100644 index 0000000..e0c3f1c --- /dev/null +++ b/config/nixos/hardware/mennos-server/zfs.nix @@ -0,0 +1,147 @@ +{ config, pkgs, ... }: + +let + # Create a script to set permissions + permissionsScript = pkgs.writeShellScriptBin "set-zfs-permissions" '' + # Set default permissions for all service directories + find /mnt/services -mindepth 1 -maxdepth 1 -type d \ + -exec chmod 775 {} \; \ + -exec chown menno:users {} \; + + # Special cases + chmod 774 /mnt/services/golink + chown 65532:users /mnt/services/golink + + chmod 754 /mnt/services/torrent + chown menno:users /mnt/services/torrent + + chmod 755 /mnt/services/proxy + chmod 755 /mnt/services/static-websites + + chown menno:users /mnt/backups + chown menno:users /mnt/backups/photos + chown menno:users /mnt/backups/services + chmod 775 /mnt/backups + chmod 775 /mnt/backups/photos + chmod 775 /mnt/backups/services + + # Set permissions for other mount points + for dir in /mnt/{ai,astrophotography,audiobooks,downloads,ISOs,movies,music,old_backups,photos,stash,tvshows,VMs}; do + chmod 755 "$dir" + chown menno:users "$dir" + done + ''; +in +{ + environment.systemPackages = with pkgs; [ + zfs + zfstools + permissionsScript + smartmontools + ]; + + # Add the permissions service + systemd.services.zfs-permissions = { + description = "Set ZFS mount permissions"; + + # Run after ZFS mounts are available + after = [ "zfs.target" ]; + requires = [ "zfs.target" ]; + + # Run on boot and every 6 hours + startAt = "*-*-* */6:00:00"; + + serviceConfig = { + Type = "oneshot"; + ExecStart = "${permissionsScript}/bin/set-zfs-permissions"; + User = "root"; + Group = "root"; + }; + }; + + # Enable ZFS support + boot.supportedFilesystems = [ + "ntfs" + "zfs" + ]; + + # ZFS system services + services.zfs = { + autoScrub = { + enable = true; + interval = "weekly"; + }; + }; + + # If you want to keep compression settings + boot.kernelParams = [ + "zfs.zfs_compressed_arc_enabled=1" # Enable compressed ARC + "zfs.zfs_arc_max=21474836480" # 20 GiB + ]; + + fileSystems = { + # backup ZFS mount points + "/mnt/backups/photos" = { + device = "backup/photos-duplicati"; + fsType = "zfs"; + }; + "/mnt/backups/services" = { + device = "backup/services-duplicati"; + fsType = "zfs"; + }; + + # datapool ZFS mount points + "/mnt/ai" = { + device = "datapool/ai"; + fsType = "zfs"; + }; + "/mnt/astrophotography" = { + device = "datapool/astro"; + fsType = "zfs"; + }; + "/mnt/audiobooks" = { + device = "datapool/audiobooks"; + fsType = "zfs"; + }; + "/mnt/downloads" = { + device = "datapool/downloads"; + fsType = "zfs"; + }; + "/mnt/ISOs" = { + device = "datapool/isos"; + fsType = "zfs"; + }; + "/mnt/movies" = { + device = "datapool/movies"; + fsType = "zfs"; + }; + "/mnt/music" = { + device = "datapool/music"; + fsType = "zfs"; + }; + "/mnt/old_backups" = { + device = "datapool/old_backups"; + fsType = "zfs"; + }; + "/mnt/photos" = { + device = "datapool/photos"; + fsType = "zfs"; + }; + "/mnt/services" = { + device = "datapool/services"; + fsType = "zfs"; + }; + "/mnt/stash" = { + device = "datapool/stash"; + fsType = "zfs"; + }; + "/mnt/tvshows" = { + device = "datapool/tv_shows"; + fsType = "zfs"; + }; + "/mnt/VMs" = { + device = "datapool/vms"; + fsType = "zfs"; + }; + }; +} diff --git a/config/nixos/hosts.nix b/config/nixos/hosts.nix new file mode 100644 index 0000000..05a6769 --- /dev/null +++ b/config/nixos/hosts.nix @@ -0,0 +1,11 @@ +{ ... }: +{ + networking.extraHosts = '' + 127.0.0.1 subsites.local + 127.0.0.1 discountoffice.nl.local + 127.0.0.1 discountoffice.be.local + 127.0.0.1 fr.discountoffice.be.local + 127.0.0.1 api.local + 127.0.0.1 mailpit.local + ''; +} diff --git a/config/nixos/packages/common/default.nix b/config/nixos/packages/common/default.nix new file mode 100644 index 0000000..71f4574 --- /dev/null +++ b/config/nixos/packages/common/default.nix @@ -0,0 +1,12 @@ +{ pkgs, ... }: +{ + imports = [ ./virtualisation.nix ]; + + environment.systemPackages = with pkgs; [ + yubikey-manager + trash-cli + sqlite # Used for managing SQLite databases (Brave Settings etc.) + xcp # Rust implementation of cp/mv command + pandoc # Document converter (Markdown, HTML, PDF etc.) (Mostly used for static site generators) + ]; +} diff --git a/config/nixos/packages/common/virtualisation.nix b/config/nixos/packages/common/virtualisation.nix new file mode 100644 index 0000000..5704751 --- /dev/null +++ b/config/nixos/packages/common/virtualisation.nix @@ -0,0 +1,39 @@ +{ + config, + pkgs, + pkgs-unstable, + ... +}: +{ + boot.kernelModules = [ "kvm-amd" ]; + + environment.systemPackages = with pkgs; [ + qemu + OVMF + ]; + + virtualisation = { + docker = { + enable = true; + package = pkgs-unstable.docker; + autoPrune.enable = true; + daemon.settings = { + "live-restore" = false; + }; + }; + + libvirtd = { + enable = true; + + qemu = { + package = pkgs.qemu; + runAsRoot = true; + swtpm.enable = true; + ovmf = { + enable = true; + packages = [ pkgs.OVMF.fd ]; + }; + }; + }; + }; +} diff --git a/config/nixos/packages/server/default.nix b/config/nixos/packages/server/default.nix new file mode 100644 index 0000000..a1f59f2 --- /dev/null +++ b/config/nixos/packages/server/default.nix @@ -0,0 +1,6 @@ +{ config, pkgs, ... }: +{ + # Import all the package modules + imports = [ + ]; +} diff --git a/config/nixos/packages/workstation/1password.nix b/config/nixos/packages/workstation/1password.nix new file mode 100644 index 0000000..8923165 --- /dev/null +++ b/config/nixos/packages/workstation/1password.nix @@ -0,0 +1,25 @@ +{ pkgs, pkgs-unstable, ... }: +{ + # Enables the 1Password CLI + programs._1password = { + enable = true; + }; + + # Enables the 1Password desktop app + programs._1password-gui = { + enable = true; + polkitPolicyOwners = [ "menno" ]; + package = pkgs-unstable._1password-gui; + }; + + environment.etc = { + "1password/custom_allowed_browsers" = { + text = '' + firefox + brave + zen + ''; + mode = "0755"; + }; + }; +} diff --git a/config/nixos/packages/workstation/default.nix b/config/nixos/packages/workstation/default.nix new file mode 100644 index 0000000..05444c2 --- /dev/null +++ b/config/nixos/packages/workstation/default.nix @@ -0,0 +1,8 @@ +{ config, pkgs, ... }: +{ + # Import all the package modules + imports = [ + ./flatpak.nix + ./1password.nix + ]; +} diff --git a/config/nixos/packages/workstation/flatpak.nix b/config/nixos/packages/workstation/flatpak.nix new file mode 100644 index 0000000..71db5a7 --- /dev/null +++ b/config/nixos/packages/workstation/flatpak.nix @@ -0,0 +1,11 @@ +{ pkgs, ... }: +{ + services.flatpak.enable = true; + systemd.services.flatpak-repo = { + wantedBy = [ "multi-user.target" ]; + path = [ pkgs.flatpak ]; + script = '' + flatpak remote-add --if-not-exists flathub https://flathub.org/repo/flathub.flatpakrepo + ''; + }; +} diff --git a/config/nixos/users.nix b/config/nixos/users.nix new file mode 100644 index 0000000..542ed6b --- /dev/null +++ b/config/nixos/users.nix @@ -0,0 +1,21 @@ +{ config, pkgs, ... }: +{ + users.users.menno = { + shell = pkgs.bash; + isNormalUser = true; + description = "Menno van Leeuwen"; + extraGroups = [ + "networkmanager" + "wheel" + "kvm" + "libvirtd" + "qemu-libvirtd" + "docker" + "video" + "render" + "users" + "input" + "adbusers" + ]; + }; +} diff --git a/config/nixos/yubikey.nix b/config/nixos/yubikey.nix new file mode 100644 index 0000000..205c5b1 --- /dev/null +++ b/config/nixos/yubikey.nix @@ -0,0 +1,109 @@ +{ config, pkgs, ... }: +let + # List of authorized YubiKey serial numbers + authorizedKeys = [ + "10627969" + "30079068" + ]; + + sudo-wrapper = pkgs.writeScriptBin "sudo" '' + #!${pkgs.bash}/bin/bash + + # Function to show both terminal and desktop notification + notify() { + echo "$1" >&2 + ${pkgs.libnotify}/bin/notify-send -u critical "Sudo Authentication" "$1" + } + + # Function to check if any of our authorized YubiKeys are present + check_yubikey() { + # Get list of connected YubiKeys + local keys=$(${pkgs.yubikey-manager}/bin/ykman list 2>/dev/null) + + # Check if any of our authorized keys are in the list + for serial in ${toString authorizedKeys}; do + if echo "$keys" | grep -q "$serial"; then + return 0 # Found an authorized key + fi + done + return 1 # No authorized keys found + } + + # Check if we already have sudo permissions + if [ "$EUID" -eq 0 ]; then + exec /run/wrappers/bin/sudo "$@" + fi + + # Check for YubiKey presence + if check_yubikey; then + # YubiKey is present, show touch prompt + if [ -t 1 ]; then # Only show terminal message if interactive + echo -e "\033[1;34mPlease touch your YubiKey to authenticate...\033[0m" >&2 + fi + ${pkgs.libnotify}/bin/notify-send -u normal \ + -i security-high \ + "YubiKey Authentication" \ + "Please touch your YubiKey to authenticate..." + fi + + # Execute sudo with all original arguments + # This will fall back to password auth if no YubiKey is present + exec /run/wrappers/bin/sudo "$@" + ''; +in +{ + services.udev.packages = [ pkgs.yubikey-personalization ]; + + programs.gnupg.agent = { + enable = true; + enableSSHSupport = true; + }; + + environment.systemPackages = with pkgs; [ + pam_u2f + libnotify + sudo-wrapper + ]; + + # Use normal U2F config without trying to modify PAM + security.pam.services = { + sudo.u2fAuth = true; + lock.u2fAuth = true; + gnome-screensaver.u2fAuth = true; + "polkit-1".u2fAuth = true; + }; + + # Enable polkit + security.polkit.enable = true; + + # Add custom polkit rules for 1Password + environment.etc."polkit-1/rules.d/90-1password-yubikey.rules".text = '' + polkit.addRule(function(action, subject) { + if (action.id == "com.1password.1Password.unlock") { + var authtype = subject.local ? "auth_admin_keep" : "auth_admin"; + return polkit.Result.AUTH_ADMIN; + } + }); + ''; + + # Make sure polkit is using the right authentication agent + services.xserver.displayManager.gdm = { + enable = true; + autoSuspend = false; + }; + + # GNOME keyring configuration + security.pam.services."gnome-keyring" = { + text = '' + auth optional pam_u2f.so + auth optional pam_unix.so nullok try_first_pass + session optional pam_keyinit.so force revoke + session optional pam_gnome_keyring.so auto_start + ''; + }; + + # Make sure the wrapper sudo is used instead of the system one + environment.shellAliases = { + sudo = "${sudo-wrapper}/bin/sudo"; + }; +}