{ config, pkgs, lib, cfg, ... }: let prefix = "lyn"; # decrypt gossip secret # change this to comply with you secret management gossip_secret_path = config.sops.secrets."all/meshnetwork/gossip_secret".path; # 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} != null) wgEnabledHosts; in lib.mapAttrsToList (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}:${toString host.wg.port}"; address = host.${version}.internal; }) filteredHosts; # helper vars to prettify meshnetwork = config.${prefix}.network; currentHost = meshnetwork.hosts.${config.networking.hostName}; wireguardPort = currentHost.wg.port; in { opt.useIPv6 = lib.mkOption { type = lib.types.bool; description = "Whether to use IPv6. Defaults to true"; default = true; }; config = { networking.firewall = { allowedUDPPorts = [ wireguardPort ]; extraCommands = '' # Allow UDP packets comming from port 1900 from a local address, # these are necessary for UPnP/IGD iptables -A INPUT -s 192.168.0.0/16 -p udp --sport 1900 -j ACCEPT ''; extraStopCommands = '' iptables -D INPUT -s 192.168.0.0/16 -p udp --sport 1900 -j ACCEPT ''; }; networking.wireguard.interfaces.wg0 = { ips = if cfg.useIPv6 then ["${currentHost.IPv6.internal}/64"] else ["${currentHost.IPv4.internal}/24"]; listenPort = wireguardPort; privateKeyFile = "/var/lib/wireguard-keys/private"; mtu = 1200; }; services.wgautomesh = { enable = true; settings = { interface = "wg0"; peers = if cfg.useIPv6 then buildPeerlist "IPv6" meshnetwork.hosts else buildPeerlist "IPv4" meshnetwork.hosts; upnp_forward_external_port = wireguardPort; }; gossipSecretFile = gossip_secret_path; #DEBUG logLevel = "trace"; }; }; }