summaryrefslogtreecommitdiff
path: root/modules
diff options
context:
space:
mode:
authoradi <adikro@disroot.org>2026-07-29 17:09:58 +0200
committeradi <adikro@disroot.org>2026-07-29 17:09:58 +0200
commit39a2b09c27bb74c9e59d1772764f901e3c8fb9e4 (patch)
tree0ba58e6fbf086a85d875df1c10f6d23bc3bbc7da /modules
parent8a820cacee1ff07ae7397d053b26e66f7086a4a4 (diff)
revamped flake.nix, removed homelab specific modulesstaging
Diffstat (limited to 'modules')
-rw-r--r--modules/audio.nix96
-rw-r--r--modules/bluetooth.nix19
-rw-r--r--modules/bootloader.nix100
-rw-r--r--modules/compat.nix28
-rw-r--r--modules/drivers.nix99
-rw-r--r--modules/files.nix55
-rw-r--r--modules/fonts.nix32
-rw-r--r--modules/gaming.nix145
-rw-r--r--modules/greet.nix32
-rw-r--r--modules/i2p.nix81
-rw-r--r--modules/localization.nix41
-rw-r--r--modules/memory.nix41
-rw-r--r--modules/monero.nix124
-rw-r--r--modules/networking.nix186
-rw-r--r--modules/niri.nix28
-rw-r--r--modules/nix-helper.nix40
-rw-r--r--modules/omnisearch.nix73
-rw-r--r--modules/persistance.nix50
-rw-r--r--modules/power.nix54
-rw-r--r--modules/security.nix72
-rw-r--r--modules/sops.nix36
-rw-r--r--modules/ssh.nix95
-rw-r--r--modules/storage.nix21
-rw-r--r--modules/syncthing.nix136
-rw-r--r--modules/tor.nix31
-rw-r--r--modules/users.nix54
-rw-r--r--modules/virtualization.nix40
27 files changed, 1809 insertions, 0 deletions
diff --git a/modules/audio.nix b/modules/audio.nix
new file mode 100644
index 0000000..e926076
--- /dev/null
+++ b/modules/audio.nix
@@ -0,0 +1,96 @@
+{
+ flake.nixosModules.audio = { config, lib, pkgs, ... }:
+ let
+ cfg = config.os.core.audio;
+ in
+ {
+ options.os.core.audio = {
+ enable = lib.mkEnableOption "audio support";
+ disable-devices.enable = lib.mkEnableOption "disables some random devices cluttering up";
+ noise-cancellation.enable = lib.mkEnableOption "RNNoise background noise cancellation";
+ };
+
+ config = lib.mkMerge [
+ (lib.mkIf cfg.enable {
+ services.pulseaudio.enable = false;
+ security.rtkit.enable = true;
+
+ services.pipewire = {
+ enable = true;
+ audio.enable = true;
+ pulse.enable = true;
+ alsa = {
+ enable = true;
+ support32Bit = true;
+ };
+ jack.enable = true;
+
+ wireplumber = {
+ enable = true;
+ extraConfig."99-lock-microphone-gain"."pulse.rules" = [{
+ matches = [ { "application.name" = "~*cord*"; } ];
+ actions.quirks = [ "no-source-volume" ];
+ }];
+ };
+ };
+ services.playerctld.enable = true;
+
+ environment.systemPackages = with pkgs; [
+ crosspipe
+ pulsemixer
+ pavucontrol
+ alsa-utils
+ ];
+ })
+
+ (lib.mkIf cfg.disable-devices.enable {
+ services.pipewire.wireplumber.extraConfig = {
+ "99-disable-devices"."monitor.alsa.rules" = [{
+ matches = [
+ { "device.name" = "~alsa_card.pci-0000_03_00.1*"; }
+ { "device.description" = "~USB Audio*"; }
+ ];
+ actions.update-props."device.disabled" = true;
+ }];
+ };
+ })
+
+ (lib.mkIf cfg.noise-cancellation.enable {
+ services.pipewire.extraConfig.pipewire."99-rnnoise" = {
+ "context.modules" = [
+ {
+ name = "libpipewire-module-filter-chain";
+ args = {
+ "node.description" = "Noise Canceling Source";
+ "media.name" = "Noise Canceling Source";
+ "filter.graph".nodes = [
+ {
+ type = "ladspa";
+ name = "rnnoise";
+ plugin = "${pkgs.rnnoise-plugin}/lib/ladspa/librnnoise_ladspa.so";
+ label = "noise_suppressor_mono";
+ control = {
+ "VAD Threshold (%)" = 50.0;
+ "VAD Grace Period (ms)" = 200.0;
+ "Retroactive VAD Grace Period (ms)" = 0.0;
+ };
+ }
+ ];
+ "capture.props" = {
+ "node.name" = "effect_input.rnnoise";
+ "node.passive" = true;
+ "audio.position" = [ "MONO" ];
+ };
+ "playback.props" = {
+ "node.name" = "effect_output.rnnoise";
+ "media.class" = "Audio/Source";
+ "audio.position" = [ "MONO" ];
+ };
+ };
+ }
+ ];
+ };
+ })
+ ];
+ };
+}
diff --git a/modules/bluetooth.nix b/modules/bluetooth.nix
new file mode 100644
index 0000000..1705db6
--- /dev/null
+++ b/modules/bluetooth.nix
@@ -0,0 +1,19 @@
+{
+ config,
+ lib,
+ pkgs,
+ ...
+}:
+let
+ cfg = config.os.srv.bluetooth;
+in
+{
+ options.os.srv.bluetooth.enable = lib.mkEnableOption "enables bluetooth support";
+ config = lib.mkIf cfg.enable {
+ hardware.bluetooth = {
+ enable = true;
+ powerOnBoot = true;
+ };
+ environment.systemPackages = [ pkgs.bluetui ];
+ };
+}
diff --git a/modules/bootloader.nix b/modules/bootloader.nix
new file mode 100644
index 0000000..e8dfc11
--- /dev/null
+++ b/modules/bootloader.nix
@@ -0,0 +1,100 @@
+{
+ config,
+ lib,
+ ...
+}:
+let
+ cfg = config.os.core.bootloader;
+in
+{
+ options.os.core.bootloader = {
+ type = lib.mkOption {
+ type = lib.types.enum [
+ "systemd-boot"
+ "grub"
+ "none"
+ ];
+ default = "systemd-boot";
+ description = "Which bootloader to use";
+ };
+
+ efi = lib.mkOption {
+ type = lib.types.bool;
+ default = if cfg.grub.device == "nodev" then true else false;
+ description = "Whether the system uses UEFI or Legacy BIOS";
+ };
+
+ timeout = lib.mkOption {
+ type = lib.types.int;
+ default = 3;
+ description = "Boot menu timeout in seconds";
+ };
+
+ grub = {
+ device = lib.mkOption {
+ type = lib.types.str;
+ default = "nodev";
+ description = "Device to install GRUB to (e.g. /dev/nvme0n1). Use 'nodev' for UEFI.";
+ };
+ useOSProber = lib.mkOption {
+ type = lib.types.bool;
+ default = false;
+ description = "Scan for other operating systems";
+ };
+ defaultEntry = lib.mkOption {
+ type = lib.types.int;
+ default = 0;
+ description = "Index of the default boot entry";
+ };
+ };
+
+ #TODO add boot.initrd.luks.reusePassphrases = true; somewhere
+ luks.enable = lib.mkEnableOption "LUKS encryption support";
+ };
+
+ config = lib.mkMerge [
+ # 1. Common Kernel & Initrd Settings
+ {
+ boot = {
+ loader = {
+ timeout = cfg.timeout;
+ efi.canTouchEfiVariables = lib.mkDefault cfg.efi;
+ };
+ supportedFilesystems = [
+ "ntfs"
+ "btrfs"
+ ];
+ kernelParams = [
+ "quiet"
+ "splash"
+ ];
+ consoleLogLevel = 0;
+ initrd.availableKernelModules = [
+ "aesni_intel"
+ "cryptd"
+ ];
+ };
+ systemd.settings.Manager.DefaultTimeoutStopSec = "5s";
+ }
+
+ # 2. Systemd-boot Implementation
+ (lib.mkIf (cfg.type == "systemd-boot") {
+ boot.loader.systemd-boot = {
+ enable = true;
+ editor = false;
+ consoleMode = "max";
+ };
+ })
+
+ # 3. GRUB Implementation
+ (lib.mkIf (cfg.type == "grub") {
+ boot.loader.grub = {
+ enable = true;
+ efiSupport = cfg.efi;
+ useOSProber = cfg.grub.useOSProber;
+ default = cfg.grub.defaultEntry;
+ enableCryptodisk = cfg.luks.enable;
+ };
+ })
+ ];
+}
diff --git a/modules/compat.nix b/modules/compat.nix
new file mode 100644
index 0000000..1ea6105
--- /dev/null
+++ b/modules/compat.nix
@@ -0,0 +1,28 @@
+{
+ config,
+ lib,
+ pkgs,
+ ...
+}:
+let
+ cfg = config.os.srv.compat;
+in
+{
+ options.os.srv.compat.enable = lib.mkEnableOption "enables compatibility with windows & x11";
+ config = lib.mkIf cfg.enable {
+ programs.xwayland = {
+ enable = true;
+ package = pkgs.xwayland-satellite;
+ };
+
+ environment.systemPackages = with pkgs; [
+ wineWow64Packages.stagingFull
+ winetricks
+ ];
+
+ environment.sessionVariables = {
+ NIXOS_OZONE_WL = "1";
+ ELECTRON_ENABLE_WAYLAND = "1";
+ };
+ };
+}
diff --git a/modules/drivers.nix b/modules/drivers.nix
new file mode 100644
index 0000000..6e74e98
--- /dev/null
+++ b/modules/drivers.nix
@@ -0,0 +1,99 @@
+{
+ config,
+ lib,
+ pkgs,
+ ...
+}:
+let
+ cfg = config.os.core.drivers;
+in
+{
+ options.os.core.drivers = {
+ enable = lib.mkEnableOption "enables hardware drivers";
+
+ cpu = lib.mkOption {
+ type = lib.types.enum [
+ "intel"
+ "amd"
+ "none"
+ ];
+ default = "none";
+ description = "cpu manufacturer for microcode and platform-specific drivers";
+ };
+
+ graphics = {
+ enable = lib.mkEnableOption "graphics support";
+ amdgpu.enable = lib.mkEnableOption "amd specific gpu features";
+ };
+
+ kernel = lib.mkOption {
+ type = lib.types.enum [
+ "stable"
+ "zen"
+ "zfs"
+ "hardened"
+ ];
+ default = "stable";
+ };
+ };
+
+ config = lib.mkIf cfg.enable (
+ lib.mkMerge [
+ {
+ hardware.enableAllFirmware = true;
+ services = {
+ smartd.enable = true;
+ fwupd.enable = true;
+ };
+ environment.systemPackages = [ pkgs.rivalcfg ];
+ }
+
+ (lib.mkIf (cfg.cpu == "amd") {
+ hardware.cpu.amd.updateMicrocode = true;
+ programs.coolercontrol.enable = true;
+ })
+
+ (lib.mkIf (cfg.cpu == "intel") {
+ hardware.cpu.intel.updateMicrocode = true;
+ services.thermald.enable = true;
+ })
+
+ (lib.mkIf cfg.graphics.enable {
+ hardware.graphics = {
+ enable = true;
+ enable32Bit = true;
+ };
+ hardware.sensor.iio.enable = true;
+ })
+
+ (lib.mkIf (cfg.graphics.enable && cfg.graphics.amdgpu.enable) {
+ services = {
+ lact.enable = true;
+ hardware.openrgb.enable = true;
+ };
+ hardware = {
+ amdgpu = {
+ initrd.enable = true;
+ overdrive.enable = true;
+ };
+ graphics.extraPackages = with pkgs; [
+ rocmPackages.clr.icd
+ libva-utils
+ ];
+ };
+ })
+ {
+ boot.kernelPackages =
+ let
+ kernels = {
+ "stable" = pkgs.linuxPackages_latest;
+ "zen" = pkgs.linuxPackages_zen;
+ "hardened" = pkgs.linuxPackages_hardened;
+ "zfs" = config.boot.zfs.package.latestCompatibleLinuxPackages;
+ };
+ in
+ kernels.${cfg.kernel} or kernels."stable";
+ }
+ ]
+ );
+}
diff --git a/modules/files.nix b/modules/files.nix
new file mode 100644
index 0000000..777a394
--- /dev/null
+++ b/modules/files.nix
@@ -0,0 +1,55 @@
+{
+ config,
+ lib,
+ pkgs,
+ ...
+}:
+let
+ cfg = config.os.srv.files;
+in
+{
+ options.os.srv.files = {
+ enable = lib.mkEnableOption "enables general file management stuff";
+ localsend.enable = lib.mkEnableOption "enables localsend for sharing files locally";
+ krusader.enable = lib.mkEnableOption "enables krusader for easier file moving using ssh";
+ };
+ config = lib.mkMerge [
+ (lib.mkIf cfg.enable {
+ # programs.thunar = {
+ # enable = true;
+ # plugins = with pkgs; [
+ # ffmpegthumbnailer
+ # libgsf
+ # poppler
+ # freetype
+ # webp-pixbuf-loader
+ # thunar-volman
+ # thunar-archive-plugin
+ # ];
+ # };
+ services = {
+ tumbler.enable = true;
+ gvfs.enable = true;
+ };
+ environment.systemPackages = with pkgs; [
+ pcmanfm
+ file-roller
+ gdu
+ pxz
+ ripunzip
+ ];
+ })
+ (lib.mkIf cfg.localsend.enable {
+ programs.localsend = {
+ enable = true;
+ openFirewall = true;
+ };
+ })
+ (lib.mkIf cfg.krusader.enable {
+ environment.systemPackages = with pkgs; [
+ krusader
+ kdePackages.kio-extras
+ ];
+ })
+ ];
+}
diff --git a/modules/fonts.nix b/modules/fonts.nix
new file mode 100644
index 0000000..344ff63
--- /dev/null
+++ b/modules/fonts.nix
@@ -0,0 +1,32 @@
+{
+ config,
+ lib,
+ pkgs,
+ ...
+}:
+let
+ cfg = config.os.core.fonts;
+in
+{
+ options.os.core.fonts.enable = lib.mkEnableOption "system-wide font and console configuration";
+
+ config = lib.mkIf cfg.enable {
+ # console = {
+ # keyMap = "pl";
+ # earlySetup = true;
+ # font = "ter-v32n";
+ # packages = with pkgs; [ terminus_font ];
+ # };
+
+ fonts.packages = with pkgs; [
+ nerd-fonts.jetbrains-mono
+ nerd-fonts.fira-mono
+ nerd-fonts.fira-code
+
+ noto-fonts
+ noto-fonts-cjk-sans
+ noto-fonts-cjk-serif
+ noto-fonts-color-emoji
+ ];
+ };
+}
diff --git a/modules/gaming.nix b/modules/gaming.nix
new file mode 100644
index 0000000..b9b6766
--- /dev/null
+++ b/modules/gaming.nix
@@ -0,0 +1,145 @@
+{
+ config,
+ lib,
+ pkgs,
+ username,
+ inputs,
+ ...
+}:
+let
+ cfg = config.os.srv.gaming;
+in
+{
+ options.os.srv.gaming = {
+ enable = lib.mkEnableOption "enables general gaming support";
+
+ tools.enable = lib.mkEnableOption "enables performance tools" // {
+ default = cfg.enable;
+ };
+ launchers.enable = lib.mkEnableOption "enables 3rd party launchers" // {
+ default = cfg.enable;
+ };
+ games.enable = lib.mkEnableOption "enables specific native games";
+ steam = {
+ enable = lib.mkEnableOption "enables the steam launcher";
+ enableSls = lib.mkEnableOption "enables the SLS Steam library modification";
+ };
+ vr.enable = lib.mkEnableOption "enables vr support";
+ };
+
+ config = lib.mkMerge [
+ # --- PERFORMANCE & TOOLING ---
+ (lib.mkIf cfg.tools.enable {
+ hardware.xone.enable = true;
+ programs = {
+ gamescope = {
+ enable = true;
+ capSysNice = true;
+ };
+
+ gamemode = {
+ enable = true;
+ enableRenice = true;
+ settings = {
+ general.renice = 10;
+ };
+ };
+ };
+ environment = {
+ sessionVariables = {
+ OPTISCALER_ShortcutKey = "0x24"; # sets the optiscaler shortcut key to be home by default
+ };
+
+ systemPackages = with pkgs; [
+ mangohud
+ theclicker
+ ludusavi
+ protonplus
+ ];
+ };
+ })
+
+ # --- EXTERNAL LAUNCHERS ---
+ (lib.mkIf cfg.launchers.enable {
+ environment.systemPackages = with pkgs; [
+ heroic
+ (prismlauncher.override {
+ additionalLibs = with pkgs; [ ocl-icd ];
+ jdks = with pkgs; [ javaPackages.compiler.temurin-bin.jdk-26 ];
+ })
+ ];
+ })
+
+ # --- SPECIFIC GAMES ---
+ (lib.mkIf cfg.games.enable {
+ environment.systemPackages = with inputs.openmw-nix.packages.${pkgs.stdenv.hostPlatform.system}; [
+ (pkgs.openttd-jgrpp)
+
+ # OpenMW Specific
+ (pkgs.openmw)
+ (pkgs.tes3cmd)
+ delta-plugin
+ groundcoverify
+ momw-configurator
+ openmw-validator
+ s3lightfixes
+ umo
+ ];
+ })
+
+ # --- STEAM ---
+ (lib.mkIf cfg.steam.enable (
+ lib.mkMerge [
+ {
+ programs.steam = {
+ enable = true;
+ localNetworkGameTransfers.openFirewall = true;
+ dedicatedServer.openFirewall = true;
+ remotePlay.openFirewall = false;
+ extest.enable = true;
+ protontricks.enable = true;
+ };
+ environment.systemPackages = with pkgs; [ steamtinkerlaunch ];
+ }
+
+ (lib.mkIf cfg.steam.enableSls {
+ environment.systemPackages = [
+ inputs.sls-steam.packages.${pkgs.stdenv.hostPlatform.system}.wrapped
+ ];
+ home-manager.users.${username} = {
+ xdg.desktopEntries = {
+ steam = {
+ name = "Steam";
+ comment = "Library modified Steam client";
+ exec = "${
+ lib.getExe' inputs.sls-steam.packages.${pkgs.stdenv.hostPlatform.system}.wrapped "SLSsteam"
+ } %U";
+ icon = "steam";
+ terminal = false;
+ type = "Application";
+ categories = [
+ "Game"
+ "Utility"
+ ];
+ mimeType = [ "x-scheme-handler/steamcmd" ];
+ };
+ };
+ };
+ })
+ ]
+ ))
+
+ # --- VR SUPPORT ---
+ (lib.mkIf cfg.vr.enable {
+ services.wivrn = {
+ enable = true;
+ openFirewall = true;
+ highPriority = true;
+ steam.importOXRRuntimes = true;
+ # defaultRuntime = true;
+ };
+ environment.systemPackages = [ pkgs.android-tools ];
+ users.users.${username}.extraGroups = [ "adbusers" ];
+ })
+ ];
+}
diff --git a/modules/greet.nix b/modules/greet.nix
new file mode 100644
index 0000000..1c01b68
--- /dev/null
+++ b/modules/greet.nix
@@ -0,0 +1,32 @@
+{
+ config,
+ lib,
+ pkgs,
+ ...
+}:
+let
+ cfg = config.os.core.greet;
+in
+{
+ options.os.core.greet.enable = lib.mkEnableOption "enables greetd daemon with tuigreet";
+ config = lib.mkIf cfg.enable {
+ services.greetd = {
+ enable = true;
+ settings = {
+ default_session = {
+ user = "greeter";
+ command = lib.concatStringsSep " " [
+ "${pkgs.tuigreet}/bin/tuigreet"
+ "--sessions ${config.services.displayManager.sessionData.desktops}/share/xsessions:${config.services.displayManager.sessionData.desktops}/share/wayland-sessions"
+ "--remember"
+ "--remember-user-session"
+ "--asterisks"
+ "--greeting 'Welcome to NixOS!'"
+ "--time"
+ ];
+ };
+ };
+ };
+ security.pam.services.greetd.enableGnomeKeyring = true;
+ };
+}
diff --git a/modules/i2p.nix b/modules/i2p.nix
new file mode 100644
index 0000000..5e36c20
--- /dev/null
+++ b/modules/i2p.nix
@@ -0,0 +1,81 @@
+{
+ config,
+ lib,
+ masterDomain,
+ securityTemplates,
+ ...
+}:
+let
+ cfg = config.os.srv.i2p;
+in
+{
+ options.os.srv.i2p = {
+ enable = lib.mkEnableOption "enables a flexible, polymorphic i2pd deployment profile";
+
+ mode = lib.mkOption {
+ type = lib.types.enum [
+ "server"
+ "client"
+ ];
+ default = "client";
+ description = "";
+ };
+ };
+
+ config = lib.mkIf cfg.enable (
+ lib.mkMerge [
+ {
+ services.i2pd = {
+ enable = true;
+ enableIPv6 = true;
+ reseed.verify = true;
+
+ yggdrasil.enable = true;
+
+ proto = {
+ http.enable = true;
+ httpProxy.enable = true;
+ socksProxy = {
+ enable = true;
+ outproxyEnable = true;
+ };
+ sam.enable = true;
+ i2pControl.enable = true;
+ };
+ };
+ }
+
+ (lib.mkIf (cfg.mode == "server") {
+ services.i2pd = {
+ bandwidth = 4096;
+
+ ntcp2.published = true;
+ ssu2.published = true;
+
+ #TODO add address
+ yggdrasil.address = "";
+ };
+
+ os.cluster.nginxProxies."i2p.${masterDomain}" = {
+ enableACME = true;
+ forceSSL = true;
+ locations."/" = {
+ proxyPass = "http://${config.os.core.network.ips.relay-vm}:7070";
+ extraConfig = securityTemplates.restrictToInternal;
+ };
+ };
+ })
+
+ (lib.mkIf (cfg.mode == "client") {
+ services.i2pd = {
+ bandwidth = 512;
+
+ ntcp2.published = false;
+ ssu2.published = false;
+
+ yggdrasil.address = "";
+ };
+ })
+ ]
+ );
+}
diff --git a/modules/localization.nix b/modules/localization.nix
new file mode 100644
index 0000000..49933fa
--- /dev/null
+++ b/modules/localization.nix
@@ -0,0 +1,41 @@
+{ config, lib, ... }:
+let
+ cfg = config.os.core.locale;
+in
+{
+ options.os.core.locale = {
+ enable = lib.mkEnableOption "system localization (timezone and language)";
+
+ timeZone = lib.mkOption {
+ type = lib.types.str;
+ default = "Europe/Warsaw";
+ description = "the system timezone.";
+ };
+
+ format = lib.mkOption {
+ type = lib.types.str;
+ default = "pl_PL.UTF-8";
+ description = "the locale used for numbers, time, and measurements.";
+ };
+ };
+ config = lib.mkIf cfg.enable {
+ time.timeZone = cfg.timeZone;
+
+ i18n = {
+ defaultLocale = "en_US.UTF-8";
+
+ extraLocaleSettings = {
+ LC_TIME = cfg.format;
+ LC_NUMERIC = cfg.format;
+ LC_MONETARY = cfg.format;
+ LC_PAPER = cfg.format;
+ LC_MEASUREMENT = cfg.format;
+ LC_COLLATE = cfg.format;
+ LC_NAME = cfg.format;
+ LC_ADDRESS = cfg.format;
+ LC_TELEPHONE = cfg.format;
+ LC_IDENTIFICATION = cfg.format;
+ };
+ };
+ };
+}
diff --git a/modules/memory.nix b/modules/memory.nix
new file mode 100644
index 0000000..b20ec8a
--- /dev/null
+++ b/modules/memory.nix
@@ -0,0 +1,41 @@
+{ config, lib, ... }:
+let
+ cfg = config.os.core.memory;
+in
+{
+ options.os.core.memory = {
+ zram = {
+ enable = lib.mkEnableOption "enables zram compression";
+ percent = lib.mkOption {
+ type = lib.types.int;
+ default = 25;
+ };
+ };
+
+ swapfile = {
+ enable = lib.mkEnableOption "enables a swapfile";
+ size = lib.mkOption {
+ type = lib.types.int;
+ default = 8;
+ };
+ };
+ };
+ config = lib.mkMerge [
+ (lib.mkIf cfg.zram.enable {
+ zramSwap = {
+ enable = true;
+ algorithm = "zstd";
+ memoryPercent = cfg.zram.percent;
+ priority = 100;
+ };
+ })
+
+ (lib.mkIf cfg.swapfile.enable {
+ swapDevices = [ {
+ device = "/.swapvol/swapfile";
+ size = cfg.swapfile.size * 1024;
+ priority = 0;
+ } ];
+ })
+ ];
+}
diff --git a/modules/monero.nix b/modules/monero.nix
new file mode 100644
index 0000000..eb21abc
--- /dev/null
+++ b/modules/monero.nix
@@ -0,0 +1,124 @@
+{
+ config,
+ lib,
+ pkgs,
+ masterDomain,
+ securityTemplates,
+ ...
+}:
+let
+ cfg = config.os.srv.monero;
+ banlist1 = pkgs.fetchurl {
+ url = "https://gui.xmr.pm/files/block.txt";
+ hash = "sha256-0ik4d66js6wvrvciza0li6bsajj8dvxsqlf09hcz7hg610szdxcw";
+ };
+ banlist2 = pkgs.fetchurl {
+ url = "https://raw.githubusercontent.com/Boog900/monero-ban-list/refs/heads/main/ban_list.txt";
+ hash = "sh256-01z4wm2mp4z1wq2wdkrm66j50gwk3r82m2ml4n0pwjcbajxkdc87";
+ };
+
+ combinedBanlist = pkgs.writeText "combined-monero-banlist.txt" ''
+ ${builtins.readFile banlist1}
+ ${builtins.readFile banlist2}
+ '';
+in
+{
+ options.os.srv.monero = {
+ wallet.enable = lib.mkEnableOption "enables the monero wallet";
+ service = {
+ enable = lib.mkEnableOption "enables hosting a monero node";
+ public = lib.mkEnableOption "makes the RPC node public (disables authentication for general wallet syncing)";
+ tor.enable = lib.mkEnableOption "exposes monero RPC via Tor Onion Service";
+ i2p.enable = lib.mkEnableOption "exposes monero RPC via I2P Tunnel";
+ };
+ };
+
+ config = lib.mkMerge [
+ (lib.mkIf cfg.wallet.enable {
+ environment.systemPackages = [ pkgs.monero-cli ];
+ })
+ (lib.mkIf cfg.service.enable {
+ assertions = [
+ {
+ assertion = if (!cfg.service.public) then config.os.srv.sops.enable else true;
+ message = "sops must be enabled";
+ }
+ {
+ assertion = if cfg.service.tor.enable then config.os.srv.tor.enable else true;
+ message = "tor must be enabled";
+ }
+ {
+ assertion = if cfg.service.i2p.enable then config.os.srv.i2p.enable else true;
+ message = "i2p must be enabled";
+ }
+ ];
+
+ sops.secrets."monero/rpc-password" = {
+ owner = "monero";
+ restartUnits = [ "monero.service" ];
+ };
+
+ services.monero = {
+ enable = true;
+ prune = true;
+ banlist = combinedBanlist;
+
+ limits = {
+ upload = 1250;
+ download = 12500;
+ threads = 8;
+ };
+
+ rpc = {
+ address = "0.0.0.0";
+ }
+ // lib.optionalAttrs (!cfg.service.public) {
+ restricted = true;
+ user = "admin";
+ password = config.sops.secrets."monero/rpc-password".path;
+ };
+
+ };
+
+ services.tor = lib.mkIf cfg.service.tor.enable {
+ # onionServices."xmr-rpc" = {
+ # to = [
+ # {
+ # port = 18081;
+ # address = config.os.core.network.ips.relay-vm;
+ # }
+ # ];
+ # };
+ };
+
+ services.i2pd = lib.mkIf cfg.service.i2p.enable {
+ # tunnels.server."xmr-rpc" = {
+ # port = 18081;
+ # address = config.os.core.network.ips.relay-vm;
+ # keys = "xmr-rpc-key.dat";
+ # inbound.length = 3;
+ # outbound.length = 3;
+ # };
+ };
+
+ os.cluster.nginxProxies."xmr.${masterDomain}" = {
+ enableACME = true;
+ forceSSL = true;
+
+ locations."/" = {
+ proxyPass = "http://${config.os.core.network.ips.relay-vm}:18081";
+ extraConfig = ''
+ proxy_read_timeout 600s;
+ proxy_send_timeout 600s;
+ client_max_body_size 50m;
+
+ ${securityTemplates.restrictToInternal}
+ '';
+ };
+ };
+
+ # Left open for P2P syncing
+ networking.firewall.allowedTCPPorts = [ 18080 ];
+ })
+ ];
+}
diff --git a/modules/networking.nix b/modules/networking.nix
new file mode 100644
index 0000000..9e4c329
--- /dev/null
+++ b/modules/networking.nix
@@ -0,0 +1,186 @@
+{
+ config,
+ lib,
+ pkgs,
+ ...
+}:
+let
+ cfg = config.os.core.network;
+in
+{
+ options.os.core.network = {
+ enable = lib.mkEnableOption "system-wide networking setup";
+ enableFirewall = lib.mkEnableOption "integrated zero-trust nftables firewall layers";
+
+ isVM = lib.mkOption {
+ type = lib.types.bool;
+ default = false;
+ description = "Set to true if this configuration is running inside a guest VM. Set to false for the bare-metal host.";
+ };
+
+ ips = lib.mkOption {
+ type = lib.types.attrsOf lib.types.str;
+ default = {
+ bare-metal = "10.0.0.2";
+ opnsense-vm = "10.0.0.1";
+ gateway-vm = "10.0.0.3";
+ auth-vm = "10.0.0.4";
+ database-vm = "10.0.0.5";
+ monitor-vm = "10.0.0.6";
+ media-vm = "10.0.0.7";
+ torrent-vm = "10.0.0.8";
+ storage-vm = "10.0.0.9";
+ web-vm = "10.0.0.10";
+ comm-vm = "10.0.0.11";
+ mail-vm = "10.0.0.12";
+ relay-vm = "10.0.0.13";
+ gameserver-vm = "10.0.0.14";
+ };
+ description = "Central registry of static IP allocations for the cluster.";
+ };
+
+ profile = lib.mkOption {
+ type = lib.types.enum [
+ "client"
+ "server"
+ ];
+ default = "client";
+ description = "Which networking profile configuration to apply";
+ };
+
+ lan = lib.mkOption {
+ description = "Physical Home Local Area Network configuration parameters.";
+ type = lib.types.submodule {
+ options = {
+ ip = lib.mkOption {
+ type = lib.types.str;
+ default = "10.0.0.2";
+ description = "The local static or leased IP assigned to this machine on the home network.";
+ };
+ range = lib.mkOption {
+ type = lib.types.str;
+ default = "10.0.0.0/24";
+ description = "The broader subnet block representing the physical home network.";
+ };
+ };
+ };
+ };
+
+ wg = lib.mkOption {
+ description = "Standard WireGuard VPN tunnel configuration parameters.";
+ type = lib.types.submodule {
+ options = {
+ ip = lib.mkOption {
+ type = lib.types.str;
+ default = "10.3.0.1";
+ description = "The explicit tunnel IP address assigned to this machine's WireGuard interface.";
+ };
+ range = lib.mkOption {
+ type = lib.types.str;
+ default = "10.3.0.0/24";
+ description = "The total addressable IP space assigned to the WireGuard network pool.";
+ };
+ };
+ };
+ };
+
+ hs = lib.mkOption {
+ description = "Headscale mesh overlay network configuration parameters.";
+ type = lib.types.submodule {
+ options = {
+ ip = lib.mkOption {
+ type = lib.types.str;
+ default = "10.4.0.1";
+ description = "The explicit mesh network IP address assigned to this machine via Headscale.";
+ };
+ range = lib.mkOption {
+ type = lib.types.str;
+ default = "10.4.0.0/24";
+ description = "The full mesh overlay allocation subnet block.";
+ };
+ };
+ };
+ };
+ };
+
+ config = lib.mkIf cfg.enable (
+ lib.mkMerge [
+ {
+ services.resolved.enable = true;
+ }
+
+ (lib.mkIf (cfg.profile == "client") {
+ networking.networkmanager = {
+ enable = true;
+ dns = "systemd-resolved";
+ wifi.macAddress = "random";
+ wifi.backend = "iwd";
+ ethernet.macAddress = "random";
+ };
+
+ systemd.services."NetworkManager-wait-online".enable = false;
+
+ environment.systemPackages = [
+ pkgs.impala
+ ];
+ })
+
+ (lib.mkIf (cfg.profile == "client" && cfg.enableFirewall) {
+ networking = {
+ firewall.enable = true;
+ nftables.enable = true;
+ };
+ })
+
+ (lib.mkIf (cfg.profile == "server") {
+ networking = {
+ useNetworkd = true;
+ useDHCP = false;
+ };
+ systemd.network = {
+ enable = true;
+ wait-online.enable = lib.mkIf (!cfg.isVM) false;
+
+ netdevs = lib.mkIf (!cfg.isVM) {
+ "10-br-srv" = {
+ netdevConfig = {
+ Name = "br-srv";
+ Kind = "bridge";
+ };
+ };
+ };
+ networks."20-host-management" = {
+ matchConfig.Name = if cfg.isVM then "eth0" else "br-srv";
+ address = [ "${cfg.lan.ip}/24" ];
+ gateway = [ cfg.ips.router ];
+ networkConfig.LinkLocalAddressing = "no";
+ };
+ };
+ boot.kernel.sysctl = {
+ "net.ipv4.ip_nonlocal_bind" = 1;
+ "net.ipv4.ip_forward" = 1;
+ };
+ })
+ (lib.mkIf
+ (
+ cfg.profile == "server"
+ && cfg.enableFirewall
+ && cfg.isVM
+ && config.networking.hostName != "vm2-gateway"
+ )
+ {
+ networking.nftables.enable = true;
+ networking.firewall = {
+ enable = true;
+ extraCommands = ''
+ nft add table ip nat 2>/dev/null || true
+ nft flush table ip nat
+ nft add chain ip nat PREROUTING { type nat hook prerouting priority dstnat \; }
+ nft add rule ip nat PREROUTING ip saddr ${cfg.ips.vm2-gateway} ip daddr ${cfg.lan.ip} redirect
+ '';
+ };
+ }
+ )
+ ]
+ );
+}
diff --git a/modules/niri.nix b/modules/niri.nix
new file mode 100644
index 0000000..58d27af
--- /dev/null
+++ b/modules/niri.nix
@@ -0,0 +1,28 @@
+{
+ inputs,
+ config,
+ lib,
+ username,
+ pkgs,
+ ...
+}:
+let
+ cfg = config.os.wm.niri;
+in
+{
+ imports = [ inputs.niri.nixosModules.niri ];
+
+ options.os.wm.niri.enable = lib.mkEnableOption "Niri";
+
+ config = lib.mkIf cfg.enable {
+ nixpkgs.overlays = [ inputs.niri.overlays.niri ];
+
+ programs.niri = {
+ enable = true;
+ package = pkgs.niri-unstable;
+ };
+
+ os.srv.compat.enable = true;
+ home-manager.users.${username}.hm.env.niri.enable = true;
+ };
+}
diff --git a/modules/nix-helper.nix b/modules/nix-helper.nix
new file mode 100644
index 0000000..5e5e133
--- /dev/null
+++ b/modules/nix-helper.nix
@@ -0,0 +1,40 @@
+{
+ config,
+ lib,
+ pkgs,
+ username,
+ ...
+}:
+let
+ cfg = config.os.srv.nix-helper;
+in
+{
+ options.os.srv.nix-helper.enable = lib.mkEnableOption "enables nix-helper";
+ config = lib.mkIf cfg.enable {
+ nix.settings = {
+ trusted-users = [
+ "root"
+ "${username}"
+ ];
+ experimental-features = [
+ "nix-command"
+ "flakes"
+ ];
+ };
+
+ programs.nh = {
+ enable = true;
+ flake = "/etc/nixos";
+ clean.extraArgs = "--keep 5";
+ };
+
+ environment.sessionVariables = {
+ NH_OS_FLAKE = "/etc/nixos";
+ };
+
+ environment.systemPackages = with pkgs; [
+ nix-output-monitor
+ nvd
+ ];
+ };
+}
diff --git a/modules/omnisearch.nix b/modules/omnisearch.nix
new file mode 100644
index 0000000..ac36184
--- /dev/null
+++ b/modules/omnisearch.nix
@@ -0,0 +1,73 @@
+{
+ config,
+ lib,
+ inputs,
+ masterDomain,
+ templates,
+ ...
+}:
+let
+ cfg = config.os.srv.omnisearch;
+in
+{
+ imports = [ inputs.omnisearch.nixosModules.default ];
+
+ options.os.srv.omnisearch = {
+ enable = lib.mkEnableOption "enables omnisearch tracking infrastructure";
+
+ role = lib.mkOption {
+ type = lib.types.enum [
+ "server"
+ "standalone"
+ ];
+ default = "standalone";
+ description = "Designates the deployment method";
+ };
+ };
+
+ config = lib.mkIf cfg.enable (
+ lib.mkMerge [
+ {
+ services.omnisearch = {
+ enable = true;
+ settings = {
+ server = {
+ host = "127.0.0.1";
+ port = 8087;
+ locale = "en";
+ domain = if cfg.role == "server" then "https://search.${masterDomain}" else "http://localhost:8087";
+ };
+ proxy = {
+ max_retries = 3;
+ randomize_username = true;
+ randomize_password = true;
+ };
+ cache = {
+ dir = "/var/cache/omnisearch";
+ ttl_search = 1800;
+ ttl_infobox = 86400;
+ };
+ };
+ };
+ }
+
+ (lib.mkIf (cfg.role == "server") {
+ assertions = [
+ {
+ assertion = config.os.srv.nginx.enable;
+ message = "Required for proxying";
+ }
+ ];
+ services.nginx.virtualHosts."search.${masterDomain}" = {
+ enableACME = true;
+ forceSSL = true;
+ locations."/" = {
+ proxyPass = "http://127.0.0.1:8087";
+ proxyWebsockets = true;
+ extraConfig = templates.restrictToInternal;
+ };
+ };
+ })
+ ]
+ );
+}
diff --git a/modules/persistance.nix b/modules/persistance.nix
new file mode 100644
index 0000000..89f3702
--- /dev/null
+++ b/modules/persistance.nix
@@ -0,0 +1,50 @@
+{
+ config,
+ lib,
+ inputs,
+ ...
+}:
+let
+ cfg = config.os.srv.persistance;
+in
+{
+ imports = [ inputs.impermanence.nixosModules.impermanence ];
+
+ options.os.srv.persistance.enable = lib.mkEnableOption "enables persistance drive maintnance";
+ config = lib.mkMerge [
+ (lib.mkIf cfg.enable {
+ environment.persistence."/persist" = {
+ hideMounts = true;
+ directories = [
+ "/var/lib/nixos"
+ "/var/lib/systemd"
+ "/var/lib/microvm"
+ ];
+ files = [
+ "/etc/machine-id"
+ ];
+ };
+ })
+ (lib.mkIf (cfg.enable && config.os.srv.ssh.server.enable) {
+ environment.persistence."/persist" = {
+ files = [
+ "/etc/ssh/ssh_host_ed25519_key"
+ "/etc/ssh/ssh_host_ed25519_key.pub"
+ ];
+ };
+ })
+ (lib.mkIf (cfg.enable && config.os.srv.crowdsec.agent.enable) {
+ environment.persistence."/persist" = lib.mkIf cfg.agent.enable {
+ hideMounts = true;
+ directories = [
+ {
+ directory = "/var/lib/crowdsec";
+ user = "crowdsec";
+ group = "crowdsec";
+ mode = "0750";
+ }
+ ];
+ };
+ })
+ ];
+}
diff --git a/modules/power.nix b/modules/power.nix
new file mode 100644
index 0000000..b3dbf91
--- /dev/null
+++ b/modules/power.nix
@@ -0,0 +1,54 @@
+{
+ config,
+ lib,
+ ...
+}:
+let
+ cfg = config.os.core.power;
+in
+{
+ options.os.core.power = {
+ enable = lib.mkEnableOption "enables power management";
+ mode = lib.mkOption {
+ type = lib.types.enum [
+ "amd"
+ "intel"
+ "none"
+ ];
+ default = "none";
+ };
+ };
+
+ config = lib.mkIf cfg.enable (
+ lib.mkMerge [
+ {
+ powerManagement.powertop.enable = true;
+ boot.kernelParams = [ "nvme_core.default_ps_max_latency_us=0" ];
+ }
+
+ (lib.mkIf (cfg.mode == "amd") {
+ services.power-profiles-daemon.enable = true;
+ boot.kernelParams = [ "amd_pstate=active" ];
+ })
+
+ (lib.mkIf (cfg.mode == "intel") {
+ services = {
+ power-profiles-daemon.enable = false;
+
+ thermald.enable = true;
+ tlp = {
+ enable = true;
+ settings = {
+ START_CHARGE_THRESH_BAT0 = 75;
+ STOP_CHARGE_THRESH_BAT0 = 80;
+ START_CHARGE_THRESH_BAT1 = 75;
+ STOP_CHARGE_THRESH_BAT1 = 80;
+ CPU_SCALING_GOVERNOR_ON_AC = "performance";
+ CPU_SCALING_GOVERNOR_ON_BAT = "powersave";
+ };
+ };
+ };
+ })
+ ]
+ );
+}
diff --git a/modules/security.nix b/modules/security.nix
new file mode 100644
index 0000000..33aa919
--- /dev/null
+++ b/modules/security.nix
@@ -0,0 +1,72 @@
+{
+ config,
+ lib,
+ pkgs,
+ username,
+ ...
+}:
+let
+ cfg = config.os.core.security;
+in
+{
+ options.os.core.security = {
+ enable = lib.mkEnableOption "core security services";
+ antivirus.enable = lib.mkEnableOption "enables clamav antivirus";
+ sandboxing.enable = lib.mkEnableOption "enables sandboxing stuff";
+ };
+ config = lib.mkIf cfg.enable (
+ lib.mkMerge [
+ {
+ security = {
+ polkit.enable = true;
+ rtkit.enable = true;
+ doas = {
+ enable = true;
+ extraRules = [
+ {
+ users = [ username ];
+ keepEnv = true;
+ persist = true;
+ }
+ ];
+ };
+ # sudo.enable = false;
+ pam.services = {
+ swaylock = { };
+ login.enableGnomeKeyring = true;
+ };
+ };
+ # environment.systemPackages = [ pkgs.doas-sudo-shim ];
+ }
+ (lib.mkIf cfg.sandboxing.enable {
+ security.apparmor = {
+ enable = true;
+ enableCache = true;
+ killUnconfinedConfinables = true;
+ packages = with pkgs; [
+ apparmor-profiles
+ roddhjav-apparmor-rules
+ ];
+ };
+ services.dbus.apparmor = "enabled";
+ specialisation.no-apparmor.configuration.security.apparmor.enable = lib.mkForce false;
+
+ programs.firejail.enable = true;
+ environment.systemPackages = with pkgs; [
+ apparmor-utils
+ apparmor-parser
+ apparmor-bin-utils
+ ];
+ })
+ {
+ services.gnome.gnome-keyring.enable = true;
+
+ environment.systemPackages = with pkgs; [
+ veracrypt
+ gocryptfs
+ keepassxc
+ ];
+ }
+ ]
+ );
+}
diff --git a/modules/sops.nix b/modules/sops.nix
new file mode 100644
index 0000000..3ca2d16
--- /dev/null
+++ b/modules/sops.nix
@@ -0,0 +1,36 @@
+{
+ config,
+ lib,
+ pkgs,
+ inputs,
+ username,
+ ...
+}:
+let
+ cfg = config.os.srv.sops;
+in
+{
+ imports = [ inputs.sops-nix.nixosModules.sops ];
+
+ options.os.srv.sops.enable = lib.mkEnableOption "enables sops-nix";
+ config = lib.mkIf cfg.enable {
+ sops = {
+ defaultSopsFile = ../../secrets/common.yaml;
+ defaultSopsFormat = "yaml";
+ age.sshKeyPaths = [ "/etc/ssh/ssh_host_ed25519_key" ];
+
+ secrets = {
+ # "syncthing/gui_password".owner = username;
+ "syncthing/encryption/keepass".owner = username;
+ "syncthing/encryption/sync".owner = username;
+ "obs/websocket_password".owner = username;
+ };
+ };
+
+ environment.systemPackages = with pkgs; [
+ sops
+ age
+ ssh-to-age
+ ];
+ };
+}
diff --git a/modules/ssh.nix b/modules/ssh.nix
new file mode 100644
index 0000000..63b2034
--- /dev/null
+++ b/modules/ssh.nix
@@ -0,0 +1,95 @@
+{
+ config,
+ lib,
+ username,
+ ...
+}:
+let
+ cfg = config.os.srv.ssh;
+ keys.main = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIC610CJfgc3yII7MpLVqzEzQGa8Tsm+dih+CTXHXTnv4";
+in
+{
+ options.os.srv.ssh = {
+ server.enable = lib.mkEnableOption "enables the ssh server module";
+ client = {
+ enable = lib.mkEnableOption "enables the ssh client module";
+ createAliases = lib.mkEnableOption "enables system-wide SSH shortcuts";
+ };
+ enableSigning = lib.mkEnableOption "enables signing git commits with ssh keys";
+ };
+
+ config = lib.mkMerge [
+ (lib.mkIf cfg.server.enable {
+ services.openssh = {
+ enable = true;
+
+ listenAddresses = [
+ {
+ addr = "127.0.0.1";
+ port = 22;
+ }
+ ]
+ ++ lib.optional (config.os.core.network ? lan.ip) {
+ addr = config.os.core.network.lan.ip;
+ port = 22;
+ }
+ ++ lib.optional (config.os.core.network ? wg.ip) {
+ addr = config.os.core.network.wg.ip;
+ port = 22;
+ }
+ ++ lib.optional (config.os.core.network ? hs.ip) {
+ addr = config.os.core.network.hs.ip;
+ port = 22;
+ };
+ hostKeys = [
+ {
+ path = "/etc/ssh/ssh_host_ed25519_key";
+ type = "ed25519";
+ }
+ ];
+ settings = {
+ PasswordAuthentication = false;
+ KbdInteractiveAuthentication = false;
+ PermitRootLogin = "no";
+
+ PubkeyAcceptedAlgorithms = "ssh-ed25519";
+ };
+ };
+
+ users.users = (
+ lib.optionalAttrs (username != "" && username != null) {
+ ${username}.openssh.authorizedKeys.keys = [
+ "${keys.main} adikro@disroot.org"
+ ];
+ }
+ );
+ })
+
+ (lib.mkIf cfg.client.enable {
+ programs.ssh.startAgent = true;
+ services.gnome.gcr-ssh-agent.enable = false;
+ })
+
+ (lib.mkIf (cfg.client.enable && cfg.client.createAliases) {
+ # TODO use hjem
+ programs.ssh.extraConfig = ''
+ Host github.com codeberg.org
+ IdentityFile /home/${username}/.ssh/main_id_ed25519.pub
+ IdentitiesOnly yes
+ User git
+
+ Host oci
+ HostName 130.162.223.123
+ User opc
+ '';
+ systemd.tmpfiles.rules = [
+ "d /home/${username}/.ssh 0700 ${username} users - -"
+ "f /home/${username}/.ssh/main_id_ed25519.pub 0644 ${username} users - ${keys.main}"
+ ];
+ })
+
+ (lib.mkIf cfg.enableSigning {
+ environment.etc."ssh/allowed_signers".text = "adikro@disroot.org ${keys.main}";
+ })
+ ];
+}
diff --git a/modules/storage.nix b/modules/storage.nix
new file mode 100644
index 0000000..8527bac
--- /dev/null
+++ b/modules/storage.nix
@@ -0,0 +1,21 @@
+{ config, lib, ... }:
+let
+ cfg = config.os.core.storage;
+in
+{
+ options.os.core.storage = {
+ enable = lib.mkEnableOption "enables storage management";
+ };
+ config = lib.mkIf cfg.enable {
+ nix.settings.auto-optimise-store = true;
+ services.fstrim.enable = true;
+ services.btrfs.autoScrub = {
+ enable = true;
+ fileSystems = [ "/" ];
+ };
+ boot.tmp = {
+ useTmpfs = true;
+ tmpfsSize = "50%";
+ };
+ };
+}
diff --git a/modules/syncthing.nix b/modules/syncthing.nix
new file mode 100644
index 0000000..0c5e53e
--- /dev/null
+++ b/modules/syncthing.nix
@@ -0,0 +1,136 @@
+{
+ config,
+ lib,
+ username,
+ ...
+}:
+let
+ cfg = config.os.srv.syncthing;
+ allFolders = {
+ "openmw-config" = {
+ path = "/home/${username}/.config/openmw";
+ id = "openmw-config";
+ devices = [ "oci" ];
+ versioning = {
+ type = "simple";
+ params.keep = "3";
+ };
+ ignorePatterns = [
+ "settings.cfg"
+ "*.log"
+ ];
+ };
+
+ "openmw-mods" = {
+ path = "/home/${username}/games/openmw";
+ id = "openmw-mods";
+ devices = [ "oci" ];
+ versioning = {
+ type = "trashcan";
+ params.cleanoutDays = "7";
+ };
+ };
+
+ "game-saves" = {
+ path = "/home/${username}/.saves";
+ id = "game-saves";
+ devices = [ "oci" ];
+ versioning = {
+ type = "staggered";
+ params = {
+ cleanInterval = "3600";
+ maxAge = "2592000";
+ };
+ };
+ };
+
+ "keepass" = {
+ path = "/home/${username}/.keepass";
+ id = "keepass";
+ devices = [
+ {
+ name = "oci";
+ encryptionPasswordFile = config.sops.secrets."syncthing/encryption/keepass".path;
+ }
+ ];
+ versioning = {
+ type = "staggered";
+ params = {
+ cleanInterval = "3600";
+ maxAge = "31536000";
+ };
+ };
+ };
+
+ "sync" = {
+ path = "/home/${username}/sync";
+ id = "sync";
+ devices = [
+ {
+ name = "oci";
+ encryptionPasswordFile = config.sops.secrets."syncthing/encryption/sync".path;
+ }
+ ];
+ versioning = {
+ type = "staggered";
+ params = {
+ cleanInterval = "3600";
+ maxAge = "15552000";
+ };
+ };
+ };
+
+ "music" = {
+ path = "/storage/music";
+ id = "music";
+ devices = [ "oci" ];
+ versioning = {
+ type = "trashcan";
+ params.cleanoutDays = "14";
+ };
+ };
+ };
+ activeFoldersSet = lib.filterAttrs (name: _: builtins.elem name cfg.activeFolders) allFolders;
+
+ syncDirs = lib.mapAttrsToList (_: folder: folder.path) activeFoldersSet;
+in
+{
+ options.os.srv.syncthing = {
+ enable = lib.mkEnableOption "enables syncthing syncing";
+
+ activeFolders = lib.mkOption {
+ type = lib.types.listOf (
+ lib.types.enum [
+ "openmw-config"
+ "openmw-mods"
+ "game-saves"
+ "keepass"
+ "sync"
+ "music"
+ ]
+ );
+ default = [
+ "keepass"
+ "sync"
+ ];
+ description = "List of Syncthing folders to enable and sync on this specific machine.";
+ };
+ };
+ config = lib.mkIf cfg.enable {
+ systemd.tmpfiles.rules = map (path: "d ${path} 0755 ${username} users -") syncDirs;
+
+ services.syncthing = {
+ enable = true;
+ user = username;
+ dataDir = "/home/${username}/.local/share/syncthing";
+ configDir = "/home/${username}/.config/syncthing";
+ # guiPasswordFile = config.sops.secrets."syncthing/gui_password".path;
+
+ settings = {
+ devices."oci".id = "DQXGVDC-KGPM6RK-5NDEBJJ-R7PEWYZ-N6Z3WFZ-TSVJG5X-235SHG4-4BEJNQJ";
+
+ folders = activeFoldersSet;
+ };
+ };
+ };
+}
diff --git a/modules/tor.nix b/modules/tor.nix
new file mode 100644
index 0000000..8777fba
--- /dev/null
+++ b/modules/tor.nix
@@ -0,0 +1,31 @@
+{
+ config,
+ lib,
+ pkgs,
+ ...
+}:
+let
+ cfg = config.os.srv.tor;
+in
+{
+ options.os.srv.tor = {
+ enable = lib.mkEnableOption "enables tor services";
+ enableBrowser = lib.mkEnableOption "enables the tor browser";
+ };
+
+ config = lib.mkMerge [
+ (lib.mkIf cfg.enable {
+ services.tor = {
+ enable = true;
+ client = {
+ enable = true;
+ dns.enable = true;
+ transparentProxy.enable = true;
+ };
+ };
+ })
+ (lib.mkIf cfg.enableBrowser {
+ environment.systemPackages = [ pkgs.tor-browser ];
+ })
+ ];
+}
diff --git a/modules/users.nix b/modules/users.nix
new file mode 100644
index 0000000..ff45a99
--- /dev/null
+++ b/modules/users.nix
@@ -0,0 +1,54 @@
+{
+ config,
+ lib,
+ pkgs,
+ username,
+ ...
+}:
+let
+ cfg = config.os.core.users;
+in
+{
+ options.os.core.users.enable = lib.mkEnableOption "enables user accounts";
+ config = lib.mkIf cfg.enable {
+ programs.fish.enable = true;
+ assertions = [
+ {
+ assertion = config.os.srv.sops.enable;
+ message = "required for storing the ssh key";
+ }
+ ];
+ sops.secrets = {
+ "users/root_password".neededForUsers = true;
+ "users/main_password".neededForUsers = true;
+ # "users/opc_password".neededForUsers = true;
+ };
+ users = {
+ mutableUsers = false;
+
+ users = {
+ "${username}" = {
+ isNormalUser = true;
+ hashedPasswordFile = config.sops.secrets."users/main_password".path;
+ shell = pkgs.fish;
+ extraGroups = lib.mkMerge [
+ [
+ "wheel"
+ "input"
+ "uinput"
+ ]
+
+ (lib.mkIf (config.os.core.drivers.graphics.enable or false) [
+ "video"
+ "render"
+ ])
+ (lib.mkIf (config.os.core.network.enable or false) [ "networkmanager" ])
+ (lib.mkIf (config.os.srv.virtualization.kvm.enable or false) [ "libvirtd" ])
+ (lib.mkIf (config.os.srv.docker.enable or false) [ "docker" ])
+ ];
+ };
+ root.hashedPasswordFile = config.sops.secrets."users/root_password".path;
+ };
+ };
+ };
+}
diff --git a/modules/virtualization.nix b/modules/virtualization.nix
new file mode 100644
index 0000000..8ff9f3f
--- /dev/null
+++ b/modules/virtualization.nix
@@ -0,0 +1,40 @@
+{
+ config,
+ lib,
+ pkgs,
+ ...
+}:
+let
+ cfg = config.os.srv.virtualization;
+in
+{
+ options.os.srv.virtualization = {
+ kvm.enable = lib.mkEnableOption "KVM/QEMU virtualization with Virt-Manager";
+ waydroid.enable = lib.mkEnableOption "Waydroid Container Virtualization";
+ };
+ config = lib.mkMerge [
+ (lib.mkIf cfg.kvm.enable {
+ virtualisation.libvirtd = {
+ enable = true;
+ qemu.package = pkgs.qemu_kvm;
+ qemu.swtpm.enable = true;
+ };
+ systemd.services.libvirt-guests.enable = false;
+ programs.virt-manager.enable = true;
+
+ boot.initrd.kernelModules =
+ (lib.optional (config.os.core.drivers.cpu == "amd") "kvm-amd")
+ ++ (lib.optional (config.os.core.drivers.cpu == "intel") "kvm-intel");
+ })
+ (lib.mkIf cfg.waydroid.enable {
+ virtualisation.waydroid = {
+ enable = true;
+ package = pkgs.waydroid-nftables;
+ };
+
+ environment.systemPackages = with pkgs; [
+ waydroid-helper
+ ];
+ })
+ ];
+}