blob: c27f32519ff5366fad251f9c4323a7731e06eb03 (
plain)
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
120
121
122
123
124
125
126
127
128
129
130
|
{
lib,
config,
self,
registry,
...
}:
{
config =
let
currenthost = config.networking.hostName;
wg = config.oxalab.wg;
# get all the networks we participate in
networks = builtins.filter (net: builtins.hasAttr "${currenthost}" net.hosts) wg;
# create wg networks
network-attrset = map (net: {
name = "30-wg-${net.networkName}";
value = {
matchConfig.Name = "wg-${net.networkName}";
networkConfig =
{
Address = net.hosts.${currenthost}.address;
IPv6AcceptRA = false; # for now static IPv6
}
// (
if net.hosts.${currenthost}.endpoint.enable then
{
IPv4Forwarding = true;
IPv6Forwarding = true;
}
else
{ }
);
};
}) networks;
systemd-networks = builtins.listToAttrs network-attrset;
# get all the networks we client in
net-client = builtins.filter (net: !net.hosts.${currenthost}.endpoint.enable) networks;
# get all the networks we are endpoint of
net-endpoint = builtins.filter (net: net.hosts.${currenthost}.endpoint.enable) networks;
# wg netdevs
# client
netdev-client-list = map (net: {
name = "30-wg-${net.networkName}";
value = {
netdevConfig = {
Kind = "wireguard";
Name = "wg-${net.networkName}";
};
wireguardConfig.PrivateKeyFile = net.hosts.${currenthost}.privateKeyFile;
# for client this is only endpoint for now
wireguardPeers =
let
endpoint = lib.attrsets.filterAttrs (_k: v: v.endpoint.enable) net.hosts;
wg-peers-attrs = lib.attrsets.mapAttrs (_k: v: {
PersistentKeepalive = 29;
PublicKey = v.publicKey;
Endpoint = "${v.endpoint.endpoint}:${toString v.endpoint.port}";
AllowedIPs = net.CIDRs;
}) endpoint;
wg-peers = lib.attrsets.attrValues wg-peers-attrs;
in
wg-peers;
};
}) net-client;
netdev-client = builtins.listToAttrs netdev-client-list;
maskip = (
net: hostattrs:
if hostattrs.endpoint.enable then
hostattrs.address
else
map (baseaddr: if lib.strings.hasInfix "." baseaddr then "${baseaddr}/32" else "${baseaddr}/128") (
map (addr: builtins.elemAt (lib.strings.splitString "/" addr) 0) hostattrs.address
)
);
# endpoint
# TODO: this requires bit more logic for allowedIPs if we have more then
# 2 endpoints e.g. for routing client -> endpoint1 -> endpoint2 ->
# client2
netdev-endpoint-list = map (net: {
name = "30-wg-${net.networkName}";
value = {
netdevConfig = {
Kind = "wireguard";
Name = "wg-${net.networkName}";
};
wireguardConfig.PrivateKeyFile = net.hosts.${currenthost}.privateKeyFile;
wireguardConfig.ListenPort = net.hosts.${currenthost}.endpoint.port;
wireguardPeers =
let
peers = lib.attrsets.filterAttrs (k: _v: k != currenthost) net.hosts;
wg-peers-attrs = lib.attrsets.mapAttrs (
_k: v:
{
PersistentKeepalive = 29;
PublicKey = v.publicKey;
# only route to /32 or /128, i.e. single client
AllowedIPs = maskip net v;
}
// (
if !isNull v.endpoint.endpoint then
{ Endpoint = "${v.endpoint.endpoint}:${toString v.endpoint.port}"; }
else
{ }
)
) peers;
wg-peers = lib.attrsets.attrValues wg-peers-attrs;
in
wg-peers;
};
}) net-endpoint;
netdev-endpoint = builtins.listToAttrs netdev-endpoint-list;
in
{
# make sure that the networkd and wg are enabled
networking.wireguard.enable = true;
systemd.network.enable = true;
systemd.network.networks = systemd-networks;
systemd.network.netdevs = netdev-client // netdev-endpoint;
};
}
|