vpn-gw: init

This commit is contained in:
Astro 2022-03-01 22:51:31 +01:00
parent d59415fdc5
commit bdca123b99
8 changed files with 205 additions and 60 deletions

View File

@ -69,6 +69,7 @@
upstream3 = "172.20.72.11"; upstream3 = "172.20.72.11";
upstream4 = "172.20.72.12"; upstream4 = "172.20.72.12";
yggdrasil = "172.20.72.62"; yggdrasil = "172.20.72.62";
vpn-gw = "172.20.72.69";
}; };
hosts6 = { hosts6 = {
dn42 = { dn42 = {
@ -130,6 +131,7 @@
upstream3 = "fd23:42:c3d2:581::b:2"; upstream3 = "fd23:42:c3d2:581::b:2";
upstream4 = "fd23:42:c3d2:581::b:3"; upstream4 = "fd23:42:c3d2:581::b:3";
yggdrasil = "fd23:42:c3d2:581:9000::1"; yggdrasil = "fd23:42:c3d2:581:9000::1";
vpn-gw = "fd23:42:c3d2:581:9001::1";
}; };
up4 = { up4 = {
anon1 = "2a00:8180:2c00:281::9:1"; anon1 = "2a00:8180:2c00:281::9:1";
@ -188,6 +190,7 @@
upstream1 = "2a00:8180:2c00:281::b:0"; upstream1 = "2a00:8180:2c00:281::b:0";
upstream4 = "2a00:8180:2c00:281::b:1"; upstream4 = "2a00:8180:2c00:281::b:1";
yggdrasil = "2a00:8180:2c00:281:9000::1"; yggdrasil = "2a00:8180:2c00:281:9000::1";
vpn-gw = "2a00:8180:2c00:281:9001::1";
}; };
}; };
subnet4 = "172.20.72.0/25"; subnet4 = "172.20.72.0/25";

View File

