summary refs log tree commit diff
path: root/modules/foundation/wireguard.nix
diff options
context:
space:
mode:
Diffstat (limited to 'modules/foundation/wireguard.nix')
-rw-r--r--modules/foundation/wireguard.nix117
1 files changed, 117 insertions, 0 deletions
diff --git a/modules/foundation/wireguard.nix b/modules/foundation/wireguard.nix
new file mode 100644
index 0000000..110a2a4
--- /dev/null
+++ b/modules/foundation/wireguard.nix
@@ -0,0 +1,117 @@
+{
+  config,
+  pkgs,
+  lib,
+  ...
+}:
+
+let
+  inherit (pkgs) iptables;
+
+  inherit (lib)
+    mkIf
+    mkEnableOption
+    mkOption
+    ;
+
+  cfg = config.foundation.wireguard;
+
+  # TODO: we might want to configure these through options?
+
+  wireguardPort = 51820;
+  wireguardIPv4 = number: subnet: "10.123.10.${number}/${subnet}";
+  wireguardIPv6 = number: subnet: "fd0f:123::${number}/${subnet}";
+
+  wireguardInterface = "wg0";
+
+  peerIPs = peerNumber: [
+    (wireguardIPv4 peerNumber "32")
+    (wireguardIPv6 peerNumber "128")
+  ];
+
+  peers = [
+    # mel
+    {
+      publicKey = "vnZoHXapCLLUhZ8A8R5W0iJ8LpWVLve29z41kkoT0BU=";
+      allowedIPs = peerIPs "2";
+    }
+
+    # andrei
+    {
+      publicKey = "qqU4uYImLfUohIwl4KBshPtTINFcs0JVALjbmwpfxRg=";
+      allowedIPs = peerIPs "3";
+    }
+
+    # sergo
+    {
+      publicKey = "qbZGMNIDZFCJC6SHtlyNIlIdGWHELceXClJCcagrj2Y=";
+      allowedIPs = peerIPs "4";
+    }
+  ];
+in
+{
+  options.foundation.wireguard = {
+    server = {
+      enable = mkEnableOption "wireguard vpn server";
+
+      externalInterface = mkOption {
+        type = lib.types.string;
+        default = "eth0";
+      };
+    };
+  };
+
+  config = mkIf cfg.server.enable {
+    age.secrets.wireguard-private-key = {
+      file = ../../secrets/wireguard-private-key.age;
+    };
+
+    # enable nat, to rename internal wireguard ips to external ip (w/ iptables)
+    networking = {
+      nat = {
+        enable = true;
+        internalInterfaces = [ wireguardInterface ];
+        inherit (cfg.server) externalInterface;
+      };
+
+      firewall = {
+        allowedUDPPorts = [ wireguardPort ];
+      };
+    };
+
+    # enable kernel support for ipv6 forwarding
+    boot.kernel.sysctl = {
+      "net.ipv6.conf.all.forwarding" = 1;
+      "net.ipv6.conf.default.forwarding" = 1;
+    };
+
+    networking.wireguard.interfaces.${wireguardInterface} = let
+      inherit (cfg.server) externalInterface;
+    in
+    {
+      inherit peers;
+
+      # ip address of server + subnet of network
+      ips = [
+        (wireguardIPv4 "1" "24")
+        (wireguardIPv6 "1" "112")
+      ];
+      listenPort = wireguardPort;
+
+      # route wireguard traffic to the internet
+      # also requires clients to have dns set. (i think)
+      # to avoid, maybe? use wg-quick + dnsmasq?
+      postSetup = ''
+        ${iptables}/bin/iptables -t nat -A POSTROUTING -s ${wireguardIPv4 "0" "24"} -o ${externalInterface} -j MASQUERADE
+        ${iptables}/bin/ip6tables -t nat -A POSTROUTING -s ${wireguardIPv6 "0" "112"} -o ${externalInterface} -j MASQUERADE
+      '';
+
+      postShutdown = ''
+        ${iptables}/bin/iptables -t nat -D POSTROUTING -s ${wireguardIPv4 "0" "24"} -o ${externalInterface} -j MASQUERADE
+        ${iptables}/bin/ip6tables -t nat -D POSTROUTING -s ${wireguardIPv6 "0" "112"} -o ${externalInterface} -j MASQUERADE
+      '';
+
+      privateKeyFile = config.age.secrets.wireguard-private-key.path;
+    };
+  };
+}