summaryrefslogtreecommitdiff
path: root/modules
diff options
context:
space:
mode:
Diffstat (limited to 'modules')
-rw-r--r--modules/foundation/default.nix1
-rw-r--r--modules/foundation/vpn.nix90
-rw-r--r--modules/tunnel/definition.nix31
-rw-r--r--modules/tunnel/ingress.nix6
4 files changed, 95 insertions, 33 deletions
diff --git a/modules/foundation/default.nix b/modules/foundation/default.nix
index 3905eb8..fa84750 100644
--- a/modules/foundation/default.nix
+++ b/modules/foundation/default.nix
@@ -6,5 +6,6 @@
./services
./monitoring
./www
+ ./vpn.nix
];
}
diff --git a/modules/foundation/vpn.nix b/modules/foundation/vpn.nix
new file mode 100644
index 0000000..1a7524d
--- /dev/null
+++ b/modules/foundation/vpn.nix
@@ -0,0 +1,90 @@
+{
+ config,
+ lib,
+ ...
+}:
+
+let
+ inherit (lib)
+ mkEnableOption
+ mkOption
+ types
+ mkIf
+ attrValues
+ replaceString
+ ;
+
+ cfg = config.foundation.vpn;
+
+ inherit (import ../../assets/vpn.nix) users;
+
+ interface = "vpn0";
+ port = 51820;
+
+ # while the tunnel uses the lower subnets for the paths,
+ # the vpn always uses subnet number 10.
+ subnetIndex = 10;
+
+ addressFromTemplate =
+ template: prefix: "${replaceString "X" (toString subnetIndex) template}/${toString prefix}";
+in
+{
+ options.foundation.vpn = {
+ enable = mkEnableOption "WireGuard VPN server";
+
+ externalInterface = mkOption {
+ type = types.str;
+ description = "External network interface";
+ };
+ };
+
+ config = mkIf cfg.enable {
+ age.secrets.wg-private-key = {
+ file = ../../secrets/wg-private-key.age;
+ owner = "systemd-network";
+ };
+
+ networking.firewall.allowedUDPPorts = [ port ];
+
+ systemd.network = {
+ netdevs."30-${interface}" = {
+ netdevConfig = {
+ Kind = "wireguard";
+ Name = interface;
+ };
+ wireguardConfig = {
+ PrivateKeyFile = config.age.secrets.wg-private-key.path;
+ ListenPort = port;
+ };
+ wireguardPeers = map (user: {
+ PublicKey = user.key;
+ AllowedIPs = [ (addressFromTemplate user.ip 32) ];
+ }) (attrValues users);
+ };
+
+ networks."30-${interface}" = {
+ name = interface;
+ address = [ (addressFromTemplate "10.123.X.1" 24) ];
+ linkConfig = {
+ RequiredForOnline = "no";
+ };
+ };
+ };
+
+ networking.nftables.tables.vpn-nat = {
+ family = "ip";
+ content = ''
+ chain postrouting {
+ type nat hook postrouting priority srcnat; policy accept;
+ iifname "${interface}" oifname "${cfg.externalInterface}" masquerade
+ }
+
+ chain forward {
+ type filter hook forward priority 0; policy accept;
+ iifname "${interface}" oifname "${cfg.externalInterface}" accept
+ iifname "${cfg.externalInterface}" oifname "${interface}" ct state established,related accept
+ }
+ '';
+ };
+ };
+}
diff --git a/modules/tunnel/definition.nix b/modules/tunnel/definition.nix
index 74ae268..82534bf 100644
--- a/modules/tunnel/definition.nix
+++ b/modules/tunnel/definition.nix
@@ -36,40 +36,11 @@
}
];
- # there are our users who are allowed to connect to any of our "paths".
- # their ip is always a template, with 'X' representing the path index.
- users = {
- mel = {
- key = "vnZoHXapCLLUhZ8A8R5W0iJ8LpWVLve29z41kkoT0BU=";
- ip = "10.123.X.101";
- };
-
- andrei = {
- key = "qqU4uYImLfUohIwl4KBshPtTINFcs0JVALjbmwpfxRg=";
- ip = "10.123.X.102";
- };
-
- sergo = {
- key = "qbZGMNIDZFCJC6SHtlyNIlIdGWHELceXClJCcagrj2Y=";
- ip = "10.123.X.103";
- };
-
- fedor = {
- key = "tEO9r8+jTpu8TBRmZ+/v087IgD/QfmofLUKs249i/F0=";
- ip = "10.123.X.104";
- };
- };
+ inherit (import ../../assets/vpn.nix) users;
# we use a website as a "mask" for vless/reality, which will tell our peers
# to pretend as if they're a user and a well-known website communicating with
# each other, even though they know that the keys don't actually match up,
# it's not possible to see that on the outside.
mask = "microsoft.com";
-
- # we don't actually need this to configure the tunnel, but this is
- # the public key of the ingress interface.
- # when creating wireguard vpn configurations for the users, this
- # is the public key of the server peer at `tunnel.rnrd.eu`.
- # the matching private key of the pair is the secret `tunnel/ingress-key`.
- ingress.public = "s5yyPCJiN0uqW0jzKIbYCF7I9TthymiRzpNt466XeWk=";
}
diff --git a/modules/tunnel/ingress.nix b/modules/tunnel/ingress.nix
index 1ea1613..f609f3d 100644
--- a/modules/tunnel/ingress.nix
+++ b/modules/tunnel/ingress.nix
@@ -38,8 +38,8 @@ in
checkReversePath = "loose";
};
- age.secrets.ingress-key = {
- file = ../../secrets/tunnel/ingress-key.age;
+ age.secrets.wg-private-key = {
+ file = ../../secrets/wg-private-key.age;
owner = "systemd-network";
};
@@ -52,7 +52,7 @@ in
Name = ingressName index;
};
wireguardConfig = {
- PrivateKeyFile = config.age.secrets.ingress-key.path;
+ PrivateKeyFile = config.age.secrets.wg-private-key.path;
ListenPort = path.port;
};
wireguardPeers = map (user: {