From 4a7bda944f14278b2c495685bba296e62ddb87a0 Mon Sep 17 00:00:00 2001 From: Fabian Montero Date: Sat, 25 Jan 2025 00:10:50 -0600 Subject: [PATCH] add ipv6 support, net module and wireguard vpn --- sys/modules/default.nix | 1 + sys/modules/net.nix | 186 +++++++++++++++++++++++++++++++ sys/platforms/vps/default.nix | 65 ++++++++++- sys/platforms/vps/networkMap.nix | 78 +++++++++++++ sys/platforms/vps/srv/net.nix | 2 +- 5 files changed, 328 insertions(+), 4 deletions(-) create mode 100644 sys/modules/net.nix create mode 100644 sys/platforms/vps/networkMap.nix diff --git a/sys/modules/default.nix b/sys/modules/default.nix index 2f2bccf..2cdd9a2 100644 --- a/sys/modules/default.nix +++ b/sys/modules/default.nix @@ -13,5 +13,6 @@ ./android.nix ./users.nix ./bluetooth.nix + ./net.nix ]; } diff --git a/sys/modules/net.nix b/sys/modules/net.nix new file mode 100644 index 0000000..7ff7721 --- /dev/null +++ b/sys/modules/net.nix @@ -0,0 +1,186 @@ +{ + config, + lib, + ... +}: +with lib; { + options.local.sys.nets = with lib.types; + mkOption { + readOnly = true; + + type = attrsOf (submodule ({config, ...}: { + options = let + v4config = config.v4; + v6config = config.v6; + in { + hosts = mkOption { + default = {}; + + type = attrsOf (submodule { + options = { + v4 = mkOption { + default = null; + + type = nullOr (submodule ({config, ...}: { + options = { + suffix = mkOption { + type = str; + }; + + address = mkOption { + type = str; + readOnly = true; + }; + + cidr = mkOption { + type = str; + readOnly = true; + }; + + single = mkOption { + type = str; + readOnly = true; + }; + }; + + config = { + address = + if v4config.bits == 0 + then config.suffix + else if v4config.bits == 32 + then v4config.subnet + else "${v4config.prefix}.${config.suffix}"; + + cidr = "${config.address}/${toString v4config.bits}"; + single = "${config.address}/32"; + }; + })); + }; + + v6 = mkOption { + default = null; + + type = nullOr (submodule ({config, ...}: { + options = { + suffix = mkOption { + type = str; + }; + + address = mkOption { + type = str; + readOnly = true; + }; + + cidr = mkOption { + type = str; + readOnly = true; + }; + + single = mkOption { + type = str; + readOnly = true; + }; + }; + + config = { + address = let + hextets = fragment: length (splitString ":" fragment); + separator = + if doubleColon + then "::" + else ":"; + doubleColon = hextets v6config.prefix + hextets config.suffix < 8; + + joined = + if v6config.bits == 128 + then v6config.prefix + else if v6config.bits == 0 + then config.suffix + else "${v6config.prefix}${separator}${config.suffix}"; + in + joined; + + cidr = "${config.address}/${toString v6config.bits}"; + single = "${config.address}/128"; + }; + })); + }; + }; + }); + }; + + v4 = mkOption { + default = null; + + type = nullOr (submodule ({config, ...}: { + options = { + bits = mkOption { + type = enum [0 8 16 24 32]; + }; + + prefix = mkOption { + type = str; + }; + + subnet = mkOption { + type = str; + readOnly = true; + }; + + cidr = mkOption { + type = str; + readOnly = true; + }; + }; + + config = { + cidr = "${config.subnet}/${toString config.bits}"; + subnet = + if config.bits != 0 + then config.prefix + strings.replicate (4 - config.bits / 8) ".0" + else "0.0.0.0"; + }; + })); + }; + + v6 = mkOption { + default = null; + + type = nullOr (submodule ({config, ...}: { + options = { + bits = mkOption { + type = + addCheck (ints.between 0 128) (b: mod b 4 == 0) + // { + description = "IPv6 subnet bits at nibble boundary"; + }; + }; + + prefix = mkOption { + type = str; + }; + + subnet = mkOption { + type = str; + readOnly = true; + }; + + cidr = mkOption { + type = str; + readOnly = true; + }; + }; + + config = { + cidr = "${config.subnet}/${toString config.bits}"; + subnet = + if config.bits == 128 || length (splitString "::" config.prefix) > 1 + then config.prefix + else "${config.prefix}::"; + }; + })); + }; + }; + })); + }; +} diff --git a/sys/platforms/vps/default.nix b/sys/platforms/vps/default.nix index b949d4c..9801183 100644 --- a/sys/platforms/vps/default.nix +++ b/sys/platforms/vps/default.nix @@ -13,6 +13,7 @@ with lib; { flakes.impermanence.nixosModule ./hardware-configuration.nix ./srv + ./networkMap.nix ]; local.sys = { @@ -50,9 +51,67 @@ with lib; { }; }; - systemd.extraConfig = '' - DefaultTimeoutStartSec=900s - ''; + networking.firewall.allowedUDPPorts = [51820]; #TODO + + systemd = { + extraConfig = '' + DefaultTimeoutStartSec=900s + ''; + + network = let + inherit (config.local.sys) nets; + in { + enable = true; + + netdevs = { + wg-vpn = { + netdevConfig = { + Name = "wg-vpn"; + Kind = "wireguard"; + }; + + wireguardConfig = { + PrivateKeyFile = "/var/trust/wg/vpn/key.priv"; + ListenPort = "51820"; + }; + + wireguardPeers = [ + { + PublicKey = "wwUp3Uu/rSxbp+6J745O+cpnZHGWOJYWfWEsTjRE3yU="; + PresharedKeyFile = "/var/trust/wg/vpn/vps-posixlycorrect.psk"; + AllowedIPs = ["${nets.vpn-posixlycorrect.v6.cidr}"]; + } + { + PublicKey = "YFqg/ED26KygSRSmGzvUXpwnXPqMOI3R3caVfAtHVks="; + PresharedKeyFile = "/var/trust/wg/vpn/vps-pixel8.psk"; + AllowedIPs = ["${nets.vpn-pixel8.v6.cidr}"]; + } + ]; + }; + }; + + networks = { + wg-vpn = { + name = "wg-vpn"; + + networkConfig = { + Address = [ + nets.vpn-vps.hosts.vps.v6.cidr + ]; + }; + + routes = [ + { + Destination = nets.vpn.v6.cidr; + } + { + Source = nets.vpn.v6.cidr; + } + ]; + }; + }; + }; + }; time.timeZone = "Europe/Amsterdam"; } diff --git a/sys/platforms/vps/networkMap.nix b/sys/platforms/vps/networkMap.nix new file mode 100644 index 0000000..473815e --- /dev/null +++ b/sys/platforms/vps/networkMap.nix @@ -0,0 +1,78 @@ +{ + config, + pkgs, + lib, + flakes, + ... +}: +with lib; { + local.sys.nets = { + default = { + v4 = { + bits = 32; + prefix = "37.205.12.34"; + }; + + v6 = { + bits = 64; + prefix = "2a03:3b40:fe:102"; + }; + + hosts = { + vps.v6.suffix = "1"; + vps.v4.suffix = ""; + }; + }; + + vpn = { + v6 = { + bits = 48; + prefix = "2a03:3b40:2b"; + }; + }; + + vpn-vps = { + v6 = { + bits = 64; + prefix = "2a03:3b40:2b:1000"; + }; + + hosts = { + vps.v6.suffix = "1"; + }; + }; + + vpn-posixlycorrect = { + v6 = { + bits = 64; + prefix = "2a03:3b40:2b:1001"; + }; + + hosts = { + posixlycorrect.v6.suffix = "1"; + }; + }; + + vpn-pixel8 = { + v6 = { + bits = 64; + prefix = "2a03:3b40:2b:1002"; + }; + + hosts = { + pixel8.v6.suffix = "1"; + }; + }; + + vpn-t14 = { + v6 = { + bits = 64; + prefix = "2a03:3b40:2b:1003"; + }; + + hosts = { + t14.v6.suffix = "1"; + }; + }; + }; +} diff --git a/sys/platforms/vps/srv/net.nix b/sys/platforms/vps/srv/net.nix index fdd3dd8..927e347 100644 --- a/sys/platforms/vps/srv/net.nix +++ b/sys/platforms/vps/srv/net.nix @@ -5,7 +5,7 @@ }: with lib; { networking = { - nftables.enable = true; + nftables.enable = false; # learn how to use this later firewall = { enable = true; allowedTCPPorts = [80 443];