summaryrefslogtreecommitdiff
path: root/modules
diff options
context:
space:
mode:
authorGregor Kleen <gkleen@yggdrasil.li>2021-11-03 23:28:00 +0100
committerGregor Kleen <gkleen@yggdrasil.li>2021-11-03 23:28:00 +0100
commit3d5b1509be78c0e9d8923af7e63f38d9dcbdefdf (patch)
treeab98231775abe2dc7ec29b98d0f6444a7b7d56a7 /modules
parentc47b09353f424eed1ef99bb41a9285ac87b051f2 (diff)
downloadnixos-3d5b1509be78c0e9d8923af7e63f38d9dcbdefdf.tar
nixos-3d5b1509be78c0e9d8923af7e63f38d9dcbdefdf.tar.gz
nixos-3d5b1509be78c0e9d8923af7e63f38d9dcbdefdf.tar.bz2
nixos-3d5b1509be78c0e9d8923af7e63f38d9dcbdefdf.tar.xz
nixos-3d5b1509be78c0e9d8923af7e63f38d9dcbdefdf.zip
yggdrasil-wg: dual stack
Diffstat (limited to 'modules')
-rw-r--r--modules/yggdrasil-wg/default.nix173
-rw-r--r--modules/yggdrasil-wg/hosts/4/sif.priv (renamed from modules/yggdrasil-wg/hosts/sif.priv)0
-rw-r--r--modules/yggdrasil-wg/hosts/4/sif.pub (renamed from modules/yggdrasil-wg/hosts/sif.pub)0
-rw-r--r--modules/yggdrasil-wg/hosts/4/surtr.priv (renamed from modules/yggdrasil-wg/hosts/surtr.priv)0
-rw-r--r--modules/yggdrasil-wg/hosts/4/surtr.pub (renamed from modules/yggdrasil-wg/hosts/surtr.pub)0
-rw-r--r--modules/yggdrasil-wg/hosts/4/vidhar.priv (renamed from modules/yggdrasil-wg/hosts/vidhar.priv)0
-rw-r--r--modules/yggdrasil-wg/hosts/4/vidhar.pub (renamed from modules/yggdrasil-wg/hosts/vidhar.pub)0
-rw-r--r--modules/yggdrasil-wg/hosts/6/sif.priv26
-rw-r--r--modules/yggdrasil-wg/hosts/6/sif.pub1
-rw-r--r--modules/yggdrasil-wg/hosts/6/surtr.priv26
-rw-r--r--modules/yggdrasil-wg/hosts/6/surtr.pub1
-rw-r--r--modules/yggdrasil-wg/hosts/6/vidhar.priv26
-rw-r--r--modules/yggdrasil-wg/hosts/6/vidhar.pub1
13 files changed, 177 insertions, 77 deletions
diff --git a/modules/yggdrasil-wg/default.nix b/modules/yggdrasil-wg/default.nix
index cef1ce4e..55064baa 100644
--- a/modules/yggdrasil-wg/default.nix
+++ b/modules/yggdrasil-wg/default.nix
@@ -4,10 +4,13 @@ with lib;
4 4
5let 5let
6 listenPort = 51820; 6 listenPort = 51820;
7 wgSubnet = "2a03:4000:52:ada:1"; 7 wgSubnet = {
8 "4" = "2a03:4000:52:ada:2";
9 "6" = "2a03:4000:52:ada:3";
10 };
8 wgSubnetLength = 80; 11 wgSubnetLength = 80;
9 wgHostLength = wgSubnetLength + 16; 12 wgHostLength = wgSubnetLength + 16;
10 batSubnet = "2a03:4000:52:ada:2"; 13 batSubnet = "2a03:4000:52:ada:1";
11 batSubnetLength = 80; 14 batSubnetLength = 80;
12 batHostLength = batSubnetLength + 16; 15 batHostLength = batSubnetLength + 16;
13 16
@@ -16,27 +19,49 @@ let
16 to = "surtr"; 19 to = "surtr";
17 endpointHost = "202.61.241.61"; 20 endpointHost = "202.61.241.61";
18 PersistentKeepalive = 25; 21 PersistentKeepalive = 25;
22 family = "4";
23 }
24 { from = "vidhar";
25 to = "surtr";
26 endpointHost = "2a03:4000:52:ada::";
27 PersistentKeepalive = 25;
28 family = "6";
29 }
30 { from = "sif";
31 to = "surtr";
32 endpointHost = "202.61.241.61";
33 PersistentKeepalive = 25;
34 family = "4";
19 } 35 }
20 { from = "sif"; 36 { from = "sif";
21 to = "surtr"; 37 to = "surtr";
22 endpointHost = "2a03:4000:52:ada::"; 38 endpointHost = "2a03:4000:52:ada::";
23 PersistentKeepalive = 25; 39 PersistentKeepalive = 25;
40 family = "6";
24 } 41 }
25 { from = "sif"; 42 { from = "sif";
26 to = "vidhar"; 43 to = "vidhar";
27 endpointHost = "192.168.2.168"; 44 endpointHost = "192.168.2.168";
28 PersistentKeepalive = 25; 45 PersistentKeepalive = 25;
46 family = "4";
29 } 47 }
30 ]; 48 ];
31 wgHostIPs = { 49 wgHostIPs = mapAttrs (_family: wgSubnet: {
32 surtr = "${wgSubnet}::/${toString wgHostLength}"; 50 surtr = "${wgSubnet}::/${toString wgHostLength}";
33 vidhar = "${wgSubnet}:1::/${toString wgHostLength}"; 51 vidhar = "${wgSubnet}:1::/${toString wgHostLength}";
34 sif = "${wgSubnet}:2::/${toString wgHostLength}"; 52 sif = "${wgSubnet}:2::/${toString wgHostLength}";
35 }; 53 }) wgSubnet;
36 greHostMACPrefixes = { 54 greHostMACPrefixes = {
37 surtr = "02:00:01:00:00"; 55 "4" = {
38 vidhar = "02:00:01:00:01"; 56 surtr = "02:00:01:00:00";
39 sif = "02:00:01:00:02"; 57 vidhar = "02:00:01:00:01";
58 sif = "02:00:01:00:02";
59 };
60 "6" = {
61 surtr = "02:00:02:00:00";
62 vidhar = "02:00:02:00:01";
63 sif = "02:00:02:00:02";
64 };
40 }; 65 };
41 batHostMACs = { 66 batHostMACs = {
42 surtr = "02:00:00:00:00:00"; 67 surtr = "02:00:00:00:00:00";
@@ -49,46 +74,47 @@ let
49 sif = ["${batSubnet}:2::/${toString batHostLength}"]; 74 sif = ["${batSubnet}:2::/${toString batHostLength}"];
50 }; 75 };
51 76
52 mkPublicKeyPath = host: ./hosts + "/${host}.pub"; 77 mkPublicKeyPath = family: host: ./hosts + "/${family}" + "/${host}.pub";
53 mkPrivateKeyPath = host: ./hosts + "/${host}.priv"; 78 mkPrivateKeyPath = family: host: ./hosts + "/${family}" + "/${host}.priv";
54 79
55 kernel = config.boot.kernelPackages; 80 kernel = config.boot.kernelPackages;
56 81
57 publicKeyPath = mkPublicKeyPath hostName; 82 publicKeyPath = family: mkPublicKeyPath family hostName;
58 privateKeyPath = mkPrivateKeyPath hostName; 83 privateKeyPath = family: mkPrivateKeyPath family hostName;
59 inNetwork = pathExists privateKeyPath && pathExists publicKeyPath; 84 inNetwork' = family: pathExists (privateKeyPath family) && pathExists (publicKeyPath family);
60 hostLinks = filter ({ from, to, ... }: thisHost from || thisHost to) links; 85 inNetwork = any inNetwork' families;
61 linkToPeer = opts@{from, to, ...}: 86 hostLinks = filterAttrs (_family: links: links != []) (mapAttrs (_family: filter ({ from, to, ... }: thisHost from || thisHost to)) links);
87 linkToPeer = family: opts@{from, to, ...}:
62 let 88 let
63 other = if thisHost from then to else from; 89 other = if thisHost from then to else from;
64 in { 90 in {
65 AllowedIPs = wgHostIPs.${other}; 91 AllowedIPs = wgHostIPs.${family}.${other};
66 PublicKey = trim (readFile (mkPublicKeyPath other)); 92 PublicKey = trim (readFile (mkPublicKeyPath family other));
67 } // (optionalAttrs (thisHost from) (linkCfgFilterCustom opts // linkMkEndpointCfg opts)); 93 } // (optionalAttrs (thisHost from) (linkCfgFilterCustom opts // linkMkEndpointCfg opts));
68 linkCfgFilterCustom = filterAttrs (n: _v: !(elem n ["from" "to" "endpointHost"])); 94 linkCfgFilterCustom = filterAttrs (n: _v: !(elem n ["from" "to" "endpointHost"]));
69 linkMkEndpointCfg = opts@{from, ...}: optionalAttrs (opts ? "endpointHost" && thisHost from) { Endpoint = "${opts.endpointHost}:${toString listenPort}"; }; 95 linkMkEndpointCfg = opts@{from, ...}: optionalAttrs (opts ? "endpointHost" && thisHost from) { Endpoint = "${opts.endpointHost}:${toString listenPort}"; };
70 linkToGreDev = opts@{from, to, ...}: 96 linkToGreDev = family: opts@{from, to, ...}:
71 let 97 let
72 other = if thisHost from then to else from; 98 other = if thisHost from then to else from;
73 in nameValuePair "yggre-${other}" { 99 in nameValuePair "yggre-${other}-${family}" {
74 netdevConfig = { 100 netdevConfig = {
75 Name = "yggre-${other}"; 101 Name = "yggre-${other}-${family}";
76 Kind = "ip6gretap"; 102 Kind = "ip6gretap";
77 }; 103 };
78 tunnelConfig = { 104 tunnelConfig = {
79 Local = stripSubnet wgHostIPs.${hostName}; 105 Local = stripSubnet wgHostIPs.${family}.${hostName};
80 Remote = stripSubnet wgHostIPs.${other}; 106 Remote = stripSubnet wgHostIPs.${family}.${other};
81 }; 107 };
82 }; 108 };
83 linkToGreNetwork = ix: opts@{from, to, ...}: 109 linkToGreNetwork = family: ix: opts@{from, to, ...}:
84 let 110 let
85 other = if thisHost from then to else from; 111 other = if thisHost from then to else from;
86 in nameValuePair "yggre-${other}" { 112 in nameValuePair "yggre-${other}" {
87 matchConfig = { 113 matchConfig = {
88 Name = "yggre-${other}"; 114 Name = "yggre-${other}-${family}";
89 }; 115 };
90 linkConfig = { 116 linkConfig = {
91 MACAddress = "${greHostMACPrefixes.${hostName}}:${toHexByte ix}"; 117 MACAddress = "${greHostMACPrefixes.${family}.${hostName}}:${toHexByte ix}";
92 RequiredForOnline = false; 118 RequiredForOnline = false;
93 }; 119 };
94 networkConfig = { 120 networkConfig = {
@@ -96,71 +122,72 @@ let
96 LinkLocalAddressing = "no"; 122 LinkLocalAddressing = "no";
97 }; 123 };
98 }; 124 };
99 125 familyToYggdrasilDev = family: nameValuePair "yggdrasil-wg-${family}" {
100 thisHost = host: builtins.match "^(ipv(4|6)\.)?${hostName}$" host != null; 126 netdevConfig = {
127 Name = "yggdrasil-wg-${family}";
128 Kind = "wireguard";
129 };
130 wireguardConfig = {
131 PrivateKeyFile = config.sops.secrets."yggdrasil-wg-${family}.priv".path;
132 ListenPort = listenPort;
133 };
134 wireguardPeers = map (opts@{to, from, ...}: { wireguardPeerConfig = linkToPeer family opts; }) hostLinks.${family};
135 };
136 familyToYggdrasilNetwork = family: nameValuePair "yggdrasil-wg-${family}" {
137 name = "yggdrasil-wg-${family}";
138 matchConfig = {
139 Name = "yggdrasil-wg-${family}";
140 };
141 address = [wgHostIPs.${family}.${hostName}];
142 routes = [
143 { routeConfig = {
144 Destination = "${wgSubnet.${family}}::/${toString wgSubnetLength}";
145 };
146 }
147 ];
148 linkConfig = {
149 RequiredForOnline = false;
150 };
151 networkConfig = {
152 Tunnel = map (opts@{from, to, ...}: let other = if thisHost from then to else from; in "yggre-${other}-${family}") hostLinks.${family};
153 };
154 };
155 familyToSopsSecret = family: nameValuePair "yggdrasil-wg-${family}.priv" (mkIf (pathExists (privateKeyPath family)) {
156 format = "binary";
157 sopsFile = privateKeyPath family;
158 mode = "0640";
159 owner = "root";
160 group = "systemd-network";
161 });
162
163 thisHost = host: host == hostName;
101 trim = str: if hasSuffix "\n" str then trim (removeSuffix "\n" str) else str; 164 trim = str: if hasSuffix "\n" str then trim (removeSuffix "\n" str) else str;
102 stripSubnet = addr: let matchRes = builtins.match "^(.*)/[0-9]+$" addr; in if matchRes == null then addr else elemAt matchRes 0; 165 stripSubnet = addr: let matchRes = builtins.match "^(.*)/[0-9]+$" addr; in if matchRes == null then addr else elemAt matchRes 0;
103 optIx = optName: xs: let 166 optIx = optName: xs: let
104 withOpts = listToAttrs (imap0 (ix: x: nameValuePair x.name (x.value // { ${optName} = ix; })) (filter (x: x.value.${optName} or false) (imap0 (ix: nameValuePair (toString ix)) xs))); 167 withOpts = listToAttrs (imap0 (ix: x: nameValuePair x.name (x.value // { ${optName} = ix; })) (filter (x: x.value.${optName} or false) (imap0 (ix: nameValuePair (toString ix)) xs)));
105 withoutOpts = listToAttrs (map (nv: nameValuePair nv.name (removeAttrs nv.value [optName])) (filter (x: !(x.value.${optName} or false)) (imap0 (ix: nameValuePair (toString ix)) xs))); 168 withoutOpts = listToAttrs (map (nv: nameValuePair nv.name (removeAttrs nv.value [optName])) (filter (x: !(x.value.${optName} or false)) (imap0 (ix: nameValuePair (toString ix)) xs)));
106 in genList (ix: withOpts.${toString ix} or withoutOpts.${toString ix}) (length xs); 169 in genList (ix: withOpts.${toString ix} or withoutOpts.${toString ix}) (length xs);
107 mkLinks = id; 170 groupFamilies = links: mapAttrs (_name: value: map (filterAttrs (k: _v: k != "family")) value) (groupBy (x: x.family) links);
171 mkLinks = groupFamilies;
172 families = attrNames links;
173 hostFamilies = attrNames hostLinks;
108 toHexByte = n: let 174 toHexByte = n: let
109 hex = toHexString n; 175 hex = toHexString n;
110 in if (stringLength hex < 2) then "0${hex}" else hex; 176 in if (stringLength hex < 2) then "0${hex}" else hex;
111in { 177in {
112 config = { 178 config = {
113 assertions = [
114 { assertion = inNetwork || !(pathExists privateKeyPath || pathExists publicKeyPath);
115 message = "yggdrasil-wg: Either both public and private keys must exist or neither.";
116 }
117 { assertion = !inNetwork || (wgHostIPs ? "${hostName}");
118 message = "yggdrasil-wg: Entry in wgHostIPs must exist.";
119 }
120 ] ++ map ({from, to, ...}: let other = if thisHost from then to else from; in { assertion = pathExists (mkPublicKeyPath other); message = "yggdrasil-wg: This host (${hostName}) has a link with ‘${other}’, but no public key is available for ‘${other}’."; }) hostLinks;
121
122 systemd.network = mkIf inNetwork { 179 systemd.network = mkIf inNetwork {
123 enable = true; 180 enable = true;
124 netdevs = { 181 netdevs = {
125 yggdrasil-wg = {
126 netdevConfig = {
127 Name = "yggdrasil-wg";
128 Kind = "wireguard";
129 };
130 wireguardConfig = {
131 PrivateKeyFile = config.sops.secrets."yggdrasil-wg.priv".path;
132 ListenPort = listenPort;
133 };
134 wireguardPeers = map (opts@{to, from, ...}: { wireguardPeerConfig = linkToPeer opts; }) hostLinks;
135 };
136 yggdrasil = { 182 yggdrasil = {
137 netdevConfig = { 183 netdevConfig = {
138 Name = "yggdrasil"; 184 Name = "yggdrasil";
139 Kind = "batadv"; 185 Kind = "batadv";
140 }; 186 };
141 }; 187 };
142 } // listToAttrs (map linkToGreDev hostLinks); 188 } // listToAttrs (map familyToYggdrasilDev hostFamilies) // listToAttrs (concatMap (family: map (linkToGreDev family) hostLinks.${family}) hostFamilies);
143 189
144 networks = { 190 networks = {
145 yggdrasil-wg = {
146 name = "yggdrasil-wg";
147 matchConfig = {
148 Name = "yggdrasil-wg";
149 };
150 address = [wgHostIPs.${hostName}];
151 routes = [
152 { routeConfig = {
153 Destination = "${wgSubnet}::/${toString wgSubnetLength}";
154 };
155 }
156 ];
157 linkConfig = {
158 RequiredForOnline = false;
159 };
160 networkConfig = {
161 Tunnel = map (opts@{from, to, ...}: let other = if thisHost from then to else from; in "yggre-${other}") hostLinks;
162 };
163 };
164 yggdrasil = { 191 yggdrasil = {
165 name = "yggdrasil"; 192 name = "yggdrasil";
166 matchConfig = { 193 matchConfig = {
@@ -178,18 +205,10 @@ in {
178 RequiredForOnline = false; 205 RequiredForOnline = false;
179 }; 206 };
180 }; 207 };
181 } // listToAttrs (imap0 linkToGreNetwork hostLinks); 208 } // listToAttrs (map familyToYggdrasilNetwork hostFamilies) // listToAttrs (concatMap (family: imap0 (linkToGreNetwork family) hostLinks.${family}) hostFamilies);
182 }; 209 };
183 210
184 sops.secrets = { 211 sops.secrets = listToAttrs (map familyToSopsSecret hostFamilies);
185 "yggdrasil-wg.priv" = mkIf (pathExists privateKeyPath) {
186 format = "binary";
187 sopsFile = privateKeyPath;
188 mode = "0640";
189 owner = "root";
190 group = "systemd-network";
191 };
192 };
193 212
194 networking.hosts = mkIf inNetwork (listToAttrs (concatMap ({name, value}: map (ip: nameValuePair (stripSubnet ip) ["${name}.yggdrasil"]) value) (mapAttrsToList nameValuePair batHostIPs))); 213 networking.hosts = mkIf inNetwork (listToAttrs (concatMap ({name, value}: map (ip: nameValuePair (stripSubnet ip) ["${name}.yggdrasil"]) value) (mapAttrsToList nameValuePair batHostIPs)));
195 214
diff --git a/modules/yggdrasil-wg/hosts/sif.priv b/modules/yggdrasil-wg/hosts/4/sif.priv
index 5641c1f2..5641c1f2 100644
--- a/modules/yggdrasil-wg/hosts/sif.priv
+++ b/modules/yggdrasil-wg/hosts/4/sif.priv
diff --git a/modules/yggdrasil-wg/hosts/sif.pub b/modules/yggdrasil-wg/hosts/4/sif.pub
index 0f6ec4a8..0f6ec4a8 100644
--- a/modules/yggdrasil-wg/hosts/sif.pub
+++ b/modules/yggdrasil-wg/hosts/4/sif.pub
diff --git a/modules/yggdrasil-wg/hosts/surtr.priv b/modules/yggdrasil-wg/hosts/4/surtr.priv
index b5d107f5..b5d107f5 100644
--- a/modules/yggdrasil-wg/hosts/surtr.priv
+++ b/modules/yggdrasil-wg/hosts/4/surtr.priv
diff --git a/modules/yggdrasil-wg/hosts/surtr.pub b/modules/yggdrasil-wg/hosts/4/surtr.pub
index abe753eb..abe753eb 100644
--- a/modules/yggdrasil-wg/hosts/surtr.pub
+++ b/modules/yggdrasil-wg/hosts/4/surtr.pub
diff --git a/modules/yggdrasil-wg/hosts/vidhar.priv b/modules/yggdrasil-wg/hosts/4/vidhar.priv
index c5b2ea99..c5b2ea99 100644
--- a/modules/yggdrasil-wg/hosts/vidhar.priv
+++ b/modules/yggdrasil-wg/hosts/4/vidhar.priv
diff --git a/modules/yggdrasil-wg/hosts/vidhar.pub b/modules/yggdrasil-wg/hosts/4/vidhar.pub
index 2807df64..2807df64 100644
--- a/modules/yggdrasil-wg/hosts/vidhar.pub
+++ b/modules/yggdrasil-wg/hosts/4/vidhar.pub
diff --git a/modules/yggdrasil-wg/hosts/6/sif.priv b/modules/yggdrasil-wg/hosts/6/sif.priv
new file mode 100644
index 00000000..56a4c6fe
--- /dev/null
+++ b/modules/yggdrasil-wg/hosts/6/sif.priv
@@ -0,0 +1,26 @@
1{
2 "data": "ENC[AES256_GCM,data:aRL5e5YWZDxsdZmlB+OMTLmA84XJ3I3MX+CWbWxNHo9FdnLN65yp3QepXG5k,iv:0TGwAaAtIivuFUduL4owWewqHEXBqAAR/FGibA8f4YM=,tag:lZzxcJtIxivv+0lgGGTTzg==,type:str]",
3 "sops": {
4 "kms": null,
5 "gcp_kms": null,
6 "azure_kv": null,
7 "hc_vault": null,
8 "age": null,
9 "lastmodified": "2021-11-03T22:06:48Z",
10 "mac": "ENC[AES256_GCM,data:rJRrcBJnmEcLp27LYO72GR62ESX9VF9115JJi5w438LGWSloEt9AS8qwC4sMwG4pe8FFhsB0108El+RcPDJaIKiNyCNP/KnFtNABJttkxd1ldFv1tP+a150ydFZyxtlyEApiLxJNv54/ut1XZfbtgWRT+YaqNjLx0Mdxvptg+5s=,iv:nn5xw8jB4PCvR9/ickJqwVWatgUg0UeUwKwM/jqCQDY=,tag:D4AqHdklo+dS1fOamTDn0A==,type:str]",
11 "pgp": [
12 {
13 "created_at": "2021-11-03T22:06:44Z",
14 "enc": "-----BEGIN PGP MESSAGE-----\n\nhF4Dgwm4NZSaLAcSAQdASEiKC1/IWGM9kw+rR9wQTooxQNjFU80myZmmK/qIBw4w\nM3oBU1Jx3XLmbbkx+okzwzHI792Mfgb2dPaMnoy7GaiwdBhDcZQBg6wxJ0bV0WcR\n0l4BJ+3IQNgHRbmluWrb6WOmwfjMQoVP8apT4TMrJ2RQVd4sLNjucgqZ71qKlPpT\nVSEsff0EwQintmGU7+9xeTJSqbTCjyGph+S/ZvWPb8yRaw+RfGlV5XpJzuETx/Y1\n=GASC\n-----END PGP MESSAGE-----\n",
15 "fp": "F1AF20B9511B63F681A14E8D51AEFBCD1DEF68F8"
16 },
17 {
18 "created_at": "2021-11-03T22:06:44Z",
19 "enc": "-----BEGIN PGP MESSAGE-----\n\nhF4DXxoViZlp6dISAQdA6KDXI2M9dQVaCTfbixQtx3TWEp3nsJrzX6xUOiVjs30w\n3dvPXRgVODNgkqg+GJQGgkyvrnnNjZU222Y8HpF8HBuFMjAigsUdpI0BoKTwSo82\n0l4BNgxO/SoxxPfekvTcqrTTL71rNjNnsR/aU3wOef2K4MUT4VpPPOsB/aGFAXNf\n/wi7sPXR0zVpafqI8ZdAupKjF+/A8wtkI2hnMi19P+zkZuG5AQ8ymlHGaCsUXWPZ\n=BfQt\n-----END PGP MESSAGE-----\n",
20 "fp": "30D3453B8CD02FE2A3E7C78C0FB536FB87AE8F51"
21 }
22 ],
23 "unencrypted_suffix": "_unencrypted",
24 "version": "3.7.1"
25 }
26} \ No newline at end of file
diff --git a/modules/yggdrasil-wg/hosts/6/sif.pub b/modules/yggdrasil-wg/hosts/6/sif.pub
new file mode 100644
index 00000000..d7723626
--- /dev/null
+++ b/modules/yggdrasil-wg/hosts/6/sif.pub
@@ -0,0 +1 @@
zIgyMw5wSernKPmMfDZ+fqaYUjbIQUhsXe+7hIZgJho=
diff --git a/modules/yggdrasil-wg/hosts/6/surtr.priv b/modules/yggdrasil-wg/hosts/6/surtr.priv
new file mode 100644
index 00000000..59000d34
--- /dev/null
+++ b/modules/yggdrasil-wg/hosts/6/surtr.priv
@@ -0,0 +1,26 @@
1{
2 "data": "ENC[AES256_GCM,data:YkLe1V2tH+osAZ01DpB5iE/CW7ACuEmOJYECmyl2oN9LoJ0mzoq+gkW/ONBn,iv:3ukCz63ECPm6c+kUmKtcefRZpWyq3F9Fbi31lyLA0Mo=,tag:R8hwaMoYej1sU++7zLq7zw==,type:str]",
3 "sops": {
4 "kms": null,
5 "gcp_kms": null,
6 "azure_kv": null,
7 "hc_vault": null,
8 "age": null,
9 "lastmodified": "2021-11-03T22:07:35Z",
10 "mac": "ENC[AES256_GCM,data:ao6Sw1yljXJ5MtiuQx7/8Dajrvn1bs9qivA6z57nAjdYbRPulLMlwq4Aqdp3FGUdw3itIqO2GLGxfdxsNcOmN73+sR3ElLJB0VfD2uPpscR5JAGtc/Z9zTyjp2n+8X2ZcxpRIK4C/v/8kI7ruz0/DDf+UyWXmEYuL2cpnuCp2T0=,iv:RpSJjMtCZPamyQN8BVrqWMc8NWz8Ni+ktTaS7eEQABo=,tag:mr736mcGxje+q20NdPk2gg==,type:str]",
11 "pgp": [
12 {
13 "created_at": "2021-11-03T22:07:34Z",
14 "enc": "-----BEGIN PGP MESSAGE-----\n\nhF4DyFKFNkTVG5oSAQdAocjF7FLoL3ZmU+TYqYNFeuA7YYueJ5lcF73p/+/Hclgw\njBsAZP7kDzZaQ+40cLfHwRFn6N0SoLlOI3P/gcLbC8hpGGsbRIDHQEPYDML1Aodu\n0l4BL1xwtqtVkdfr/YxCZgUeBgjuN9wcCqzKy+VeWNGOpM+l6A7Fnn51ycFLLiCg\nzHzBhYhkpHwU6wE8DAG7w1awvbZTSGpQhruoQu3TVCgdIdpgEdbCRcDptDDoAKS7\n=BezJ\n-----END PGP MESSAGE-----\n",
15 "fp": "7ED22F4AA7BB55728B643DC5471B7D88E4EF66F8"
16 },
17 {
18 "created_at": "2021-11-03T22:07:34Z",
19 "enc": "-----BEGIN PGP MESSAGE-----\n\nhF4DXxoViZlp6dISAQdAzqWPGgn4kKXUIsZscibGXyyihcISJDam75X5lZMfVVsw\nht/PSnpV/U0K8N7ABJ4YLSadxrCZ3L3EdoQWovAVIZpDf5slFN4C9RTgHQ4QOl4y\n0l4BoUau5bHJMvNXERmjCSg5dNrF4EsYA6qd1hRlSOj8Vfgl0rwcrvt99GGSXs4l\nqFRb9khKkN/dPrUZEynZl4xo+gyGM5PIwNkre+1SGD9AYTqN91WOFVHiokpsSxId\n=InEY\n-----END PGP MESSAGE-----\n",
20 "fp": "30D3453B8CD02FE2A3E7C78C0FB536FB87AE8F51"
21 }
22 ],
23 "unencrypted_suffix": "_unencrypted",
24 "version": "3.7.1"
25 }
26} \ No newline at end of file
diff --git a/modules/yggdrasil-wg/hosts/6/surtr.pub b/modules/yggdrasil-wg/hosts/6/surtr.pub
new file mode 100644
index 00000000..78f5000d
--- /dev/null
+++ b/modules/yggdrasil-wg/hosts/6/surtr.pub
@@ -0,0 +1 @@
6V2EjwvZ07Pebc9g9TNqIlQu57MvqyUsCeIOzky4Txw=
diff --git a/modules/yggdrasil-wg/hosts/6/vidhar.priv b/modules/yggdrasil-wg/hosts/6/vidhar.priv
new file mode 100644
index 00000000..d2a30501
--- /dev/null
+++ b/modules/yggdrasil-wg/hosts/6/vidhar.priv
@@ -0,0 +1,26 @@
1{
2 "data": "ENC[AES256_GCM,data:a62p277CP9O3P7H888tpU7sYB4Yf97FdUBEsVA1LBjgyKSETaHx/nC1AN3zD,iv:GUZyh5wI1KNPoUrJgPZcrB4xqIL9t88IZxDJYIbmVyc=,tag:8f4b1kGIltxLBApVzWNK3A==,type:str]",
3 "sops": {
4 "kms": null,
5 "gcp_kms": null,
6 "azure_kv": null,
7 "hc_vault": null,
8 "age": null,
9 "lastmodified": "2021-11-03T22:08:03Z",
10 "mac": "ENC[AES256_GCM,data:DYVkiZUQgVXacVTab21+RqERTrwbKt4eiHB1pWpoTx9gyJIpNX4zOYOeWzye5u7oEh6Gsd0+LepRt3k5ne0BvkctDrVcElHREaIOh8+Dt/kC6x3RzZbyIG5IhVz1WPePAYXIIAtbYy4Ummp4gOxCsQ7mx1yod/tEEQ8bzNy3nhI=,iv:IpFZrxS5s6cx99DAifT7JDfTb0Kcu02w5ffTv+IPkYs=,tag:OwqBZC63PGbshj0W+JZa5w==,type:str]",
11 "pgp": [
12 {
13 "created_at": "2021-11-03T22:08:03Z",
14 "enc": "-----BEGIN PGP MESSAGE-----\n\nhF4DbYDvGI0HDr0SAQdAG9h5v/5dQvH2I2F+0hRLWwKbTBeQgq1+OA2v0tEk9hUw\n4vt1Wt56cx4BbkhagNVX35UVS+yrJjJB9d+CDWSJCMegicew6IHqelnCv8Zglrxm\n0l4BI866f5QVEEP4+UVJeKlxqcwwW8xgJTvi1rgmACBhvnwDoq3ImO1S+PEDJx/N\noQodaudvWTCkzAq2ChpITv3KMF8IV9n88ivk7n40jj8siECO19J0GOTAxGsG3Dfv\n=R/DA\n-----END PGP MESSAGE-----\n",
15 "fp": "A1C7C95E6CAF0A965CB47277BCF50A89C1B1F362"
16 },
17 {
18 "created_at": "2021-11-03T22:08:03Z",
19 "enc": "-----BEGIN PGP MESSAGE-----\n\nhF4DXxoViZlp6dISAQdA6n6jG3A5oRo5VrJeXejiFKmEibWZ32O5+m1FrfXMrhUw\nxAIy7qTBKl4jU1zlTFF8up45vzSTZTAvOhG4Nt3hmniJOXZpc6L18HVMLU1ka6CH\n0l4BvQ6n//4okOLO97OhInFijX58u5v5QbNdrcHYte8yctZ5bu9Ssqo0PpJo5MWZ\nX1SLzAdllgHbAdHgrhq/F5o2SN9tAbaxREKDQzV73TLvfIGOPjDRgoFgQHXRhu6N\n=OQrL\n-----END PGP MESSAGE-----\n",
20 "fp": "30D3453B8CD02FE2A3E7C78C0FB536FB87AE8F51"
21 }
22 ],
23 "unencrypted_suffix": "_unencrypted",
24 "version": "3.7.1"
25 }
26} \ No newline at end of file
diff --git a/modules/yggdrasil-wg/hosts/6/vidhar.pub b/modules/yggdrasil-wg/hosts/6/vidhar.pub
new file mode 100644
index 00000000..b8135102
--- /dev/null
+++ b/modules/yggdrasil-wg/hosts/6/vidhar.pub
@@ -0,0 +1 @@
jdaF4sx+dhdkTNGxQI6g6JV4XwXgD9QQJQ4f0NYy1gY=