@ -393,6 +393,12 @@ in
reflect = true; reflect = true;
sourcePort = 1337; sourcePort = 1337;
} }
{
destination = config.site.net.core.hosts4.vpn-gw;
proto = "udp";
reflect = true;
sourcePort = config.site.vpn.wireguard.port;
}
]; ];
interfaces = { interfaces = {
core = { core = {

39
config/net/vpn.nix Normal file
View File

@ -0,0 +1,39 @@
{ config, ... }:
{
site.net.vpn = {
vlan = null;
domainName = "core.zentralwerk.org";
hosts4 = {
vpn-gw = "172.20.76.225";
};
hosts6 = {
dn42 = {
vpn-gw = "fd23:42:c3d2:585::1";
};
up4 = {
vpn-gw = "2a00:8180:2c00:285::1";
};
};
subnet4 = "172.20.76.224/28";
subnets6 = {
dn42 = "fd23:42:c3d2:585::/64";
up4 = "2a00:8180:2c00:285::/64";
};
};
site.hosts.vpn-gw = {
role = "container";
interfaces = {
core = {
hwaddr = "0A:14:42:01:26:01";
type = "veth";
};
vpn = {
type = "wireguard";
};
};
ospf = {
allowedUpstreams = [ "upstream4" ];
};
};
}

View File

@ -1,62 +1,66 @@
-----BEGIN PGP MESSAGE----- -----BEGIN PGP MESSAGE-----
hQEMA2PKcvDMvlKLAQf/V2MD1fBh0U1etre+SS2b9+moT5iWamjcaXNVBUt5nqJ2 hQEMA2PKcvDMvlKLAQf+N/pS4pF0x1+2L78gGXy9Jl+Fm5AiTHHPvOMsb6lEYUa/
yGtbK3k1yJ1S4RDOUen+Boiqs8ew31QlKXm1FVV4g5C0GWyBKbEES2HJSMd1wWF0 D52lxOpYJ23248iZeRv+tyXyB1gUain/1HZPLkHe+JS/p4Sl81/tRcKDoDLxf09m
sdPMnjTxspZk137qrIjknhzBi95zhPXwTT8/p9CKcADy+Fv+Lco8AYsh4hu6K7ZS EBjKAdlPpjdFUCRY3Byc8ZowyE/6G8RMXtYIqb5k8VMqVy+X/vP28PWeKRd3UfY5
jzy/znR0AMDfGQ1zm4BYbo+0srC3jMsM9DWbsM3npKJd0rfSPqkC2Vsuu0ilNJts OLK/C60fxWQLGColvONjcr1YGOu6eBZo4lskuJsSjPj9qyeAkktMiEK6aY/WmtKC
X7i8716XVGmzQBgdXAhOxNerXSjTZvelMYMVwOaWGQlLMdZpy92IY9iUcPXRM3uf g4jfED4OdvdX/ala3paAYPt1dopjMUby5kIkbGhjN3GDYuMaWFiFt5nE9kMi8Ozt
k2emytYJAJC2LC5X+L8PVFByy8blYOBWpriBrI3JENLrAZhEW7Pvf8UK4ii9speC iQohMRrybYd1g81+lUPNBhlkO+M+QN0/M5jG68I48dLrAXDFkIY68//26VBkCGJq
UbysdIzVTYXGJRi/DBxHSm0iJzbSTEDi69VBucySMhOdS2M1VPHxca9zzqyUfCSp oCdsV/qev+Ll7ig2YJ7ijIGp2uqhC/zQ4u+z6MgoyO8Pwc0EA78eYpG4UcbT2v/V
0Wp5K6NyvB2UArVmJNYP1HbMntrs7G2Y3+6xU9+7s2z+Lz4a2L1ym895+jgknmT5 a20fFL3E6sb9D8GBvImz01Vn42LfsXpfZWSerb3QjZ0jOgv2IPw30Ee+y4tLAoVP
doEQTgpZcv2+olATfETDpVkrIvfz/7WyCp+oU5HVStxqfIMLvR6chFxGiCL8pGS2 9/4ahX0q04ByGUfWYx/rIUEdoLVZylQzxfRm2KkSat0LfAoAiMWdf0nBhwGTkywy
Jy+71Uu77FsqT9Hr9LnYQW1G/sPkXpN81Qgo36RUV6sCknVGS3ftIGKp4EwFSLOJ QF4/6xUO5WW3rJYVf3iNUVyCDp4X3Ep8TVM6/w8VGB1m1tVON2eqAczuHOIFkmiZ
qNIeTDHzdxvutTd2z8e3Kogx04eYBipHgAj2IhRujjGGDusb7spZSFm68U7X6xbJ ENtqe/3BwLp4n9CEaWlJAyjBJ7uzls7riZcGRPUXb6pfBDFszScvRzYXvaOaLHRa
KEPC7ts7aVbOIKT8C/4CATYKqFT/Heq2pMqJow/6QN3+4dqNfbwibrN73xQQV53/ eqDgXz2IeUrEHrvzIOtRYpwav+DD/vGyIuOaUbAJULc2J6TcQSfhA0f4pqo+VAw+
InvPr3lZMtQwwvGRgKrqZRaBbL7ErBGbitjB+q2Xg5Mppd+17qZ2bCXEQxn10HTy geBNyd95BTA3MmfqfZ8D1YIaLeFYcANBUMI5f7offF7XsHoO7WQ4wSQmu60g0462
HA6Yc+QBL4Zjq+bYmV2qKoYNvG05o3OY/0dQaHz5KjZU+S9bYUBy3rqRte4+cWf9 KRDMlv5TEp20sh/cErjKz9L3w6MTBVo5V4M2zAfMDB1QAiRVU94KLeoMIjeYT2Yd
9Yq7YSXnfcAKHZSiWrS2mOjJ0rDl1/1kekav7eKxKuy1psnghMbJt4oqVQ7z3h3G 94zrc869dMUS9juwNa/6jPaT+1AXbkHxcE/a2kk/BYLxuea2kg+KvNVPWtpRBQPn
WATXmTR4N1SH4ZECqVI+I4m88yOyv+0Io138BW3pmg94NKgFDUytTWUUPY8OQAYE 0CDLNcJbYQJ/Qj8BnPPCvPThzlGCTxCk0lLBje4iz4qWk4gZLJHGgjUdrj0YXgo1
XTB7TNALK6Mv8fVkedufZnmVuPIIBUT06D8k0jwmb9aWQ2O627uwaslqWJ8RVw8c 8WSOXnylK+AL8+w831jg8PLIYG2FDJnc4+ZKhaB/JQynigIiqq8809aYV7hdiXsr
fEd7/ZXfFqHPcdjJg/UfTrazGHaUwAty3mLaCB/WnCo7JPtGb1HTeH++kLPbTMzk r7n5S+js0QRfJOLyfTTaTCiVHKAUdvJmGjUdYR9lUDW/ZVeX8wqCxVsj8AyaNs+3
qjbAee4fjw19+3mv3GKXhwwiTuUZBhVtot1jH9GCaZqeymL47At8dID6pHiLQui+ XSnDrLpAYt1Qixk6lavW6KA5Jncqh9wm8sqg7CDqaeBlUrGRTpqJhaO0KNMNzzhp
umGdGjx0fNdBmxZY/XrUCkwqUOdT5gsMIwzMG9VKwTNLWYQ710QNUvKyGVFV+tOo 1Sa9kT15B40zvQ77JGuxl4+MgViXk0eNIkT5oB62yShBE0URg16GDVNWTx8Ze9UD
6NYhV8IchDQQDjy1+xZmGCZzeq609PMpLjXlcvNMWEGAYPEGDXiDxydVCx1J8vuy PiKqZJJ9D7CwOpR6AMcbkVFRZr1bihx1ISbfeJLaEft5Cs7XuQv6Z0Ljxa6Ty2wu
F1YBZkCVFSbEculwWHeShAA3G3fp0ZeTvxnUz25cLpLPoo9saDPtZ4alvTKCLFzA N6VmLh05uDghfLmVYMNa64TixSQdedBUJPqWcz2PKubYeRQRcVG+UktzhK1E0I3t
wyth7VmGXiWvB3DJ4B2YkJesQCwFAE8VOoUhnTWf4OyKKDl7bSMT8yTRvFZSCvDo wkyFnHXR6MnpXWY+2wXoqaPfJGc5t+dOuUSj5itpVpmeCDomxHTGPYSljr2As/LT
GzKZTfxU8uqZhyEkGe+qmI9LpzlqRsVj4P9J0nXetSxX1ZPCZK1sOUX9CxDMGBav 6UXyluzFYm4nvmeJMbJKWYUShIBtYvKEYK4y8QNbNutEw6gLh3KN8K3NUFTm6eYq
y/kClWsHhBGhSih0GSqFMYNqbibAUthecUs2/ErnrWuQMJ/qiYk8hmqkb5hb5ylO KisbTWWm9ai7urYyk73SxbMM0AdW2e1SajAnBLNAgQLdaWinRKjrCYEZFvXqp3Xh
jIwCL/MYstsPWrgRQSxmpj3ouWiTqLHheHAhkNBTyldUkI63LIRI9eqOHAXamV1b Am1WvFCR/QGoSgNFUDmKSgoBQHAM+UWUbUoCKuC6seJd/thiB0DJNhO1k85l8c5N
rb9hbV4co5WEz1q0Ayh7+swju+h1T4R2fpZuVSBFUJMiQdUxOJwx91uoLOEwOaYS pXir8twpnqe9kr+QabCL4v8cQxi8Bsq+ITQp+bbwuZTDNFJIOfmzpdSzGDDrRZ1P
y69HV0Ww/42IWYekZL4UsEcfADLFjCvrTeBjXKcWo+OI8iJRJ+LVdSFUwH9ww9Pg 6BakQVL7oOWjfulTd9Lk7q4AOpjxECqxlu53/71pzy2Ztx4OyOzMzMPDl4T5RK6G
qY3L2N/is2xX6KA8x+WZsCBmBtq2E31LLJj6DRxYFqH9YQHl+lVkJmphpk6G0ynW GZ8NqrNpwOcF8UZHkygQtiZ4fLkF81czrwOEPvsSxsfyCaUl+Ei2KK4JBoKI9lZI
GAJFcEcBLj0hH1PsQMYsP3Vbxny0rfscQ+3vwApUvIhwipfyuKlMJZxaA+mvHByD HUROck8DtvM7C9P5PUb+vhf+qDiEDJLlSGDkAc4wsBu5JHSvaZdJvTEQ0wCg1NUl
htpQOGQt/yUW81JyN0atnK5scmiSJA9ZIY7/6yIANFY+LSyQGRi33OaSg0t8r9ja QbToxhJ2qdpDERoR4ChbM5XYjMDFYxNLD5GZoBx229g6ag4y0p+Q/35x7C4y2PXf
06rkvz77EkNbkDJoR9/uqnbw91qzHQeaMAzcyPkGG6BduMMXdxwTgx16ocozkX4V wSmcmKqVKQn3z8OsdoY4KyGvESEudlTWLFVtWvItRc2xZKSlS/hrzweA7FgR23Cm
zgFTwQoI063M//xs1JEINe/H1D/gTNrPx8MgXADWkPYrafgDzyA9bmmLx7/vjOGj 5CUisyzY/U6psLBnv7d3iMVWIQID7EJp80KXGPuc+Y2Ulhqe4FJ9I8VuSi3BEhKK
BkNYq7CouXUTJxCiqyw4a56xxp81EZU80ay0y3oRRajbwZ0C1+P8MoRQ3aPKvBNw hIf+I8GjB7OisFpKKmZiNhg2h6SlORvn+0NmU5nII344e2doxz5gJhkLA7ApHuOI
G7X8JS42Ye7QaMrumfSw4fD3X84lCgWDxGTDAz7OM1PQo/7XtxAGHRDvIdlaYrD8 QEBqSV3CANGyiXk9l5EK0qK8U7hF02Gy3NQdRWn/CTuVbtjU7tHlOS6WgfKLgq04
F07ScKv0OxA2CWQOxJph1d5zlKbkYA61fw9N27lYke1rHooWVvjO1IU8Sk+B0obN /gQG3T9yboLK/ipVvWhswN/vEWxHSE5hQxltM0TcrwByNswQEfFxbhUhupOGxTzO
+M4iLf7S4KeTh2AiOGTkZxC/SYXbzDmTo9r3IpRNdYsqCPL6hPTT/QwS5Ph1KH5T EuxcmNCctUSpnDZHoCjUheZkzvhtGKnrcSDT26kJiis8WmALjIxacQ4d3XaUmnPD
5k3VnN/KVu/yrZW1zkHorJ5OZ2DdkVSuDbdTBw/tDmDAjlp01+4FA80xWfed+f/c vl+o5rX2v66kUw8mYjs/0u/EcVA4VdAlA+5FBRnwDgoxy9QBMLTIqlqEympSvEuN
zH+Wg+2GMYJrcNp+8iUkh4oDOqHzSabF2hjlfIChyCPjXWU/9KPxTLF+7aQePaCj cLY8LVuh9EfYgDIYXzWhGlTcSNY7ezR/IMOkDfCwsPHkf1WnZB1RuQxQO7MP6N20
m6NQYWq8ERfyQxN5vVLjYBpmU/7VE5Uw6Rr7+tkFa5BvjwTkweMo1afrGmQBIblY l5vk0095Swps7BhVVZ43KTYH/EL7QdKLXXbc/9npuFZYWcaPoxIpNZpO/d6g/K5A
P1xMb78r4DCHPmDoopTX/xute17MpLYHQx49z4AX7RYozs66VoQnhtXl7CbtRM68 0TSmMNM8VT/1f87jyETBVV+RCfF++OtjpRW1UtO9PNCp0BJ8Vlb0pq854rrB/5y0
stubbtRPEoQsq/DwQZ60Gw89DSd6Z71TPWbj+uQ1xE2kgm1oXNzziDPTrU9ZJ8pS EqOc1VXgZYDzHmqzvt0acsX4IjoQzb9EMKSRlCyD8XVY7Biv9xsN3SLmRZp9WKqJ
2GDDNviKTeuMqrpifA3ZONQbKn4R5vgThBfsRxa9sa65ghTcRYtIhBOYA9Ole0N2 GDNeT/FxJADMwx/KXnMKLq0wgh/xjmD/f/lyzPOnLUwjzt4ycuSh44JG43UZgsSS
3oWtY3kym8pYYyhSLF7OKXZerukYQBOz8m+/D5h7f8UbPwEA6tSG8PwJm19eSpBx vQ+c7B5mloPLzW4t1AcgT3UyXLJYeZ8AFmEJ/o0v11buRA3PN2k7FPuY/+rEqJVB
nhM0C8ak3vZsY4GO2XLqJCGLx8BDPHEfQcjOt/8MgnZvEME2cSC73vXpGmrwgjeN TfAkVt49/IYEQcgfbXjT2tFnHihpAzPL2Q7+trtL57Vw/C94kxOaMHzWjoYqBHmB
HnfIyhl8PX3Hsx4j5XqMyAx1/FdRC6pLT+be/Hs/cowgNb5E7c6jiCkIeprg++q6 Lm8PI8I39hzrDNzDrv7dAzZmYrXTtPoV+4/OcvBF3ZrYxPUK3It/g8YDRmYyuhge
2baySeOnIj9V+LKC5g2ybTq76wkdB14bv93SefNmbebWW/lRsKJu0jk00DDj7LKb zPD566puc/+fxlYjebYnrhsY4OFPoyEz9Yg9+C1V3IhQ318SifeJPGpeJcX30Ti7
/psnMocx/J5EUez/u8GUPXxpFKEgcZO8ouzBgDWv+cjnn7jH7KUQGJa4pGNAfz15 QmzlZWGQCOwRSXXb7qDkN//EJmx40xPANbpUZn2QOu3mNGUsKaCow7yDpCKr62cV
ngysEcRueWruU48rbdpCSdHA+wSkMVXtA8B6MFIsNVK0ohbQjbKRbOmMdJdMrNh7 PQ6CIee7Luom8vYPSATIeRLpqz76gz4E8iV3K4lnPYD8nRsMcMx3Ra9YCEkCxQxg
GxiF84oUezI+J6XY5hRDasiqe4Gh+w2dHvkokioVwCCKTJJkMbra5WOdCRTXtVsQ p59kXBBWt32X8UbmfVA9cw2JZoi0pnjQfdxyZpGYPEiL9bZWtMFPqm79EB4dasvj
ABKVqAh7jiIz+Rqu/NyEOhF68liSp3VCrjNMRqvsKD8ruYG3FkHpOp9qq8ScM6uy fu4Ie8PXDkBVfa9dlh4VCAMJuUbycytuIIU5gSEYAm9ZHaHLHGRih6o97lB1tIoM
xO0JFnRZbxJmhnY5oeBktYqQOm8I+ofZkAUeLH0qRNR8TLeg998n9e+4Ok3QsA2y O4apciEedqaonRA0HHqa21d50K5APjhcg0x2m4yBh6uEtaZK1iqP9VRP74EQ8xrn
PyxRhRIcsohAKu6gyNIbK9WKasDO2+HDKSqIaJygOWkALnxehJCGUo4lpikZBWQG J9Qp9iKwgDRC2yOuVxC00U5Fd3bX8c84DBh24EXzxH8+rmwES8aCGw1E0AgjLEQN
sciksKyKDGggoE2gm9nyP/Tl88qQg7Cn/raiVwvt/0bJWMGFR/TjIK7HLHzp2SO0 ssrFi/ic7CNMQnvvSwUd8PLdGcDRsJp6FcbJ/717u/gn06zolxsoSOBpRrwvVd8R
89U0kpOe2pp2Waz4HpKIGYKYG1wJaem2dgL9jDypM378dNVt9Mkj1c5Cok9TIRQ0 6WSRj3wy8n7fU3gRoE59jTWJc1PplY7WsMTY9puJXpz1NvLHI88CsD4WKTV7M9QD
01DqNgXw/DtE5ZWDQM+p0lN0f6tOKed6JfNgv4QU/Joq4SBMqXZyr7mG6tpPn29N e++EqdiTbJiz7zBkF0MlZzM+nj4Hr8izF0wpAMRpRS6oEG69hSXM2az884NJ8Xtl
2T7CG8rtt2eRip6n1HE8hM+KJT90wjIwI1utTN3IzuIughiX2SJ8h9pnxZuaAN+9 p4qoD2O88rZuNKQ1GJUKvDemFnT225QMkgOKmBDw+lC5OO+E7DxMJYCmmB+6N9ih
7aS/P4tf4a5WuPPOlu4v0ZnZ+5xAt67tHYCvcASP N45QUszb2m8JMonYUnT/va/7gQrfncHU3t+wjY7sdEoaPkm25lRi6dcZFB8yrfjj
=5NFQ km3qEJhzD4AlRzgj9+qQfHFQmkGxrKVdYQvozYNbuLKhkQClROEdxdRHZ4VwqVaF
3uRxDSLDCopVHpoHRkawI6smFo/IIUE8EX1hXVSu5KrxobEWkqolqkBZg23AcssC
PsdYCNQu6DMJs71YGzhLiQGOYbdxKrnfDFjSGCipE3z+hCnYBvQwQ+5xSEGkTOV/
T3StIhb2a4ZcUlK3KIrYEpr01hQ=
=zbiO
-----END PGP MESSAGE----- -----END PGP MESSAGE-----

View File

@ -252,4 +252,17 @@
}; };
site.dyndnsKey = "SECRET"; site.dyndnsKey = "SECRET";
site.vpn.wireguard = {
privateKey = "wPNXY4ED3Jz3Kz0KOmvfQOou6/wHrgqSsykaMYrtb28=";
peers = [ {
# privateKey: GOdfeizQZjPmyYnh3LMI3LrYeEtqYMyOvK8KASVgI1Q=
publicKey = "4aTjdm/APMTERczvtnLXRFYjSWYsmwPFTumjyno4nx4=";
allowedIPs = [
"172.20.76.226"
"fd23:42:c3d2:585::/64"
"2a00:8180:2c00:285::/64"
];
} ];
};
} }

