{ config, self, lib, inputs, options, pkgs, ... }: with lib; let cfg = config.services.malobeo.vpn; peers = import ./peers.nix; myPeer = if cfg.name == "" then peers.${config.networking.hostName} else 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" "address" "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"; }; autostart = mkOption { default = true; type = types.bool; description = lib.mdDoc "whether to autostart vpn interface on boot"; }; name = mkOption { default = ""; type = types.str; description = '' Name of the host in peers.nix, if empty uses hostname ''; }; privateKeyFile = mkOption { default = ""; type = types.str; description = '' Path to private key ''; }; }; }; config = mkIf cfg.enable { assertions = [ { assertion = !(myPeer.role != "client" && myPeer.role != "server"); message = '' VPN Role must be either client or server, nothing else! ''; } ]; boot.kernel.sysctl."net.ipv4.ip_forward" = mkIf (myPeer.role == "server") 1; networking.wg-quick = { interfaces = { malovpn = { mtu = 1340; #seems to be necessary to proxypass nginx traffic through vpn address = [ "${myPeer.address}/24" ]; autostart = cfg.autostart; 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 postUp = mkIf (myPeer.role == "server") '' ${pkgs.iptables}/bin/iptables -t nat -A POSTROUTING -s 10.100.0.0/24 -o enp0s3 -j MASQUERADE ''; # This undoes the above command postDown = mkIf (myPeer.role == "server") '' ${pkgs.iptables}/bin/iptables -t nat -D POSTROUTING -s 10.100.0.0/24 -o enp0s3 -j MASQUERADE ''; privateKeyFile = cfg.privateKeyFile; peers = filteredPeerlist; }; }; }; #networking.nat = mkIf (myPeer.role == "server"){ # enable = true; # internalInterfaces = [ "microvm" ]; # externalInterface = "eth0"; #change to your interface name #}; }; }