diff --git a/flake.nix b/flake.nix index c50d7df..67e7f0d 100644 --- a/flake.nix +++ b/flake.nix @@ -23,6 +23,7 @@ mkLocalModsInput lanzaboote.nixosModules.lanzaboote inputs.microvm.nixosModules.host + ./hosts/network.nix ]; }; passInputs = { diff --git a/hosts/network.nix b/hosts/network.nix new file mode 100644 index 0000000..a5ba3ca --- /dev/null +++ b/hosts/network.nix @@ -0,0 +1,77 @@ +{lib, ...}: let + prefix = "lyn"; + + #define wireguard subnets + wg_subnets = { + v4 = "10.35.0.1/24"; + v6 = "fd1a:acab:cafe:1337::/64"; + }; + + #Below is where all hosts are defined + hosts = { + wg-gateway = { + wg = { + enabled = true; + pubkey = "lol"; + port = 51820; + }; + v4 = { + public = "78.47.226.47"; + # we use 10.35.0.0/16 as a range for private subnets, specifically 10.35.0.0/24 for wireguard peers + internal = "10.35.0.1"; + }; + v6 = { + public = "2a01:4f8:1c1b:d2db::"; + # 1aacabcafe is the global ID and 1337 is the wireguard peer subnet ID, resulting in the ULA fd1a:acab:cafe:1337::/64 + internal = "fd1a:acab:cafe:1337:8f4c:68cd"; + }; + }; + supernova = { + wg = { + enabled = true; + pubkey = "lol"; + port = 51820; + }; + v4 = { + public = ""; + # we use 10.35.0.0/16 as a range for private subnets, specifically 10.35.0.0/24 for wireguard peers + internal = "10.35.0.2"; + }; + v6 = { + public = ""; + # 1aacabcafe is the global ID and 1337 is the wireguard peer subnet ID, resulting in the ULA fd1a:acab:cafe:1337::/64 + internal = "fd1a:acab:cafe:1337:6722:3657"; + }; + }; + }; + + # function to make a peerlist suitable for wgautomesh + buildPeerlist = version: hosts: let + #filter out hosts that have wg.enabled set to false + wgEnabledHosts = lib.filterAttrs (_: host: host.wg.enabled or false) hosts; + #filter out hosts that don't support IP{$version} + filteredHosts = lib.filterAttrs (_: host: host.${version}.public != "") wgEnabledHosts; + in + lib.mapAttrs (name: host: { + pubkey = host.wg.pubkey; + #if there is no public IP, make endpoint null so wgautomesh knows it unknown + endpoint = + if host.${version}.public == "" + then null + else host.${version}.public; + address = host.${version}.internal; + }) + filteredHosts; +in { + ${prefix}.network = { + IPv4 = { + wg_subnet = wg_subnets.v4; + peerlist = buildPeerlist "v4" hosts; + }; + IPv6 = { + wg_subnet = wg_subnets.v6; + peerlist = buildPeerlist "v6" hosts; + }; + inherit hosts; + }; +} diff --git a/hosts/wg-gateway/default.nix b/hosts/wg-gateway/default.nix index ed87bde..ccacb82 100644 --- a/hosts/wg-gateway/default.nix +++ b/hosts/wg-gateway/default.nix @@ -17,6 +17,9 @@ lyn.users.lyn.enable = true; # network + + lyn.services.wgautomesh.enable = true; + networking.useDHCP = false; networking.hostName = "wg-gateway"; # Define your hostname. systemd.network.enable = true; diff --git a/modules/services/wgautomesh.nix b/modules/services/wgautomesh.nix new file mode 100644 index 0000000..b1da2df --- /dev/null +++ b/modules/services/wgautomesh.nix @@ -0,0 +1,34 @@ +{ + config, + pkgs, + lib, + cfg, + ... +}: { + opt.useIPv6 = lib.mkOption { + type = lib.types.bool; + description = "Whether to use IPv6. Defaults to true"; + default = true; + }; + # helper vars to prettify + currentHost = lyn.network.hosts.${networking.hostName}; + wireguardPort = currentHost.wg.port; + + networking.wireguard.interfaces.wg0 = { + ips = ["${lyn.network.IPv4.wg_subnet}"]; + listenPort = cfg.wireguardPort; + privateKeyFile = "/var/lib/wireguard-keys/private"; + mtu = 1420; + }; + services.wgautomesh = { + enable = true; + services.wgautomesh.settings = { + interface = "wg0"; + peers = + if opt.useIPv6 + then lyn.network.IPv6.peerlist + else lyn.network.IPv4.peerlist; + upnp_forward_external_port = wireguardPort; + }; + }; +}