View File

@ -529,6 +529,30 @@ let
}; };
}; };
}; };
vpnOpts = {
privateKey = mkOption {
type = types.str;
};
port = mkOption {
type = types.int;
default = 1337;
};
peers = mkOption {
type = with types; listOf (submodule {
options = {
publicKey = mkOption {
type = str;
};
allowedIPs = mkOption {
type = listOf str;
};
};
});
};
};
in in
{ {
options.site = { options.site = {
@ -551,6 +575,8 @@ in
dyndnsKey = mkOption { dyndnsKey = mkOption {
type = types.str; type = types.str;
}; };
vpn.wireguard = vpnOpts;
}; };
config.warnings = config.warnings =
@ -585,7 +611,7 @@ in
else [] else []
) (builtins.attrNames config.site.hosts); ) (builtins.attrNames config.site.hosts);
in in
(reportCollisions "VLAN tag" (x: [x.vlan]) config.site.net) ++ (reportCollisions "VLAN tag" (x: lib.optional (x.vlan != null) x.vlan) config.site.net) ++
(reportCollisions "IPv4 subnet" (x: if x.subnet4 == null then [] else [x.subnet4]) config.site.net) ++ (reportCollisions "IPv4 subnet" (x: if x.subnet4 == null then [] else [x.subnet4]) config.site.net) ++
(reportCollisions "IPv6 subnet" (x: builtins.attrValues x.subnets6) config.site.net) ++ (reportCollisions "IPv6 subnet" (x: builtins.attrValues x.subnets6) config.site.net) ++
ospfUpstreamXorGw; ospfUpstreamXorGw;

