-
Notifications
You must be signed in to change notification settings - Fork 15
/
wireguard.nix
119 lines (87 loc) · 3.28 KB
/
wireguard.nix
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
{ lib, config, ... }:
let
inherit (lib) types;
wireguardNetworks = lib.filterAttrs (name: net: net.enable && net.backend == "wireguard") config.vpn.networks;
in {
options.vpn.networks = lib.mkOption {
type = types.attrsOf (types.submodule {
options.backend = lib.mkOption {
type = types.enum [ "wireguard" ];
};
options.server.wireguard.publicKey = lib.mkOption {
type = types.str;
};
options.server.wireguard.privateKeyFile = lib.mkOption {
type = types.path;
};
options.clients = lib.mkOption {
type = types.attrsOf (types.submodule {
options.wireguard.publicKey = lib.mkOption {
type = types.str;
};
options.wireguard.privateKeyFile = lib.mkOption {
type = types.path;
};
});
};
config.server.port = lib.mkDefault 51820;
});
};
config.nodes = lib.mkMerge (lib.flip lib.mapAttrsToList wireguardNetworks (name: net:
let
interface = "nixus-${name}";
parsedSubnet = lib.ip.parseSubnet net.subnet;
in {
${net.server.node}.configuration = lib.mkMerge [
{
networking.firewall.allowedUDPPorts = [ net.server.port ];
networking.firewall.trustedInterfaces = [ interface ];
# Needed for both networking between clients and for client -> internet
boot.kernel.sysctl."net.ipv4.conf.${interface}.forwarding" = true;
networking.wg-quick.interfaces.${interface} = {
address = [ "${net.server.subnetIp}/${toString parsedSubnet.cidr}" ];
listenPort = net.server.port;
privateKeyFile = net.server.wireguard.privateKeyFile;
peers = lib.mapAttrsToList (clientNode: clientValue: {
publicKey = clientValue.wireguard.publicKey;
allowedIPs = [ "${clientValue.subnetIp}/32" ];
}) net.clients;
};
}
(lib.mkIf net.server.internetGateway {
networking.nat = {
enable = true;
externalInterface = net.server.internetGatewayInterface;
internalInterfaces = [ interface ];
};
networking.wg-quick.interfaces.${interface} = {
postUp = ''
iptables -t nat -A POSTROUTING -j MASQUERADE \
-s ${parsedSubnet.subnet} -o ${net.server.internetGatewayInterface}
'';
postDown = ''
iptables -t nat -D POSTROUTING -j MASQUERADE \
-s ${parsedSubnet.subnet} -o ${net.server.internetGatewayInterface}
'';
};
})
];
}
// lib.flip lib.mapAttrs net.clients (clientNode: clientValue: {
configuration = {
networking.firewall.trustedInterfaces = [ interface ];
networking.wg-quick.interfaces.${interface} = {
address = [ "${clientValue.subnetIp}/${toString parsedSubnet.cidr}" ];
privateKeyFile = clientValue.wireguard.privateKeyFile;
peers = lib.singleton {
publicKey = net.server.wireguard.publicKey;
allowedIPs = if clientValue.internetGateway
then [ "0.0.0.0/0" ]
else [ parsedSubnet.subnet ];
endpoint = "${config.nodes.${net.server.node}.configuration.networking.public.ipv4}:${toString net.server.port}";
persistentKeepalive = 25;
};
};
};
})));
}