{ config, self, lib, inputs, options, pkgs, ... }: with lib; let cfg = config.services.malobeo.vpn; peers = import ./peers.nix; myPeer = peers.${cfg.name}; peerList = builtins.filter (peer: peer.role != myPeer.role) (builtins.attrValues peers); peerListWithEndpoint = map (host: if host.role == "server" then host // { endpoint = "${host.publicIp}:${builtins.toString host.listenPort}"; } else host ) peerList; filteredPeerlist = map (host: builtins.removeAttrs host [ "role" "ips" "listenPort" "publicIp" ] ) peerListWithEndpoint; in { options = { services.malobeo.vpn = { enable = mkOption { default = false; type = types.bool; description = lib.mdDoc "Setup wireguard to access malobeo maintainance vpn"; }; name = mkOption { default = ""; type = types.str; description = '' Name of the host in peers.nix ''; }; privateKey = mkOption { default = ""; type = types.str; description = '' Path to private key ''; }; }; }; imports = [ inputs.microvm.nixosModules.host ]; config = mkIf cfg.enable { assertions = [ #{ # assertion = !(myPeer != "client" && cfg.role != "server"); # message = '' # VPN Role must be either client or server, nothing else! # ''; #} ]; networking.wireguard = { enable = true; interfaces = { wg0 = { ips = myPeer.ips; listenPort = mkIf (myPeer.role == "server") myPeer.listenPort; # This allows the wireguard server to route your traffic to the internet and hence be like a VPN # For this to work you have to set the dnsserver IP of your router (or dnsserver of choice) in your clients postSetup = mkIf (myPeer.role == "server") '' ${pkgs.iptables}/bin/iptables -t nat -A POSTROUTING -s 10.100.0.0/24 -o eth0 -j MASQUERADE ''; # This undoes the above command postShutdown = mkIf (myPeer.role == "server") '' ${pkgs.iptables}/bin/iptables -t nat -D POSTROUTING -s 10.100.0.0/24 -o eth0 -j MASQUERADE ''; privateKey = cfg.privateKey; peers = filteredPeerlist; }; }; }; }; }