View File

@ -0,0 +1,51 @@
{ hostName, config, lib, pkgs, ... }:
let
privateKeyFile = ifName:
"/run/wireguard-keys/${ifName}.key";
ifName = "vpn";
in
{
systemd.services = {
"wireguard-key-${ifName}" = {
description = "Create key file for wireguard interface '${ifName}'";
requiredBy = [ "systemd-networkd.service" ];
before = [ "systemd-networkd.service" ];
serviceConfig.Type = "oneshot";
script = ''
#! ${pkgs.runtimeShell} -e
F=${privateKeyFile ifName}
mkdir -p -m 0700 $(dirname $F)
chown systemd-network:systemd-network $(dirname $F)
rm -f $F
cat >$F <<EOF
${config.site.vpn.wireguard.privateKey}
EOF
chmod 0400 $F
chown systemd-network:systemd-network $F
'';
};
};
systemd.network.netdevs.vpn = {
netdevConfig = {
Name = ifName;
Kind = "wireguard";
};
wireguardConfig = {
PrivateKeyFile = privateKeyFile ifName;
ListenPort = config.site.vpn.wireguard.port;
};
wireguardPeers = map ({ publicKey, allowedIPs }: {
wireguardPeerConfig = {
PublicKey = publicKey;
AllowedIPs = allowedIPs;
};
}) config.site.vpn.wireguard.peers;
};
environment.systemPackages = [
pkgs.wireguard-tools
];
}

View File

@ -39,5 +39,8 @@ in {
] ++ ] ++
optionals (hostName == "netboot") [ optionals (hostName == "netboot") [
./container/netboot.nix ./container/netboot.nix
] ++
optionals (hostName == "vpn-gw") [
./container/vpn.nix
]; ];
} }