GPIO 23 service used gpioset 0 23=1 on BCM2712 chip 0 instead of the RP1 chip (base 512), writing to a critical pin and freezing the system. Commented out until correct chip is confirmed. SSH opened with PasswordAuthentication + PermitRootLogin for first deployment. Lock down after initial boot.
239 lines
8.2 KiB
Nix
239 lines
8.2 KiB
Nix
{ config, lib, pkgs, paths, self, keys, ... }:
|
|
|
|
let
|
|
# Backlight fallback for CM5 display quirk
|
|
# The kernel driver usually handles this, but some boots need a kick
|
|
backlightFixScript = pkgs.writeShellScript "backlight-fix" ''
|
|
# Try sysfs backlight control
|
|
for bl in /sys/class/backlight/*/brightness; do
|
|
if [ -f "$bl" ]; then
|
|
max=$(cat "$(dirname "$bl")/max_brightness" 2>/dev/null || echo 100)
|
|
echo "$max" > "$bl" 2>/dev/null || true
|
|
fi
|
|
done
|
|
'';
|
|
in
|
|
|
|
{
|
|
# Basic Host Info
|
|
networking.hostName = "uConsole";
|
|
time.timeZone = "America/Montreal";
|
|
i18n.defaultLocale = "en_CA.UTF-8";
|
|
|
|
# System State
|
|
system.stateVersion = "25.05";
|
|
|
|
# Boot & Hardware (migrated to kernel bootloader per nixos-raspberrypi deprecation notice)
|
|
boot.loader.raspberry-pi.bootloader = "kernel";
|
|
# kernel managed by nixos-raspberrypi module — don't override, patches are version-specific
|
|
# boot.kernelPackages = pkgs.linuxPackages_latest;
|
|
|
|
# Networking
|
|
networking.networkmanager.enable = true;
|
|
services.openssh = {
|
|
enable = true;
|
|
# TODO: lock down after first deployment
|
|
settings.PermitRootLogin = lib.mkForce "yes";
|
|
settings.PasswordAuthentication = lib.mkForce true;
|
|
};
|
|
|
|
# User
|
|
users.users.gortium = {
|
|
isNormalUser = true;
|
|
extraGroups = [ "wheel" "networkmanager" "video" "dialout" "kismet" ];
|
|
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
|
|
libgpiod # GPIO control (for internal USB hub, AIO modules)
|
|
|
|
# ===== 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 =====
|
|
# meshtastic not available in nixpkgs 25.11 stable; install manually:
|
|
# nix shell nixpkgs#meshtastic -c meshtastic
|
|
reticulumStack # Reticulum Network Stack (rnsd, rnsh, rncp, rnx, rnpath, etc.)
|
|
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
|
|
];
|
|
|
|
# Packages noted but not in unstable nixpkgs:
|
|
# - metasploit: unfree; install manually via Git clone
|
|
# - burpsuite: unfree Java app (Community Edition available for download)
|
|
# - sidechannel: not a distinct PyPI package; functionality covered by
|
|
# the Reticulum stack. For LXMF GUI client, install Sideband manually
|
|
# from github.com/markqvist/Sideband
|
|
|
|
# ============================================================
|
|
# 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, radio, and WiFi
|
|
# ============================================================
|
|
boot.kernelModules = [
|
|
"mt7921u" # MediaTek MT7921 USB WiFi (uConsole AC1200)
|
|
"88x2bu" # Realtek 8812/8821BU USB WiFi (common adapter)
|
|
"rtl8xxxu" # RTL8188/8192/8723 USB WiFi
|
|
"rtl2832_sdr" # RTL-SDR kernel module
|
|
"dvb_usb_rtl28xxu" # RTL-SDR DVB-T
|
|
];
|
|
|
|
boot.blacklistedKernelModules = [ ];
|
|
|
|
# ============================================================
|
|
# 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: open ports for Reticulum (optional)
|
|
# ============================================================
|
|
networking.firewall.allowedTCPPorts = [ 22 ]; # SSH only
|
|
networking.firewall.allowedUDPPorts = [ ];
|
|
# Reticulum uses its own encryption and doesn't need open ports
|
|
# for basic mesh operations (peer-to-peer discovery).
|
|
# For TCP interfaces, open additional ports as needed.
|
|
|
|
# ============================================================
|
|
# Display & Desktop (Hyprland Wayland compositor)
|
|
# ============================================================
|
|
programs.hyprland = {
|
|
enable = true;
|
|
xwayland.enable = true;
|
|
};
|
|
services.displayManager.sddm = {
|
|
enable = true;
|
|
wayland.enable = true;
|
|
};
|
|
|
|
# ============================================================
|
|
# CM5 Display Backlight Fix
|
|
# The kernel driver initializes backlight, but some boots fail.
|
|
# This service kicks it after boot as a reliable fallback.
|
|
# ============================================================
|
|
systemd.services.cm5-backlight-fix = {
|
|
description = "CM5 Display Backlight Fix";
|
|
after = [ "multi-user.target" ];
|
|
wantedBy = [ "multi-user.target" ];
|
|
serviceConfig = {
|
|
Type = "oneshot";
|
|
ExecStart = "${backlightFixScript}";
|
|
};
|
|
};
|
|
|
|
# ============================================================
|
|
# Internal USB Hub Enable (GPIO 23) — DISABLED
|
|
# This service freeze the CM5 because gpioset 0 23=1 writes
|
|
# to the wrong GPIO chip (BCM2712 native, not RP1).
|
|
# Enable manually after boot once the correct chip is confirmed:
|
|
# gpioset 0 23=1 # on chip 0 (BCM2712, CORE_VOLT or critical)
|
|
# gpioset 512 23=1 # on chip 512 (RP1, likely correct)
|
|
# ============================================================
|
|
# systemd.services.enable-gpio23-usb-hub = {
|
|
# description = "Enable Internal USB Hub (GPIO 23)";
|
|
# before = [ "network.target" ];
|
|
# wantedBy = [ "multi-user.target" ];
|
|
# serviceConfig = {
|
|
# Type = "oneshot";
|
|
# RemainAfterExit = true;
|
|
# ExecStart = "${pkgs.libgpiod}/bin/gpioset 0 23=1";
|
|
# ExecStop = "${pkgs.libgpiod}/bin/gpioset 0 23=0";
|
|
# };
|
|
# };
|
|
}
|