{ config, lib, pkgs, keys, ... }: { networking.hostName = "uConsole"; time.timeZone = "America/Montreal"; i18n.defaultLocale = "en_CA.UTF-8"; system.stateVersion = "25.11"; # Boot & Hardware boot.loader.raspberry-pi.bootloader = "kernel"; # SSH — root access avec clés gortium + ai-worker services.openssh = { enable = true; settings = { PermitRootLogin = lib.mkForce "prohibit-password"; PasswordAuthentication = lib.mkForce false; }; }; users.users.root.openssh.authorizedKeys.keys = with keys; [ users.gortium.main users.ai-worker.main ]; # Age secret for gortium password (file created by user) age.secrets.gortium_password = { file = ../../secrets/gortium_password.age; }; # WiFi via NetworkManager networking.networkmanager.enable = true; # Firmware hardware.enableRedistributableFirmware = true; # Hyprland Wayland compositor (manual start — no SDDM) programs.hyprland = { enable = true; xwayland.enable = true; }; # HackerGadgets AIO v2 board hardware.uconsole-cm5-aio-v2 = { enable = true; bootRails = { GPS = false; LORA = false; SDR = false; USB = false; }; enableGPS = false; }; # User users.users.gortium = { isNormalUser = true; extraGroups = [ "wheel" "networkmanager" "video" "dialout" "kismet" ]; hashedPasswordFile = config.age.secrets.gortium_password.path; openssh.authorizedKeys.keys = [ keys.users.gortium.main keys.users.gortium.gitea ]; }; security.sudo.extraRules = [ { users = [ "gortium" ]; commands = [{ command = "ALL"; options = [ "NOPASSWD" ]; }]; } ]; # ============================================================ # Package groups # ============================================================ # ============================================================ # CROSS-COMPILE REMOVALS — packages removed for aarch64 bootstrap # ============================================================ # These packages fail to cross-compile for aarch64. # Install them natively AFTER the first successful switch. # # Removed: Reason: # hashcat — Makefile calls gcc directly (cross-compiler not used) # neovim — Same as hashcat: Makefile calls gcc directly (cross-compiler not used) # clamav — cmake try_run + Rust proc-macro linker for aarch64 # sdrpp — glfw/wxPython cross-compile fails # gqrx — Qt5 cross-compile cascade fails # emacs-pgtk → emacs-nox — GTK3 + mailutils → gss → shishi chain # viking — GTK3 GPS map editor # foxtrotgps — GTK2 GPS app # js8call — QtQuick3D dep # wsjtx — qtbase/Qt5 linker fails (collect2: ld returned 1) # fldigi — same: qtbase/Qt5 linker fails # ============================================================ environment.systemPackages = with pkgs; [ # ===== Base ===== # emacs-pgtk — removed for bootstrap (GTK3 cross-compile fails) # emacs-nox — removed for bootstrap (depends on mailutils -> gss -> shishi, cross-compile fails) git ripgrep fd htop tmux # ===== HAM Radio ===== # wsjtx — removed for aarch64 bootstrap (qtbase/Qt5 cross-compile linker fails) # fldigi — removed for aarch64 bootstrap (qtbase/Qt5 cross-compile linker fails) pat # Winlink client direwolf # AX.25 packet modem chirp # Radio programming tool hamlib # Ham radio control libraries trustedqsl # Logbook of the World (LoTW) # ===== SDR / RF ===== # sdrpp — removed for aarch64 cross-compile bootstrap (glfw/wxPython fails) # gqrx — removed for aarch64 cross-compile bootstrap (Qt5 cascade fails) rtl-sdr # RTL-SDR drivers & utilities inspectrum # Offline signal analysis soapysdr-with-plugins # SoapySDR + hardware support plugins # ===== Mesh / LoRa ===== reticulumStack # Reticulum Network Stack lxmf # LXMF messaging protocol nomadnet # Nomad Network client # ===== Security ===== nmap aircrack-ng kismet # Wi-Fi monitor / IDS bettercap # MITM/network attack framework wireshark-cli # Packet analyzer john # John the Ripper sqlmap # SQL injection tool # ===== GPS / Maps ===== # foxtrotgps — removed for aarch64 cross-compile bootstrap (GTK2 fails) # viking — removed for aarch64 cross-compile bootstrap (GTK3 fails) gpsbabel # GPS data conversion ]; # ============================================================ # Reticulum Service (rnsd) # ============================================================ systemd.services.rnsd = { description = "Reticulum Network Stack Daemon"; wants = [ "network-online.target" ]; after = [ "network-online.target" ]; wantedBy = [ "multi-user.target" ]; serviceConfig = { User = "gortium"; Group = "gortium"; ExecStart = "${pkgs.reticulumStack}/bin/rnsd"; Restart = "always"; RestartSec = "10s"; LimitNOFILE = 65536; }; }; # ============================================================ # Kismet Service (Wi-Fi monitoring / mesh node) # ============================================================ systemd.services.kismet = { description = "Kismet Wi-Fi Monitor & IDS"; wants = [ "network-online.target" ]; after = [ "network-online.target" ]; wantedBy = [ "multi-user.target" ]; serviceConfig = { User = "gortium"; Group = "kismet"; ExecStart = "${pkgs.kismet}/bin/kismet -c wlan0 --log-base=/home/gortium/kismet_logs --no-nc-ui"; Restart = "always"; RestartSec = "10s"; }; }; # ============================================================ # Kernel modules for SDR and radio # ============================================================ boot.kernelModules = [ "88x2bu" # Realtek 8812/8821BU USB WiFi "rtl8xxxu" # RTL8188/8192/8723 USB WiFi "rtl2832_sdr" # RTL-SDR kernel module "dvb_usb_rtl28xxu" # RTL-SDR DVB-T ]; # ============================================================ # Extra udev rules for SDR and HAM radio devices # ============================================================ services.udev.packages = with pkgs; [ rtl-sdr ]; # ============================================================ # Enable IPv6 for Reticulum mesh # ============================================================ networking.enableIPv6 = true; # ============================================================ # Firewall # ============================================================ networking.firewall.allowedTCPPorts = [ 22 ]; networking.firewall.allowedUDPPorts = [ ]; # ============================================================ # agenix-rekey — automatic secret re-encryption at deploy time # ============================================================ age.rekey = { # Master identities for encrypting secrets (on Thierry's laptop) masterIdentities = [ "/home/gortium/.ssh/gortium_ssh_key" ]; # uConsole SSH host pubkey — for automatic rekey at build time # Once uConsole is deployed, replace with actual pubkey from: # ssh-keyscan uConsole.local | ssh-to-age hostPubkey = "age1qyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqs3290gq"; # dummy — replace after bootstrap }; # Enable remote builder (distributed build via lazyworkhorse server) services.remoteBuilder.enable = true; } # Pipewire overlay: drop libcamera (fixes aarch64 cross-compile — rpi-pisp blocks) nixpkgs.overlays = [ (final: prev: { pipewire = prev.pipewire.override { libcamera = null; }; })