{ config, pkgs, lib, ... }: let choose = paths: builtins.head (builtins.filter (p: builtins.pathExists p) paths); in { options.local = { hostname = lib.mkOption { type = lib.types.str; default = "nixos-default"; description = "System hostname"; }; username = lib.mkOption { type = lib.types.str; default = "user"; description = "Primary user username"; }; userDescription = lib.mkOption { type = lib.types.str; default = "NixOS User"; description = "Primary user description"; }; address = lib.mkOption { type = lib.types.str; default = "10.1.1.100"; description = "Static IP address"; }; }; imports = [ (choose [ ./modules/desktop-manager/sway_greetd_homemanager.nix ../desktop-manager/sway_greetd_homemanager.nix ]) (choose [ ./modules/local/hostname_username.nix ../local/hostname_username.nix ]) (choose [ ./modules/local/networking_local.nix ../local/networking_local.nix ]) (choose [ ./modules/bootloader/seabios-assigned-iso-at-birth.nix ../bootloader/seabios-assigned-iso-at-birth.nix ]) (choose [ ./modules/lix-default.nix ../lix-default.nix ]) (choose [ ./modules/secrets-config/sops-wireguard.nix ../secrets-config/sops-wireguard.nix ]) # Optionally to enable remote building: ./modules/toolsets/remote_building.nix #./modules/songsheet/wavelog/docker-compose.nix #./modules/secrets-config/sops-the-blank-system.nix ]; config = { # https://wiki.archlinux.org/title/WireGuard # https://wiki.nixos.org/wiki/WireGuard local.hostname = "nixos-local-wireguard-server"; local.username = "wireguardprg_local"; local.userDescription = "NixOS PRG OpenVPN Service (Local)"; local.address = "10.1.1.6"; system.stateVersion = "25.11"; # enable NAT networking.nat = { enable = true; enableIPv6 = true; externalInterface = "ens18"; internalInterfaces = ["wg0"]; }; networking.wireguard.interfaces = { wg0 = { listenPort = 51820; # This allows the wireguard server to route your traffic to the internet and hence be like a VPN # Note: You ***really should*** to use IPv6 addresses, to ensure that there is no long term risk of *local* IPv4 address exhaustion. # How IPv6 works - Basically imagine IPv4 with hexadecimal, but without forcing you to learn it, the handrule # for local assignments is to start with fc00::, where appending "1" after the infix `::` as suffix gives you a proper address, # "fc00::1" (imagine this as 10.0.0.1 in IPv4 thought, where technically it is "252.0.0.0.0.0.0.0.0.0.0.0.0.0.0.1" # in IPv6 dotted hexadecimal notation). # Then you can add additional infix before the suffix to go more inside of the address prefix space, for example "fc00::1:1" # becomes in IPv4 thinking as 10.0.1.1 (in IPv6 " 252.0.0.0.0.0.0.0.0.0.0.0.0.1.0.255"). # As you might have noticed, that each semicolon is assigned into 16 bits, thus you can assign each subnet address from # in IPv4 like-thinking from .1 to .65536, thus in hexadecimal from ::1 to ::ffff. # Prefixes are read 1:1 from IPv4 thinking, but you have 1 to 128 length range, instead of 1 to 31. # IPv6 IP assignments, let us use the following IPv6 network range pre-set "fc00:5182::" aka. "252.0.81.130.0.0.0.0.0.0.0.0.0.0.0.0" # Why? Because we just be just in case and consistent with documenting to everyone. # Why 5182(0)? WireGuard server is running on port 51820, # thus we can use the "5182" infix in the IPv6 prefix to make it more memorable and less likely to cause confusion # with other local network services in the future. postSetup = '' ${pkgs.iptables}/bin/ip6tables -A FORWARD -i wg0 -j ACCEPT ${pkgs.iptables}/bin/ip6tables -t nat -A POSTROUTING -s fc00:5182::1:1/112 -o eth0 -j MASQUERADE ''; # Undo the above postShutdown = '' ${pkgs.iptables}/bin/ip6tables -D FORWARD -i wg0 -j ACCEPT ${pkgs.iptables}/bin/ip6tables -t nat -D POSTROUTING -s fc00:5182::1:1/112 -o eth0 -j MASQUERADE ''; privateKeyFile = config.sops.secrets.wireguard_private.path; #presharedKeyFile = config.sops.secrets.wireguard_preshared.path; }; }; networking.firewall.allowedTCPPorts = [ 51820 ]; networking.firewall.allowedUDPPorts = [ 51820 ]; }; }