2026-06-12 16:02:13 -04:00
|
|
|
{ config, lib, pkgs, keys, ... }:
|
|
|
|
|
|
|
|
|
|
{
|
|
|
|
|
networking.hostName = "uConsole";
|
|
|
|
|
time.timeZone = "America/Montreal";
|
|
|
|
|
i18n.defaultLocale = "en_CA.UTF-8";
|
|
|
|
|
system.stateVersion = "25.11";
|
|
|
|
|
|
2026-06-18 15:23:06 -04:00
|
|
|
# Boot & Hardware
|
|
|
|
|
boot.loader.raspberry-pi.bootloader = "kernel";
|
|
|
|
|
|
2026-06-12 20:47:11 -04:00
|
|
|
# SSH — root access avec clés gortium + ai-worker
|
2026-06-12 16:02:13 -04:00
|
|
|
services.openssh = {
|
|
|
|
|
enable = true;
|
2026-06-12 20:47:11 -04:00
|
|
|
settings = {
|
|
|
|
|
PermitRootLogin = lib.mkForce "prohibit-password";
|
|
|
|
|
PasswordAuthentication = lib.mkForce false;
|
2026-06-12 16:15:30 -04:00
|
|
|
};
|
|
|
|
|
};
|
2026-06-12 16:02:13 -04:00
|
|
|
|
2026-06-12 20:47:11 -04:00
|
|
|
users.users.root.openssh.authorizedKeys.keys = with keys; [
|
|
|
|
|
users.gortium.main
|
|
|
|
|
users.ai-worker.main
|
2026-06-12 16:02:13 -04:00
|
|
|
];
|
|
|
|
|
|
2026-06-17 08:26:48 -04:00
|
|
|
# Age secret for gortium password (file created by user)
|
2026-06-14 19:53:40 -04:00
|
|
|
age.secrets.gortium_password = {
|
2026-06-16 19:09:24 -04:00
|
|
|
file = ../../secrets/gortium_password.age;
|
2026-06-14 19:53:40 -04:00
|
|
|
};
|
|
|
|
|
|
2026-06-18 15:23:06 -04:00
|
|
|
# WiFi via NetworkManager
|
2026-06-12 20:47:11 -04:00
|
|
|
networking.networkmanager.enable = true;
|
2026-06-12 16:02:13 -04:00
|
|
|
|
2026-06-12 20:47:11 -04:00
|
|
|
# Firmware
|
|
|
|
|
hardware.enableRedistributableFirmware = true;
|
2026-06-13 13:47:35 -04:00
|
|
|
|
2026-06-14 19:56:33 -04:00
|
|
|
# Hyprland Wayland compositor (manual start — no SDDM)
|
|
|
|
|
programs.hyprland = {
|
|
|
|
|
enable = true;
|
|
|
|
|
xwayland.enable = true;
|
|
|
|
|
};
|
2026-06-18 15:23:06 -04:00
|
|
|
|
2026-06-16 19:00:50 -04:00
|
|
|
# HackerGadgets AIO v2 board
|
|
|
|
|
hardware.uconsole-cm5-aio-v2 = {
|
|
|
|
|
enable = true;
|
|
|
|
|
bootRails = {
|
2026-06-17 08:26:48 -04:00
|
|
|
GPS = false;
|
|
|
|
|
LORA = false;
|
|
|
|
|
SDR = false;
|
|
|
|
|
USB = false;
|
2026-06-16 19:00:50 -04:00
|
|
|
};
|
2026-06-17 08:26:48 -04:00
|
|
|
enableGPS = false;
|
2026-06-16 19:00:50 -04:00
|
|
|
};
|
|
|
|
|
|
2026-06-18 15:23:06 -04:00
|
|
|
# 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
|
|
|
|
|
# ============================================================
|
|
|
|
|
environment.systemPackages = with pkgs; [
|
|
|
|
|
# ===== Base =====
|
|
|
|
|
emacs-pgtk
|
|
|
|
|
git
|
|
|
|
|
ripgrep
|
|
|
|
|
fd
|
|
|
|
|
htop
|
|
|
|
|
tmux
|
|
|
|
|
neovim
|
|
|
|
|
|
|
|
|
|
# ===== HAM Radio =====
|
|
|
|
|
js8call
|
|
|
|
|
wsjtx
|
|
|
|
|
fldigi
|
|
|
|
|
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 # SDR++ spectrum analyzer
|
|
|
|
|
gqrx # SDR receiver GUI
|
|
|
|
|
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 # Packet analyzer
|
|
|
|
|
hashcat # GPU password cracker
|
|
|
|
|
john # John the Ripper
|
|
|
|
|
sqlmap # SQL injection tool
|
|
|
|
|
|
|
|
|
|
# ===== GPS / Maps =====
|
|
|
|
|
foxtrotgps
|
|
|
|
|
viking # GPS map editor
|
|
|
|
|
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 = [ ];
|
2026-06-18 17:17:29 -04:00
|
|
|
# ============================================================
|
|
|
|
|
# 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;
|
2026-06-18 17:19:29 -04:00
|
|
|
}
|