diff --git a/flake.nix b/flake.nix index de0bd78..571b2b7 100644 --- a/flake.nix +++ b/flake.nix @@ -87,8 +87,7 @@ nixserver = { modules = [ nixos-mailserver.nixosModules.default - ./system/hardware/hp_probook_g0.nix - ./system/hosts/nixserver + ./system/devices/hp-probook-g0-server.nix ]; }; router-emmc = rec { @@ -97,10 +96,8 @@ specialArgs.router-lib = if developing then import /${devPath}/nixos-router/lib.nix { inherit (nixpkgs) lib; } else nixos-router.lib.${system}; specialArgs.server-config = nixosConfigurations.nixserver.config; modules = [ - ./system/hardware/bpi_r3/emmc.nix - ./system/hosts/router + (import ./system/devices/bpi-r3-router.nix "emmc") (if developing then (import /${devPath}/nixos-router) else nixos-router.nixosModules.default) - { networking.hostName = "router"; } ]; }; router-sd = rec { @@ -109,18 +106,15 @@ specialArgs.router-lib = if developing then import /${devPath}/nixos-router/lib.nix { inherit (nixpkgs) lib; } else nixos-router.lib.${system}; specialArgs.server-config = nixosConfigurations.nixserver.config; modules = [ - ./system/hardware/bpi_r3/sd.nix - ./system/hosts/router + (import ./system/devices/bpi-r3-router.nix "sd") (if developing then (import /${devPath}/nixos-router) else nixos-router.nixosModules.default) - { networking.hostName = "router"; } ]; }; nixmsi = rec { system = "x86_64-linux"; modules = [ nix-gaming.nixosModules.pipewireLowLatency - ./system/hardware/msi_delta_15.nix - ./system/hosts/nixmsi.nix + ./system/devices/msi-delta-15-workstation.nix ]; home.common.enableNixosModule = false; home.common.extraSpecialArgs = { diff --git a/system/README.md b/system/README.md new file mode 100644 index 0000000..9bb609b --- /dev/null +++ b/system/README.md @@ -0,0 +1,5 @@ +- `hardware`: basic config for a device, specifies screen resolution, + gpu, etc +- `hosts`: mostly hardware-agnostic, specifies config for device "roles" +- `devices`: per-device config, like partition tables. This is the entry + points which import modules from `hardware` and `hosts` diff --git a/system/devices/README.md b/system/devices/README.md new file mode 100644 index 0000000..56c3763 --- /dev/null +++ b/system/devices/README.md @@ -0,0 +1,2 @@ +This folder is for device-specific, non-portable config. See `../hosts` +for device-agnostic configuration. diff --git a/system/devices/bpi-r3-router.nix b/system/devices/bpi-r3-router.nix new file mode 100644 index 0000000..9a94b98 --- /dev/null +++ b/system/devices/bpi-r3-router.nix @@ -0,0 +1,43 @@ +storage: + +{ config, ... }: + +let + rootUuid = "44444444-4444-4444-8888-888888888888"; + rootPart = "/dev/disk/by-uuid/${rootUuid}"; +in + +{ + imports = [ + ../hardware/bpi-r3/${storage}.nix + ../hosts/router + ]; + networking.hostName = "nixos-router"; + + fileSystems = { + # mount root on tmpfs + "/" = { device = "none"; fsType = "tmpfs"; neededForBoot = true; + options = [ "defaults" "size=2G" "mode=755" ]; }; + "/persist" = + { device = rootPart; fsType = "btrfs"; neededForBoot = true; + options = [ "compress=zstd:15" "subvol=@" ]; }; + "/boot" = + { device = rootPart; fsType = "btrfs"; neededForBoot = true; + options = [ "subvol=@boot" ]; }; + "/nix" = + { device = rootPart; fsType = "btrfs"; neededForBoot = true; + options = [ "compress=zstd:15" "subvol=@nix" ]; }; + }; + + impermanence = { + enable = true; + path = /persist; + directories = [ + { directory = /home/${config.common.mainUsername}; user = config.common.mainUsername; group = "users"; mode = "0700"; } + { directory = /root; mode = "0700"; } + ]; + }; + + # technically hostapd/lan0..4 interface config should be here as well + # but for easier demonstration i'll keep it all in ../hosts/router +} diff --git a/system/devices/hp-probook-g0-server.nix b/system/devices/hp-probook-g0-server.nix new file mode 100644 index 0000000..bc6cc5f --- /dev/null +++ b/system/devices/hp-probook-g0-server.nix @@ -0,0 +1,54 @@ +{ config, ... }: + +let + efiPart = "/dev/disk/by-uuid/3E2A-A5CB"; + rootUuid = "6aace237-9b48-4294-8e96-196759a5305b"; + rootPart = "/dev/disk/by-uuid/${rootUuid}"; +in { + imports = [ + ../hardware/hp-probook-g0.nix + ../hosts/nixserver + ]; + + boot.loader = { + grub = { + enable = true; + device = "nodev"; + efiSupport = true; + efiInstallAsRemovable = true; + }; + efi.efiSysMountPoint = "/boot/efi"; + }; + fileSystems = { + "/" = { device = "none"; fsType = "tmpfs"; neededForBoot = true; + options = [ "defaults" "size=2G" "mode=755" ]; }; + "/persist" = + { device = rootPart; fsType = "btrfs"; neededForBoot = true; + options = [ "compress=zstd:15" ]; }; + "/boot" = + { device = rootPart; fsType = "btrfs"; neededForBoot = true; + options = [ "compress=zstd:15" "subvol=boot" ]; }; + "/boot/efi" = + { device = efiPart; fsType = "vfat"; }; + }; + services.beesd = { + filesystems.root = { + spec = "UUID=${rootUuid}"; + hashTableSizeMB = 128; + extraOptions = [ "--loadavg-target" "8.0" ]; + }; + }; + + zramSwap.enable = true; + swapDevices = [ ]; + + impermanence = { + enable = true; + path = /persist; + directories = [ + { directory = /home/${config.common.mainUsername}; user = config.common.mainUsername; group = "users"; mode = "0700"; } + { directory = /root; } + { directory = /nix; } + ]; + }; +} diff --git a/system/devices/msi-delta-15-workstation.nix b/system/devices/msi-delta-15-workstation.nix new file mode 100644 index 0000000..9493010 --- /dev/null +++ b/system/devices/msi-delta-15-workstation.nix @@ -0,0 +1,114 @@ +# device-specific non-portable config +let + efiPart = "/dev/disk/by-uuid/D77D-8CE0"; + + encPart = "/dev/disk/by-uuid/ce6ccdf0-7b6a-43ae-bfdf-10009a55041a"; + cryptrootUuid = "f4edc0df-b50b-42f6-94ed-1c8f88d6cdbb"; + cryptroot = "/dev/disk/by-uuid/${cryptrootUuid}"; + + dataPart = "/dev/disk/by-uuid/f1447692-fa7c-4bd6-9cb5-e44c13fddfe3"; + datarootUuid = "fa754b1e-ac83-4851-bf16-88efcd40b657"; + dataroot = "/dev/disk/by-uuid/${datarootUuid}"; +in { + imports = [ + ../hardware/msi-delta-15.nix + ../hosts/nixmsi.nix + ]; + + boot.initrd = { + # insert crypto_keyfile into initrd so that grub can tell the kernel the + # encryption key once I unlock the /boot partition + secrets."/crypto_keyfile.bin" = "/boot/initrd/crypto_keyfile.bin"; + luks.devices."cryptroot" = { + device = encPart; + # idk whether this is needed but it works + preLVM = true; + # see https://asalor.blogspot.de/2011/08/trim-dm-crypt-problems.html before enabling + allowDiscards = true; + # improve SSD performance + bypassWorkqueues = true; + keyFile = "/crypto_keyfile.bin"; + }; + luks.devices."dataroot" = { + device = dataPart; + preLVM = true; + allowDiscards = true; + bypassWorkqueues = true; + keyFile = "/crypto_keyfile.bin"; + }; + }; + boot.loader = { + grub = { + enable = true; + enableCryptodisk = true; + efiSupport = true; + # nodev = disable bios support + device = "nodev"; + }; + efi.canTouchEfiVariables = true; + efi.efiSysMountPoint = "/boot/efi"; + }; + boot.resumeDevice = cryptroot; + boot.kernelParams = [ + "resume=/@swap/swapfile" + # resume_offset = $(btrfs inspect-internal map-swapfile -r path/to/swapfile) + "resume_offset=533760" + ]; + fileSystems = let + device = cryptroot; + fsType = "btrfs"; + # max compression! my cpu is pretty good anyway + compress = "compress=zstd:15"; + discard = "discard=async"; + neededForBoot = true; + in { + # mount root on tmpfs + "/" = { device = "none"; fsType = "tmpfs"; inherit neededForBoot; + options = [ "defaults" "size=2G" "mode=755" ]; }; + "/persist" = + { inherit device fsType neededForBoot; + options = [ discard compress "subvol=@" ]; }; + "/nix" = { inherit device fsType neededForBoot; + options = [ discard compress "subvol=@nix" "noatime" ]; }; + "/swap" = { inherit device fsType neededForBoot; + options = [ discard "subvol=@swap" "noatime" ]; }; + "/home" = { inherit device fsType; + options = [ discard compress "subvol=@home" ]; }; + # why am I even bothering with creating this subvolume every time if I don't use snapshots anyway? + "/.snapshots" = + { inherit device fsType; + options = [ discard compress "subvol=@snapshots" ]; }; + "/boot" = { inherit device fsType neededForBoot; + options = [ discard compress "subvol=@boot" ]; }; + "/boot/efi" = + { device = efiPart; fsType = "vfat"; inherit neededForBoot; }; + "/data" = + { device = dataroot; fsType = "btrfs"; + options = [ discard compress ]; }; + }; + + impermanence = { + enable = true; + path = /persist; + }; + + # fix for my realtek usb ethernet adapter + services.tlp.settings.USB_DENYLIST = "0bda:8156"; + + swapDevices = [ { device = "/swap/swapfile"; } ]; + + # dedupe + services.beesd = { + # i have a lot of ram :tonystark: + filesystems.cryptroot = { + spec = "UUID=${cryptrootUuid}"; + hashTableSizeMB = 128; + extraOptions = [ "--loadavg-target" "8.0" ]; + }; + filesystems.dataroot = { + spec = "UUID=${datarootUuid}"; + hashTableSizeMB = 256; + extraOptions = [ "--loadavg-target" "8.0" ]; + }; + }; +} diff --git a/system/hardware/README.md b/system/hardware/README.md new file mode 100644 index 0000000..dcfe533 --- /dev/null +++ b/system/hardware/README.md @@ -0,0 +1,3 @@ +This specifies the "lowest common denominator" of all NixOS configs for +this device. It simply specifies the hardware (screen resolutions, GPUs, +etc). For specific device configs, see `../devices`. diff --git a/system/hardware/bpi_r3/bpi-r3-atf-backport-mkimage-support.patch b/system/hardware/bpi-r3/bpi-r3-atf-backport-mkimage-support.patch similarity index 100% rename from system/hardware/bpi_r3/bpi-r3-atf-backport-mkimage-support.patch rename to system/hardware/bpi-r3/bpi-r3-atf-backport-mkimage-support.patch diff --git a/system/hardware/bpi_r3/default.nix b/system/hardware/bpi-r3/default.nix similarity index 100% rename from system/hardware/bpi_r3/default.nix rename to system/hardware/bpi-r3/default.nix diff --git a/system/hardware/bpi_r3/emmc.nix b/system/hardware/bpi-r3/emmc.nix similarity index 100% rename from system/hardware/bpi_r3/emmc.nix rename to system/hardware/bpi-r3/emmc.nix diff --git a/system/hardware/bpi_r3/image.nix b/system/hardware/bpi-r3/image.nix similarity index 100% rename from system/hardware/bpi_r3/image.nix rename to system/hardware/bpi-r3/image.nix diff --git a/system/hardware/bpi_r3/image.sh b/system/hardware/bpi-r3/image.sh similarity index 100% rename from system/hardware/bpi_r3/image.sh rename to system/hardware/bpi-r3/image.sh diff --git a/system/hardware/bpi_r3/mt7986-default-bootcmd.patch b/system/hardware/bpi-r3/mt7986-default-bootcmd.patch similarity index 100% rename from system/hardware/bpi_r3/mt7986-default-bootcmd.patch rename to system/hardware/bpi-r3/mt7986-default-bootcmd.patch diff --git a/system/hardware/bpi_r3/mt7986a-bananapi-bpi-r3-wireless.dts b/system/hardware/bpi-r3/mt7986a-bananapi-bpi-r3-wireless.dts similarity index 100% rename from system/hardware/bpi_r3/mt7986a-bananapi-bpi-r3-wireless.dts rename to system/hardware/bpi-r3/mt7986a-bananapi-bpi-r3-wireless.dts diff --git a/system/hardware/bpi_r3/pkgs.nix b/system/hardware/bpi-r3/pkgs.nix similarity index 100% rename from system/hardware/bpi_r3/pkgs.nix rename to system/hardware/bpi-r3/pkgs.nix diff --git a/system/hardware/bpi_r3/sd.nix b/system/hardware/bpi-r3/sd.nix similarity index 100% rename from system/hardware/bpi_r3/sd.nix rename to system/hardware/bpi-r3/sd.nix diff --git a/system/hardware/hp_probook_g0.nix b/system/hardware/hp-probook-g0.nix similarity index 100% rename from system/hardware/hp_probook_g0.nix rename to system/hardware/hp-probook-g0.nix diff --git a/system/hardware/msi_delta_15.nix b/system/hardware/msi-delta-15.nix similarity index 100% rename from system/hardware/msi_delta_15.nix rename to system/hardware/msi-delta-15.nix diff --git a/system/hosts/README.md b/system/hosts/README.md new file mode 100644 index 0000000..8c16a43 --- /dev/null +++ b/system/hosts/README.md @@ -0,0 +1,3 @@ +This folder is for (mostly) hardware-agnostic configs. See `../devices` +for device-specific config, e.g. the partition tables (those modules +also reference `../hardware`) diff --git a/system/hosts/nixmsi.nix b/system/hosts/nixmsi.nix index 407d2fa..3422372 100644 --- a/system/hosts/nixmsi.nix +++ b/system/hosts/nixmsi.nix @@ -3,17 +3,7 @@ , config , ... }: -let - efiPart = "/dev/disk/by-uuid/D77D-8CE0"; - - encPart = "/dev/disk/by-uuid/ce6ccdf0-7b6a-43ae-bfdf-10009a55041a"; - cryptrootUuid = "f4edc0df-b50b-42f6-94ed-1c8f88d6cdbb"; - cryptroot = "/dev/disk/by-uuid/${cryptrootUuid}"; - - dataPart = "/dev/disk/by-uuid/f1447692-fa7c-4bd6-9cb5-e44c13fddfe3"; - datarootUuid = "fa754b1e-ac83-4851-bf16-88efcd40b657"; - dataroot = "/dev/disk/by-uuid/${datarootUuid}"; - /* +/* # for old kernel versions zenKernels = pkgs.callPackage "${nixpkgs}/pkgs/os-specific/linux/kernel/zen-kernels.nix"; zenKernel = (version: sha256: (zenKernels { @@ -33,52 +23,14 @@ let }; }).zen); zenKernelPackages = version: sha256: pkgs.linuxPackagesFor (zenKernel version sha256); - */ -in { +*/ + +{ system.stateVersion = "22.11"; ### SECTION 1: HARDWARE/BOOT PARAMETERS ### boot = { - initrd = { - # insert crypto_keyfile into initrd so that grub can tell the kernel the - # encryption key once I unlock the /boot partition - secrets."/crypto_keyfile.bin" = "/boot/initrd/crypto_keyfile.bin"; - luks.devices."cryptroot" = { - device = encPart; - # idk whether this is needed but it works - preLVM = true; - # see https://asalor.blogspot.de/2011/08/trim-dm-crypt-problems.html before enabling - allowDiscards = true; - # improve SSD performance - bypassWorkqueues = true; - keyFile = "/crypto_keyfile.bin"; - }; - luks.devices."dataroot" = { - device = dataPart; - preLVM = true; - allowDiscards = true; - bypassWorkqueues = true; - keyFile = "/crypto_keyfile.bin"; - }; - }; - resumeDevice = cryptroot; - kernelParams = [ - "resume=/@swap/swapfile" - # resume_offset = $(btrfs inspect-internal map-swapfile -r path/to/swapfile) - "resume_offset=533760" - ]; - loader = { - grub = { - enable = true; - enableCryptodisk = true; - efiSupport = true; - # nodev = disable bios support - device = "nodev"; - }; - efi.canTouchEfiVariables = true; - efi.efiSysMountPoint = "/boot/efi"; - }; kernel.sysctl = { "vm.dirty_ratio" = 4; "vm.dirty_background_ratio" = 2; @@ -101,12 +53,6 @@ in { opengl.extraPackages = with pkgs; [ vulkan-validation-layers ]; }; - # services.openssh.enable = true; - - services.tlp.enable = true; - # fix for my realtek usb ethernet adapter - services.tlp.settings.USB_DENYLIST = "0bda:8156"; - # see modules/vfio.nix vfio.enable = true; vfio.libvirtdGroup = [ config.common.mainUsername ]; @@ -118,63 +64,7 @@ in { externalInterface = "enp7s0f4u1c2"; }; - fileSystems = let - device = cryptroot; - fsType = "btrfs"; - # max compression! my cpu is pretty good anyway - compress = "compress=zstd:15"; - discard = "discard=async"; - neededForBoot = true; - in { - # mount root on tmpfs - "/" = { device = "none"; fsType = "tmpfs"; inherit neededForBoot; - options = [ "defaults" "size=2G" "mode=755" ]; }; - "/persist" = - { inherit device fsType neededForBoot; - options = [ discard compress "subvol=@" ]; }; - "/nix" = { inherit device fsType neededForBoot; - options = [ discard compress "subvol=@nix" "noatime" ]; }; - "/swap" = { inherit device fsType neededForBoot; - options = [ discard "subvol=@swap" "noatime" ]; }; - "/home" = { inherit device fsType; - options = [ discard compress "subvol=@home" ]; }; - # why am I even bothering with creating this subvolume every time if I don't use snapshots anyway? - "/.snapshots" = - { inherit device fsType; - options = [ discard compress "subvol=@snapshots" ]; }; - "/boot" = { inherit device fsType neededForBoot; - options = [ discard compress "subvol=@boot" ]; }; - "/boot/efi" = - { device = efiPart; fsType = "vfat"; inherit neededForBoot; }; - "/data" = - { device = dataroot; fsType = "btrfs"; - options = [ discard compress ]; }; - }; - - impermanence = { - enable = true; - path = /persist; - }; - - swapDevices = [ { device = "/swap/swapfile"; } ]; - - # dedupe - services.beesd = { - # i have a lot of ram :tonystark: - filesystems.cryptroot = { - spec = "UUID=${cryptrootUuid}"; - hashTableSizeMB = 128; - extraOptions = [ "--loadavg-target" "8.0" ]; - }; - filesystems.dataroot = { - spec = "UUID=${datarootUuid}"; - hashTableSizeMB = 256; - extraOptions = [ "--loadavg-target" "8.0" ]; - }; - }; - ### SECTION 2: SYSTEM CONFIG/ENVIRONMENT ### - console.font = "${pkgs.terminus_font}/share/consolefonts/ter-v32n.psf.gz"; networking.useDHCP = true; # networking.firewall.enable = false; @@ -241,4 +131,3 @@ in { services.sshd.enable = true; boot.binfmt.emulatedSystems = [ "aarch64-linux" ]; } - diff --git a/system/hosts/nixserver/default.nix b/system/hosts/nixserver/default.nix index b5a3c25..64c1bfb 100644 --- a/system/hosts/nixserver/default.nix +++ b/system/hosts/nixserver/default.nix @@ -6,10 +6,6 @@ let cfg = config.server; - efiPart = "/dev/disk/by-uuid/3E2A-A5CB"; - rootUuid = "6aace237-9b48-4294-8e96-196759a5305b"; - rootPart = "/dev/disk/by-uuid/${rootUuid}"; - hosted-domains = map (prefix: if prefix == null then cfg.domainName else "${prefix}.${cfg.domainName}") @@ -40,69 +36,32 @@ in { ]; system.stateVersion = "22.11"; - - boot = { - loader = { - grub = { - enable = true; - device = "nodev"; - efiSupport = true; - efiInstallAsRemovable = true; - }; - efi.efiSysMountPoint = "/boot/efi"; - }; - }; - fileSystems = { - "/" = { device = "none"; fsType = "tmpfs"; neededForBoot = true; - options = [ "defaults" "size=2G" "mode=755" ]; }; - "/persist" = - { device = rootPart; fsType = "btrfs"; neededForBoot = true; - options = [ "compress=zstd:15" ]; }; - "/boot" = - { device = rootPart; fsType = "btrfs"; neededForBoot = true; - options = [ "compress=zstd:15" "subvol=boot" ]; }; - "/boot/efi" = - { device = efiPart; fsType = "vfat"; }; - }; - zramSwap.enable = true; - swapDevices = [ ]; - impermanence = { - enable = true; - path = /persist; - directories = [ - { directory = /home/${config.common.mainUsername}; user = config.common.mainUsername; group = "users"; mode = "0700"; } - { directory = /root; } - { directory = /nix; } - { directory = /var/www/${cfg.domainName}; } - ]; - }; - services.beesd = { - filesystems.root = { - spec = "UUID=${rootUuid}"; - hashTableSizeMB = 128; - extraOptions = [ "--loadavg-target" "8.0" ]; - }; - }; - console.font = "${pkgs.terminus_font}/share/consolefonts/ter-v24n.psf.gz"; + impermanence.directories = [ + { directory = /var/www/${cfg.domainName}; } + ]; networking.useDHCP = true; networking.firewall = { enable = true; - allowedTCPPorts = [ - # ssh - 22 - # dns - 53 853 - # http/s - 80 443 + allowedTCPPorts = lib.mkMerge [ + [ + # ssh + 22 + # http/s + 80 443 + ] + (lib.mkIf config.services.unbound.enable [ + # dns + 53 853 + ]) ]; - allowedUDPPorts = [ + allowedUDPPorts = lib.mkIf config.services.unbound.enable [ # dns 53 853 ]; }; # UNBOUND - users.users.${config.common.mainUsername}.extraGroups = [ config.services.unbound.group ]; + users.users.${config.common.mainUsername}.extraGroups = lib.mkIf config.services.unbound.enable [ config.services.unbound.group ]; #networking.resolvconf.extraConfig = '' # name_servers="127.0.0.1 ::1" diff --git a/system/hosts/router/default.nix b/system/hosts/router/default.nix index 988151d..07feab6 100644 --- a/system/hosts/router/default.nix +++ b/system/hosts/router/default.nix @@ -7,8 +7,6 @@ , ... }: let - rootUuid = "44444444-4444-4444-8888-888888888888"; - rootPart = "/dev/disk/by-uuid/${rootUuid}"; cfg = config.router-settings; hapdConfig = { inherit (cfg) country_code wpa_passphrase; @@ -219,7 +217,23 @@ let hosted-domains = builtins.attrNames server-config.services.nginx.virtualHosts; in { - router-settings.domainName = "pavluk.org"; + imports = [ ./options.nix ]; + system.stateVersion = "22.11"; + + boot.kernel.sysctl = { + "net.ipv4.conf.all.src_valid_mark" = true; + "net.ipv4.conf.default.src_valid_mark" = true; + "net.ipv4.conf.all.forwarding" = true; + "net.ipv6.conf.all.forwarding" = true; + }; + + services.openssh.enable = true; + services.fail2ban = { + enable = true; + ignoreIP = [ netCidr4 netCidr6 ]; + maxretry = 10; + }; + router-settings.dhcpReservations = [ { ipAddress = serverAddress4; macAddress = cfg.serverMac; } @@ -267,47 +281,8 @@ in { target4.address = serverAddress4; target6.address = serverAddress6; }) rangesUdpOnly; - imports = [ ./options.nix ]; - system.stateVersion = "22.11"; - fileSystems = { - # mount root on tmpfs - "/" = { device = "none"; fsType = "tmpfs"; neededForBoot = true; - options = [ "defaults" "size=2G" "mode=755" ]; }; - "/persist" = - { device = rootPart; fsType = "btrfs"; neededForBoot = true; - options = [ "compress=zstd:15" "subvol=@" ]; }; - "/boot" = - { device = rootPart; fsType = "btrfs"; neededForBoot = true; - options = [ "subvol=@boot" ]; }; - "/nix" = - { device = rootPart; fsType = "btrfs"; neededForBoot = true; - options = [ "compress=zstd:15" "subvol=@nix" ]; }; - }; - impermanence = { - enable = true; - path = /persist; - directories = [ - { directory = /home/${config.common.mainUsername}; user = config.common.mainUsername; group = "users"; mode = "0700"; } - { directory = /root; mode = "0700"; } - { directory = /var/db/dhcpcd; mode = "0755"; } - { directory = /var/lib/private/kea; mode = "0750"; } - # for wireguard key - { directory = /secrets; mode = "0000"; } - ]; - }; - boot.kernel.sysctl = { - "net.ipv4.conf.all.src_valid_mark" = true; - "net.ipv4.conf.default.src_valid_mark" = true; - "net.ipv4.conf.all.forwarding" = true; - "net.ipv6.conf.all.forwarding" = true; - }; - services.openssh.enable = true; - services.fail2ban = { - enable = true; - ignoreIP = [ netCidr4 netCidr6 ]; - maxretry = 10; - }; router.enable = true; + # 2.4g ap router.interfaces.wlan0 = { bridge = "br0"; hostapd.enable = true; @@ -321,6 +296,7 @@ in { ht_capab = "[LDPC][SHORT-GI-20][SHORT-GI-40][TX-STBC][RX-STBC1][MAX-AMSDU-7935]"; } // hapdConfig; }; + # 5g ap router.interfaces.wlan1 = { bridge = "br0"; hostapd.enable = true; @@ -337,6 +313,7 @@ in { vht_capab = "[RXLDPC][SHORT-GI-80][SHORT-GI-160][TX-STBC-2BY1][SU-BEAMFORMER][SU-BEAMFORMEE][MU-BEAMFORMER][MU-BEAMFORMEE][RX-ANTENNA-PATTERN][TX-ANTENNA-PATTERN][RX-STBC-1][SOUNDING-DIMENSION-4][BF-ANTENNA-4][VHT160][MAX-MPDU-11454][MAX-A-MPDU-LEN-EXP7]"; } // hapdConfig; }; + # ethernet lan0-3 router.interfaces.lan0 = { bridge = "br0"; systemdLinkLinkConfig.MACAddressPolicy = "persistent"; @@ -353,15 +330,21 @@ in { bridge = "br0"; systemdLinkLinkConfig.MACAddressPolicy = "persistent"; }; + # sfp lan4 router.interfaces.lan4 = { bridge = "br0"; systemdLinkLinkConfig.MACAddressPolicy = "persistent"; }; - /*router.interfaces.lan5 = { + /* + # sfp lan5 + router.interfaces.lan5 = { bridge = "br0"; + # i could try to figure out why this doesn't work... but i don't even have sfp to plug into this systemdLinkMatchConfig.OriginalName = "eth1"; systemdLinkLinkConfig.MACAddressPolicy = "persistent"; - };*/ + }; + */ + # ethernet wan router.interfaces.wan = { dependentServices = [ { service = "wireguard-wg0"; inNetns = false; } @@ -371,7 +354,11 @@ in { dhcpcd.enable = true; networkNamespace = "wan"; }; + # disable default firewall as it uses iptables + # (and we have our own firewall) networking.firewall.enable = false; + # br0, which bridges all lan devices + # this is "the" lan device router.interfaces.br0 = { dependentServices = [ { service = "unbound"; bindType = "wants"; } ]; ipv4.addresses = [ { @@ -390,7 +377,7 @@ in { gateways = [ gatewayAddr6 ]; radvdSettings.AdvAutonomous = true; coreradSettings.autonomous = true; - # don't autoallocate addresses + # don't autoallocate addresses, keep autonomous ones keaSettings.pools = [ ]; # just assign the reservations keaSettings.reservations = map (res: { @@ -412,6 +399,7 @@ in { ipv6.radvd.enable = true; ipv6.kea.enable = true; }; + router.networkNamespaces.default = { # set routing table depending on packet mark rules = [ @@ -420,6 +408,7 @@ in { # don't add vpn_table as it should be the default { ipv6 = false; extraArgs = [ "fwmark" iot_table "table" iot_table ]; } { ipv6 = true; extraArgs = [ "fwmark" iot_table "table" iot_table ]; } + # below is dnat config ] ++ builtins.concatLists (map (rule: let table = if rule.inVpn then 0 else wan_table; forEachPort = func: port: @@ -436,15 +425,18 @@ in { ++ lib.optionals (rule.udp && rule.target4 != null) (map (x: { ipv6 = false; extraArgs = x; }) (gen 32 "udp" rule.target4)) ++ lib.optionals (rule.tcp && rule.target6 != null) (map (x: { ipv6 = true; extraArgs = x; }) (gen 128 "tcp" rule.target6)) ++ lib.optionals (rule.udp && rule.target6 != null) (map (x: { ipv6 = true; extraArgs = x; }) (gen 128 "udp" rule.target6)) - ) (builtins.filter (x: (x.tcp || x.udp) && dnatRuleMode x == "rule") cfg.dnatRules)); + # nftables rules + # things to note: this has the code for switching between rtables + # otherwise, boring stuff nftables.stopJsonRules = mkFlushRules {}; nftables.jsonRules = mkRules { selfIp4 = gatewayAddr4; selfIp6 = gatewayAddr6; lans = [ "br0" ]; wans = [ "wg0" "veth-wan-a" ]; + logPrefix = "lan "; netdevIngressWanRules = with notnft.dsl; with payload; [ # check oif only from vpn # dont check it from veth-wan-a because of dnat fuckery and because we already check packets coming from wan there @@ -470,7 +462,6 @@ in { [(is.eq meta.iifname "veth-wan-a") (is.eq meta.oifname "br0") accept] # allow dnat ("ct status dnat" doesn't work) ]; - logPrefix = "lan "; inetInboundWanRules = with notnft.dsl; with payload; [ [(is.eq th.dport 22) accept] [(is.eq ip.saddr (cidr netnsCidr4)) accept] @@ -539,6 +530,11 @@ in { }; }; }; + # veths are virtual ethernet cables + # veth-wan-a - located in the default namespace + # veth-wan-b - located in the wan namespace + # this allows routing traffic to wan namespace from default namespace via veth-wan-a + # (and vice versa) router.veths.veth-wan-a.peerName = "veth-wan-b"; router.interfaces.veth-wan-a = { ipv4.addresses = [ netnsParsedCidr4 ]; @@ -566,6 +562,7 @@ in { address = wanNetnsAddr6; inherit (netnsParsedCidr6) prefixLength; } ]; + # allow wan->default namespace communication ipv4.routes = [ { extraArgs = [ netCidr4 "via" mainNetnsAddr4 ]; } ]; @@ -574,6 +571,7 @@ in { ]; }; router.networkNamespaces.wan = { + # this is the even more boring nftables config nftables.stopJsonRules = mkFlushRules {}; nftables.jsonRules = mkRules { selfIp4 = wanNetnsAddr4; @@ -634,11 +632,15 @@ in { }; }; + # vpn socket is in wan namespace, meaning traffic gets sent through the wan namespace + # vpn interface is in default namespace, meaning it can be used in the default namespace networking.wireguard.interfaces.wg0 = cfg.wireguard // { socketNamespace = "wan"; interfaceNamespace = "init"; }; + # use main netns's address instead of 127.0.0.1 + # this ensures all network namespaces can access it networking.resolvconf.extraConfig = '' name_servers="${mainNetnsAddr4} ${mainNetnsAddr6}" ''; @@ -662,7 +664,7 @@ in { module-config = ''"validator python iterator"''; local-zone = [ ''"local." static'' - ''"${cfg.domainName}." typetransparent'' + ''"${server-config.server.domainName}." typetransparent'' ]; local-data = builtins.concatLists (map (domain: [ @@ -676,7 +678,7 @@ in { }; networking.hosts."${serverAddress4}" = hosted-domains; networking.hosts."${serverAddress6}" = hosted-domains; - systemd.services.unbound = { + systemd.services.unbound = lib.mkIf config.services.unbound.enable { environment.PYTHONPATH = "${unbound-python}/${unbound-python.sitePackages}"; environment.MDNS_ACCEPT_NAMES = "^.*\\.local\\.$"; # load vpn_domains.json and vpn_ips.json, as well as unvpn_domains.json and unvpn_ips.json @@ -710,7 +712,6 @@ in { }; # run an extra sshd so we can connect even if forwarding/routing between namespaces breaks - # i don't want to connect by uart each time something goes wrong systemd.services.sshd-wan = { description = "SSH Daemon (WAN)"; wantedBy = [ "multi-user.target" ]; @@ -742,6 +743,7 @@ in { startWhenNeeded = false; }; + # share printers (and allow unbound to resolve .local) services.avahi = { enable = true; hostName = "router"; @@ -757,4 +759,12 @@ in { # it takes a stupidly long time when done via qemu # (also it's supposed to be disabled by default but it was enabled for me, why?) documentation.man.generateCaches = false; + + impermanence.directories = [ + # for wireguard key + { directory = /secrets; mode = "0000"; } + # my custom impermanence module doesnt detect it + { directory = /var/db/dhcpcd; mode = "0755"; } + { directory = /var/lib/private/kea; mode = "0750"; } + ]; } diff --git a/system/modules/common.nix b/system/modules/common.nix index 6738c75..a5720cb 100644 --- a/system/modules/common.nix +++ b/system/modules/common.nix @@ -55,11 +55,18 @@ ] ++ (lib.optionals (cfg.resolution == "1920x1080") [ "fbcon=font:TER16x32" ]); + console.font = + lib.mkIf (cfg.resolution == "1920x1080" || cfg.resolution == "1366x768") { + "1920x1080" = "${pkgs.terminus_font}/share/consolefonts/ter-v32n.psf.gz"; + "1366x768" = "${pkgs.terminus_font}/share/consolefonts/ter-v24n.psf.gz"; + }.${cfg.resolution}; boot.loader.grub = lib.mkIf (cfg.resolution != null) { gfxmodeEfi = cfg.resolution; gfxmodeBios = cfg.resolution; }; + networking.usePredictableInterfaceNames = lib.mkDefault true; + hardware.enableRedistributableFirmware = true; services.openssh.settings.PasswordAuthentication = false; services.tlp.settings.USB_EXCLUDE_PHONE = 1;