Compare commits
1 Commits
master
...
nek0-mailt
Author | SHA1 | Date |
---|---|---|
Nek0 - | a04e725988 |
|
@ -78,10 +78,6 @@ ausgeführt.
|
|||
|
||||
### LXC-Containers auf Server
|
||||
|
||||
Warum Container? Mehrere Routing-Tabellen verteile auf virtuelle
|
||||
Router statt Policy Routing oder Virtual Routing Functions. Container
|
||||
sind einfach zwischen Servern migrierbar.
|
||||
|
||||
Ein Server erwartet die für ihn (`location = hostName`) konfigurierten
|
||||
Container. systemd versucht sie zu starten. Das wird erst nach
|
||||
`build-container` funktionieren, welches das Rootfs anlegt.
|
||||
|
|
|
@ -26,11 +26,11 @@ Alle Stecker im Haus sind in Schema A gecrimpt.
|
|||
| | ![][gi] B 2.05.02 | ![][gi] UVB 1.09 | | 14 |
|
||||
| ![][ri] B 4.02.01 *v* | ![][gi] B 2.05.05 | ![][gi] UVB 1.10 | | 15 |
|
||||
| ![][ri] B 4.01.01 *v* | ![][gi] B 2.05.06 | ![][gi] 1.06 | | 16 |
|
||||
| ![][ri] B 4.03.01 *v* | ![][gi] B 2.05.03 *v* | ![][gi] 1.16 *v* | | 17 |
|
||||
| ![][ri] B 4.03.01 | ![][gi] B 2.05.03 *v* | | | 17 |
|
||||
| ![][ri] B 4.04.01 *v* | ![][gi] B 2.05.07 *v* | | | 18 |
|
||||
| ![][ri] B 4.05.02 *v* | ![][gi] B 2.06 | | | 19 |
|
||||
| ![][ri] B 4.06.01 *v* | ![][ri] B 2.07 | | | 20 |
|
||||
| ![][ri] B 4.07.05 *v* | | | | 21 |
|
||||
| ![][ri] B 4.06.01 | ![][ri] B 2.07 | | | 20 |
|
||||
| ![][ri] B 4.07.05 | | | | 21 |
|
||||
| ![][ri] B 4.08.01 | | | | 22 |
|
||||
| ![][ri] B 4.09.01 *v* | | | | 23 |
|
||||
| ![][ri] B 4.10.01 *v* | | | | 24 |
|
||||
|
|
885
config/ap.nix
885
config/ap.nix
File diff suppressed because it is too large
Load Diff
|
@ -1,9 +1,4 @@
|
|||
{ config, lib, ... }:
|
||||
|
||||
let
|
||||
# https://github.com/NixOS/nixpkgs/pull/206965
|
||||
concatMapAttrsRecursive = with lib; f: flip pipe [ (mapAttrs f) attrValues (foldl' recursiveUpdate { }) ];
|
||||
in
|
||||
{ lib, ... }:
|
||||
{
|
||||
imports = [
|
||||
# Secrets
|
||||
|
@ -14,8 +9,7 @@ in
|
|||
./switch.nix
|
||||
./ap.nix
|
||||
./server.nix
|
||||
]
|
||||
] ++
|
||||
# IP networks
|
||||
++ lib.filesystem.listFilesRecursive ./net;
|
||||
|
||||
lib.filesystem.listFilesRecursive ./net;
|
||||
}
|
||||
|
|
|
@ -8,74 +8,65 @@
|
|||
fixed-hosts = {
|
||||
"172.22.99.96" = "08:00:27:bb:8c:b3";
|
||||
"172.22.99.98" = "08:00:27:aa:90:e2";
|
||||
# "astrom" = "aa:00:5b:08:f0:5c";
|
||||
# "astron" = "aa:00:5b:08:f0:5b";
|
||||
# "batman" = "5c:cf:7f:c0:05:28";
|
||||
# "beere" = "b8:27:eb:ac:65:d2";
|
||||
# "beere2" = "b8:27:eb:53:0b:27";
|
||||
# "bender.hq.c3de.de" = "00:23:df:7e:c8:0a";
|
||||
# "cider" = "00:0d:93:75:ee:fa";
|
||||
"dacbert" = "dc:a6:32:e0:46:bf";
|
||||
"dn42" = "aa:00:42:7a:32:46";
|
||||
# "drucker" = "00:23:c3:d2:12:0f";
|
||||
# "feile" = "aa:00:5b:12:c1:f7";
|
||||
# "fernandopoo" = "aa:00:f7:52:85:27";
|
||||
# "fhem" = "b8:27:eb:9e:8b:db";
|
||||
# "git" = "aa:00:47:d8:57:10";
|
||||
"glotzbert" = "90:1b:0e:88:da:0a";
|
||||
# "wled-nix-snowflake" = "44:17:93:10:77:e8";
|
||||
# "wled-fairy-dust" = "3c:61:05:e3:2f:ad";
|
||||
# "wled-warnbert" = "3c:61:05:fc:21:37";
|
||||
# "wled-matrix" = "e8:db:84:e4:f4:30";
|
||||
# "ledball1" = "b8:27:eb:53:0b:27";
|
||||
# Beleuchtungskiste auf Traverse über Fernseher
|
||||
# "ledbeere" = "b8:27:eb:60:99:59";
|
||||
# "leviathan" = "00:ff:08:31:db:e5";
|
||||
# "lisbeth" = "b8:27:eb:a5:ee:5c";
|
||||
# "marenz-build" = "44:1e:a1:59:2e:e8";
|
||||
# "matemat" = "a2:1b:7c:e8:19:72";
|
||||
# "minecraft" = "4a:57:d3:64:fe:e9";
|
||||
# "moleflap" = "aa:00:0d:b1:6c:67";
|
||||
# "monit" = "00:23:ae:94:e7:19";
|
||||
"pipebert" = "ec:a8:6b:fe:b4:cb";
|
||||
# "public-access-proxy" = "12:24:5f:bd:9b:e7";
|
||||
"pulsebert" = "b8:27:eb:16:31:61";
|
||||
# "ruststripe1" = "06:32:0e:39:21:69";
|
||||
"schalter" = "b8:27:eb:ac:65:d2";
|
||||
# "semanta" = "00:ff:e4:bb:ea:2a";
|
||||
# "server2" = "d0:67:e5:f3:57:10";
|
||||
# "server3" = "e4:1f:13:2e:4f:c0";
|
||||
# "server4" = "00:9c:02:a9:26:01";
|
||||
# "sharing" = "00:23:c3:d2:75:18";
|
||||
# "sofafon" = "b8:27:eb:23:8d:01";
|
||||
# "storage2" = "42:5e:0f:4e:f3:cc";
|
||||
# "ustriper" = "aa:bb:95:33:bb:aa";
|
||||
# "wiefelspuetz" = "aa:00:7f:01:8a:d0";
|
||||
# "wormhole" = "00:23:c3:d2:00:76";
|
||||
# "www1" = "aa:00:13:8b:03:47";
|
||||
# "riscbert" = "6c:cf:39:00:05:95";
|
||||
"astrom.hq.c3d2.de" = "aa:00:5b:08:f0:5c";
|
||||
"astron.hq.c3d2.de" = "aa:00:5b:08:f0:5b";
|
||||
"batman.hq.c3d2.de" = "5c:cf:7f:c0:05:28";
|
||||
"beere.hq.c3d2.de" = "b8:27:eb:ac:65:d2";
|
||||
"beere2.hq.c3d2.de" = "b8:27:eb:53:0b:27";
|
||||
"bender.hq.c3de.de" = "00:23:df:7e:c8:0a";
|
||||
"cider.hq.c3d2.de" = "00:0d:93:75:ee:fa";
|
||||
"dacbert.hq.c3d2.de" = "dc:a6:32:31:b6:32";
|
||||
"dn42.hq.c3d2.de" = "aa:00:42:7a:32:46";
|
||||
"drucker.hq.c3d2.de" = "00:23:c3:d2:12:0f";
|
||||
"feile.hq.c3d2.de" = "aa:00:5b:12:c1:f7";
|
||||
"fernandopoo.hq.c3d2.de" = "aa:00:f7:52:85:27";
|
||||
"fhem.hq.c3d2.de" = "b8:27:eb:9e:8b:db";
|
||||
"git.hq.c3d2.de" = "aa:00:47:d8:57:10";
|
||||
"glotzbert.hq.c3d2.de" = "ec:a8:6b:fe:b4:cb";
|
||||
"icq.hq.c3d2.de" = "aa:00:30:f6:27:89";
|
||||
"jabber1.hq.c3d2.de" = "aa:00:0b:19:8f:14";
|
||||
"jabber2.hq.c3d2.de" = "aa:00:3d:6a:23:b8";
|
||||
"knot.hq.c3d2.de" = "52:54:cf:fd:ce:3f";
|
||||
"ledball1.hq.c3d2.de" = "b8:27:eb:53:0b:27";
|
||||
"ledbeere.hq.c3d2.de" = "b8:27:eb:60:99:59";
|
||||
"leviathan.hq.c3d2.de" = "00:ff:08:31:db:e5";
|
||||
"lisbeth.hq.c3d2.de" = "b8:27:eb:a5:ee:5c";
|
||||
"marenz-build.hq.c3d2.de" = "44:1e:a1:59:2e:e8";
|
||||
"matemat.hq.c3d2.de" = "a2:1b:7c:e8:19:72";
|
||||
"minecraft.hq.c3d2.de" = "4a:57:d3:64:fe:e9";
|
||||
"moleflap.hq.c3d2.de" = "aa:00:0d:b1:6c:67";
|
||||
"monit.hq.c3d2.de" = "00:23:ae:94:e7:19";
|
||||
"public-access-proxy.hq.c3d2.de" = "12:24:5f:bd:9b:e7";
|
||||
"pulsebert.hq.c3d2.de" = "b8:27:eb:16:31:61";
|
||||
"ruststripe1.hq.c3d2.de" = "06:32:0e:39:21:69";
|
||||
"schalter.hq.c3d2.de" = "b8:27:eb:4c:be:ff";
|
||||
"semanta.hq.c3d2.de" = "00:ff:e4:bb:ea:2a";
|
||||
"server2.hq.c3d2.de" = "d0:67:e5:f3:57:10";
|
||||
"server3.hq.c3d2.de" = "e4:1f:13:2e:4f:c0";
|
||||
"server4.hq.c3d2.de" = "00:9c:02:a9:26:01";
|
||||
"sharing.hq.c3d2.de" = "00:23:c3:d2:75:18";
|
||||
"sofafon.hq.c3d2.de" = "b8:27:eb:23:8d:01";
|
||||
"storage2.hq.c3d2.de" = "42:5e:0f:4e:f3:cc";
|
||||
"ustriper.hq.c3d2.de" = "aa:bb:95:33:bb:aa";
|
||||
"wiefelspuetz.hq.c3d2.de" = "aa:00:7f:01:8a:d0";
|
||||
"wormhole.hq.c3d2.de" = "00:23:c3:d2:00:76";
|
||||
"www1.hq.c3d2.de" = "aa:00:13:8b:03:47";
|
||||
};
|
||||
time = 300;
|
||||
max-time = 30 * 24 * 3600;
|
||||
router = "c3d2-gw3";
|
||||
time = 86400;
|
||||
max-time = 2592000;
|
||||
router = "c3d2-anon";
|
||||
};
|
||||
domainName = "c3d2.zentralwerk.org";
|
||||
dynamicDomain = true;
|
||||
subnet4 = "172.22.99.0/24";
|
||||
hosts4 = {
|
||||
bgp = "172.22.99.250";
|
||||
c3d2-anon = "172.22.99.1";
|
||||
c3d2-gw1 = "172.22.99.2";
|
||||
c3d2-gw2 = "172.22.99.3";
|
||||
c3d2-gw3 = "172.22.99.4";
|
||||
dacbert = "172.22.99.203";
|
||||
schalter = "172.22.99.204";
|
||||
glotzbert = "172.22.99.205";
|
||||
pulsebert = "172.22.99.208";
|
||||
pipebert = "172.22.99.209";
|
||||
bgp = "172.22.99.250";
|
||||
dn42 = "172.22.99.253";
|
||||
};
|
||||
ipv6Router = "c3d2-gw3";
|
||||
hosts6.dn42 = {
|
||||
bgp = "fd23:42:c3d2:523::c3d2:ff0b";
|
||||
c3d2-anon = "fd23:42:c3d2:523::c3d2:1";
|
||||
|
@ -89,11 +80,12 @@
|
|||
c3d2-gw1 = "2a00:8180:2c00:223::c3d2:2";
|
||||
c3d2-gw2 = "2a00:8180:2c00:223::c3d2:3";
|
||||
c3d2-gw3 = "2a00:8180:2c00:223::c3d2:4";
|
||||
pipebert = "2a00:8180:2c00:223:eea8:6bff:fefe:b4cb";
|
||||
};
|
||||
hosts6.yggdrasil.c3d2-gw3 = "30c:c3d2:b946:76d0::1";
|
||||
subnets6 = {
|
||||
dn42 = "fd23:42:c3d2:523::/64";
|
||||
up4 = "2a00:8180:2c00:223::/64";
|
||||
yggdrasil = "30c:c3d2:b946:76d0::/64";
|
||||
};
|
||||
};
|
||||
|
||||
|
@ -120,21 +112,21 @@
|
|||
c3d2.hwaddr = "0A:14:48:01:21:01";
|
||||
core.hwaddr = "0A:14:48:01:21:00";
|
||||
};
|
||||
ospf.allowedUpstreams = [ "flpk-gw" "freifunk" "upstream4" "upstream3" "anon1" ];
|
||||
ospf.allowedUpstreams = [ "upstream3" "upstream4" "upstream1" "anon1" "freifunk" ];
|
||||
};
|
||||
c3d2-gw2 = makeGateway {
|
||||
interfaces = {
|
||||
c3d2.hwaddr = "0A:14:48:01:21:03";
|
||||
core.hwaddr = "0A:14:48:01:21:02";
|
||||
};
|
||||
ospf.allowedUpstreams = [ "upstream3" "upstream4" "anon1" "freifunk" ];
|
||||
ospf.allowedUpstreams = [ "upstream1" "upstream3" "upstream4" "anon1" "freifunk" ];
|
||||
};
|
||||
c3d2-gw3 = makeGateway {
|
||||
interfaces = {
|
||||
c3d2.hwaddr = "0A:14:48:01:21:05";
|
||||
core.hwaddr = "0A:14:48:01:21:04";
|
||||
};
|
||||
ospf.allowedUpstreams = [ "upstream4" "upstream3" "anon1" "freifunk" ];
|
||||
ospf.allowedUpstreams = [ "upstream4" "upstream3" "upstream1" "anon1" "freifunk" ];
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
|
@ -1,47 +0,0 @@
|
|||
{
|
||||
site.net.c3d2iot = {
|
||||
dhcp = {
|
||||
start = "10.22.0.2";
|
||||
end = "10.22.255.253";
|
||||
router = "iot-gw";
|
||||
server = "iot-gw";
|
||||
# devices don't often change and a missing DNS record causes trouble
|
||||
time = 3600;
|
||||
max-time = 24 * 3600;
|
||||
};
|
||||
dynamicDomain = true;
|
||||
domainName = "c3d2iot.zentralwerk.org";
|
||||
hosts4 = {
|
||||
iot-gw = "10.22.0.1";
|
||||
};
|
||||
hosts6 = {
|
||||
dn42 = {
|
||||
iot-gw = "fd23:42:c3d2:587:ffff:ffff:ffff:ffff";
|
||||
};
|
||||
};
|
||||
subnet4 = "10.22.0.0/16";
|
||||
subnets6 = {
|
||||
dn42 = "fd23:42:c3d2:587::/64";
|
||||
up4 = "2a00:8180:2c00:287::/64";
|
||||
};
|
||||
};
|
||||
|
||||
site.hosts.iot-gw = {
|
||||
# TODO: needs to be done more granular, aka allow c3d2 and serv network
|
||||
# firewall.enable = true;
|
||||
interfaces = {
|
||||
core = {
|
||||
hwaddr = "0A:22:48:01:24:01";
|
||||
type = "veth";
|
||||
};
|
||||
c3d2iot = {
|
||||
hwaddr = "0A:22:48:01:24:00";
|
||||
type = "veth";
|
||||
};
|
||||
};
|
||||
ospf = {
|
||||
allowedUpstreams = [ "upstream4" "upstream3" "anon1" ];
|
||||
};
|
||||
role = "container";
|
||||
};
|
||||
}
|
|
@ -4,18 +4,10 @@ let
|
|||
in
|
||||
{
|
||||
site.net.cluster = {
|
||||
ipv6Router = "cls-gw";
|
||||
domainName = "cluster.zentralwerk.org";
|
||||
extraRecords = map (host: {
|
||||
data = {
|
||||
service = "ceph-mon";
|
||||
proto = "tcp";
|
||||
priority = 1;
|
||||
weight = 1;
|
||||
port = 6789;
|
||||
target = host;
|
||||
};
|
||||
name = "@";
|
||||
data = "1 1 6789 ${host}";
|
||||
name = "_ceph-mon._tcp";
|
||||
type = "SRV";
|
||||
}) cephMonServers
|
||||
++
|
||||
|
@ -133,7 +125,7 @@ in
|
|||
let
|
||||
makeServer = {
|
||||
role = "client";
|
||||
model = "nixos";
|
||||
model = "proxmox";
|
||||
interfaces = builtins.foldl' (interfaces: net:
|
||||
interfaces // {
|
||||
"${net}".type = "bridge";
|
||||
|
@ -144,13 +136,10 @@ in
|
|||
"mgmt"
|
||||
"serv"
|
||||
"c3d2"
|
||||
"c3d2iot"
|
||||
"pub"
|
||||
"priv23"
|
||||
"priv31"
|
||||
"priv45"
|
||||
"bmx"
|
||||
"flpk"
|
||||
];
|
||||
};
|
||||
in {
|
||||
|
@ -166,7 +155,7 @@ in
|
|||
type = "veth";
|
||||
};
|
||||
};
|
||||
ospf.allowedUpstreams = [ "upstream4" "upstream3" "anon1" "freifunk" ];
|
||||
ospf.allowedUpstreams = [ "upstream4" "upstream1" "upstream3" "anon1" "freifunk" ];
|
||||
};
|
||||
server3 = makeServer;
|
||||
server5 = makeServer;
|
||||
|
@ -174,6 +163,5 @@ in
|
|||
server7 = makeServer;
|
||||
server8 = makeServer;
|
||||
server9 = makeServer;
|
||||
server10 = makeServer;
|
||||
};
|
||||
}
|
||||
|
|
|
@ -1,38 +0,0 @@
|
|||
{
|
||||
site.net.coloradio = {
|
||||
domainName = "coloradio.zentralwerk.org";
|
||||
subnet4 = "192.168.9.0/24";
|
||||
hosts4 = {
|
||||
coloradio-gw = "192.168.9.1";
|
||||
coloradio-in = "192.168.9.2";
|
||||
};
|
||||
|
||||
ipv6Router = "coloradio-gw";
|
||||
subnets6.dn42 = "fd23:42:c3d2:590::/64";
|
||||
hosts6.dn42 = {
|
||||
coloradio-gw = "fd23:42:c3d2:590::1";
|
||||
};
|
||||
};
|
||||
|
||||
site.hosts = {
|
||||
coloradio-gw = {
|
||||
role = "container";
|
||||
interfaces = {
|
||||
core = {
|
||||
type = "veth";
|
||||
hwaddr = "0A:14:48:01:06:08";
|
||||
gw4 = null;
|
||||
gw6 = null;
|
||||
};
|
||||
coloradio = {
|
||||
type = "veth";
|
||||
hwaddr = "0A:14:48:01:06:09";
|
||||
gw4 = null;
|
||||
gw6 = null;
|
||||
};
|
||||
};
|
||||
ospf.allowedUpstreams =
|
||||
[ "upstream4" "upstream3" "freifunk" ];
|
||||
};
|
||||
};
|
||||
}
|
|
@ -50,12 +50,6 @@
|
|||
priv41-gw = "172.20.72.65";
|
||||
priv42-gw = "172.20.72.67";
|
||||
priv43-gw = "172.20.72.68";
|
||||
priv44-gw = "172.20.72.70";
|
||||
priv45-gw = "172.20.72.72";
|
||||
priv46-gw = "172.20.72.73";
|
||||
priv47-gw = "172.20.72.74";
|
||||
priv48-gw = "172.20.72.75";
|
||||
priv49-gw = "172.20.72.76";
|
||||
priv5-gw = "172.20.72.15";
|
||||
priv6-gw = "172.20.72.16";
|
||||
priv7-gw = "172.20.72.17";
|
||||
|
@ -69,12 +63,12 @@
|
|||
server6 = "172.20.72.56";
|
||||
server7 = "172.20.72.57";
|
||||
server8 = "172.20.72.58";
|
||||
server9 = "172.20.72.59";
|
||||
upstream1 = "172.20.72.6";
|
||||
upstream2 = "172.20.72.10";
|
||||
upstream3 = "172.20.72.11";
|
||||
upstream4 = "172.20.72.12";
|
||||
coloradio-gw = "172.20.72.62";
|
||||
vpn-gw = "172.20.72.69";
|
||||
flpk-gw = "172.20.72.71";
|
||||
iot-gw = "172.20.72.77";
|
||||
yggdrasil = "172.20.72.62";
|
||||
};
|
||||
hosts6 = {
|
||||
dn42 = {
|
||||
|
@ -84,10 +78,8 @@
|
|||
c3d2-gw1 = "fd23:42:c3d2:581::c3d2:1";
|
||||
c3d2-gw2 = "fd23:42:c3d2:581::c3d2:2";
|
||||
c3d2-gw3 = "fd23:42:c3d2:581::c3d2:3";
|
||||
cls-gw = "fd23:42:c3d2:581::c3d2:4";
|
||||
freifunk = "fd23:42:c3d2:581:8000::1";
|
||||
mgmt-gw = "fd23:42:c3d2:581::8:3";
|
||||
iot-gw = "fd23:42:c3d2:581::8:7";
|
||||
priv1-gw = "fd23:42:c3d2:581::c:0";
|
||||
priv10-gw = "fd23:42:c3d2:581::c:9";
|
||||
priv11-gw = "fd23:42:c3d2:581::c:a";
|
||||
|
@ -125,13 +117,7 @@
|
|||
priv40-gw = "fd23:42:c3d2:581::c:27";
|
||||
priv41-gw = "fd23:42:c3d2:581::c:28";
|
||||
priv42-gw = "fd23:42:c3d2:581::c:29";
|
||||
priv43-gw = "fd23:42:c3d2:581::c:2a";
|
||||
priv44-gw = "fd23:42:c3d2:581::c:2b";
|
||||
priv45-gw = "fd23:42:c3d2:581::c:2c";
|
||||
priv46-gw = "fd23:42:c3d2:581::c:2d";
|
||||
priv47-gw = "fd23:42:c3d2:581::c:2e";
|
||||
priv48-gw = "fd23:42:c3d2:581::c:2f";
|
||||
priv49-gw = "fd23:42:c3d2:581::c:30";
|
||||
priv43-gw = "fd23:42:c3d2:581::c:30";
|
||||
priv5-gw = "fd23:42:c3d2:581::c:4";
|
||||
priv6-gw = "fd23:42:c3d2:581::c:5";
|
||||
priv7-gw = "fd23:42:c3d2:581::c:6";
|
||||
|
@ -139,10 +125,11 @@
|
|||
priv9-gw = "fd23:42:c3d2:581::c:8";
|
||||
pub-gw = "fd23:42:c3d2:581::8:2";
|
||||
serv-gw = "fd23:42:c3d2:581::8:1";
|
||||
upstream1 = "fd23:42:c3d2:581::b:0";
|
||||
upstream2 = "fd23:42:c3d2:581::b:1";
|
||||
upstream3 = "fd23:42:c3d2:581::b:2";
|
||||
upstream4 = "fd23:42:c3d2:581::b:3";
|
||||
vpn-gw = "fd23:42:c3d2:581:9001::1";
|
||||
coloradio-gw = "fd23:42:c3d2:581:9009::1";
|
||||
yggdrasil = "fd23:42:c3d2:581:9000::1";
|
||||
};
|
||||
up4 = {
|
||||
anon1 = "2a00:8180:2c00:281::9:1";
|
||||
|
@ -154,7 +141,6 @@
|
|||
cls-gw = "2a00:8180:2c00:281::8:4";
|
||||
freifunk = "2a00:8180:2c00:281:8000::1";
|
||||
mgmt-gw = "2a00:8180:2c00:281::8:3";
|
||||
iot-gw = "2a00:8180:2c00:281::8:7";
|
||||
priv1-gw = "2a00:8180:2c00:281::c:0";
|
||||
priv10-gw = "2a00:8180:2c00:281::c:9";
|
||||
priv11-gw = "2a00:8180:2c00:281::c:a";
|
||||
|
@ -192,22 +178,16 @@
|
|||
priv40-gw = "2a00:8180:2c00:281::c:27";
|
||||
priv41-gw = "2a00:8180:2c00:281::c:28";
|
||||
priv42-gw = "2a00:8180:2c00:281::c:29";
|
||||
priv43-gw = "2a00:8180:2c00:281::c:2a";
|
||||
priv44-gw = "2a00:8180:2c00:281::c:2b";
|
||||
priv45-gw = "2a00:8180:2c00:281::c:2c";
|
||||
priv46-gw = "2a00:8180:2c00:281::c:2d";
|
||||
priv47-gw = "2a00:8180:2c00:281::c:2e";
|
||||
priv48-gw = "2a00:8180:2c00:281::c:2f";
|
||||
priv49-gw = "2a00:8180:2c00:281::c:30";
|
||||
priv43-gw = "2a00:8180:2c00:281::c:30";
|
||||
priv5-gw = "2a00:8180:2c00:281::c:4";
|
||||
priv6-gw = "2a00:8180:2c00:281::c:5";
|
||||
priv7-gw = "2a00:8180:2c00:281::c:6";
|
||||
priv8-gw = "2a00:8180:2c00:281::c:7";
|
||||
priv9-gw = "2a00:8180:2c00:281::c:8";
|
||||
serv-gw = "2a00:8180:2c00:281::8:1";
|
||||
upstream1 = "2a00:8180:2c00:281::b:0";
|
||||
upstream4 = "2a00:8180:2c00:281::b:1";
|
||||
vpn-gw = "2a00:8180:2c00:281:9001::1";
|
||||
coloradio-gw = "2a00:8180:2c00:281:9009::1";
|
||||
yggdrasil = "2a00:8180:2c00:281:9000::1";
|
||||
};
|
||||
};
|
||||
subnet4 = "172.20.72.0/25";
|
||||
|
@ -238,10 +218,10 @@
|
|||
};
|
||||
ospf = {
|
||||
allowedUpstreams =
|
||||
[ "upstream4" "upstream3" "anon1" "freifunk" ];
|
||||
[ "upstream4" "upstream1" "upstream3" "anon1" "freifunk" ];
|
||||
stubNets4 = [ "172.20.0.0/14" "10.0.0.0/8" ];
|
||||
stubNets6 =
|
||||
[ "fd00::/8" "2a00:8180:2c00:200::/56" ];
|
||||
[ "fd00::/8" "2a02:8106:208:5200::/56" "2a02:8106:211:e900::/56" ];
|
||||
};
|
||||
role = "container";
|
||||
};
|
||||
|
|
|
@ -1,65 +0,0 @@
|
|||
{
|
||||
site.net.flpk = {
|
||||
domainName = "flpk.zentralwerk.org";
|
||||
ipv6Router = "flpk-gw";
|
||||
subnet4 = "45.158.40.160/27";
|
||||
# we get a /56
|
||||
subnets6.flpk = "2a0f:5382:acab:1400::/64";
|
||||
hosts4 = {
|
||||
flpk-gw = "45.158.40.160";
|
||||
notice-me-senpai = "45.158.40.162"; # tlms monitoring
|
||||
sshlog = "45.158.40.163";
|
||||
caveman = "45.158.40.164";
|
||||
# tlms-37c3-ctf vm on server9
|
||||
ctf = "45.158.40.165";
|
||||
mastodon = "45.158.40.166";
|
||||
c3d2-web = "45.158.40.167";
|
||||
mail = "45.158.40.168";
|
||||
dresden-zone-dns = "45.158.40.169";
|
||||
# server7 = "45.158.40.170"; # unused
|
||||
rtrlab = "45.158.40.171"; # temporary
|
||||
};
|
||||
hosts6.flpk = {
|
||||
flpk-gw = "2a0f:5382:acab:1400::c3d2";
|
||||
notice-me-senpai = "2a0f:5382:acab:1400:2de:5bff:fef9:e23e"; # tlms-monitoring
|
||||
sshlog = "2a0f:5382:acab:1400::22";
|
||||
caveman = "2a0f:5382:acab:1400::a4";
|
||||
# tlms-37c3-ctf vm on server9
|
||||
ctf = "2a0f:5382:acab:1400::a5";
|
||||
mastodon = "2a0f:5382:acab:1400::a6";
|
||||
c3d2-web = "2a0f:5382:acab:1400::a7";
|
||||
# mail = "2a0f:5382:acab:1400::a8"; # we don't have an PTR for IPv6 and it gets way more often marked as spam
|
||||
dresden-zone-dns = "2a0f:5382:acab:1400::a9";
|
||||
# server7 = "2a0f:5382:acab:1400::aa";
|
||||
rtrlab = "2a0f:5382:acab:1400::ab";
|
||||
};
|
||||
};
|
||||
|
||||
site.hosts.flpk-gw = {
|
||||
interfaces = {
|
||||
core = {
|
||||
hwaddr = "0A:14:48:b7:e4:91";
|
||||
type = "veth";
|
||||
};
|
||||
flpk = {
|
||||
hwaddr = "0A:14:48:01:16:01";
|
||||
type = "veth";
|
||||
};
|
||||
up-flpk = {
|
||||
type = "wireguard";
|
||||
upstream = {
|
||||
provider = "flpk";
|
||||
noNat = {
|
||||
subnets4 = [ "45.158.40.160/27" ];
|
||||
subnets6 = [ "2a0f:5382:acab:1400::/56" ];
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
ospf = {
|
||||
allowedUpstreams = [ "upstream4" "upstream3" "freifunk" ];
|
||||
upstreamInstance = 2;
|
||||
};
|
||||
role = "container";
|
||||
};
|
||||
}
|
|
@ -63,15 +63,7 @@
|
|||
ap62 = "10.0.0.102";
|
||||
ap63 = "10.0.0.103";
|
||||
ap64 = "10.0.0.104";
|
||||
ap65 = "10.0.0.105";
|
||||
ap66 = "10.0.0.106";
|
||||
ap67 = "10.0.0.107";
|
||||
ap68 = "10.0.0.108";
|
||||
ap69 = "10.0.0.109";
|
||||
ap7 = "10.0.0.47";
|
||||
ap70 = "10.0.0.110";
|
||||
ap71 = "10.0.0.111";
|
||||
ap72 = "10.0.0.112";
|
||||
ap8 = "10.0.0.48";
|
||||
ap9 = "10.0.0.49";
|
||||
logging = "10.0.0.251";
|
||||
|
@ -103,10 +95,6 @@
|
|||
switch-c3d2-main = "10.0.0.14";
|
||||
switch-d1 = "10.0.0.13";
|
||||
switch-dach = "10.0.0.17";
|
||||
switch-b3 = "10.0.0.18";
|
||||
switch-ds1 = "10.0.0.20";
|
||||
switch-ds2 = "10.0.0.21";
|
||||
switch-ds3 = "10.0.0.22";
|
||||
};
|
||||
hosts6 = {
|
||||
dn42 = {
|
||||
|
@ -171,15 +159,7 @@
|
|||
ap62 = "fd23:42:c3d2:580::4:3e";
|
||||
ap63 = "fd23:42:c3d2:580::4:3f";
|
||||
ap64 = "fd23:42:c3d2:580::4:40";
|
||||
ap65 = "fd23:42:c3d2:580::4:41";
|
||||
ap66 = "fd23:42:c3d2:580::4:42";
|
||||
ap67 = "fd23:42:c3d2:580::4:43";
|
||||
ap68 = "fd23:42:c3d2:580::4:44";
|
||||
ap69 = "fd23:42:c3d2:580::4:45";
|
||||
ap7 = "fd23:42:c3d2:580::4:7";
|
||||
ap70 = "fd23:42:c3d2:580::4:46";
|
||||
ap71 = "fd23:42:c3d2:580::4:47";
|
||||
ap72 = "fd23:42:c3d2:580::4:48";
|
||||
ap8 = "fd23:42:c3d2:580::4:8";
|
||||
ap9 = "fd23:42:c3d2:580::4:9";
|
||||
mgmt-gw = "fd23:42:c3d2:580:ffff:ffff:ffff:ffff";
|
||||
|
@ -211,7 +191,7 @@
|
|||
};
|
||||
ospf = {
|
||||
allowedUpstreams =
|
||||
[ "upstream4" "upstream3" "anon1" "freifunk" ];
|
||||
[ "upstream4" "upstream1" "upstream3" "anon1" "freifunk" ];
|
||||
};
|
||||
role = "container";
|
||||
};
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{ lib, ... }:
|
||||
let
|
||||
privCount = 49;
|
||||
privCount = 43;
|
||||
seq = n: max:
|
||||
if n <= max
|
||||
then [ n ] ++ seq (n + 1) max
|
||||
|
@ -16,9 +16,9 @@ lib.mkMerge (
|
|||
site.net."priv${toString n}" = {
|
||||
dhcp = {
|
||||
server = "priv${toString n}-gw";
|
||||
time = 300;
|
||||
max-time = 60 * 24 * 3600;
|
||||
router = "priv${toString n}-gw";
|
||||
time = 120;
|
||||
max-time = 86400;
|
||||
router = "priv${toString n}-gw.priv${toString n}";
|
||||
};
|
||||
domainName = "priv${toString n}.zentralwerk.org";
|
||||
dynamicDomain = true;
|
||||
|
@ -38,7 +38,7 @@ lib.mkMerge (
|
|||
core.type = "veth";
|
||||
"priv${toString n}".type = "veth";
|
||||
};
|
||||
ospf.allowedUpstreams = [ "upstream4" "upstream3" "anon1" "freifunk" ];
|
||||
ospf.allowedUpstreams = [ "upstream4" "upstream3" "upstream1" "anon1" "freifunk" ];
|
||||
};
|
||||
}
|
||||
) (seq 1 privCount)
|
||||
|
@ -58,12 +58,10 @@ lib.mkMerge (
|
|||
subnet4 = "172.20.75.0/27";
|
||||
dhcp = {
|
||||
start = "172.20.75.2";
|
||||
end = "172.20.75.30";
|
||||
end = "172.20.75.31";
|
||||
fixed-hosts = {
|
||||
"172.20.75.2" = "ac:1f:6b:dc:93:8e";
|
||||
"172.20.75.3" = "ac:1f:6b:dc:95:de";
|
||||
"172.20.75.9" = "ac:1f:6b:dc:95:df";
|
||||
"172.20.75.7" = "60:33:4b:0b:cd:fc";
|
||||
"172.20.75.9" = "00:11:32:22:95:79";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
@ -204,6 +202,7 @@ lib.mkMerge (
|
|||
dhcp = {
|
||||
start = "172.20.73.194";
|
||||
end = "172.20.73.254";
|
||||
max-time = lib.mkForce 2592000;
|
||||
};
|
||||
};
|
||||
priv20 = {
|
||||
|
@ -238,10 +237,9 @@ lib.mkMerge (
|
|||
end = "172.20.73.190";
|
||||
fixed-hosts = {
|
||||
"172.20.73.162" = "da:2c:3a:2c:87:22";
|
||||
"172.20.73.163" = "b8:27:eb:16:31:61";
|
||||
"172.20.73.164" = "ca:71:c4:90:3e:c7";
|
||||
"172.20.73.163" = "ca:9f:27:b2:bf:6d";
|
||||
"172.20.73.164" = "60:01:94:6f:81:a6";
|
||||
};
|
||||
time = lib.mkForce 900;
|
||||
};
|
||||
};
|
||||
priv24 = {
|
||||
|
@ -305,11 +303,7 @@ lib.mkMerge (
|
|||
subnet4 = "172.20.75.208/28";
|
||||
dhcp = {
|
||||
start = "172.20.75.210";
|
||||
end = "172.20.75.221";
|
||||
fixed-hosts = {
|
||||
# zw-ev-vm
|
||||
"172.20.75.222" = "92:a8:00:49:a6:61";
|
||||
};
|
||||
end = "172.20.75.222";
|
||||
};
|
||||
};
|
||||
priv32 = {
|
||||
|
@ -408,54 +402,6 @@ lib.mkMerge (
|
|||
end = "172.20.76.110";
|
||||
};
|
||||
};
|
||||
priv44 = {
|
||||
hosts4 = { priv44-gw = "172.20.77.97"; };
|
||||
subnet4 = "172.20.77.96/28";
|
||||
dhcp = {
|
||||
start = "172.20.77.98";
|
||||
end = "172.20.77.110";
|
||||
};
|
||||
};
|
||||
priv45 = {
|
||||
hosts4 = { priv45-gw = "172.20.77.161"; };
|
||||
subnet4 = "172.20.77.160/28";
|
||||
dhcp = {
|
||||
start = "172.20.77.162";
|
||||
end = "172.20.77.174";
|
||||
};
|
||||
};
|
||||
priv46 = {
|
||||
hosts4 = { priv46-gw = "172.20.77.225"; };
|
||||
subnet4 = "172.20.77.224/28";
|
||||
dhcp = {
|
||||
start = "172.20.77.226";
|
||||
end = "172.20.77.238";
|
||||
};
|
||||
};
|
||||
priv47 = {
|
||||
hosts4 = { priv47-gw = "172.20.76.161"; };
|
||||
subnet4 = "172.20.76.160/28";
|
||||
dhcp = {
|
||||
start = "172.20.76.162";
|
||||
end = "172.20.76.174";
|
||||
};
|
||||
};
|
||||
priv48 = {
|
||||
hosts4 = { priv48-gw = "172.20.77.33"; };
|
||||
subnet4 = "172.20.77.32/28";
|
||||
dhcp = {
|
||||
start = "172.20.77.34";
|
||||
end = "172.20.77.46";
|
||||
};
|
||||
};
|
||||
priv49 = {
|
||||
hosts4 = { priv49-gw = "172.20.76.49"; };
|
||||
subnet4 = "172.20.76.48/28";
|
||||
dhcp = {
|
||||
start = "172.20.76.50";
|
||||
end = "172.20.76.62";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
site.hosts = {
|
||||
|
@ -574,7 +520,7 @@ lib.mkMerge (
|
|||
hwaddr = "0A:14:47:02:2A:19";
|
||||
};
|
||||
};
|
||||
ospf.allowedUpstreams = [ "upstream3" "upstream4" "anon1" "freifunk" ];
|
||||
ospf.allowedUpstreams = [ "upstream3" "upstream4" "upstream1" "anon1" "freifunk" ];
|
||||
};
|
||||
priv18-gw = {
|
||||
interfaces = {
|
||||
|
@ -732,42 +678,6 @@ lib.mkMerge (
|
|||
priv43.hwaddr = "0A:14:48:01:2A:53";
|
||||
};
|
||||
};
|
||||
priv44-gw = {
|
||||
interfaces = {
|
||||
core.hwaddr = "0A:14:48:01:2A:54";
|
||||
priv44.hwaddr = "0A:14:48:01:2A:55";
|
||||
};
|
||||
};
|
||||
priv45-gw = {
|
||||
interfaces = {
|
||||
core.hwaddr = "0A:14:48:01:2A:56";
|
||||
priv45.hwaddr = "0A:14:48:01:2A:57";
|
||||
};
|
||||
};
|
||||
priv46-gw = {
|
||||
interfaces = {
|
||||
core.hwaddr = "0A:14:48:01:2A:58";
|
||||
priv46.hwaddr = "0A:14:48:01:2A:59";
|
||||
};
|
||||
};
|
||||
priv47-gw = {
|
||||
interfaces = {
|
||||
core.hwaddr = "0A:14:48:01:2A:5A";
|
||||
priv47.hwaddr = "0A:14:48:01:2A:5B";
|
||||
};
|
||||
};
|
||||
priv48-gw = {
|
||||
interfaces = {
|
||||
core.hwaddr = "0A:14:48:01:2A:5C";
|
||||
priv48.hwaddr = "0A:14:48:01:2A:5D";
|
||||
};
|
||||
};
|
||||
priv49-gw = {
|
||||
interfaces = {
|
||||
core.hwaddr = "0A:14:48:01:2A:5E";
|
||||
priv49.hwaddr = "0A:14:48:01:2A:5F";
|
||||
};
|
||||
};
|
||||
};
|
||||
} ]
|
||||
)
|
||||
|
|
|
@ -1,31 +1,19 @@
|
|||
{
|
||||
site.net.pub = {
|
||||
dhcp = {
|
||||
start = "172.20.78.2";
|
||||
end = "172.20.79.253";
|
||||
router = "pub-gw";
|
||||
end = "172.20.79.254";
|
||||
max-time = 3600;
|
||||
router = "pub-gw.pub";
|
||||
server = "pub-gw";
|
||||
time = 120;
|
||||
max-time = 12 * 3600;
|
||||
start = "172.20.78.2";
|
||||
time = 300;
|
||||
};
|
||||
domainName = "pub.zentralwerk.org";
|
||||
dynamicDomain = true;
|
||||
hosts4 = {
|
||||
pub-gw = "172.20.78.1";
|
||||
};
|
||||
hosts6 = {
|
||||
dn42 = {
|
||||
pub-gw = "fd23:42:c3d2:583::1";
|
||||
};
|
||||
flpk = {
|
||||
pub-gw = "2a0f:5382:acab:1403::1";
|
||||
};
|
||||
};
|
||||
hosts4 = { pub-gw = "172.20.78.1"; };
|
||||
hosts6 = { dn42 = { pub-gw = "fd23:42:c3d2:583::1"; }; };
|
||||
subnet4 = "172.20.78.0/23";
|
||||
subnets6 = {
|
||||
dn42 = "fd23:42:c3d2:583::/64";
|
||||
flpk = "2a0f:5382:acab:1403::/64";
|
||||
};
|
||||
subnets6 = { dn42 = "fd23:42:c3d2:583::/64"; };
|
||||
};
|
||||
|
||||
site.hosts.pub-gw = {
|
||||
|
@ -41,7 +29,6 @@
|
|||
};
|
||||
ospf = {
|
||||
allowedUpstreams = [ "anon1" "freifunk" ];
|
||||
allowedUpstreams6 = [ "flpk-gw" "anon1" "freifunk" ];
|
||||
};
|
||||
role = "container";
|
||||
};
|
||||
|
|
|
@ -3,12 +3,7 @@
|
|||
# not switched, only a wifi
|
||||
vlan = null;
|
||||
# leave space for vxlan
|
||||
mtu = 1574;
|
||||
subnet4 = "10.0.57.0/24";
|
||||
hosts4 = {
|
||||
ap57 = "10.0.57.1";
|
||||
ap58 = "10.0.57.2";
|
||||
};
|
||||
mtu = 2048;
|
||||
hosts6.dn42 = {
|
||||
ap57 = "fd23:42:c3d2:584::39";
|
||||
ap58 = "fd23:42:c3d2:584::40";
|
||||
|
|
|
@ -7,136 +7,123 @@
|
|||
serv-gw = "172.20.73.1";
|
||||
dns = "172.20.73.2";
|
||||
stats = "172.20.73.3";
|
||||
dresden-zone = "172.20.73.4";
|
||||
tlms-elastic = "172.20.73.7"; # tlms
|
||||
radius = "172.20.73.4";
|
||||
zeit = "172.20.73.5";
|
||||
minecraft = "172.20.73.6";
|
||||
used1 = "172.20.73.7";
|
||||
dnscache = "172.20.73.8";
|
||||
tlms-ctfd = "172.20.73.9"; # tlms
|
||||
buzzrelay = "172.20.73.15";
|
||||
used2 = "172.20.73.9";
|
||||
used3 = "172.20.73.10";
|
||||
used4 = "172.20.73.11";
|
||||
used5 = "172.20.73.12";
|
||||
logging = "172.20.73.13";
|
||||
used6 = "172.20.73.14";
|
||||
c3d2-web = "172.20.73.15";
|
||||
deployer = "172.20.73.16";
|
||||
used7 = "172.20.73.17";
|
||||
used8 = "172.20.73.18";
|
||||
used9 = "172.20.73.19";
|
||||
ipa = "172.20.73.20";
|
||||
matemat = "172.20.73.21";
|
||||
used10 = "172.20.73.22";
|
||||
used11 = "172.20.73.23";
|
||||
used12 = "172.20.73.24";
|
||||
spaceapi = "172.20.73.25";
|
||||
used13 = "172.20.73.26";
|
||||
mucbot = "172.20.73.27";
|
||||
used14 = "172.20.73.28";
|
||||
used15 = "172.20.73.29";
|
||||
used16 = "172.20.73.30";
|
||||
used17 = "172.20.73.31";
|
||||
scrape = "172.20.73.32";
|
||||
pretalx = "172.20.73.33";
|
||||
vaultwarden = "172.20.73.34";
|
||||
uranus = "172.20.73.37"; # tlms
|
||||
tram-borzoi = "172.20.73.38"; # tlms
|
||||
borken-data-hoarder = "172.20.73.39"; # tlms
|
||||
matrix = "172.20.73.40";
|
||||
activity-relay = "172.20.73.41";
|
||||
luulaatsch-asterisk = "172.20.73.42";
|
||||
used19 = "172.20.73.33";
|
||||
used20 = "172.20.73.34";
|
||||
used21 = "172.20.73.35";
|
||||
used22 = "172.20.73.36";
|
||||
used23 = "172.20.73.37";
|
||||
used24 = "172.20.73.38";
|
||||
used25 = "172.20.73.39";
|
||||
used26 = "172.20.73.40";
|
||||
# unused = "172.22.73.41";
|
||||
mailtngbert = "172.22.73.42";
|
||||
grafana = "172.20.73.43";
|
||||
kibana = "172.20.73.44";
|
||||
public-access-proxy = "172.20.73.45";
|
||||
marenz = "172.20.73.46";
|
||||
network-homepage = "172.20.73.47";
|
||||
home-assistant = "172.20.73.48";
|
||||
leonos = "172.20.73.47";
|
||||
minetest = "172.20.73.48";
|
||||
hydra = "172.20.73.49";
|
||||
owncast = "172.20.73.50";
|
||||
nfsroot = "172.20.73.51";
|
||||
netboot = "172.20.73.50";
|
||||
vps1 = "172.20.73.51";
|
||||
ticker = "172.20.73.52";
|
||||
gitea = "172.20.73.53";
|
||||
stream = "172.20.73.54";
|
||||
jabber = "172.20.73.55";
|
||||
mobilizon = "172.20.73.56";
|
||||
radiobert = "172.20.73.57";
|
||||
# mail = "172.20.73.58";
|
||||
mail = "172.20.73.58";
|
||||
keycloak = "172.20.73.59";
|
||||
sdrweb = "172.20.73.60";
|
||||
knot = "172.20.73.61";
|
||||
bind = "172.20.73.61";
|
||||
blogs = "172.20.73.62";
|
||||
staging-data-hoarder = "172.20.73.64"; # tlms
|
||||
oparl = "172.20.73.65";
|
||||
hedgedoc = "172.20.73.66";
|
||||
mediawiki = "172.20.73.67";
|
||||
gnunet = "172.20.73.68";
|
||||
data-hoarder = "172.20.73.69"; # tlms
|
||||
broker = "172.20.73.70";
|
||||
ftp = "172.20.73.71";
|
||||
auth = "172.20.73.72";
|
||||
doubleblind-science = "172.20.73.73";
|
||||
prometheus = "172.20.73.75";
|
||||
drone = "172.20.73.77";
|
||||
# FILL IN THE HOLES BEFORE APPENDING!
|
||||
};
|
||||
ipv6Router = "serv-gw";
|
||||
subnets6.dn42 = "fd23:42:c3d2:582::/64";
|
||||
subnets6.up4 = "2a00:8180:2c00:282::/64";
|
||||
hosts6.dn42 = {
|
||||
knot = "fd23:42:c3d2:582:cd7:56ff:fe69:6366";
|
||||
blogs = "fd23:42:c3d2:582:b8a8:7dff:fee8:5ac2";
|
||||
bind = "fd23:42:c3d2:582:cd7:56ff:fe69:6366";
|
||||
blogs = "fd42:42:c3d2:582:b8a8:7dff:fee8:5ac2";
|
||||
c3d2-web = "fd23:42:c3d2:582:642e:95ff:fe34:49f9";
|
||||
dns = "fd23:42:c3d2:582:2:0:0:2";
|
||||
dnscache = "fd23:42:c3d2:582:f096:dbff:fee8:427d";
|
||||
gitea = "fd23:42:c3d2:582:702a:daff:fe35:83be";
|
||||
grafana = "fd23:42:c3d2:582:4042:fbff:fe4b:2de8";
|
||||
hydra = "fd23:42:c3d2:582:e2cb:4eff:fe3b:f94b";
|
||||
hydra = "fd23:42:c3d2:582:e03c:d7ff:fe8e:fe16";
|
||||
jabber = "fd23:42:c3d2:582:b869:ccff:fe46:902a";
|
||||
# mail = "fd23:42:c3d2:582:88c0:41ff:fe70:d6cd";
|
||||
keycloak = "fd23:42:c3d2:582:c48:bbff:fe87:721d";
|
||||
logging = "fd23:42:c3d2:582:6811:edff:fe40:89c6";
|
||||
mail = "fd23:42:c3d2:582:88c0:41ff:fe70:d6cd";
|
||||
matemat = "fd23:42:c3d2:582:f82b:1bff:fedc:8572";
|
||||
minetest = "fd23:42:c3d2:582:c3a:42ff:fe5d:b20c";
|
||||
mobilizon = "fd23:42:c3d2:582:48d1:5cff:fea7:1676";
|
||||
mongo = "fd23:42:c3d2:582:14ec:c8ff:fe0a:fc5c";
|
||||
mucbot = "fd23:42:c3d2:582:28db:dff:fe6b:e89a";
|
||||
netboot = "fd23:42:c3d2:582:2:0:0:6";
|
||||
radiobert = "fd23:42:c3d2:582:e65f:1ff:fe5d:1679";
|
||||
radius = "fd23:42:c3d2:582:2:0:0:4";
|
||||
sdrweb = "fd23:42:c3d2:582:3078:bbff:fe76:e9ef";
|
||||
serv-gw = "fd23:42:c3d2:582::1";
|
||||
spaceapi = "fd23:42:c3d2:582:1457:adff:fe93:62e9";
|
||||
stats = "fd23:42:c3d2:582:2:0:0:3";
|
||||
staging-data-hoarder = "fd23:42:c3d2:582:2de:5bff:fef9:e23d";
|
||||
oparl = "fd23:42:c3d2:582:2de:9aff:fece:3879";
|
||||
gnunet = "fd23:42:c3d2:582:44";
|
||||
broker = "fd23:42:c3d2:582:46";
|
||||
ftp = "fd23:42:c3d2:582:47";
|
||||
network-homepage = "fd23:42:c3d2:582:2f";
|
||||
owncast = "fd23:42:c3d2:582:32";
|
||||
prometheus = "fd23:42:c3d2:582:4b";
|
||||
buzzrelay = "fd23:42:c3d2:582:f";
|
||||
oxigraph = "fd23:42:c3d2:582:4c";
|
||||
luulaatsch-asterisk = "fd23:42:c3d2:582:2a";
|
||||
stream = "fd23:42:c3d2:583:dc91:c7ff:fe51:d1c5";
|
||||
zeit = "fd23:42:c3d2:582:2:0:0:5";
|
||||
};
|
||||
hosts6.up4 = {
|
||||
knot = "2a00:8180:2c00:282:cd7:56ff:fe69:6366";
|
||||
bind = "2a00:8180:2c00:282:cd7:56ff:fe69:6366";
|
||||
blogs = "2a00:8180:2c00:282:b8a8:7dff:fee8:5ac2";
|
||||
c3d2-web = "2a00:8180:2c00:282:642e:95ff:fe34:49f9";
|
||||
dns = "2a00:8180:2c00:282:2:0:0:2";
|
||||
dnscache = "2a00:8180:2c00:282:f096:dbff:fee8:427d";
|
||||
gitea = "2a00:8180:2c00:282:702a:daff:fe35:83be";
|
||||
grafana = "2a00:8180:2c00:282:4042:fbff:fe4b:2de8";
|
||||
hydra = "2a00:8180:2c00:282:e2cb:4eff:fe3b:f94b";
|
||||
hydra = "2a00:8180:2c00:282:e03c:d7ff:fe8e:fe16";
|
||||
jabber = "2a00:8180:2c00:282:b869:ccff:fe46:902a";
|
||||
# mail = "2a00:8180:2c00:282:88c0:41ff:fe70:d6cd";
|
||||
keycloak = "2a00:8180:2c00:282:c48:bbff:fe87:721d";
|
||||
logging = "2a00:8180:2c00:282:6811:edff:fe40:89c6";
|
||||
mail = "2a00:8180:2c00:282:88c0:41ff:fe70:d6cd";
|
||||
matemat = "2a00:8180:2c00:282:f82b:1bff:fedc:8572";
|
||||
minetest = "2a00:8180:2c00:282:c3a:42ff:fe5d:b20c";
|
||||
mobilizon = "2a00:8180:2c00:282:48d1:5cff:fea7:1676";
|
||||
mongo = "2a00:8180:2c00:282:14ec:c8ff:fe0a:fc5c";
|
||||
mucbot = "2a00:8180:2c00:282:28db:dff:fe6b:e89a";
|
||||
netboot = "2a00:8180:2c00:282:2:0:0:6";
|
||||
public-access-proxy = "2a00:8180:2c00:282:1024:5fff:febd:9be7";
|
||||
radiobert = "2a00:8180:2c00:282:e65f:1ff:fe5d:1679";
|
||||
radius = "2a00:8180:2c00:282:2:0:0:4";
|
||||
scrape = "2a00:8180:2c00:282:e073:50ff:fef5:eb6e";
|
||||
sdrweb = "2a00:8180:2c00:282:3078:bbff:fe76:e9ef";
|
||||
serv-gw = "2a00:8180:2c00:282::1";
|
||||
spaceapi = "2a00:8180:2c00:282:1457:adff:fe93:62e9";
|
||||
stats = "2a00:8180:2c00:282:2:0:0:3";
|
||||
stream = "2a00:8180:2c00:282:dc91:c7ff:fe51:d1c5";
|
||||
stream = "fd23:42:c3d2:583:dc91:c7ff:fe51:d1c5";
|
||||
ticker = "2a00:8180:2c00:282:b407:40ff:fec1:81f2";
|
||||
staging-data-hoarder = "2a00:8180:2c00:282:2de:5bff:fef9:e23d";
|
||||
oparl = "2a00:8180:2c00:282:2de:9aff:fece:3879";
|
||||
|
||||
serv-gw = "2a00:8180:2c00:282::1";
|
||||
luulaatsch-asterisk = "2a00:8180:2c00:282::2a";
|
||||
drone = "2a00:8180:2c00:282::2b";
|
||||
pretalx = "2a00:8180:2c00:282::2c";
|
||||
matrix = "2a00:8180:2c00:282::2d";
|
||||
activity-relay = "2a00:8180:2c00:282::2e";
|
||||
network-homepage = "2a00:8180:2c00:282::2f";
|
||||
vaultwarden = "2a00:8180:2c00:282::31";
|
||||
owncast = "2a00:8180:2c00:282::32";
|
||||
mediawiki = "2a00:8180:2c00:282::43";
|
||||
gnunet = "2a00:8180:2c00:282::44";
|
||||
data-hoarder = "2a00:8180:2c00:282::45";
|
||||
broker = "2a00:8180:2c00:282::46";
|
||||
ftp = "2a00:8180:2c00:282::47";
|
||||
auth = "2a00:8180:2c00:282::48";
|
||||
dresden-zone = "2a00:8180:2c00:282::49";
|
||||
prometheus = "2a00:8180:2c00:282::4b";
|
||||
oxigraph = "2a00:8180:2c00:282::4c";
|
||||
hedgedoc = "2a00:8180:2c00:282::6";
|
||||
buzzrelay = "2a00:8180:2c00:282::f";
|
||||
zeit = "2a00:8180:2c00:282:2:0:0:5";
|
||||
};
|
||||
};
|
||||
|
||||
|
@ -160,6 +147,9 @@
|
|||
dnscache = makeContainer {
|
||||
services.dnscache.enable = true;
|
||||
};
|
||||
netboot = makeContainer {
|
||||
interfaces.serv.hwaddr = "0A:14:48:01:15:01";
|
||||
};
|
||||
serv-gw = makeContainer {
|
||||
interfaces = {
|
||||
core = {
|
||||
|
@ -175,16 +165,10 @@
|
|||
};
|
||||
};
|
||||
ospf.allowedUpstreams =
|
||||
[ "upstream4" "upstream3" "anon1" "freifunk" ];
|
||||
[ "upstream4" "upstream1" "upstream3" "anon1" "freifunk" ];
|
||||
};
|
||||
stats = makeContainer {
|
||||
interfaces.serv.hwaddr = "0A:14:48:01:15:00";
|
||||
};
|
||||
|
||||
hydra = {
|
||||
role = "client";
|
||||
model = "nixos";
|
||||
interfaces.serv.type = "phys";
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
|
@ -2,10 +2,159 @@
|
|||
let
|
||||
servHosts = config.site.net.serv.hosts4;
|
||||
inherit (config.site.net.c3d2.hosts4) dn42;
|
||||
inherit (config.site.net.flpk.hosts4) c3d2-web;
|
||||
in
|
||||
{
|
||||
site.hosts = {
|
||||
upstream1 = {
|
||||
forwardPorts = [
|
||||
{
|
||||
destination = "${servHosts.public-access-proxy}:80";
|
||||
proto = "tcp";
|
||||
reflect = true;
|
||||
sourcePort = 80;
|
||||
}
|
||||
{
|
||||
destination = "${servHosts.public-access-proxy}:443";
|
||||
proto = "tcp";
|
||||
reflect = true;
|
||||
sourcePort = 443;
|
||||
}
|
||||
{
|
||||
destination = dn42;
|
||||
proto = "udp";
|
||||
reflect = true;
|
||||
sourcePort = 2325;
|
||||
}
|
||||
{
|
||||
destination = dn42;
|
||||
proto = "udp";
|
||||
reflect = true;
|
||||
sourcePort = 2399;
|
||||
}
|
||||
{
|
||||
destination = dn42;
|
||||
proto = "udp";
|
||||
reflect = true;
|
||||
sourcePort = 2327;
|
||||
}
|
||||
{
|
||||
destination = dn42;
|
||||
proto = "udp";
|
||||
reflect = true;
|
||||
sourcePort = 2338;
|
||||
}
|
||||
{
|
||||
destination = dn42;
|
||||
proto = "udp";
|
||||
reflect = true;
|
||||
sourcePort = 2339;
|
||||
}
|
||||
{
|
||||
destination = dn42;
|
||||
proto = "udp";
|
||||
reflect = true;
|
||||
sourcePort = 40533;
|
||||
}
|
||||
{
|
||||
destination = dn42;
|
||||
proto = "udp";
|
||||
reflect = true;
|
||||
sourcePort = 61699;
|
||||
}
|
||||
{
|
||||
destination = "172.20.74.210:22";
|
||||
proto = "tcp";
|
||||
reflect = true;
|
||||
sourcePort = 2222;
|
||||
}
|
||||
{
|
||||
destination = "172.20.74.210:443";
|
||||
proto = "tcp";
|
||||
reflect = true;
|
||||
sourcePort = 8443;
|
||||
}
|
||||
{
|
||||
destination = "172.20.73.47:22";
|
||||
proto = "tcp";
|
||||
reflect = true;
|
||||
sourcePort = 2223;
|
||||
}
|
||||
{
|
||||
destination = "172.20.73.48:30000";
|
||||
proto = "udp";
|
||||
reflect = true;
|
||||
sourcePort = 30000;
|
||||
}
|
||||
{
|
||||
destination = config.site.net.core.hosts4.yggdrasil;
|
||||
proto = "tcp";
|
||||
reflect = true;
|
||||
sourcePort = 1337;
|
||||
}
|
||||
];
|
||||
interfaces = {
|
||||
core = {
|
||||
hwaddr = "0A:14:48:01:26:00";
|
||||
type = "veth";
|
||||
};
|
||||
up1 = {
|
||||
hwaddr = "00:23:74:D7:2D:7C";
|
||||
type = "veth";
|
||||
upstream = {
|
||||
link = null;
|
||||
noNat = { subnets6 = [ "2a02:8106:208:5200::/56" ]; };
|
||||
provider = "vodafone";
|
||||
staticIpv4Address = "24.134.104.53";
|
||||
upBandwidth = 52500;
|
||||
};
|
||||
};
|
||||
};
|
||||
ospf.upstreamInstance = 3;
|
||||
role = "container";
|
||||
};
|
||||
|
||||
upstream2 = {
|
||||
forwardPorts = [
|
||||
{
|
||||
destination = "172.20.75.9:1194";
|
||||
proto = "udp";
|
||||
reflect = true;
|
||||
sourcePort = 1194;
|
||||
}
|
||||
{
|
||||
destination = "172.20.74.210:22";
|
||||
proto = "tcp";
|
||||
reflect = true;
|
||||
sourcePort = 2222;
|
||||
}
|
||||
{
|
||||
destination = "172.20.74.210:443";
|
||||
proto = "tcp";
|
||||
reflect = true;
|
||||
sourcePort = 8443;
|
||||
}
|
||||
];
|
||||
interfaces = {
|
||||
core = {
|
||||
hwaddr = "0A:14:48:01:27:00";
|
||||
type = "veth";
|
||||
};
|
||||
up2 = {
|
||||
hwaddr = "00:23:74:D7:42:7C";
|
||||
type = "veth";
|
||||
upstream = {
|
||||
link = null;
|
||||
noNat = { subnets6 = [ "2a02:8106:208:e900::/56" ]; };
|
||||
provider = "vodafone";
|
||||
staticIpv4Address = null;
|
||||
upBandwidth = 52500;
|
||||
};
|
||||
};
|
||||
};
|
||||
ospf.upstreamInstance = 4;
|
||||
role = "container";
|
||||
};
|
||||
|
||||
upstream3 = {
|
||||
interfaces = {
|
||||
core = {
|
||||
|
@ -28,191 +177,221 @@ in
|
|||
role = "container";
|
||||
};
|
||||
|
||||
upstream4 = rec {
|
||||
upstream4 = {
|
||||
forwardPorts = [
|
||||
{ # http
|
||||
destination = servHosts.public-access-proxy;
|
||||
{
|
||||
destination = "172.20.73.45";
|
||||
proto = "tcp";
|
||||
reflect = true;
|
||||
sourcePort = 80;
|
||||
}
|
||||
{ # https
|
||||
destination = servHosts.public-access-proxy;
|
||||
{
|
||||
destination = "172.20.73.45";
|
||||
proto = "tcp";
|
||||
reflect = true;
|
||||
sourcePort = 443;
|
||||
}
|
||||
{ # gemini
|
||||
destination = "${c3d2-web}:1965";
|
||||
proto = "tcp";
|
||||
sourcePort = 1965;
|
||||
}
|
||||
{
|
||||
destination = servHosts.knot;
|
||||
destination = "172.20.73.61";
|
||||
proto = "tcp";
|
||||
reflect = false;
|
||||
sourcePort = 53;
|
||||
}
|
||||
{
|
||||
destination = servHosts.knot;
|
||||
destination = "172.20.73.61";
|
||||
proto = "udp";
|
||||
reflect = false;
|
||||
sourcePort = 53;
|
||||
}
|
||||
{
|
||||
destination = dn42;
|
||||
proto = "udp";
|
||||
reflect = true;
|
||||
sourcePort = 2325;
|
||||
}
|
||||
{
|
||||
destination = dn42;
|
||||
proto = "udp";
|
||||
reflect = true;
|
||||
sourcePort = 2327;
|
||||
}
|
||||
{
|
||||
destination = dn42;
|
||||
proto = "udp";
|
||||
reflect = true;
|
||||
sourcePort = 2337;
|
||||
}
|
||||
{
|
||||
destination = dn42;
|
||||
proto = "udp";
|
||||
reflect = true;
|
||||
sourcePort = 2338;
|
||||
}
|
||||
{
|
||||
destination = dn42;
|
||||
proto = "udp";
|
||||
reflect = true;
|
||||
sourcePort = 2339;
|
||||
}
|
||||
{
|
||||
destination = dn42;
|
||||
proto = "udp";
|
||||
reflect = true;
|
||||
sourcePort = 2340;
|
||||
}
|
||||
{
|
||||
destination = dn42;
|
||||
proto = "udp";
|
||||
sourcePort = 2342;
|
||||
}
|
||||
{
|
||||
destination = dn42;
|
||||
proto = "udp";
|
||||
reflect = true;
|
||||
sourcePort = 2399;
|
||||
}
|
||||
{
|
||||
destination = dn42;
|
||||
proto = "udp";
|
||||
reflect = true;
|
||||
sourcePort = 24699;
|
||||
}
|
||||
{
|
||||
destination = dn42;
|
||||
proto = "udp";
|
||||
reflect = true;
|
||||
sourcePort = 64699;
|
||||
}
|
||||
{
|
||||
destination = "${servHosts.leonos}:22";
|
||||
proto = "tcp";
|
||||
reflect = true;
|
||||
sourcePort = 2223;
|
||||
}
|
||||
{
|
||||
destination = servHosts.minetest;
|
||||
proto = "udp";
|
||||
reflect = true;
|
||||
sourcePort = 30000;
|
||||
}
|
||||
# ?
|
||||
{
|
||||
destination = "172.22.99.175:22";
|
||||
proto = "tcp";
|
||||
reflect = true;
|
||||
sourcePort = 2224;
|
||||
}
|
||||
{
|
||||
destination = servHosts.gitea;
|
||||
proto = "tcp";
|
||||
reflect = true;
|
||||
sourcePort = 22;
|
||||
}
|
||||
{
|
||||
destination = servHosts.jabber;
|
||||
proto = "tcp";
|
||||
reflect = true;
|
||||
sourcePort = 5222;
|
||||
}
|
||||
{
|
||||
destination = servHosts.jabber;
|
||||
proto = "tcp";
|
||||
reflect = true;
|
||||
sourcePort = 5223;
|
||||
}
|
||||
{
|
||||
destination = servHosts.jabber;
|
||||
proto = "tcp";
|
||||
reflect = true;
|
||||
sourcePort = 5269;
|
||||
}
|
||||
{
|
||||
destination = servHosts.jabber;
|
||||
proto = "tcp";
|
||||
reflect = true;
|
||||
sourcePort = 3478;
|
||||
}
|
||||
{
|
||||
destination = servHosts.jabber;
|
||||
proto = "tcp";
|
||||
reflect = true;
|
||||
sourcePort = 3479;
|
||||
}
|
||||
{
|
||||
destination = servHosts.jabber;
|
||||
proto = "udp";
|
||||
reflect = true;
|
||||
sourcePort = 3478;
|
||||
}
|
||||
{
|
||||
destination = servHosts.jabber;
|
||||
proto = "udp";
|
||||
reflect = true;
|
||||
sourcePort = 3479;
|
||||
}
|
||||
# leon's vps1
|
||||
{
|
||||
destination = "${servHosts.vps1}:22";
|
||||
proto = "tcp";
|
||||
reflect = true;
|
||||
sourcePort = 2225;
|
||||
}
|
||||
{
|
||||
destination = servHosts.mail;
|
||||
proto = "tcp";
|
||||
reflect = true;
|
||||
sourcePort = 25;
|
||||
}
|
||||
{
|
||||
destination = servHosts.mail;
|
||||
proto = "tcp";
|
||||
reflect = true;
|
||||
sourcePort = 465;
|
||||
}
|
||||
{
|
||||
destination = servHosts.mail;
|
||||
proto = "tcp";
|
||||
reflect = true;
|
||||
sourcePort = 587;
|
||||
}
|
||||
{
|
||||
destination = servHosts.mail;
|
||||
proto = "tcp";
|
||||
reflect = true;
|
||||
sourcePort = 110;
|
||||
}
|
||||
{
|
||||
destination = servHosts.mail;
|
||||
proto = "tcp";
|
||||
reflect = true;
|
||||
sourcePort = 143;
|
||||
}
|
||||
{
|
||||
destination = servHosts.mail;
|
||||
proto = "tcp";
|
||||
reflect = true;
|
||||
sourcePort = 993;
|
||||
}
|
||||
{
|
||||
destination = servHosts.mail;
|
||||
proto = "tcp";
|
||||
reflect = true;
|
||||
sourcePort = 995;
|
||||
}
|
||||
# poelzi
|
||||
{
|
||||
destination = "172.20.73.162:22";
|
||||
proto = "tcp";
|
||||
reflect = true;
|
||||
sourcePort = 2323;
|
||||
}
|
||||
# jan
|
||||
{
|
||||
destination = "172.20.75.3:51820";
|
||||
proto = "udp";
|
||||
sourcePort = 30057;
|
||||
}
|
||||
# zw-ev RDP
|
||||
{
|
||||
destination = "172.20.75.222:3389";
|
||||
proto = "tcp";
|
||||
reflect = true;
|
||||
sourcePort = 45000;
|
||||
}
|
||||
{
|
||||
destination = config.site.net.core.hosts4.vpn-gw;
|
||||
proto = "udp";
|
||||
sourcePort = config.site.vpn.wireguard.port;
|
||||
destination = config.site.net.core.hosts4.yggdrasil;
|
||||
proto = "tcp";
|
||||
reflect = true;
|
||||
}
|
||||
{
|
||||
destination = servHosts.gnunet;
|
||||
proto = "tcp";
|
||||
sourcePort = 2086;
|
||||
}
|
||||
# dresden zone
|
||||
{
|
||||
destination = servHosts.dresden-zone;
|
||||
proto = "udp";
|
||||
sourcePort = 51844;
|
||||
}
|
||||
# data-hoarder
|
||||
{
|
||||
destination = servHosts.data-hoarder;
|
||||
proto = "udp";
|
||||
sourcePort = 51820;
|
||||
}
|
||||
{
|
||||
destination = "${servHosts.data-hoarder}:22";
|
||||
proto = "tcp";
|
||||
sourcePort = 2269;
|
||||
}
|
||||
# data-hoarder-staging
|
||||
{
|
||||
destination = "${servHosts.staging-data-hoarder}:51820";
|
||||
proto = "udp";
|
||||
sourcePort = 51821;
|
||||
}
|
||||
{
|
||||
destination = "${servHosts.ftp}:22";
|
||||
proto = "tcp";
|
||||
sourcePort = 1022;
|
||||
}
|
||||
# coloRadio
|
||||
{
|
||||
proto = "tcp";
|
||||
sourcePort = 8000;
|
||||
destination = "192.168.9.127";
|
||||
sourcePort = 1337;
|
||||
}
|
||||
];
|
||||
interfaces = {
|
||||
|
@ -238,12 +417,7 @@ in
|
|||
};
|
||||
};
|
||||
};
|
||||
ospf = {
|
||||
upstreamInstance = 8;
|
||||
stubNets4 = [
|
||||
"${interfaces.up4-pppoe.upstream.staticIpv4Address}/32"
|
||||
];
|
||||
};
|
||||
ospf.upstreamInstance = 8;
|
||||
role = "container";
|
||||
};
|
||||
|
||||
|
@ -264,7 +438,7 @@ in
|
|||
};
|
||||
};
|
||||
ospf = {
|
||||
allowedUpstreams = [ "upstream3" "upstream4" "freifunk" ];
|
||||
allowedUpstreams = [ "upstream1" "upstream3" "upstream4" "freifunk" ];
|
||||
upstreamInstance = 5;
|
||||
};
|
||||
role = "container";
|
||||
|
|
|
@ -1,40 +0,0 @@
|
|||
{ ... }:
|
||||
{
|
||||
site.net.vpn = {
|
||||
vlan = null;
|
||||
domainName = "core.zentralwerk.org";
|
||||
ipv6Router = "vpn-gw";
|
||||
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 = [ "flpk-gw" "anon1" "freifunk" ];
|
||||
};
|
||||
};
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
{
|
||||
site.hosts.yggdrasil = {
|
||||
role = "container";
|
||||
interfaces = {
|
||||
core = {
|
||||
hwaddr = "0A:14:48:01:26:ff";
|
||||
type = "veth";
|
||||
};
|
||||
};
|
||||
ospf = {
|
||||
allowedUpstreams =
|
||||
[ "upstream4" "upstream1" "upstream3" "anon1" "freifunk" ];
|
||||
stubNets6 = [ "200::/7" ];
|
||||
};
|
||||
|
||||
services.yggdrasil.enable = true;
|
||||
};
|
||||
}
|
|
@ -1,84 +1,63 @@
|
|||
-----BEGIN PGP MESSAGE-----
|
||||
|
||||
hQEMA2PKcvDMvlKLAQf9H11MeVsKpyi49/f8YxayUL8mbu8FEuUEW2F4N6MbThXz
|
||||
/kEweXTs3m9KywyieiF17S2UE/02b5E2533sn41mRa5Jo3vmGPb6WANRkoB7YLOO
|
||||
T770KStpvdIH8vljhGj3eFrNk64POch9fPrGMt8pz4uYcmKgjYhKNb4iUqFj8ZIi
|
||||
RsdheQ78MnY37df7IzLQmFGZs1jIA773rHN6aVomOqNBTzfVTQO41zKATzbrKpW4
|
||||
qqau3kn1fbQTab1FedJMEqk1YPhD1H8Pyhib3ff7JpPeWxkUzuZt+grAUD59aJsr
|
||||
ZX93USKoHSuJ5tUCY3dfmpiaetH2qjOmjI2ysCYGENLqAW440k/1U/Z58B0/ezTZ
|
||||
RTyU2GPbf7kpC2VL8EDZSTwLkDMB+mmXlZffF3bB1rdmZCahzjk4X9awKSXLIVTV
|
||||
ShGx2z9sI1pjmtz5CzXA7Ry0wmfJJ8gFM4DUaPCs2KghHVurGY4lmn1VWw80VtXn
|
||||
+u2dqhYTtdgxArwGV4EsKYBqRRAjsKn9NWXRo+WXIhH9EPzHioJGwKgbDw/n69Qa
|
||||
zMBNfePDj1HapEILaTq7jL/K67+07hDMVOnkUJL/lE2yzwCKkb0PnWAGgzXyOCQG
|
||||
p4ih9+samGMM7rIjxM1eI892MuAlrf+awkHY6P4cwU9vKxKHbqmqeRbOe8wUBuqg
|
||||
kmF9MCOPsCrS/5Dtr0JoR9WTnByLvekPbChW3ANMzAuHtKrjE7H583Z+ql52iYcj
|
||||
cLqlDP/1XzXu7dwfm3VcY0VD73Qy9gAHaOXcMHk6nOFzPiiAjVuqrw+pC7qS3SxJ
|
||||
pnzbyRz4ourfMymsfGj0aMlZknCcWidR366gnVLVDw19hWQ+s76cBJ1sKh/dNpUo
|
||||
d9h5qC7mlZ1RTHZFS8RKF1WODcq9h9W+CkQUg0y2R6EztEdVnc263fgwJH1VFAZW
|
||||
vsYhFehx1TJ/X/miMvScUDedrA1xcD+gs2zhXi5lYpk2U3HpfvGpEkLJaTzAXQiX
|
||||
7MxTBjnWviHv0s4ozeLICQDp81QqPNgCskaWf2I+9tYjU0Ob2I2ZqQ4LCx4UAraV
|
||||
iHmrszgP3OvkqRnidX1sYxwu7NUxZQK+Nmpb+N0+PyDErZdHNfpgl0erh0YswPOf
|
||||
Cc6WLsp9B2YkLNNGLxJnpYJEccE3I23JJ5/2A/4ZbfUZnDA6jKTx4qXj4ScygY0S
|
||||
kBiCwIaX2xEPOpQ61fE0xzV2xXnfGBT7IgcTwjL1ilOIWrWRbCad1wIlaL1c5lfv
|
||||
chCdv3ItWL9rwQvv3aiFm1oq3PL0Tp5qdth5ylmcyFwLRNVJKmZC79tD9/XYx1LG
|
||||
NTAWtMqR2dsz44nTPvn3x+HI08Ll3UbGK64hKlfjUjjYUUMCDwXXSl1HiunzZVa9
|
||||
5aVMD/Eg5TzzuS1aL1y01cfBhjZH5guFRxl6KUuNzIjAWh4rScCplTWfKtSQVhTO
|
||||
ZwAAuY3TZ5R4M/PFNLXCByUMI+nivKazVhVZSVMPTU1ENYrSFVKURsvuLwju8Pan
|
||||
K026oBtPdnaetOkERZJzayiPA2KCqN/LkPNMsmfniAZedj+7SUmyYigwMVRWFuB+
|
||||
HLPzZSDb4WJD53OiJhYdFlblEtTATZ2JdOBEATHB7wQqxBTNKheYTKV3ALZnu0d/
|
||||
6jOlRNHeAD6XlyAvTyuMFiU1qHEACmFN4EQ2y7yR9TI8KmCKkP6wXPzavtVjB/ll
|
||||
qeozsjD1BDhHhQLmOra8yXuZ9NoWkgNUtn9HRhbMlv0XjrPerkJ+xv0HQudI6Hyy
|
||||
sEj3fJY5l47CauUOaMmzSf/+ONSE5YQ6eh8Q6RNqpjKJ7HKJqgBDsVCcfkbA6Dtp
|
||||
KaQcUr4Q8cGoYejqUt9glVnmJDYicebdZFt9BA8i/mCykKvPpsGc/oFyh+u5lFjd
|
||||
GiFr4QlULSZsO3Yfv4xeFPWqkJ7xMeX65zPc+q5MH2+8pYXL6l/7U3yFI4gEXACX
|
||||
xiWrnvi8KWhju0GMHji/obUHuaudzYRaWdQWb7ga/xw2Q3UagXZxvM0arOliQT1P
|
||||
1EvHdN8U7xahKo9kGYAn2sgbOEMuoLC+MRkBE2PocC1TqU8LRootXXah4oJMglvu
|
||||
80MJYCZ5AvbMeW/lpnrtx9v9gbumP1bl/fxzi+fksMJzjwrQlgjdTM2peNVRP2OT
|
||||
EQFQm3jtqLqtKo0Oc7BtExevVzb0eGH8L/3Y2NUZCsLkY+KvIZe6O+8nBOcX4GeU
|
||||
nxSypDDTNxP0bhjMYaSI+eIVFRhEvCHdtscbtzpiOdsAUq9C20HDNTjeJ4QlpP4t
|
||||
/8nfywmBvgQ3ddujkRX7iGYzGebHOKfJwSXksT+md2wslx/CvMumEvK3CRN2OLK/
|
||||
dS3deYWLy3DLRJA5bgcp/OAnVKNGt3EGQq11ucup23Fm3jINCgEVzccW/X2AP0uV
|
||||
cyEFudLnMuHERcjcAHfXHqPCqqohSo+MNGZwoKLjXWSctY7dlofILlwShauBR/Gb
|
||||
HnArSBPuQaWQRX8gtWIwwjUmy2a63cgKIrvhtSGQO7JY32/omZjAYSGJQ2zppZh+
|
||||
aluD1TMos69ThHITEaLApO18xzWHlHFxdP0v9sPx1BUhd6NaZiXvjWQnTjBlepjn
|
||||
xntPyEsM4xypmEAViQeWz7WJdm5O7NhafoFQyn1i+fVysO/ru+LBRFmXp2xwfVUw
|
||||
Z8m1bCNAZ3ZOro2VIztQsgO9Zv1tycteII+wP+RicDIYaaHnLYbGznbuTtYNAyqb
|
||||
rBd2uHwlUjVqEfSMlnmdsOcF34ssGF6hU8bBgU3d44BeQCzYpCaxN0MQCCPK/d+V
|
||||
R/KDe1C1QkDEifDL0wvAZ6uyPPakpQlPi0pTA/20Vfc16LQiCISWBrLWoE3MmtGV
|
||||
ocAQe1M+xt+1pjOMlv7vPJ5Wfb3zeQ3yL/+d+qL54kr0cHSAF5mE6GjMYscWjott
|
||||
Vz81RjFgt8ci3pdzDK3W1Zt97qUcFBG+4liQpJZVB3we/v6mhJaQ9lcyb/G1Urk1
|
||||
GynGtWzzk8aXHMeVi5cfNAGqigxuwl8lMDYlCRoT+q6lzCFqIk+P9avoCZRXCS62
|
||||
FzVz8lwhDaslYoC+SdWQl7hq6gdxdRFvx+n+nHWcKprGVJ82f9wVid7fqwKh++2P
|
||||
bNequ4JORLCofyJ1QWYTv/Ep/RQW1rNdgrEf+SUXtK+HSxz6ZwRYCyz2OdBqJgLt
|
||||
df6s3ivk4ekkowF0h+8a62+aQpHmW9rWVFdP1ibUeThxsyLu41Y4/6LG8FhKxn8U
|
||||
Qyz9xJvP3QhSrf4LgY8hDb4I8YbZFYrNqlkaeT9ulcbR9bilNJJ8vbpPt0/gsDNx
|
||||
hbkaL6grhoyva/dDbnUIuYoSRJUCp4I6lBczyYXBtP900jSNH4ezJS0HRarRHf1V
|
||||
vn5J2xWQnFzbbYAlY4wbzjDRqKwShx/koe9q4JSvs2cYc6tg7Aw1cjJcrmo+TORo
|
||||
cdoN4S5iL3babk788B8FHjZJeMnoEyqFzzHgq+bSzR4RrhIUVPf6PTIiMMcUt20j
|
||||
seYUAwZC0I4cJU81Y+ok8nVuOHxRucr9A0MWhjaY05+rdM+TmwFVHDuPGoy0fKOQ
|
||||
Acj1EAPhhAQGQRXlq7tlbPrsJCHxHpQvCcawIGVYf9Ci0QwDd4q3s5nR5rSW2LUy
|
||||
+MJh57Rutd7H0Exgj7+KDkEoBxAJMMYuiOm9FJBZ7rxBe9dYjih0vv0ORsMjWTgW
|
||||
Jr5IxxXuLgIHsMOIL/Z3TS+omXqia6SAWcEogh6QwXdKrt/HZnKJIpUF5roTPmFK
|
||||
iFTMh3brwkJ2FF8Xgf3MYKnb5WHplQvK8hkLb98rz7J2YqwPY52vaNPQInnocfEs
|
||||
pYTQTVb2OhRop/nMSr/77vNirnGocySg6IWpQnwU8pc4evtdmX6G0Q4rdHpwy3DE
|
||||
21w7SOIYAaDKJj9gmsUiik8lCIn58xL+lgZjt1OuB1LP3P5OZ8rZ7Ff+S6Cdltyy
|
||||
Gn/Q0YBFRD1JtM2anXOGhX/bqsJyvmqD4NsO1dogT8GDd9TJLSbUFdY0zoCk6xfJ
|
||||
BKQ/IwN7mfXMRmqlJaZgGwzywPpoViQ6iHHIfGNGnqjNwltGHJDefGMLPos03c40
|
||||
fHqsfCJfseTEUZtreKp/B2RiZeqYg72emcpqWs+q9C2Warrn52GeKpFzKJlELeTL
|
||||
WpIhuaYI1WEbeoMdBJrV7207U4Ufd4sHTC2QOQOXoRCNMBUHF77vMvgaPHPVETTg
|
||||
fEzpuDpoTnU79LMWdME0MkGvsCudbBrupNwC15ULt7mNuA2SalfrYxkNskvPKYAh
|
||||
sg87w/zkl/IVIk5tvSdN44Gvji7vVZvMkfVcyk5o8OU4IZUxy/iRTZUzvBZrqzaA
|
||||
CFHl+QwXLgApwphApTBEZGWZMCdP1FD21QXNUt4sXWB8eW419p0a6oJFwGPEkRMD
|
||||
XTJMjhCqP7SJUDPWIS1CuI33bdOuyjGeUSeb0Xe1IYuxWqPBI0oNJL3s6K+V98Ut
|
||||
meIVIUCOo+sOS64UqdBmcbAkFSnE04xxiFN7jOd3Bfr+2aRDOMYlozM2j+H2oDBF
|
||||
JyMEZAY2Nn7s2iqyK66q70DLku2x9kmuuY1U6jUxuvYn3id6D5tk4+BhvbSXpvHo
|
||||
a0pGupBsx2pIY+uHQafwErqGNoH6BAhARq8aeRzNZrPlcfyTiTZ2xYsh40AVYx0S
|
||||
fNcWNhi4/ZVamjveZD1Gg/w6u4ouzrrBS3PeOebuBrVkUExitZ4QnvZe8Vda/YcY
|
||||
miV13I66Ks6ZTALSeZ4Hd0b7yjsZnNiBkmAMCClYM8qcrOfGJsAGhi/V4uIzrz0Z
|
||||
LAMMX5Il3xwDhN/463hP89GTWymwQ2s6R2Y5e4TNUzt/2fajPy7ENDT1htnObeIR
|
||||
cEsjz7vCkMplEK6tVNbfp7PxfOrH3SnBkkG1A+QlWPrHL3J8Ck4hVq6XKhRwPRgM
|
||||
8ERpyTgTRmwvPEGXQptVsStFKvqhS8jsJDkxadGFJaOhgqzysIhJUgbO8335oW6M
|
||||
efyeKPih0zwr2RUq1sKE9KW9T8vnwT2V5BRw3LjZ99NP3ONiuhXflVyLevnGLkmY
|
||||
7VScu8rGlKij6jW9mIiAL/UA0nt9Dh/vJZGDTh4bMHVwJb0yFMfsbw==
|
||||
=EhAz
|
||||
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
|
||||
=or0t
|
||||
-----END PGP MESSAGE-----
|
||||
|
|
|
@ -2,8 +2,6 @@
|
|||
{
|
||||
site.net = {
|
||||
core.ospf.secret = "encrypted";
|
||||
pub.wifi.ieee80211rKey = "2dc40abba46da9490ea0e00f93f18ce5";
|
||||
c3d2.wifi.ieee80211rKey = "d1b1fa2461efc0df9e2d96579607b7f6";
|
||||
};
|
||||
|
||||
site.hosts = {
|
||||
|
@ -45,6 +43,7 @@
|
|||
ap40.password = "encrypted";
|
||||
ap41.password = "encrypted";
|
||||
ap42.password = "encrypted";
|
||||
ap43.password = "encrypted";
|
||||
ap44.password = "encrypted";
|
||||
ap45.password = "encrypted";
|
||||
ap46.password = "encrypted";
|
||||
|
@ -61,29 +60,13 @@
|
|||
ap57.password = "encrypted";
|
||||
ap58.password = "encrypted";
|
||||
ap59.password = "encrypted";
|
||||
ap60.password = "encrypted";
|
||||
ap61.password = "encrypted";
|
||||
ap63.password = "encrypted";
|
||||
ap64.password = "encrypted";
|
||||
ap65.password = "encrypted";
|
||||
ap66.password = "encrypted";
|
||||
ap67.password = "encrypted";
|
||||
ap68.password = "encrypted";
|
||||
ap69.password = "encrypted";
|
||||
ap70.password = "encrypted";
|
||||
ap71.password = "encrypted";
|
||||
ap72.password = "encrypted";
|
||||
switch-a1.password = "encrypted";
|
||||
switch-b1.password = "encrypted";
|
||||
switch-b2.password = "encrypted";
|
||||
switch-b3.password = "encrypted";
|
||||
switch-c1.password = "encrypted";
|
||||
switch-c3d2-main.password = "encrypted";
|
||||
switch-d1.password = "encrypted";
|
||||
switch-dach.password = "encrypted";
|
||||
switch-ds1.password = "encrypted";
|
||||
switch-ds2.password = "encrypted";
|
||||
switch-ds3.password = "encrypted";
|
||||
|
||||
upstream4.interfaces.up4-pppoe.upstream = {
|
||||
user = "encrypted";
|
||||
|
@ -96,75 +79,74 @@
|
|||
privateKey = "encrypted";
|
||||
publicKey = "encrypted";
|
||||
};
|
||||
flpk-gw.interfaces.up-flpk.wireguard = {
|
||||
addresses = [ "fec0::1/64" "192.168.0.1/24" ];
|
||||
endpoint = "0.0.0.1";
|
||||
privateKey = "encrypted";
|
||||
publicKey = "encrypted";
|
||||
};
|
||||
|
||||
yggdrasil.services.yggdrasil.keys = ''
|
||||
{
|
||||
"PublicKey": "0000000000000000000000000000000000000000000000000000000000000000",
|
||||
"PrivateKey": "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
|
||||
}
|
||||
'';
|
||||
|
||||
ap1.wifi."platform/qca953x_wmac".ssids."uebergangsnetz".psk = "encrypted";
|
||||
ap10.wifi."platform/qca953x_wmac".ssids = {
|
||||
"iz-dresden.org".psk = "encrypted";
|
||||
};
|
||||
ap11.wifi."platform/ahb/18100000.wmac".ssids."braeunigkoschnik".psk = "encrypted";
|
||||
ap11.wifi."platform/qca955x_wmac".ssids."braeunigkoschnik".psk = "encrypted";
|
||||
ap12.wifi."platform/ar934x_wmac".ssids = {
|
||||
"IrèneMélix".psk = "encrypted";
|
||||
"paperheart".psk = "encrypted";
|
||||
};
|
||||
ap15.wifi."platform/ahb/18100000.wmac".ssids."etz250".psk = "encrypted";
|
||||
ap17.wifi."platform/ahb/18100000.wmac".ssids = {
|
||||
ap15.wifi."platform/qca955x_wmac".ssids."etz250".psk = "encrypted";
|
||||
ap17.wifi."platform/qca955x_wmac".ssids = {
|
||||
"EDUB".psk = "encrypted";
|
||||
"Zweitwohnsitz".psk = "encrypted";
|
||||
"e-Stuetzpunkt".psk = "encrypted";
|
||||
};
|
||||
ap18.wifi."platform/qca953x_wmac".ssids."Restaurierung Wolff/Kober".psk = "encrypted";
|
||||
ap19.wifi."platform/qca953x_wmac".ssids = {
|
||||
"Bockwurst".psk = "encrypted";
|
||||
"Studio 01127".psk = "encrypted";
|
||||
"Walter".psk = "encrypted";
|
||||
};
|
||||
ap2.wifi = {
|
||||
"pci0000:00/0000:00:00.0".ssids."C3D2".psk = "encrypted";
|
||||
"platform/ahb/18100000.wmac".ssids = {
|
||||
"C3D2 legacy".psk = "encrypted";
|
||||
"C3D2 IoT".psk = "encrypted";
|
||||
};
|
||||
"pci0000:01/0000:01:00.0".ssids."C3D2".psk = "encrypted";
|
||||
"platform/qca955x_wmac".ssids."C3D2 legacy".psk = "encrypted";
|
||||
};
|
||||
ap21.wifi = {
|
||||
"pci0000:00/0000:00:00.0".ssids."ZW stage".psk = "encrypted";
|
||||
"platform/qca956x_wmac".ssids."ZW stage legacy".psk = "encrypted";
|
||||
};
|
||||
ap23.wifi = {
|
||||
"pci0000:00/0000:00:00.0".ssids."LBK Network".psk = "encrypted";
|
||||
"platform/ahb/18100000.wmac".ssids."LBK Network".psk = "encrypted";
|
||||
"platform/qca956x_wmac".ssids."LBK Network".psk = "encrypted";
|
||||
};
|
||||
ap24.wifi."platform/ar933x_wmac".ssids."farbwerk".psk = "encrypted";
|
||||
ap25.wifi."platform/ar933x_wmac".ssids."farbwerk".psk = "encrypted";
|
||||
ap26.wifi."pci0000:00/0000:00:00.0".ssids."Dezember".psk = "encrypted";
|
||||
ap29.wifi = {
|
||||
"pci0000:00/0000:00:00.0".ssids."jungnickel-fotografie".psk = "encrypted";
|
||||
"platform/ahb/18100000.wmac".ssids."jungnickel-fotografie".psk = "encrypted";
|
||||
"platform/qca956x_wmac".ssids."jungnickel-fotografie".psk = "encrypted";
|
||||
};
|
||||
ap3.wifi = {
|
||||
"pci0000:00/0000:00:00.0".ssids."C3D2".psk = "encrypted";
|
||||
"platform/ar934x_wmac".ssids."C3D2 legacy".psk = "encrypted";
|
||||
};
|
||||
ap30.wifi."platform/ahb/18100000.wmac".ssids."WLANb0402".psk = "encrypted";
|
||||
ap30.wifi."platform/qca956x_wmac".ssids."WLANb0402".psk = "encrypted";
|
||||
ap31.wifi = {
|
||||
"pci0000:00/0000:00:00.0".ssids."C3D2".psk = "encrypted";
|
||||
"platform/ahb/18100000.wmac".ssids = {
|
||||
"platform/qca956x_wmac".ssids = {
|
||||
"C3D2 legacy" = { "psk" = "encrypted"; };
|
||||
"C3D2 IoT" = { "psk" = "encrypted"; };
|
||||
"FOTOAKADEMIEdd" = { "psk" = "encrypted"; };
|
||||
};
|
||||
};
|
||||
ap32.wifi = {
|
||||
"pci0000:00/0000:00:00.0".ssids."ZW stage".psk = "encrypted";
|
||||
"platform/ahb/18100000.wmac".ssids."ZW stage legacy".psk = "encrypted";
|
||||
"platform/qca956x_wmac".ssids."ZW stage legacy".psk = "encrypted";
|
||||
};
|
||||
ap33.wifi = {
|
||||
"pci0000:00/0000:00:00.0".ssids."C3D2".psk = "encrypted";
|
||||
"platform/ahb/18100000.wmac".ssids."C3D2 legacy".psk = "encrypted";
|
||||
"platform/qca956x_wmac".ssids."C3D2 legacy".psk = "encrypted";
|
||||
};
|
||||
ap34.wifi."pci0000:00/0000:00:00.0".ssids."etz250".psk = "encrypted";
|
||||
ap34.wifi."platform/ahb/18100000.wmac".ssids."etz250".psk = "encrypted";
|
||||
ap35.wifi."platform/ahb/18100000.wmac".ssids."Koch".psk = "encrypted";
|
||||
ap35.wifi."platform/qca956x_wmac".ssids."Koch".psk = "encrypted";
|
||||
ap36.wifi."platform/ar933x_wmac".ssids."C3D2 legacy".psk = "encrypted";
|
||||
ap37.wifi = {
|
||||
"pci0000:00/0000:00:00.0".ssids."hechtfilm.de".psk = "encrypted";
|
||||
|
@ -175,26 +157,26 @@
|
|||
"ZW heinrichsgarten" = { "psk" = "encrypted"; };
|
||||
"plop" = { "psk" = "encrypted"; };
|
||||
};
|
||||
"platform/ahb/18100000.wmac".ssids = {
|
||||
"platform/qca956x_wmac".ssids = {
|
||||
"ZW heinrichsgarten" = { "psk" = "encrypted"; };
|
||||
"plop" = { "psk" = "encrypted"; };
|
||||
"millimeter" = { "psk" = "encrypted"; };
|
||||
};
|
||||
};
|
||||
ap39.wifi."platform/10180000.wmac".ssids."EckiTino".psk = "encrypted";
|
||||
ap4.wifi."platform/ahb/18100000.wmac".ssids."jam-circle.de".psk = "encrypted";
|
||||
ap4.wifi."platform/qca955x_wmac".ssids."jam-circle.de".psk = "encrypted";
|
||||
ap40.wifi = {
|
||||
"pci0000:00/0000:00:00.0".ssids."M".psk = "encrypted";
|
||||
"platform/ahb/18100000.wmac".ssids."M legacy".psk = "encrypted";
|
||||
"platform/qca956x_wmac".ssids."M legacy".psk = "encrypted";
|
||||
};
|
||||
ap41.wifi = {
|
||||
"pci0000:00/0000:00:00.0".ssids."Walter".psk = "encrypted";
|
||||
"platform/ahb/18100000.wmac".ssids."Walter".psk = "encrypted";
|
||||
"platform/qca956x_wmac".ssids."Walter".psk = "encrypted";
|
||||
};
|
||||
ap42.wifi = {
|
||||
"pci0000:00/0000:00:00.0".ssids."jam-circle.de".psk = "encrypted";
|
||||
"platform/ahb/18100000.wmac".ssids."jam-circle.de legacy".psk = "encrypted";
|
||||
"platform/qca956x_wmac".ssids."jam-circle.de legacy".psk = "encrypted";
|
||||
};
|
||||
ap43.wifi."platform/qca955x_wmac".ssids."Kaffeetasse".psk = "encrypted";
|
||||
ap44.wifi = {
|
||||
"1e140000.pcie/pci0000:00/0000:00:00.0/0000:01:00.0".ssids."ZW stage legacy".psk = "encrypted";
|
||||
"1e140000.pcie/pci0000:00/0000:00:01.0/0000:02:00.0".ssids."ZW stage".psk = "encrypted";
|
||||
|
@ -225,7 +207,7 @@
|
|||
"1e140000.pcie/pci0000:00/0000:00:00.0/0000:01:00.0".ssids."ZW stage legacy".psk = "encrypted";
|
||||
"1e140000.pcie/pci0000:00/0000:00:01.0/0000:02:00.0".ssids."ZW stage".psk = "encrypted";
|
||||
};
|
||||
ap5.wifi."platform/ahb/18100000.wmac".ssids."verbalwerk.de".psk = "encrypted";
|
||||
ap5.wifi."platform/qca955x_wmac".ssids."verbalwerk.de".psk = "encrypted";
|
||||
ap50.wifi = {
|
||||
"1e140000.pcie/pci0000:00/0000:00:00.0/0000:01:00.0".ssids = {
|
||||
"ZW stage legacy".psk = "encrypted";
|
||||
|
@ -235,7 +217,7 @@
|
|||
};
|
||||
ap51.wifi = {
|
||||
"pci0000:01/0000:01:00.0".ssids."antrares".psk = "encrypted";
|
||||
"platform/ahb/18100000.wmac".ssids."antrares".psk = "encrypted";
|
||||
"platform/qca955x_wmac".ssids."antrares".psk = "encrypted";
|
||||
};
|
||||
ap52.wifi = {
|
||||
"1e140000.pcie/pci0000:00/0000:00:00.0/0000:01:00.0".ssids."ZW stage legacy".psk = "encrypted";
|
||||
|
@ -244,15 +226,15 @@
|
|||
ap53.wifi."platform/qca953x_wmac".ssids."Karen Koschnick".psk = "encrypted";
|
||||
ap54.wifi = {
|
||||
"pci0000:00/0000:00:00.0".ssids."Abyssinia".psk = "encrypted";
|
||||
"platform/ahb/18100000.wmac".ssids."Abyssinia".psk = "encrypted";
|
||||
"platform/qca956x_wmac".ssids."Abyssinia".psk = "encrypted";
|
||||
};
|
||||
ap55.wifi = {
|
||||
"pci0000:00/0000:00:00.0".ssids."MagLAN".psk = "encrypted";
|
||||
"platform/ahb/18100000.wmac".ssids."MagLAN (legacy)".psk = "encrypted";
|
||||
"platform/qca956x_wmac".ssids."MagLAN (legacy)".psk = "encrypted";
|
||||
};
|
||||
ap56.wifi = {
|
||||
"pci0000:00/0000:00:00.0".ssids."MagLAN".psk = "encrypted";
|
||||
"platform/ahb/18100000.wmac".ssids."MagLAN (legacy)".psk = "encrypted";
|
||||
"platform/qca956x_wmac".ssids."MagLAN (legacy)".psk = "encrypted";
|
||||
};
|
||||
ap57.wifi = {
|
||||
"pci0000:00/0000:00:00.0".ssids."Zentralwerk".psk = "encrypted";
|
||||
|
@ -265,57 +247,7 @@
|
|||
"pci0000:00/0000:00:00.0".ssids."Ebs 5000".psk = "encrypted";
|
||||
"platform/ahb/18100000.wmac".ssids."Ebs 2000".psk = "encrypted";
|
||||
};
|
||||
ap60.wifi = {
|
||||
"pci0000:00/0000:00:00.0".ssids."Abyssinia".psk = "encrypted";
|
||||
"platform/ahb/18100000.wmac".ssids."Abyssinia".psk = "encrypted";
|
||||
};
|
||||
ap61.wifi = {
|
||||
"pci0000:00/0000:00:00.0".ssids."tomiru".psk = "encrypted";
|
||||
"platform/ahb/18100000.wmac".ssids."tomiru".psk = "encrypted";
|
||||
};
|
||||
ap62.wifi = {
|
||||
"pci0000:00/0000:00:00.0".ssids."Wolke7".psk = "encrypted";
|
||||
"platform/ahb/18100000.wmac".ssids."Wolke7 legacy".psk = "encrypted";
|
||||
};
|
||||
ap63.wifi = {
|
||||
"pci0000:00/0000:00:00.0".ssids."EckiTino".psk = "encrypted";
|
||||
"platform/ahb/18100000.wmac".ssids."EckiTino legacy".psk = "encrypted";
|
||||
};
|
||||
ap64.wifi = {
|
||||
"platform/ahb/18100000.wmac".ssids."Princess Castle".psk = "encrypted";
|
||||
};
|
||||
ap65.wifi = {
|
||||
"1e140000.pcie/pci0000:00/0000:00:00.0/0000:01:00.0".ssids = {
|
||||
"farbwerk".psk = "encrypted";
|
||||
"Kaffeetasse".psk = "encrypted";
|
||||
};
|
||||
"1e140000.pcie/pci0000:00/0000:00:01.0/0000:02:00.0".ssids."farbwerk".psk = "encrypted";
|
||||
};
|
||||
ap66.wifi = {
|
||||
"pci0000:00/0000:00:00.0".ssids."Buschfunk4.03".psk = "encrypted";
|
||||
"platform/ahb/18100000.wmac".ssids."Buschfunk4.03 legacy".psk = "encrypted";
|
||||
};
|
||||
ap67.wifi = {
|
||||
"1e140000.pcie/pci0000:00/0000:00:01.0/0000:02:00.0".ssids."farbwerk".psk = "encrypted";
|
||||
"1e140000.pcie/pci0000:00/0000:00:01.0/0000:02:00.0+1".ssids."farbwerk".psk = "encrypted";
|
||||
};
|
||||
ap68.wifi = {
|
||||
"1e140000.pcie/pci0000:00/0000:00:01.0/0000:02:00.0".ssids."farbwerk".psk = "encrypted";
|
||||
"1e140000.pcie/pci0000:00/0000:00:01.0/0000:02:00.0+1".ssids."farbwerk".psk = "encrypted";
|
||||
};
|
||||
ap69.wifi = {
|
||||
"pci0000:00/0000:00:00.0".ssids."LIZA".psk = "encrypted";
|
||||
"platform/ahb/18100000.wmac".ssids."LIZA".psk = "encrypted";
|
||||
};
|
||||
ap7.wifi."platform/qca953x_wmac".ssids."mino".psk = "encrypted";
|
||||
ap70.wifi = {
|
||||
"pci0000:00/0000:00:00.0".ssids."M".psk = "encrypted";
|
||||
"platform/ahb/18100000.wmac".ssids."M legacy".psk = "encrypted";
|
||||
};
|
||||
ap72.wifi = {
|
||||
"1e140000.pcie/pci0000:00/0000:00:01.0/0000:02:00.0".ssids."farbwerk".psk = "encrypted";
|
||||
"1e140000.pcie/pci0000:00/0000:00:01.0/0000:02:00.0+1".ssids."farbwerk".psk = "encrypted";
|
||||
};
|
||||
ap8.wifi = {
|
||||
"pci0000:00/0000:00:00.0".ssids."C3D2".psk = "encrypted";
|
||||
"platform/ar934x_wmac".ssids = {
|
||||
|
@ -326,18 +258,5 @@
|
|||
ap9.wifi."platform/qca953x_wmac".ssids."Herzzbuehne".psk = "encrypted";
|
||||
};
|
||||
|
||||
site.dyndnsKey = "oYmxXCIa0nArp0679L6v+y/UfnhripOudLv+R5Cop8I=";
|
||||
|
||||
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"
|
||||
];
|
||||
} ];
|
||||
};
|
||||
site.dyndnsKey = "SECRET";
|
||||
}
|
||||
|
|
|
@ -14,7 +14,7 @@ let
|
|||
)
|
||||
) {} (builtins.attrValues containers);
|
||||
|
||||
makeServer = _name: {
|
||||
makeServer = name: {
|
||||
role = "server";
|
||||
model = "pc";
|
||||
interfaces = bridgeInterfaces // {
|
||||
|
|
|
@ -8,30 +8,10 @@
|
|||
|
||||
links = {
|
||||
switch-a2.ports = [ "7" ];
|
||||
priv25.ports = [
|
||||
# A6: Kleiner Saal Schaltschrank
|
||||
"1"
|
||||
# Kabinett A10
|
||||
"2"
|
||||
"3"
|
||||
# A16: Buehne rechts unten
|
||||
"4"
|
||||
# artnet node
|
||||
"5"
|
||||
# Panel A2: Foyer
|
||||
"8"
|
||||
# Panel A8: Kleiner Saal Buehne
|
||||
];
|
||||
priv31.ports = [
|
||||
# A4: Buero
|
||||
"6"
|
||||
];
|
||||
# A3: Techniklager
|
||||
# (DS23: Hackcenter vor kleinem Saal)
|
||||
|
||||
# A17: Grosser Saal ueber der Buehne
|
||||
# switch-a2 Port 13
|
||||
# Panel A6: kl Saal hinten
|
||||
priv25.ports = [ "2" "3" "4" "5" ];
|
||||
priv31.ports = [ "6" ];
|
||||
pub.ports = [ "8" ];
|
||||
iso4.ports = [ "1" ];
|
||||
};
|
||||
};
|
||||
switch-a2 = {
|
||||
|
@ -42,9 +22,6 @@
|
|||
links = {
|
||||
switch-c1.ports = [ "1" ];
|
||||
switch-a1.ports = [ "2" ];
|
||||
switch-ds1.ports = [ "3" ];
|
||||
switch-ds2.ports = [ "4" ];
|
||||
switch-ds3.ports = [ "5" ];
|
||||
ap44.ports = [ "10" ];
|
||||
ap45.ports = [ "11" ];
|
||||
ap46.ports = [ "12" ];
|
||||
|
@ -56,9 +33,9 @@
|
|||
};
|
||||
};
|
||||
|
||||
switch-b3 = {
|
||||
switch-b1 = {
|
||||
role = "switch";
|
||||
model = "junos";
|
||||
model = "linksys-srw2048";
|
||||
location = "Haus B Souterrain";
|
||||
interfaces = { mgmt.type = "phys"; };
|
||||
|
||||
|
@ -68,144 +45,127 @@
|
|||
# Ports 21-24 unten seitlich (optional optisch)
|
||||
# Port 7 geht aktuell nach Turm C Erdgeschoss und dadurch zur Ecce
|
||||
links = {
|
||||
ap23.ports = [ "ge-0/0/10" ];
|
||||
ap8.ports = [ "ge-0/0/16" ];
|
||||
iso1.ports = [ "ge-0/0/2" ];
|
||||
iso2.ports = [ "ge-0/0/3" ];
|
||||
iso3.ports = [ "ge-0/0/4" ];
|
||||
coloradio.ports = [
|
||||
# Patchpanel C8
|
||||
"ge-0/0/22"
|
||||
];
|
||||
c3d2.ports = [
|
||||
"ge-0/0/5"
|
||||
"ge-0/0/8"
|
||||
# riscbert
|
||||
"ge-0/0/13"
|
||||
];
|
||||
server1 = {
|
||||
group = "3";
|
||||
ports = [
|
||||
"ge-0/0/24"
|
||||
"ge-0/0/25"
|
||||
"ge-1/0/24"
|
||||
"ge-1/0/25"
|
||||
];
|
||||
};
|
||||
ap23.ports = [ "g10" ];
|
||||
ap8.ports = [ "g16" ];
|
||||
c3d2.ports = [ "g23" ];
|
||||
iso1.ports = [ "g2" ];
|
||||
iso2.ports = [ "g3" ];
|
||||
iso3.ports = [ "g4" ];
|
||||
mgmt.ports = [ "g1" ];
|
||||
serv.ports = [ "g22" ];
|
||||
# server1 had g46,g47,g48 too but this switch has too few
|
||||
# port-channel groups
|
||||
server1.ports = [ "g24" ];
|
||||
server2 = {
|
||||
group = "1";
|
||||
ports = [
|
||||
"ge-0/0/38" "ge-0/0/39"
|
||||
"ge-1/0/32" "ge-1/0/33"
|
||||
];
|
||||
ports = [ "g12" "g38" "g39" "g40" ];
|
||||
};
|
||||
hydra = {
|
||||
server5 = {
|
||||
group = "6";
|
||||
ports = [ "g17" "g18" "g19" "g20" ];
|
||||
};
|
||||
server6 = {
|
||||
group = "8";
|
||||
ports = [ "g5" "g6" "g7" "g8" ];
|
||||
};
|
||||
server7 = {
|
||||
group = "7";
|
||||
trunk = false;
|
||||
ports = [
|
||||
"ge-0/0/14" "ge-0/0/15"
|
||||
"ge-1/0/14" "ge-1/0/15"
|
||||
];
|
||||
ports = [ "g9" "g11" "g14" "g15" ];
|
||||
};
|
||||
server10 = {
|
||||
server8 = {
|
||||
group = "5";
|
||||
ports = [
|
||||
"ge-0/0/36" "ge-0/0/37"
|
||||
"ge-1/0/36" "ge-1/0/37"
|
||||
];
|
||||
ports = [ "g35" "g36" "g37" "g13" ];
|
||||
};
|
||||
switch-b2 = {
|
||||
group = "3";
|
||||
ports = [ "g25" "g26" "g27" "g28" ];
|
||||
};
|
||||
switch-c1 = {
|
||||
group = "2";
|
||||
ports = [ "ge-0/0/30" "ge-0/0/31" "ge-1/0/30" "ge-1/0/31" ];
|
||||
ports = [ "g29" "g30" "g31" "g32" ];
|
||||
};
|
||||
switch-c3d2-main = {
|
||||
group = "4";
|
||||
ports = [
|
||||
"ge-0/0/26"
|
||||
"ge-0/0/27"
|
||||
"ge-1/0/26"
|
||||
"ge-1/0/27"
|
||||
];
|
||||
ports = [ "g41" "g42" "g43" "g44" ];
|
||||
};
|
||||
switch-d1.ports = [ "ge-0/0/34" ];
|
||||
switch-d1.ports = [ "g34" ];
|
||||
};
|
||||
};
|
||||
switch-b2 = {
|
||||
role = "switch";
|
||||
model = "3com-4200G";
|
||||
location = "Haus B Souterrain";
|
||||
interfaces = { mgmt.type = "phys"; };
|
||||
|
||||
ap1.ports = [ "ge-1/0/8" ];
|
||||
ap11.ports = [ "ge-1/0/10" ];
|
||||
ap34.ports = [ "ge-1/0/12" ];
|
||||
ap18.ports = [ "ge-1/0/18" ];
|
||||
ap29.ports = [ "ge-0/0/46" ];
|
||||
ap30.ports = [ "ge-1/0/22" ];
|
||||
ap35.ports = [ "ge-1/0/23" ];
|
||||
ap37.ports = [ "ge-1/0/39" ];
|
||||
ap63.ports = [ "ge-1/0/17" ];
|
||||
ap40.ports = [ "ge-1/0/21" ];
|
||||
ap41.ports = [ "ge-0/0/47" ];
|
||||
ap42.ports = [ "ge-1/0/6" ];
|
||||
ap5.ports = [ "ge-1/0/7" ];
|
||||
ap51.ports = [ "ge-1/0/13" ];
|
||||
ap53.ports = [ "ge-0/0/7" ];
|
||||
ap72.ports = [ "ge-1/0/38" ];
|
||||
ap55.ports = [ "ge-1/0/19" ];
|
||||
ap56.ports = [ "ge-1/0/9" ];
|
||||
ap60.ports = [ "ge-1/0/20" ];
|
||||
ap62.ports = [ "ge-0/0/11" ];
|
||||
ap65.ports = [ "ge-0/0/9" ];
|
||||
ap66.ports = [ "ge-1/0/43" ];
|
||||
links = {
|
||||
ap1.ports = [ "GigabitEthernet 1/0/8" ];
|
||||
ap11.ports = [ "GigabitEthernet 1/0/10" ];
|
||||
ap15.ports = [ "GigabitEthernet 1/0/12" ];
|
||||
ap18.ports = [ "GigabitEthernet 1/0/18" ];
|
||||
ap24.ports = [ "GigabitEthernet 1/0/34" ];
|
||||
ap25.ports = [ "GigabitEthernet 1/0/35" ];
|
||||
ap29.ports = [ "GigabitEthernet 1/0/36" ];
|
||||
ap30.ports = [ "GigabitEthernet 1/0/22" ];
|
||||
ap35.ports = [ "GigabitEthernet 1/0/23" ];
|
||||
ap37.ports = [ "GigabitEthernet 1/0/39" ];
|
||||
ap39.ports = [ "GigabitEthernet 1/0/17" ];
|
||||
ap40.ports = [ "GigabitEthernet 1/0/21" ];
|
||||
ap41.ports = [ "GigabitEthernet 1/0/37" ];
|
||||
ap42.ports = [ "GigabitEthernet 1/0/6" ];
|
||||
ap5.ports = [ "GigabitEthernet 1/0/7" ];
|
||||
ap51.ports = [ "GigabitEthernet 1/0/13" ];
|
||||
ap53.ports = [ "GigabitEthernet 1/0/15" ];
|
||||
ap54.ports = [ "GigabitEthernet 1/0/38" ];
|
||||
ap55.ports = [ "GigabitEthernet 1/0/19" ];
|
||||
ap56.ports = [ "GigabitEthernet 1/0/9" ];
|
||||
mgmt.ports = [
|
||||
"ge-0/0/0"
|
||||
"ge-0/0/1"
|
||||
"ge-1/0/44"
|
||||
"GigabitEthernet1/0/1"
|
||||
# server3
|
||||
"GigabitEthernet1/0/41"
|
||||
# server1
|
||||
"GigabitEthernet1/0/42"
|
||||
"GigabitEthernet1/0/43"
|
||||
# server5
|
||||
"GigabitEthernet1/0/44"
|
||||
# server6
|
||||
"GigabitEthernet1/0/45"
|
||||
# server7
|
||||
"ge-1/0/45"
|
||||
"ge-1/0/46"
|
||||
"GigabitEthernet1/0/46"
|
||||
# server8
|
||||
"ge-1/0/47"
|
||||
"GigabitEthernet1/0/47"
|
||||
# server9
|
||||
"ge-1/0/48"
|
||||
"GigabitEthernet1/0/48"
|
||||
];
|
||||
flpk.ports = [
|
||||
# server7
|
||||
"ge-0/0/40"
|
||||
];
|
||||
priv1.ports = [ "ge-1/0/3" ];
|
||||
priv19.ports = [ "ge-1/0/40" ];
|
||||
priv2.ports = [ "ge-1/0/4" ];
|
||||
priv24.ports = [ "ge-0/0/6" "ge-1/0/16" ];
|
||||
priv3.ports = [ "ge-1/0/5" ];
|
||||
priv30.ports = [ "ge-0/0/12" ];
|
||||
priv49.ports = [ "ge-1/0/1" ];
|
||||
ap67.ports = [ "ge-1/0/34" ];
|
||||
ap68.ports = [ "ge-1/0/35" ];
|
||||
ap69.ports = [ "ge-0/0/35" ];
|
||||
ap64.ports = [ "ge-0/0/45" ];
|
||||
priv1.ports = [ "GigabitEthernet 1/0/3" ];
|
||||
priv19.ports = [ "GigabitEthernet 1/0/40" ];
|
||||
priv2.ports = [ "GigabitEthernet 1/0/4" ];
|
||||
priv24.ports = [ "GigabitEthernet 1/0/14" "GigabitEthernet 1/0/16" ];
|
||||
priv3.ports = [ "GigabitEthernet 1/0/5" ];
|
||||
pub.ports = [
|
||||
"ge-1/0/11"
|
||||
"GigabitEthernet 1/0/11"
|
||||
"GigabitEthernet 1/0/20"
|
||||
"GigabitEthernet 1/0/24"
|
||||
];
|
||||
server3 = {
|
||||
group = "1";
|
||||
ports = [ "GigabitEthernet1/0/30" "GigabitEthernet1/0/31" ];
|
||||
};
|
||||
server9 = {
|
||||
group = "10";
|
||||
group = "3";
|
||||
ports = [
|
||||
"ge-0/0/28"
|
||||
"ge-0/0/29"
|
||||
"ge-1/0/28"
|
||||
"ge-1/0/29"
|
||||
"GigabitEthernet1/0/2"
|
||||
"GigabitEthernet1/0/29"
|
||||
"GigabitEthernet1/0/32"
|
||||
];
|
||||
};
|
||||
server8 = {
|
||||
group = "6";
|
||||
switch-b1 = {
|
||||
group = "2";
|
||||
ports = [
|
||||
"ge-0/0/41"
|
||||
"ge-0/0/42"
|
||||
"ge-1/0/41"
|
||||
"ge-1/0/42"
|
||||
];
|
||||
};
|
||||
server6 = {
|
||||
group = "9";
|
||||
ports = [
|
||||
"ge-0/0/18"
|
||||
"ge-0/0/19"
|
||||
"ge-1/0/0"
|
||||
"ge-1/0/2"
|
||||
"TenGigabitEthernet 1/1/1"
|
||||
"GigabitEthernet 1/0/25"
|
||||
"GigabitEthernet 1/0/26"
|
||||
"GigabitEthernet 1/0/27"
|
||||
"GigabitEthernet 1/0/28"
|
||||
];
|
||||
};
|
||||
};
|
||||
|
@ -223,7 +183,7 @@
|
|||
group = "1";
|
||||
ports = [ "15-16" ];
|
||||
};
|
||||
switch-b3 = {
|
||||
switch-b1 = {
|
||||
group = "2";
|
||||
ports = [ "21-24" ];
|
||||
};
|
||||
|
@ -238,15 +198,13 @@
|
|||
ap19.ports = [ "17" ];
|
||||
ap26.ports = [ "18" ];
|
||||
ap38.ports = [ "7" ];
|
||||
ap61.ports = [ "13" ];
|
||||
# Iso nets
|
||||
iso1.ports = [ "9" ];
|
||||
iso2.ports = [ "10" ];
|
||||
iso3.ports = [ "11" ];
|
||||
iso4.ports = [ "12" ];
|
||||
iso5.ports = [ "13" ];
|
||||
iso6.ports = [ "14" ];
|
||||
# Saal Foyer
|
||||
priv25.ports = [ "20" ];
|
||||
};
|
||||
};
|
||||
|
||||
|
@ -258,7 +216,7 @@
|
|||
|
||||
links = {
|
||||
mgmt.ports = [ "1" ];
|
||||
switch-b3 = {
|
||||
switch-b1 = {
|
||||
group = "1";
|
||||
ports = [ "21-24" ];
|
||||
};
|
||||
|
@ -269,8 +227,11 @@
|
|||
# Fenster
|
||||
ap33.ports = [ "5" ];
|
||||
c3d2.ports = [ "8-20" ];
|
||||
# Testing
|
||||
ap-test1.ports = [ "4" ];
|
||||
bmx.ports = [ "7" ];
|
||||
# tmp Datenspuren: VOC
|
||||
iso4.ports = [ "4" "6" "7" ];
|
||||
iso4.ports = [ "6" ];
|
||||
};
|
||||
};
|
||||
|
||||
|
@ -281,7 +242,7 @@
|
|||
interfaces = { mgmt.type = "phys"; };
|
||||
|
||||
links = {
|
||||
switch-b3 = {
|
||||
switch-b1 = {
|
||||
group = "1";
|
||||
ports = [ "1" ];
|
||||
};
|
||||
|
@ -304,7 +265,7 @@
|
|||
links = {
|
||||
switch-d1 = {
|
||||
group = "1";
|
||||
ports = [ "12" ];
|
||||
ports = [ "1" ];
|
||||
};
|
||||
ap3.ports = [ "1" ];
|
||||
ap59.ports = [ "2" ];
|
||||
|
@ -328,142 +289,8 @@
|
|||
up3.ports = [ "3" ];
|
||||
# unifiac-mesh
|
||||
ap57.ports = [ "10" ];
|
||||
# TLMS tetra and traffic-stop-box
|
||||
c3d2.ports = [ "19,20" ];
|
||||
};
|
||||
};
|
||||
|
||||
switch-ds1 = {
|
||||
role = "switch";
|
||||
model = "3com-5500G";
|
||||
location = "Foyer";
|
||||
interfaces = { mgmt.type = "phys"; };
|
||||
|
||||
links = {
|
||||
# Public
|
||||
pub.ports = [
|
||||
"GigabitEthernet1/0/1"
|
||||
"GigabitEthernet1/0/2"
|
||||
"GigabitEthernet1/0/3"
|
||||
"GigabitEthernet1/0/4"
|
||||
"GigabitEthernet1/0/5"
|
||||
"GigabitEthernet1/0/6"
|
||||
"GigabitEthernet1/0/7"
|
||||
"GigabitEthernet1/0/8"
|
||||
"GigabitEthernet1/0/9"
|
||||
"GigabitEthernet1/0/10"
|
||||
"GigabitEthernet1/0/11"
|
||||
"GigabitEthernet1/0/12"
|
||||
"GigabitEthernet1/0/13"
|
||||
"GigabitEthernet1/0/14"
|
||||
"GigabitEthernet1/0/15"
|
||||
];
|
||||
# Stage uplink
|
||||
priv25.ports = [
|
||||
"GigabitEthernet1/0/16"
|
||||
"GigabitEthernet1/0/17"
|
||||
"GigabitEthernet1/0/18"
|
||||
"GigabitEthernet1/0/19"
|
||||
];
|
||||
# Freifunk
|
||||
bmx.ports = [
|
||||
"GigabitEthernet1/0/20"
|
||||
"GigabitEthernet1/0/21"
|
||||
"GigabitEthernet1/0/22"
|
||||
"GigabitEthernet1/0/23"
|
||||
];
|
||||
# Uplink
|
||||
switch-a2.ports = [ "GigabitEthernet1/0/24" ];
|
||||
};
|
||||
};
|
||||
|
||||
switch-ds2 = {
|
||||
role = "switch";
|
||||
model = "3com-5500G";
|
||||
location = "Grosser Saal oben";
|
||||
interfaces = { mgmt.type = "phys"; };
|
||||
|
||||
links = {
|
||||
# Public
|
||||
pub.ports = [
|
||||
"GigabitEthernet1/0/1"
|
||||
"GigabitEthernet1/0/2"
|
||||
"GigabitEthernet1/0/3"
|
||||
"GigabitEthernet1/0/4"
|
||||
"GigabitEthernet1/0/5"
|
||||
"GigabitEthernet1/0/6"
|
||||
"GigabitEthernet1/0/7"
|
||||
"GigabitEthernet1/0/8"
|
||||
"GigabitEthernet1/0/9"
|
||||
"GigabitEthernet1/0/10"
|
||||
"GigabitEthernet1/0/11"
|
||||
"GigabitEthernet1/0/12"
|
||||
"GigabitEthernet1/0/13"
|
||||
"GigabitEthernet1/0/14"
|
||||
"GigabitEthernet1/0/15"
|
||||
"GigabitEthernet1/0/16"
|
||||
"GigabitEthernet1/0/17"
|
||||
"GigabitEthernet1/0/18"
|
||||
"GigabitEthernet1/0/19"
|
||||
];
|
||||
# Stage uplink
|
||||
priv25.ports = [
|
||||
"GigabitEthernet1/0/20"
|
||||
"GigabitEthernet1/0/21"
|
||||
];
|
||||
# VOC isolated
|
||||
iso4.ports = [
|
||||
"GigabitEthernet1/0/22"
|
||||
"GigabitEthernet1/0/23"
|
||||
];
|
||||
# Uplink
|
||||
switch-a2.ports = [ "GigabitEthernet1/0/24" ];
|
||||
};
|
||||
};
|
||||
|
||||
switch-ds3 = {
|
||||
firstboot = true;
|
||||
role = "switch";
|
||||
model = "3com-5500G";
|
||||
location = "Kleiner Saal";
|
||||
interfaces = { mgmt.type = "phys"; };
|
||||
|
||||
links = {
|
||||
# Public
|
||||
pub.ports = [
|
||||
"GigabitEthernet1/0/1"
|
||||
"GigabitEthernet1/0/2"
|
||||
"GigabitEthernet1/0/3"
|
||||
"GigabitEthernet1/0/4"
|
||||
"GigabitEthernet1/0/5"
|
||||
"GigabitEthernet1/0/6"
|
||||
"GigabitEthernet1/0/7"
|
||||
"GigabitEthernet1/0/8"
|
||||
"GigabitEthernet1/0/9"
|
||||
"GigabitEthernet1/0/10"
|
||||
"GigabitEthernet1/0/11"
|
||||
"GigabitEthernet1/0/12"
|
||||
"GigabitEthernet1/0/13"
|
||||
"GigabitEthernet1/0/14"
|
||||
"GigabitEthernet1/0/15"
|
||||
"GigabitEthernet1/0/16"
|
||||
"GigabitEthernet1/0/17"
|
||||
"GigabitEthernet1/0/18"
|
||||
"GigabitEthernet1/0/19"
|
||||
];
|
||||
# Stage uplink
|
||||
priv25.ports = [
|
||||
"GigabitEthernet1/0/20"
|
||||
"GigabitEthernet1/0/21"
|
||||
];
|
||||
# VOC isolated
|
||||
iso4.ports = [
|
||||
"GigabitEthernet1/0/22"
|
||||
"GigabitEthernet1/0/23"
|
||||
];
|
||||
# Uplink
|
||||
switch-a2.ports = [ "GigabitEthernet1/0/24" ];
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -18,15 +18,11 @@ in
|
|||
c3d2 = 5;
|
||||
cluster = 6;
|
||||
bmx = 7;
|
||||
flpk = 8;
|
||||
coloradio = 9;
|
||||
# Modems
|
||||
up1 = 10;
|
||||
up2 = 11;
|
||||
up3 = 12;
|
||||
up4 = 13;
|
||||
# Isolated other stuff
|
||||
c3d2iot = 20;
|
||||
# Isolated neighbors directly connectied with their modems
|
||||
iso1 = 101;
|
||||
iso2 = 102;
|
||||
|
|
BIN
contact.md.asc
BIN
contact.md.asc
Binary file not shown.
11
doc/hello.md
11
doc/hello.md
|
@ -55,14 +55,10 @@ Von geeigneten Routern haben wir stets zu wenige übrig, so dass wir sie
|
|||
gemeinsam kaufen und bezahlen müssen. Such dir einen aus, dann
|
||||
bestellen und konfigurieren wir ihn.
|
||||
|
||||
* Zyxel WSM20 (Multy M1) ([25€](https://geizhals.de/zyxel-multy-m1-v101058.html))
|
||||
* TP-Link Archer C7 v2 ([58€](http://geizhals.de/tp-link-archer-c7-v2-a923544.html))
|
||||
* Ubiquiti UniFi nanoHD ([150€](https://geizhals.de/ubiquiti-unifi-nanohd-uap-nanohd-a1802819.html))
|
||||
* [Jedes Gerät auf dem OpenWRT läuft](https://openwrt.org/supported_devices)
|
||||
|
||||
Die genannten Preise sind unverbindlich und schwanken stark mit den
|
||||
Situationen rund um die Straße von Malaka, Rotem Meer und
|
||||
Suez-Kanal. Auf eBay gibts gebrauchte Geräte.
|
||||
|
||||
![WLAN-Router](https://upload.wikimedia.org/wikipedia/commons/thumb/3/34/Linksys-Wireless-G-Router.jpg/280px-Linksys-Wireless-G-Router.jpg)
|
||||
|
||||
### Netzverteilung
|
||||
|
@ -158,8 +154,11 @@ mitbenutzen indem wir dir ein [VLAN](https://de.wikipedia.org/wiki/VLAN)
|
|||
konfigurieren, welches nur dein Kabelmodem und deine Datendose bekommen.
|
||||
|
||||
|
||||
---
|
||||
# Sprechstunden
|
||||
|
||||
Dienstags und Donnerstags 16:00-18:00 Uhr
|
||||
|
||||
[C3D2](https://www.c3d2.de/space.html), Haus B Souterrain, genau in der Mitte
|
||||
|
||||
|
||||
![Kernnetz visualisiert von eri!](core.png)
|
||||
|
|
16
doc/vpn.md
16
doc/vpn.md
|
@ -1,16 +0,0 @@
|
|||
# Wireguard VPN Dialin
|
||||
|
||||
## wg-quick template
|
||||
|
||||
```ini
|
||||
[Interface]
|
||||
Address = 172.20.76.TODO/28
|
||||
Address = fd23:42:c3d2:585::TODO/64
|
||||
Address = 2a00:8180:2c00:285::TODO/64
|
||||
PrivateKey = TODO
|
||||
|
||||
[Peer]
|
||||
PublicKey = PG2VD0EB+Oi+U5/uVMUdO5MFzn59fAck6hz8GUyLMRo=
|
||||
AllowedIPs = 0.0.0.0/0, ::/0
|
||||
Endpoint = upstream4.dyn.zentralwerk.org:1337
|
||||
```
|
100
flake.lock
100
flake.lock
|
@ -1,53 +1,32 @@
|
|||
{
|
||||
"nodes": {
|
||||
"dns-nix": {
|
||||
"inputs": {
|
||||
"flake-utils": "flake-utils",
|
||||
"nixpkgs": [
|
||||
"nixpkgs"
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1703643450,
|
||||
"narHash": "sha256-EUUF5oxFFPX/etKm0FNQg+7MPHQlNjmM1XhNgyDf7A0=",
|
||||
"owner": "SuperSandro2000",
|
||||
"repo": "dns.nix",
|
||||
"rev": "70dcce71560d4253f63812fa36dee994c81ae814",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "SuperSandro2000",
|
||||
"repo": "dns.nix",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"flake-utils": {
|
||||
"locked": {
|
||||
"lastModified": 1614513358,
|
||||
"narHash": "sha256-LakhOx3S1dRjnh0b5Dg3mbZyH0ToC9I8Y2wKSkBaTzU=",
|
||||
"owner": "numtide",
|
||||
"repo": "flake-utils",
|
||||
"rev": "5466c5bbece17adaab2d82fae80b46e807611bf3",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "numtide",
|
||||
"repo": "flake-utils",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nixpkgs": {
|
||||
"locked": {
|
||||
"lastModified": 1713634877,
|
||||
"narHash": "sha256-+tmLKU8N+YMIIBRPmWFueaytsbSDu4wqGnxc3RKYZwk=",
|
||||
"owner": "SuperSandro2000",
|
||||
"lastModified": 1641924320,
|
||||
"narHash": "sha256-DuOpJqoMmQ3Yk4C64QQHFaByhbSIi872He6z5BXY1YM=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "84f20dcf85434cd2e2a163ec3a30937c78cc26b2",
|
||||
"rev": "05f3de54d568dba52efaad966f0e09bfea796dcb",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "SuperSandro2000",
|
||||
"ref": "nixos-23.11",
|
||||
"owner": "NixOS",
|
||||
"ref": "release-21.11",
|
||||
"repo": "nixpkgs",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nixpkgs-master": {
|
||||
"locked": {
|
||||
"lastModified": 1641927215,
|
||||
"narHash": "sha256-96otEPy5y/4aeM6Sjl//Qr8v3+CdjTBNtnS4eKyoY0U=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "0fdbcb2355f0681908cc9fef0cc9138f938ae1a3",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"type": "github"
|
||||
}
|
||||
|
@ -55,46 +34,25 @@
|
|||
"openwrt": {
|
||||
"flake": false,
|
||||
"locked": {
|
||||
"lastModified": 1713442482,
|
||||
"narHash": "sha256-OAcv1qiM2V6wPQm4Tz2QnnDpw34pifG6QRDZea7AP9o=",
|
||||
"ref": "openwrt-23.05",
|
||||
"rev": "9b33b74ef71225442361d5192d3a727be212c3cd",
|
||||
"revCount": 58296,
|
||||
"lastModified": 1641673875,
|
||||
"narHash": "sha256-Eb9tVxE9Pmob/xWZ6wRt95cTycPeyPkyyaaWaz6cWtA=",
|
||||
"ref": "openwrt-21.02",
|
||||
"rev": "6ced8cad8edd2a04fc6bb914c333c8aac9a1c825",
|
||||
"revCount": 50927,
|
||||
"type": "git",
|
||||
"url": "https://git.openwrt.org/openwrt/openwrt.git"
|
||||
},
|
||||
"original": {
|
||||
"ref": "openwrt-23.05",
|
||||
"ref": "openwrt-21.02",
|
||||
"type": "git",
|
||||
"url": "https://git.openwrt.org/openwrt/openwrt.git"
|
||||
}
|
||||
},
|
||||
"openwrt-imagebuilder": {
|
||||
"inputs": {
|
||||
"nixpkgs": [
|
||||
"nixpkgs"
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1713693953,
|
||||
"narHash": "sha256-DsJ/pzBSF3CxQWyiw4V3k96h7Q3UaRnQnL1N9tw+uWg=",
|
||||
"owner": "astro",
|
||||
"repo": "nix-openwrt-imagebuilder",
|
||||
"rev": "d4dc8c84f4397be494ae834709276f099df892e7",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "astro",
|
||||
"repo": "nix-openwrt-imagebuilder",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"root": {
|
||||
"inputs": {
|
||||
"dns-nix": "dns-nix",
|
||||
"nixpkgs": "nixpkgs",
|
||||
"openwrt": "openwrt",
|
||||
"openwrt-imagebuilder": "openwrt-imagebuilder"
|
||||
"nixpkgs-master": "nixpkgs-master",
|
||||
"openwrt": "openwrt"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
44
flake.nix
44
flake.nix
|
@ -2,22 +2,13 @@
|
|||
description = "Zentralwerk network";
|
||||
|
||||
inputs = {
|
||||
dns-nix = {
|
||||
url = "github:SuperSandro2000/dns.nix";
|
||||
inputs.nixpkgs.follows = "nixpkgs";
|
||||
};
|
||||
nixpkgs.url = "github:SuperSandro2000/nixpkgs/nixos-23.11";
|
||||
openwrt = {
|
||||
url = "git+https://git.openwrt.org/openwrt/openwrt.git?ref=openwrt-23.05";
|
||||
flake = false;
|
||||
};
|
||||
openwrt-imagebuilder = {
|
||||
url = "github:astro/nix-openwrt-imagebuilder";
|
||||
inputs.nixpkgs.follows = "nixpkgs";
|
||||
};
|
||||
nixpkgs.url = "github:NixOS/nixpkgs/release-21.11";
|
||||
nixpkgs-master.url = "github:NixOS/nixpkgs";
|
||||
openwrt.url = "git+https://git.openwrt.org/openwrt/openwrt.git?ref=openwrt-21.02";
|
||||
openwrt.flake = false;
|
||||
};
|
||||
|
||||
outputs = inputs@{ self, dns-nix, nixpkgs, openwrt, openwrt-imagebuilder }:
|
||||
outputs = inputs@{ self, nixpkgs, nixpkgs-master, openwrt }:
|
||||
let
|
||||
system = "x86_64-linux";
|
||||
systems = [ system ];
|
||||
|
@ -27,23 +18,24 @@
|
|||
self.lib.nixosSystem {
|
||||
inherit system;
|
||||
modules = [ self.nixosModule ];
|
||||
specialArgs = {
|
||||
hostName = name;
|
||||
inherit (self) lib;
|
||||
inherit inputs dns-nix self;
|
||||
};
|
||||
specialArgs.hostName = name;
|
||||
specialArgs.lib = self.lib;
|
||||
specialArgs.self = self;
|
||||
specialArgs.inputs = inputs;
|
||||
specialArgs.nixpkgs-master = nixpkgs-master;
|
||||
};
|
||||
in {
|
||||
# Config, and utilities
|
||||
lib = nixpkgs.lib.extend (_final: _prev:
|
||||
lib = nixpkgs.lib.extend (final: prev:
|
||||
import ./nix/lib {
|
||||
inherit self openwrt;
|
||||
inherit (nixpkgs.legacyPackages.x86_64-linux) lib pkgs;
|
||||
inherit self;
|
||||
inherit openwrt;
|
||||
pkgs = nixpkgs.legacyPackages.x86_64-linux;
|
||||
});
|
||||
|
||||
# Everything that can be built locally outside of NixOS
|
||||
packages = forAllSystems (system:
|
||||
import ./nix/pkgs { inherit self nixpkgs system openwrt-imagebuilder; }
|
||||
import ./nix/pkgs { inherit self nixpkgs system; }
|
||||
);
|
||||
|
||||
# Configuration for nixosConfigurations
|
||||
|
@ -76,10 +68,12 @@
|
|||
''
|
||||
);
|
||||
wrappers = {
|
||||
"all-device-scripts" = hydraJob;
|
||||
"all-device-scripts" = pkg:
|
||||
hydraJob pkg;
|
||||
|
||||
"export-config" = exportFileWrapper;
|
||||
"switch-.*" = exportFileWrapper;
|
||||
"ap.*-image" = exportFileWrapper;
|
||||
"ap.*" = exportFileWrapper;
|
||||
};
|
||||
in
|
||||
builtins.mapAttrs (name: pkg:
|
||||
|
|
|
@ -4,14 +4,14 @@
|
|||
|
||||
let
|
||||
result = pkgs.lib.evalModules {
|
||||
args = {
|
||||
inherit self pkgs;
|
||||
};
|
||||
modules = [
|
||||
(
|
||||
{ lib, ... }:
|
||||
with lib;
|
||||
{
|
||||
config._module.args = {
|
||||
inherit self pkgs;
|
||||
};
|
||||
options.assertions = mkOption {
|
||||
type = with types; listOf unspecified;
|
||||
internal = true;
|
||||
|
|
|
@ -158,11 +158,6 @@ let
|
|||
type = with types; nullOr (submodule { options = dhcpOpts; });
|
||||
default = null;
|
||||
};
|
||||
ipv6Router = mkOption {
|
||||
description = "Who sends router advertisements?";
|
||||
type = with types; nullOr str;
|
||||
default = config.site.net.${name}.dhcp.router or null;
|
||||
};
|
||||
domainName = mkOption {
|
||||
description = "Domain name option";
|
||||
type = types.str;
|
||||
|
@ -178,7 +173,7 @@ let
|
|||
type = enum [ "A" "AAAA" "MX" "SRV" "CNAME" "TXT" ];
|
||||
};
|
||||
data = mkOption {
|
||||
type = oneOf [ str (attrsOf (oneOf [ int str ])) ];
|
||||
type = str;
|
||||
};
|
||||
};
|
||||
});
|
||||
|
@ -194,13 +189,6 @@ let
|
|||
type = with types; nullOr int;
|
||||
default = null;
|
||||
};
|
||||
wifi.ieee80211rKey = mkOption {
|
||||
type = with types; nullOr str;
|
||||
default = null;
|
||||
description = ''
|
||||
Key between WiFi access points for Fast Transition
|
||||
'';
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
|
@ -221,11 +209,6 @@ let
|
|||
type = with types; nullOr int;
|
||||
default = null;
|
||||
};
|
||||
noNat.subnets4 = mkOption {
|
||||
type = with types; listOf str;
|
||||
default = [];
|
||||
description = "Do not NAT traffic from these public static subnets";
|
||||
};
|
||||
noNat.subnets6 = mkOption {
|
||||
type = with types; listOf str;
|
||||
default = [];
|
||||
|
@ -241,7 +224,7 @@ let
|
|||
};
|
||||
};
|
||||
|
||||
interfaceOpts = { ... }: {
|
||||
interfaceOpts = { name, ... }: {
|
||||
options = {
|
||||
hwaddr = mkOption {
|
||||
type = with types; nullOr str;
|
||||
|
@ -360,8 +343,7 @@ let
|
|||
# isRouter = Part of the core network?
|
||||
default =
|
||||
config.site.hosts.${name}.interfaces ? core &&
|
||||
config.site.net.core.hosts4 ? ${name} &&
|
||||
config.site.hosts.${name}.role == "container";
|
||||
config.site.net.core.hosts4 ? ${name};
|
||||
description = "Should this host route?";
|
||||
};
|
||||
firewall.enable = mkOption {
|
||||
|
@ -412,11 +394,6 @@ let
|
|||
default = [];
|
||||
description = "Accept default routes from these OSPF routers, in order of preference";
|
||||
};
|
||||
ospf.allowedUpstreams6 = mkOption {
|
||||
type = with types; listOf str;
|
||||
default = config.site.hosts.${name}.ospf.allowedUpstreams;
|
||||
description = "Accept IPv6 default routes from these OSPF3 routers, in order of preference";
|
||||
};
|
||||
ospf.upstreamInstance = mkOption {
|
||||
type = with types; nullOr int;
|
||||
default = null;
|
||||
|
@ -438,6 +415,16 @@ let
|
|||
type = types.bool;
|
||||
default = false;
|
||||
};
|
||||
services.yggdrasil = {
|
||||
enable = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
};
|
||||
keys = mkOption {
|
||||
type = types.str;
|
||||
default = "";
|
||||
};
|
||||
};
|
||||
links = mkOption {
|
||||
description = "Which port is connected to what other device? Keys are either network names or known hostnames.";
|
||||
default = {};
|
||||
|
@ -446,61 +433,32 @@ let
|
|||
wifi = mkOption {
|
||||
default = {};
|
||||
type = with types; attrsOf (submodule (
|
||||
{ config, ... }: {
|
||||
{ name, ... }: {
|
||||
options = {
|
||||
band = mkOption {
|
||||
type = enum [ "2g" "5g" ];
|
||||
default =
|
||||
if config.channel >= 1 && config.channel <= 14
|
||||
then "2g"
|
||||
else if config.channel >= 32 && config.channel <= 177
|
||||
then "5g"
|
||||
else throw "What band is channel ${toString config.channel}?";
|
||||
};
|
||||
htmode = mkOption {
|
||||
type = enum [ "HT20" "HT40-" "HT40+" "HT40" "VHT80" ];
|
||||
type = enum [ "HT20" "HT40-" "HT40+" "VHT80" ];
|
||||
};
|
||||
channel = mkOption {
|
||||
type = int;
|
||||
};
|
||||
ssids = mkOption {
|
||||
type = attrsOf (submodule ({ config, ... }: {
|
||||
options = {
|
||||
net = mkOption {
|
||||
type = str;
|
||||
type = attrsOf (submodule (
|
||||
{ name, ... }: {
|
||||
options = {
|
||||
net = mkOption {
|
||||
type = str;
|
||||
};
|
||||
psk = mkOption {
|
||||
type = nullOr str;
|
||||
default = null;
|
||||
};
|
||||
mode = mkOption {
|
||||
type = enum [ "ap" "sta" ];
|
||||
default = "ap";
|
||||
};
|
||||
};
|
||||
psk = mkOption {
|
||||
type = nullOr str;
|
||||
default = null;
|
||||
};
|
||||
hidden = mkOption {
|
||||
type = bool;
|
||||
default = false;
|
||||
};
|
||||
encryption = mkOption {
|
||||
type = enum [ "none" "owe" "wpa2" "wpa3" ];
|
||||
default =
|
||||
if config.psk == null
|
||||
then "none"
|
||||
else "wpa3";
|
||||
};
|
||||
mode = mkOption {
|
||||
type = enum [ "ap" "sta" ];
|
||||
default = "ap";
|
||||
};
|
||||
ifname = mkOption {
|
||||
type = nullOr str;
|
||||
default = null;
|
||||
};
|
||||
disassocLowAck = mkOption {
|
||||
type = bool;
|
||||
default = true;
|
||||
description = ''
|
||||
Disable for wireless bridges.
|
||||
'';
|
||||
};
|
||||
};
|
||||
}));
|
||||
}
|
||||
));
|
||||
};
|
||||
};
|
||||
}
|
||||
|
@ -521,7 +479,7 @@ let
|
|||
type = types.int;
|
||||
};
|
||||
peers = mkOption {
|
||||
type = with types; attrsOf (submodule ({ ... }: {
|
||||
type = with types; attrsOf (submodule ({ name, ... }: {
|
||||
options = {
|
||||
asn = mkOption {
|
||||
type = types.int;
|
||||
|
@ -571,30 +529,6 @@ 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
|
||||
{
|
||||
options.site = {
|
||||
|
@ -604,7 +538,6 @@ in
|
|||
type = with types; attrsOf (submodule netOpts);
|
||||
};
|
||||
|
||||
|
||||
hosts = mkOption {
|
||||
description = "All the static hosts";
|
||||
default = {};
|
||||
|
@ -618,23 +551,6 @@ in
|
|||
dyndnsKey = mkOption {
|
||||
type = types.str;
|
||||
};
|
||||
|
||||
vpn.wireguard = vpnOpts;
|
||||
|
||||
mqttServer = {
|
||||
host = mkOption {
|
||||
type = types.str;
|
||||
default = config.site.net.serv.hosts4.broker;
|
||||
};
|
||||
user = mkOption {
|
||||
type = types.str;
|
||||
default = "user";
|
||||
};
|
||||
password = mkOption {
|
||||
type = types.str;
|
||||
default = "secret";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
config.warnings =
|
||||
|
@ -669,7 +585,7 @@ in
|
|||
else []
|
||||
) (builtins.attrNames config.site.hosts);
|
||||
in
|
||||
(reportCollisions "VLAN tag" (x: lib.optional (x.vlan != null) x.vlan) config.site.net) ++
|
||||
(reportCollisions "VLAN tag" (x: [x.vlan]) 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) ++
|
||||
ospfUpstreamXorGw;
|
||||
|
@ -738,67 +654,5 @@ in
|
|||
in map (vlan: {
|
||||
assertion = builtins.length vlanNets.${vlan} == 1;
|
||||
message = "VLAN ${vlan} is used by more than one network: ${lib.concatStringsSep " " vlanNets.${vlan}}";
|
||||
}) (builtins.attrNames vlanNets))
|
||||
++
|
||||
# Duplicate switch port check
|
||||
builtins.concatMap (hostName:
|
||||
let
|
||||
ports = lib.unique (
|
||||
builtins.concatMap (linkName:
|
||||
config.site.hosts.${hostName}.links.${linkName}.ports
|
||||
) (builtins.attrNames config.site.hosts.${hostName}.links)
|
||||
);
|
||||
linksOfPort = port:
|
||||
builtins.attrNames (
|
||||
lib.filterAttrs (_: { ports, ... }: builtins.elem port ports)
|
||||
config.site.hosts.${hostName}.links
|
||||
);
|
||||
in map (port: {
|
||||
assertion = builtins.length (linksOfPort port) == 1;
|
||||
message = "${hostName}: port ${port} is used in more than one link: ${lib.concatStringsSep " " (linksOfPort port)}";
|
||||
}) ports
|
||||
) (builtins.attrNames config.site.hosts)
|
||||
++
|
||||
# Duplicate switch port group check
|
||||
builtins.concatMap (hostName:
|
||||
let
|
||||
groups = lib.unique (
|
||||
builtins.filter builtins.isString (
|
||||
builtins.map (linkName:
|
||||
config.site.hosts.${hostName}.links.${linkName}.group
|
||||
) (builtins.attrNames config.site.hosts.${hostName}.links)
|
||||
)
|
||||
);
|
||||
linksOfGroup = wantedGroup:
|
||||
builtins.attrNames (
|
||||
lib.filterAttrs (_: { group, ... }: group == wantedGroup)
|
||||
config.site.hosts.${hostName}.links
|
||||
);
|
||||
in map (group: {
|
||||
assertion = builtins.length (linksOfGroup group) == 1;
|
||||
message = "${hostName}: group ${group} is used in more than one link: ${lib.concatStringsSep " " (linksOfGroup group)}";
|
||||
}) groups
|
||||
) (builtins.attrNames config.site.hosts)
|
||||
++
|
||||
# wifi psk checks
|
||||
builtins.concatMap (hostName:
|
||||
builtins.concatMap (wifiPath:
|
||||
map (ssid:
|
||||
let
|
||||
ssidConf = config.site.hosts.${hostName}.wifi.${wifiPath}.ssids.${ssid};
|
||||
in
|
||||
if builtins.elem ssidConf.encryption [ "none" "owe" ]
|
||||
then {
|
||||
assertion = ssidConf.psk == null;
|
||||
message = "${hostName}: SSID ${ssid} has encryption ${ssidConf.encryption} but a PSK is set";
|
||||
}
|
||||
else if builtins.elem ssidConf.encryption [ "wpa2" "wpa3" ]
|
||||
then {
|
||||
assertion = ssidConf.psk != null;
|
||||
message = "${hostName}: SSID ${ssid} has encryption ${ssidConf.encryption} but no PSK is set";
|
||||
}
|
||||
else throw "Unsupported WiFi encryption ${ssidConf.encryption}"
|
||||
) (builtins.attrNames config.site.hosts.${hostName}.wifi.${wifiPath}.ssids)
|
||||
) (builtins.attrNames config.site.hosts.${hostName}.wifi)
|
||||
) (builtins.attrNames config.site.hosts);
|
||||
}) (builtins.attrNames vlanNets));
|
||||
}
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
{ self, lib, openwrt, pkgs }:
|
||||
{ self, pkgs, openwrt }:
|
||||
|
||||
rec {
|
||||
inherit (import ./config { inherit self pkgs; }) config;
|
||||
config = (import ./config { inherit self pkgs; }).config;
|
||||
|
||||
netmasks = import ./netmasks.nix;
|
||||
|
||||
subnet = import ./subnet { inherit pkgs; };
|
||||
|
||||
dns = import ./dns.nix { inherit config lib; };
|
||||
dns = import ./dns.nix { inherit pkgs config; };
|
||||
|
||||
openwrtModels = import ./openwrt-models.nix { inherit self openwrt; };
|
||||
|
||||
|
@ -15,9 +15,8 @@ rec {
|
|||
let
|
||||
models =
|
||||
builtins.filter ({ models, ... }:
|
||||
self.lib.any ({ model, vendor, ... }:
|
||||
model == wantedModel ||
|
||||
"${vendor}_${model}" == wantedModel
|
||||
self.lib.any ({ model, ... }:
|
||||
model == wantedModel
|
||||
) models
|
||||
) openwrtModels;
|
||||
result =
|
||||
|
|
136
nix/lib/dns.nix
136
nix/lib/dns.nix
|
@ -1,18 +1,15 @@
|
|||
{ config, lib }:
|
||||
{ pkgs, config }:
|
||||
|
||||
let
|
||||
lib = pkgs.lib;
|
||||
in
|
||||
rec {
|
||||
ns = "dns.serv.zentralwerk.org";
|
||||
internalNS = [ ns ];
|
||||
# public servers (slaves)
|
||||
publicNS = [
|
||||
"ns.c3d2.de"
|
||||
"ns.spaceboyz.net"
|
||||
"ns1.supersandro.de"
|
||||
];
|
||||
|
||||
publicIPv4 = config.site.hosts.upstream4.interfaces.up4-pppoe.upstream.staticIpv4Address;
|
||||
|
||||
dynamicReverseZones4 = [
|
||||
publicNS = [ "ns.c3d2.de" "ns.spaceboyz.net" ];
|
||||
|
||||
dynamicReverseZones = [
|
||||
"73.20.172.in-addr.arpa"
|
||||
"74.20.172.in-addr.arpa"
|
||||
"75.20.172.in-addr.arpa"
|
||||
|
@ -21,25 +18,7 @@ rec {
|
|||
"78.20.172.in-addr.arpa"
|
||||
"79.20.172.in-addr.arpa"
|
||||
"99.22.172.in-addr.arpa"
|
||||
"22.10.in-addr.arpa"
|
||||
];
|
||||
dynamicReverseZones6 = [
|
||||
"2.0.0.0.c.2.0.8.1.8.0.0.a.2.ip6.arpa"
|
||||
"4.1.b.a.c.a.2.8.3.5.f.0.a.2.ip6.arpa"
|
||||
"5.0.2.d.3.c.2.4.0.0.3.2.d.f.ip6.arpa"
|
||||
];
|
||||
|
||||
mapI = start: end: f:
|
||||
if start >= end
|
||||
then []
|
||||
else [ (f start) ] ++ mapI (start + 1) end f;
|
||||
isRfc1918Reverse = reverse:
|
||||
builtins.any (suffix: lib.hasSuffix suffix reverse) ([
|
||||
"10.in-addr.arpa"
|
||||
"168.192.in-addr.arpa"
|
||||
] ++ mapI 0 32 (i:
|
||||
"${toString (16 + i)}.172.in-addr.arpa"
|
||||
));
|
||||
|
||||
localZones =
|
||||
let
|
||||
|
@ -64,9 +43,8 @@ rec {
|
|||
);
|
||||
|
||||
# generate zones only for nets with hosts
|
||||
namedNets = lib.filterAttrs (_name: { hosts4, hosts6, dynamicDomain, ... }:
|
||||
hosts4 != {} ||
|
||||
hosts6 != {} ||
|
||||
namedNets = lib.filterAttrs (name: { hosts4, hosts6, dynamicDomain, ... }:
|
||||
(hosts4 != [] && hosts6 != []) ||
|
||||
dynamicDomain
|
||||
) config.site.net;
|
||||
|
||||
|
@ -99,7 +77,7 @@ rec {
|
|||
"${zone}" = true;
|
||||
}
|
||||
) {} (builtins.attrNames reverseHosts4)
|
||||
) ++ dynamicReverseZones4
|
||||
) ++ dynamicReverseZones
|
||||
);
|
||||
|
||||
# turns `::` into `0000:0000:0000:0000:0000:0000:0000:0000`
|
||||
|
@ -145,65 +123,59 @@ rec {
|
|||
# `{ dn42 = { "...ip6.arpa" = "lo.core.zentralwerk.dn42"; }; }`
|
||||
reverseHosts6 = builtins.foldl' (result: net: lib.recursiveUpdate result (
|
||||
builtins.mapAttrs (ctx: hosts:
|
||||
builtins.foldl' (result: host:
|
||||
let
|
||||
domain =
|
||||
if ctx == "dn42"
|
||||
then "${net}.zentralwerk.dn42"
|
||||
else namedNets.${net}.domainName;
|
||||
in
|
||||
lib.recursiveUpdate result {
|
||||
"${ipv6ToReverse hosts.${host}}" = "${host}.${domain}";
|
||||
}
|
||||
) {} (builtins.attrNames hosts)
|
||||
if ctx == "yggdrasil"
|
||||
then {}
|
||||
else
|
||||
builtins.foldl' (result: host:
|
||||
let
|
||||
domain =
|
||||
if ctx == "dn42"
|
||||
then "${net}.zentralwerk.dn42"
|
||||
else if builtins.match "up.*" ctx != null
|
||||
then namedNets.${net}.domainName
|
||||
else throw "Invalid IPv6 context: ${ctx}";
|
||||
in
|
||||
lib.recursiveUpdate result {
|
||||
"${ipv6ToReverse hosts.${host}}" = "${host}.${domain}";
|
||||
}
|
||||
) {} (builtins.attrNames hosts)
|
||||
) namedNets.${net}.hosts6
|
||||
)) {} (builtins.attrNames namedNets);
|
||||
|
||||
# `{ dn42 = [ "....ip6.arpa" ]; }`
|
||||
reverseZones6 = builtins.mapAttrs (_ctx: reverseHosts6ctx:
|
||||
reverseZones6 = builtins.mapAttrs (ctx: reverseHosts6ctx:
|
||||
builtins.attrNames (
|
||||
builtins.foldl' (result: rname:
|
||||
result // {
|
||||
"${builtins.substring ((128 - reverseZone6Size) / 2) (72 - ((128 - reverseZone6Size) / 2)) rname}" = true;
|
||||
}) {} (builtins.attrNames reverseHosts6ctx)
|
||||
)
|
||||
builtins.foldl' (result: rname: result // {
|
||||
"${builtins.substring ((128 - reverseZone6Size) / 2) (72 - ((128 - reverseZone6Size) / 2)) rname}" = true;
|
||||
}) {} (builtins.attrNames reverseHosts6ctx)
|
||||
)
|
||||
) reverseHosts6;
|
||||
|
||||
in [ {
|
||||
name = "zentralwerk.org";
|
||||
ns = publicNS;
|
||||
records = [ {
|
||||
name = "@";
|
||||
type = "A";
|
||||
data = publicIPv4;
|
||||
} {
|
||||
name = "www";
|
||||
type = "A";
|
||||
data = publicIPv4;
|
||||
} {
|
||||
name = "@";
|
||||
type = "AAAA";
|
||||
data = config.site.net.serv.hosts6.up4.network-homepage;
|
||||
} {
|
||||
name = "www";
|
||||
type = "AAAA";
|
||||
data = config.site.net.serv.hosts6.up4.network-homepage;
|
||||
} ];
|
||||
records = [];
|
||||
} {
|
||||
name = "zentralwerk.dn42";
|
||||
ns = internalNS;
|
||||
records = [ ];
|
||||
records = [ {
|
||||
name = "ipa";
|
||||
type = "A";
|
||||
data = config.site.net.serv.hosts4.ipa;
|
||||
} ];
|
||||
} {
|
||||
name = "dyn.zentralwerk.org";
|
||||
ns = publicNS;
|
||||
records = [ {
|
||||
name = "upstream4";
|
||||
name = "upstream1";
|
||||
type = "A";
|
||||
data = publicIPv4;
|
||||
data = "24.134.104.53";
|
||||
} {
|
||||
name = "upstream2";
|
||||
type = "A";
|
||||
data = "24.134.252.105";
|
||||
} ];
|
||||
} ]
|
||||
++
|
||||
builtins.concatLists (
|
||||
} ] ++ builtins.concatLists (
|
||||
builtins.attrValues (
|
||||
builtins.mapAttrs (net: { dynamicDomain, hosts4, hosts6, extraRecords, ... }: [
|
||||
{
|
||||
|
@ -219,20 +191,14 @@ rec {
|
|||
records =
|
||||
hosts4Records hosts4 ++
|
||||
lib.optionals (hosts6 ? up4) (hosts6Records hosts6.up4) ++
|
||||
lib.optionals (hosts6 ? flpk) (hosts6Records hosts6.flpk) ++
|
||||
extraRecords;
|
||||
dynamic = dynamicDomain;
|
||||
}
|
||||
]) namedNets
|
||||
)
|
||||
)
|
||||
++
|
||||
map (zone: {
|
||||
) ++ map (zone: {
|
||||
name = zone;
|
||||
ns =
|
||||
if isRfc1918Reverse zone
|
||||
then internalNS
|
||||
else publicNS;
|
||||
ns = internalNS;
|
||||
records =
|
||||
map (reverse: {
|
||||
name = builtins.head (
|
||||
|
@ -244,16 +210,17 @@ rec {
|
|||
builtins.filter (lib.hasSuffix ".${zone}")
|
||||
(builtins.attrNames reverseHosts4)
|
||||
);
|
||||
dynamic = builtins.elem zone dynamicReverseZones4;
|
||||
dynamic = builtins.elem zone dynamicReverseZones;
|
||||
}) reverseZones4
|
||||
++
|
||||
builtins.concatMap (ctx:
|
||||
++ builtins.concatMap (ctx:
|
||||
map (zone: {
|
||||
name = zone;
|
||||
ns =
|
||||
if ctx == "dn42"
|
||||
then internalNS
|
||||
else publicNS;
|
||||
else if builtins.match "up.*" ctx != null
|
||||
then publicNS
|
||||
else throw "Invalid IPv6 context: ${ctx}";
|
||||
records =
|
||||
map (reverse: {
|
||||
name = builtins.substring 0 ((128 - reverseZone6Size) / 2 - 1) reverse;
|
||||
|
@ -263,7 +230,6 @@ rec {
|
|||
builtins.filter (lib.hasSuffix ".${zone}")
|
||||
(builtins.attrNames reverseHosts6.${ctx})
|
||||
);
|
||||
dynamic = builtins.elem zone dynamicReverseZones6;
|
||||
}) reverseZones6.${ctx}
|
||||
) (builtins.attrNames reverseZones6);
|
||||
}
|
||||
|
|
|
@ -28,14 +28,8 @@ let
|
|||
builtins.filter (word:
|
||||
word != [] && word != ""
|
||||
) tokens;
|
||||
command =
|
||||
if words != []
|
||||
then builtins.head words
|
||||
else "-";
|
||||
args =
|
||||
if words != []
|
||||
then builtins.tail words
|
||||
else [];
|
||||
command = builtins.head words;
|
||||
args = builtins.tail words;
|
||||
|
||||
makeLinkFromArg = port: arg:
|
||||
builtins.foldl' (result: interface:
|
||||
|
@ -95,9 +89,7 @@ let
|
|||
|
||||
ucidef_set_interfaces_lan_wan.ports =
|
||||
makeLinkFromArg "lan" (builtins.elemAt args 0) //
|
||||
self.lib.optionalAttrs (builtins.length args > 1) (
|
||||
makeLinkFromArg "wan" (builtins.elemAt args 1)
|
||||
);
|
||||
makeLinkFromArg "wan" (builtins.elemAt args 1);
|
||||
};
|
||||
in
|
||||
if commands ? ${command}
|
||||
|
|
|
@ -47,16 +47,7 @@ in
|
|||
Forward true
|
||||
Server "${config.site.net.serv.hosts4.spaceapi}" "${toString networkPort}"
|
||||
Server "${config.site.net.serv.hosts4.grafana}" "${toString networkPort}"
|
||||
Server "${config.site.net.serv.hosts4.prometheus}" "${toString networkPort}"
|
||||
'';
|
||||
plugins.mqtt = ''
|
||||
<Publish "broker">
|
||||
Host "${config.site.mqttServer.host}"
|
||||
User "${config.site.mqttServer.user}"
|
||||
Password "${config.site.mqttServer.password}"
|
||||
ClientId "collectd-${hostName}"
|
||||
</Publish>
|
||||
'';
|
||||
}) (lib.optionalAttrs (hostName != "stats") {
|
||||
plugins.network = ''
|
||||
Server "${config.site.net.serv.hosts6.dn42.stats}" "${toString networkPort}"
|
||||
|
@ -90,7 +81,7 @@ in
|
|||
Host "inbert.c3d2.de"
|
||||
Host "heise.de"
|
||||
'';
|
||||
}) (lib.optionalAttrs config.services.kea.dhcp4.enable {
|
||||
}) (lib.optionalAttrs config.services.dhcpd4.enable {
|
||||
plugins.exec =
|
||||
let
|
||||
maxTimeout = builtins.foldl' (maxTimeout: net:
|
||||
|
@ -104,8 +95,8 @@ in
|
|||
else maxTimeout
|
||||
) 180 (builtins.attrNames config.site.net);
|
||||
in ''
|
||||
Exec "${execUser}" "/run/wrappers/bin/collectd-dhcpcount" "${toString maxTimeout}"
|
||||
'';
|
||||
Exec "${execUser}" "${pkgs.ruby}/bin/ruby" "${./dhcpcount.rb}" "${toString maxTimeout}"
|
||||
'';
|
||||
}) (lib.optionalAttrs config.services.unbound.enable {
|
||||
plugins.exec = ''
|
||||
Exec "${execUser}" "${pkgs.ruby}/bin/ruby" "${./unbound.rb}"
|
||||
|
@ -115,29 +106,4 @@ in
|
|||
Exec "nobody" "${self.packages.${system}.starlink-stats}/bin/starlink-stats" "192.168.100.1:9200"
|
||||
'';
|
||||
}) ];
|
||||
|
||||
|
||||
systemd.services.collectd = lib.mkIf config.services.kea.dhcp4.enable {
|
||||
after = [ "kea-dhcp4-server.service" ];
|
||||
};
|
||||
|
||||
security.wrappers = lib.mkIf config.services.kea.dhcp4.enable {
|
||||
collectd-dhcpcount =
|
||||
let
|
||||
dhcpcount = pkgs.runCommand "dhcpcount" {
|
||||
src = ./dhcpcount.rb;
|
||||
buildInputs = [ pkgs.ruby ];
|
||||
} ''
|
||||
cp $src dhcpcount.rb
|
||||
patchShebangs dhcpcount.rb
|
||||
mkdir -p $out/bin
|
||||
cp dhcpcount.rb $out/bin/dhcpcount
|
||||
'';
|
||||
in {
|
||||
setuid = true;
|
||||
owner = "root";
|
||||
group = "root";
|
||||
source = "${dhcpcount}/bin/dhcpcount";
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
|
@ -1,28 +1,36 @@
|
|||
#!/usr/bin/env ruby
|
||||
|
||||
require 'csv'
|
||||
require 'date'
|
||||
|
||||
INTERVAL = 60
|
||||
TIMEOUT = ARGV[0].to_i # TODO: now unused
|
||||
hostname = CSV::readlines("/proc/sys/kernel/hostname").join.strip
|
||||
INTERVAL = 10
|
||||
TIMEOUT = ARGV[0].to_i
|
||||
hostname = IO::readlines("/proc/sys/kernel/hostname").join.strip
|
||||
STDOUT.sync = true
|
||||
|
||||
loop do
|
||||
seen = {}
|
||||
count = 0
|
||||
now = Time.now.to_i
|
||||
|
||||
CSV::readlines("/var/lib/kea/kea-leases4.csv", headers: true).each do |rec|
|
||||
h = rec.to_h
|
||||
addr = h["hwaddr"]
|
||||
next unless addr
|
||||
last = h["expire"].to_i
|
||||
elapsed = now - last
|
||||
next if elapsed >= TIMEOUT
|
||||
addr = nil
|
||||
starts = nil
|
||||
|
||||
unless seen[addr]
|
||||
count += 1
|
||||
seen[addr] = true
|
||||
IO::readlines("/var/lib/dhcp/dhcpd.leases").each do |line|
|
||||
if line =~ /^lease (.+) \{/
|
||||
addr = $1
|
||||
|
||||
starts = nil
|
||||
elsif line =~ /starts \d+ (.+?);/
|
||||
starts = DateTime.parse($1).to_time
|
||||
elsif line =~ /^\}/
|
||||
now = Time.now
|
||||
if starts and
|
||||
now >= starts and now < starts + TIMEOUT
|
||||
|
||||
unless seen[addr]
|
||||
count += 1
|
||||
seen[addr] = true
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
puts "PUTVAL \"#{hostname}/exec-dhcpd/current_sessions-leases\" interval=#{INTERVAL} N:#{count}"
|
||||
|
|
|
@ -1,9 +1,7 @@
|
|||
# Routing daemon configuration
|
||||
{ hostName, config, lib, pkgs, ... }:
|
||||
{ hostName, config, options, lib, pkgs, ... }:
|
||||
|
||||
let
|
||||
hostNameEscaped = builtins.replaceStrings [ "-" ] [ "_" ] hostName;
|
||||
|
||||
hostConf = config.site.hosts.${hostName};
|
||||
|
||||
upstreamInterfaces = lib.filterAttrs (_: { upstream, ... }:
|
||||
|
@ -12,11 +10,17 @@ let
|
|||
|
||||
isUpstream = upstreamInterfaces != {};
|
||||
|
||||
ipv6RouterNets = builtins.attrNames (
|
||||
lib.filterAttrs (net: { ipv6Router, ... }:
|
||||
ipv6Router == hostName
|
||||
) config.site.net
|
||||
);
|
||||
# Configuring a gateway? If so, this is the associated net.
|
||||
gatewayNet =
|
||||
let
|
||||
m = builtins.match "(.+)-gw" hostName;
|
||||
in if hostName == "c3d2-gw3"
|
||||
then "c3d2"
|
||||
else if m == [ "cls" ]
|
||||
then "cluster"
|
||||
else if m == null
|
||||
then null
|
||||
else builtins.head m;
|
||||
|
||||
enumerate = n: list:
|
||||
if list == []
|
||||
|
@ -59,95 +63,83 @@ in
|
|||
''
|
||||
else ''
|
||||
export all;
|
||||
''}
|
||||
''}
|
||||
};
|
||||
}
|
||||
protocol device {
|
||||
scan time 10;
|
||||
}
|
||||
# Import address ranges of upstream interfaces so that
|
||||
# internal traffic to local public services take no detours
|
||||
# if the default router takes another upstream gateway.
|
||||
protocol direct {
|
||||
ipv4 {
|
||||
${if isUpstream
|
||||
then ''
|
||||
# No RFC1918, RFC6598
|
||||
import where net !~ [ 100.64.0.0/10 ] && net !~ [ 10.0.0.0/8 ] && net !~ [ 172.16.0.0/12 ] && net !~ [ 192.168.0.0/16 ];
|
||||
''
|
||||
else ""}
|
||||
};
|
||||
ipv6;
|
||||
interface ${lib.concatMapStringsSep ", " (iface:
|
||||
''"${iface}"''
|
||||
)(builtins.attrNames hostConf.interfaces)};
|
||||
check link yes;
|
||||
}
|
||||
${lib.optionalString isUpstream ''
|
||||
# Import address ranges of upstream interfaces so that
|
||||
# internal traffic to local public services take no detours
|
||||
# if the default router takes another upstream gateway.
|
||||
protocol direct {
|
||||
ipv4 {
|
||||
# No RFC6598
|
||||
import where net !~ 100.64.0.0/10
|
||||
# No RFC1918
|
||||
&& net !~ 10.0.0.0/8
|
||||
&& net !~ 172.16.0.0/12
|
||||
&& net !~ 192.168.0.0/16;
|
||||
};
|
||||
ipv6;
|
||||
interface ${lib.concatMapStringsSep ", " (iface:
|
||||
''"${iface}"''
|
||||
)(builtins.attrNames upstreamInterfaces)};
|
||||
check link yes;
|
||||
}
|
||||
''}
|
||||
|
||||
${lib.optionalString (
|
||||
builtins.match "anon.*" hostName != null ||
|
||||
hostName == "flpk-gw"
|
||||
) ''
|
||||
${lib.optionalString (builtins.match "anon.*" hostName != null) ''
|
||||
# BIRD routing table for Wireguard transport
|
||||
ipv4 table vpn_table;
|
||||
ipv4 table vpn4_table;
|
||||
|
||||
# Kernel routing table for Wireguard transport
|
||||
protocol kernel VPN {
|
||||
# "vpn_table" configured on anon routers
|
||||
protocol kernel VPN4 {
|
||||
# "vpn4_table" configured on anon routers
|
||||
kernel table 100;
|
||||
ipv4 {
|
||||
export all;
|
||||
table vpn_table;
|
||||
table vpn4_table;
|
||||
};
|
||||
}
|
||||
''}
|
||||
|
||||
${lib.optionalString (ipv6RouterNets != []) ''
|
||||
${lib.optionalString (gatewayNet != null) ''
|
||||
# Router advertisements
|
||||
protocol radv {
|
||||
rdnss ${config.site.net.serv.hosts6.dn42.dnscache};
|
||||
|
||||
${lib.concatMapStrings (net: ''
|
||||
interface "${net}" {
|
||||
min ra interval 10;
|
||||
max ra interval 60;
|
||||
solicited ra unicast yes;
|
||||
${if (config.site.net.${net}.dhcp.server or null) == null
|
||||
then ''
|
||||
# Do not use DHCP6.
|
||||
managed no;
|
||||
'' else ''
|
||||
# Use DHCP6 for DynDNS.
|
||||
managed yes;
|
||||
''}
|
||||
interface "${gatewayNet}" {
|
||||
min ra interval 10;
|
||||
max ra interval 60;
|
||||
|
||||
${builtins.concatStringsSep "\n" (
|
||||
map (subnet6: ''
|
||||
prefix ${subnet6} {
|
||||
preferred lifetime 600;
|
||||
valid lifetime 1800;
|
||||
};
|
||||
'') (builtins.attrValues config.site.net.${net}.subnets6)
|
||||
)}
|
||||
${builtins.concatStringsSep "\n" (
|
||||
map (subnet6: ''
|
||||
prefix ${subnet6} {
|
||||
preferred lifetime 600;
|
||||
valid lifetime 1800;
|
||||
};
|
||||
'') (builtins.attrValues config.site.net.${gatewayNet}.subnets6)
|
||||
)}
|
||||
|
||||
dnssl "${config.site.net.${net}.domainName}";
|
||||
};
|
||||
'') ipv6RouterNets}
|
||||
dnssl "${config.site.net.${gatewayNet}.domainName}";
|
||||
};
|
||||
}
|
||||
''}
|
||||
|
||||
# OSPFv2 for site-local IPv4
|
||||
protocol ospf v2 ZW4 {
|
||||
ipv4 {
|
||||
import all;
|
||||
# OSPF is self-contained
|
||||
export none;
|
||||
export where net != 0.0.0.0/0 && source != RTS_BGP;
|
||||
};
|
||||
area 0 {
|
||||
${builtins.concatStringsSep "\n" (
|
||||
builtins.attrValues (
|
||||
builtins.mapAttrs (net: _:
|
||||
# Enable OSPF only on networks with a secret.
|
||||
# Enable OSPF only on networks with a secret. Others
|
||||
# are treated as a stubnet whose routes to
|
||||
# advertise.
|
||||
if config.site.net ? "${net}" && config.site.net.${net}.ospf.secret != null
|
||||
then ''
|
||||
interface "${net}" {
|
||||
|
@ -158,12 +150,12 @@ in
|
|||
password "${config.site.net.${net}.ospf.secret}";
|
||||
};
|
||||
''
|
||||
else ''
|
||||
interface "${net}" {
|
||||
stub yes;
|
||||
cost 10;
|
||||
};
|
||||
else if config.site.net ? "${net}" && config.site.net.${net}.subnet4 != null
|
||||
then ''
|
||||
# Advertise route of network ${net}
|
||||
stubnet ${config.site.net.${net}.subnet4} {};
|
||||
''
|
||||
else ""
|
||||
) hostConf.interfaces
|
||||
)
|
||||
)}
|
||||
|
@ -178,7 +170,7 @@ in
|
|||
|
||||
${lib.optionalString isUpstream ''
|
||||
# OSPFv2 to advertise my default route
|
||||
protocol ospf v2 ZW4_${hostNameEscaped} {
|
||||
protocol ospf v2 ZW4_${hostName} {
|
||||
ipv4 {
|
||||
export where net = 0.0.0.0/0;
|
||||
};
|
||||
|
@ -211,19 +203,14 @@ in
|
|||
${text}
|
||||
|
||||
# OSPFv2 to receive a default route from ${upstream}
|
||||
protocol ospf v2 ZW4_${
|
||||
builtins.replaceStrings [ "-" ] [ "_" ] upstream
|
||||
} {
|
||||
protocol ospf v2 ZW4_${upstream} {
|
||||
ipv4 {
|
||||
import filter {
|
||||
preference = preference + ${toString (100 - n)};
|
||||
accept;
|
||||
};
|
||||
${lib.optionalString (
|
||||
builtins.match "anon.*" hostName != null ||
|
||||
hostName == "flpk-gw"
|
||||
) ''
|
||||
table vpn_table;
|
||||
${lib.optionalString (builtins.match "anon.*" hostName != null) ''
|
||||
table vpn4_table;
|
||||
''}
|
||||
};
|
||||
area 0 {
|
||||
|
@ -232,11 +219,7 @@ in
|
|||
builtins.mapAttrs (net: _:
|
||||
# Enable OSPF only on interfaces with a secret.
|
||||
lib.optionalString (config.site.net.${net}.ospf.secret != null) ''
|
||||
interface "${net}" instance ${
|
||||
builtins.replaceStrings [ "-" ] [ "_" ] (
|
||||
toString config.site.hosts.${upstream}.ospf.upstreamInstance
|
||||
)
|
||||
} {
|
||||
interface "${net}" instance ${toString config.site.hosts.${upstream}.ospf.upstreamInstance} {
|
||||
hello 10;
|
||||
wait 20;
|
||||
authentication cryptographic;
|
||||
|
@ -256,15 +239,15 @@ in
|
|||
# OSPFv3 for site-local IPv6
|
||||
protocol ospf v3 ZW6 {
|
||||
ipv6 {
|
||||
import all;
|
||||
# OSPF is self-contained
|
||||
export none;
|
||||
export where net != ::/0 && source != RTS_BGP;
|
||||
};
|
||||
area 0 {
|
||||
${builtins.concatStringsSep "\n" (
|
||||
builtins.attrValues (
|
||||
builtins.mapAttrs (net: _:
|
||||
# Enable OSPF only on networks with a secret.
|
||||
# Enable OSPF only on networks with a secret. Others
|
||||
# are treated as a stubnet whose routes to
|
||||
# advertise.
|
||||
if config.site.net.${net}.ospf.secret != null
|
||||
then ''
|
||||
interface "${net}" {
|
||||
|
@ -275,12 +258,12 @@ in
|
|||
password "${config.site.net.${net}.ospf.secret}";
|
||||
};
|
||||
''
|
||||
else ''
|
||||
interface "${net}" {
|
||||
stub yes;
|
||||
cost 10;
|
||||
};
|
||||
''
|
||||
else builtins.concatStringsSep "\n" (
|
||||
map (subnet6: ''
|
||||
# Advertise route of network ${net}
|
||||
stubnet ${subnet6} {};
|
||||
'') (builtins.attrValues config.site.net.${net}.subnets6)
|
||||
)
|
||||
) hostConf.physicalInterfaces
|
||||
)
|
||||
)}
|
||||
|
@ -296,7 +279,7 @@ in
|
|||
|
||||
${lib.optionalString isUpstream ''
|
||||
# OSPFv3 to advertise my default route
|
||||
protocol ospf v3 ZW6_${hostNameEscaped} {
|
||||
protocol ospf v3 ZW6_${hostName} {
|
||||
ipv6 {
|
||||
export where net = ::/0;
|
||||
};
|
||||
|
@ -329,9 +312,7 @@ in
|
|||
${text}
|
||||
|
||||
# OSPFv3 to receive a default route from ${upstream}
|
||||
protocol ospf v3 ZW6_${
|
||||
builtins.replaceStrings [ "-" ] [ "_" ] upstream
|
||||
} {
|
||||
protocol ospf v3 ZW6_${upstream} {
|
||||
ipv6 {
|
||||
import filter {
|
||||
preference = preference + ${toString (100 - n)};
|
||||
|
@ -344,11 +325,7 @@ in
|
|||
builtins.mapAttrs (net: _:
|
||||
# Enable OSPF only on interfaces with a secret.
|
||||
lib.optionalString (config.site.net.${net}.ospf.secret != null) ''
|
||||
interface "${net}" instance ${
|
||||
builtins.replaceStrings [ "-" ] [ "_" ] (
|
||||
toString config.site.hosts.${upstream}.ospf.upstreamInstance
|
||||
)
|
||||
} {
|
||||
interface "${net}" instance ${toString config.site.hosts.${upstream}.ospf.upstreamInstance} {
|
||||
hello 10;
|
||||
wait 20;
|
||||
authentication cryptographic;
|
||||
|
@ -362,7 +339,7 @@ in
|
|||
}
|
||||
'';
|
||||
n = n + 1;
|
||||
}) { text = ""; n = 0; } hostConf.ospf.allowedUpstreams6
|
||||
}) { text = ""; n = 0; } hostConf.ospf.allowedUpstreams
|
||||
).text}
|
||||
|
||||
# Zentralwerk DN42
|
||||
|
@ -373,8 +350,11 @@ in
|
|||
protocol static {
|
||||
ipv6;
|
||||
route fd23:42:c3d2:580::/57 unreachable;
|
||||
# TODO: remove
|
||||
route 2a02:8106:208:5200::/56 unreachable;
|
||||
# TODO: remove
|
||||
route 2a02:8106:211:e900::/56 unreachable;
|
||||
route 2a00:8180:2c00:200::/56 unreachable;
|
||||
route 2a0f:5382:acab:1400::/56 unreachable;
|
||||
}
|
||||
|
||||
${lib.optionalString (hostConf.bgp != null) ''
|
||||
|
@ -436,8 +416,8 @@ in
|
|||
];
|
||||
};
|
||||
instance = {
|
||||
ipv4 = "ZW4_${hostNameEscaped}";
|
||||
ipv6 = "ZW6_${hostNameEscaped}";
|
||||
ipv4 = "ZW4_${hostName}";
|
||||
ipv6 = "ZW6_${hostName}";
|
||||
};
|
||||
checkService = addressFamily: {
|
||||
description = "Check connectivity for ${addressFamily}";
|
||||
|
@ -447,7 +427,7 @@ in
|
|||
User = "bird2";
|
||||
Group = "bird2";
|
||||
};
|
||||
path = with pkgs; [ bird2 iputils ];
|
||||
path = [ pkgs.bird2 "/run/wrappers" ];
|
||||
script = ''
|
||||
STATE=unknown
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
{ config, lib, modulesPath, pkgs, ... }:
|
||||
{ config, lib, modulesPath, ... }:
|
||||
|
||||
{
|
||||
imports = [
|
||||
|
@ -6,19 +6,22 @@
|
|||
(modulesPath + "/virtualisation/lxc-container.nix")
|
||||
];
|
||||
|
||||
environment = {
|
||||
etc."machine-id".text = builtins.substring 0 8 (builtins.hashString "sha256" config.networking.hostName);
|
||||
systemPackages = with pkgs; [
|
||||
ripgrep
|
||||
];
|
||||
boot = {
|
||||
isContainer = true;
|
||||
loader = {
|
||||
initScript.enable = true;
|
||||
};
|
||||
};
|
||||
|
||||
environment.etc."machine-id".text =
|
||||
builtins.substring 0 8 (
|
||||
builtins.hashString "sha256" config.networking.hostName
|
||||
);
|
||||
|
||||
nix = {
|
||||
settings = {
|
||||
sandbox = false;
|
||||
max-jobs = lib.mkDefault 4;
|
||||
cores = lib.mkDefault 4;
|
||||
};
|
||||
useSandbox = false;
|
||||
maxJobs = lib.mkDefault 1;
|
||||
buildCores = lib.mkDefault 1;
|
||||
};
|
||||
|
||||
systemd.services =
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
# ISC DHCP/IPv4 server configuration
|
||||
{ hostName, config, lib, ... }:
|
||||
{ hostName, inputs, config, lib, ... }:
|
||||
|
||||
let
|
||||
dhcpNets =
|
||||
|
@ -8,331 +8,81 @@ let
|
|||
dhcp.server == hostName
|
||||
) config.site.net;
|
||||
|
||||
concatMapDhcpNets = f:
|
||||
lib.pipe dhcpNets [
|
||||
(builtins.mapAttrs f)
|
||||
builtins.attrValues
|
||||
(map (r: if builtins.isList r then r else [ r ]))
|
||||
builtins.concatLists
|
||||
];
|
||||
|
||||
enabled = builtins.length (builtins.attrNames dhcpNets) > 0;
|
||||
in
|
||||
{
|
||||
services.kea.dhcp4 = lib.mkIf enabled {
|
||||
services.dhcpd4 = lib.optionalAttrs enabled {
|
||||
enable = true;
|
||||
|
||||
settings = {
|
||||
interfaces-config.interfaces = builtins.attrNames dhcpNets;
|
||||
dhcp-ddns.enable-updates = true;
|
||||
ddns-send-updates = true;
|
||||
# TODO: use with kea >= 2.5.0
|
||||
# ddns-conflict-resolution-mode = "check-exists-with-dhcid";
|
||||
ddns-use-conflict-resolution = false;
|
||||
ddns-replace-client-name = "when-not-present";
|
||||
expired-leases-processing.hold-reclaimed-time = builtins.foldl' lib.max
|
||||
3600 (concatMapDhcpNets (net: { dhcp, ... }: dhcp.max-time));
|
||||
interfaces = builtins.attrNames dhcpNets;
|
||||
|
||||
subnet4 = concatMapDhcpNets (net: { vlan, subnet4, hosts4, dhcp, domainName, ... }: {
|
||||
id = vlan;
|
||||
subnet = subnet4;
|
||||
pools = [ {
|
||||
pool = "${dhcp.start} - ${dhcp.end}";
|
||||
} ];
|
||||
renew-timer = builtins.ceil (.5 * dhcp.time);
|
||||
rebind-timer = builtins.ceil (.85 * dhcp.time);
|
||||
valid-lifetime = dhcp.time;
|
||||
option-data = [ {
|
||||
space = "dhcp4";
|
||||
name = "routers";
|
||||
code = 3;
|
||||
data = config.site.net.${net}.hosts4.${dhcp.router};
|
||||
} {
|
||||
space = "dhcp4";
|
||||
name = "domain-name";
|
||||
code = 15;
|
||||
data = domainName;
|
||||
} {
|
||||
space = "dhcp4";
|
||||
name = "domain-name-servers";
|
||||
code = 6;
|
||||
data = "${config.site.net.serv.hosts4.dnscache}, 9.9.9.9";
|
||||
} ];
|
||||
ddns-qualifying-suffix = domainName;
|
||||
reservations = lib.pipe dhcp.fixed-hosts [
|
||||
(builtins.mapAttrs (fixedAddr: hwaddr:
|
||||
if hosts4 ? ${fixedAddr}
|
||||
then # fixedAddr is a known hostname
|
||||
let
|
||||
name = fixedAddr;
|
||||
addr = hosts4.${fixedAddr};
|
||||
in {
|
||||
hostname = "${name}.${net}.zentralwerk.org";
|
||||
hw-address = hwaddr;
|
||||
ip-address = addr;
|
||||
extraConfig = ''
|
||||
${builtins.concatStringsSep "\n" (
|
||||
builtins.attrValues (
|
||||
builtins.mapAttrs (net: { dhcp, subnet4Net, subnet4Len, domainName, ...}:
|
||||
''
|
||||
ddns-update-style standard;
|
||||
key dyndns {
|
||||
algorithm hmac-sha256;
|
||||
secret ${config.site.dyndnsKey};
|
||||
};
|
||||
zone ${domainName}. {
|
||||
primary ${config.site.net.serv.hosts4.dns};
|
||||
primary6 ${config.site.net.serv.hosts6.dn42.dns};
|
||||
key dyndns;
|
||||
}
|
||||
else
|
||||
let
|
||||
names = builtins.attrNames (
|
||||
lib.filterAttrs (_: hostAddr:
|
||||
hostAddr == fixedAddr
|
||||
) hosts4);
|
||||
name = builtins.head names;
|
||||
in
|
||||
if builtins.length names > 0
|
||||
then { # fixedAddr is IPv4 of a known hostname
|
||||
hostname = "${name}.${net}.zentralwerk.org";
|
||||
hw-address = hwaddr;
|
||||
ip-address = hosts4.${name};
|
||||
} # fixedAddr is IPv4?
|
||||
else {
|
||||
hw-address = hwaddr;
|
||||
ip-address = fixedAddr;
|
||||
${lib.concatMapStrings ({ name, dynamic, ... }:
|
||||
lib.optionalString (
|
||||
dynamic &&
|
||||
lib.hasSuffix ".in-addr.arpa" name
|
||||
) ''
|
||||
zone ${name}. {
|
||||
primary ${config.site.net.serv.hosts4.dns};
|
||||
primary6 ${config.site.net.serv.hosts6.dn42.dns};
|
||||
key dyndns;
|
||||
}
|
||||
''
|
||||
) config.site.dns.localZones}
|
||||
|
||||
option arch code 93 = unsigned integer 16;
|
||||
group {
|
||||
default-lease-time ${toString dhcp.time};
|
||||
max-lease-time ${toString dhcp.max-time};
|
||||
option routers ${config.site.net.${net}.hosts4.${builtins.replaceStrings [".${net}"] [""] dhcp.router}};
|
||||
option domain-name "${domainName}";
|
||||
option domain-name-servers 172.20.73.8, 9.9.9.9;
|
||||
ddns-domainname "${domainName}";
|
||||
|
||||
next-server ${config.site.net.serv.hosts4.netboot};
|
||||
if option arch = 00:00 {
|
||||
filename "netboot.xyz.kpxe";
|
||||
} else {
|
||||
filename "netboot.xyz.efi";
|
||||
}
|
||||
))
|
||||
builtins.attrValues
|
||||
(builtins.filter (r: r != null))
|
||||
];
|
||||
});
|
||||
|
||||
match-client-id = false;
|
||||
host-reservation-identifiers = [ "hw-address" ];
|
||||
subnet ${subnet4Net} netmask ${lib.netmasks.${toString subnet4Len}} {
|
||||
range ${dhcp.start} ${dhcp.end};
|
||||
}
|
||||
|
||||
# Netbooting
|
||||
option-def = [ {
|
||||
name = "PXEDiscoveryControl";
|
||||
code = 6;
|
||||
space = "vendor-encapsulated-options-space";
|
||||
type = "uint8";
|
||||
array = false;
|
||||
} {
|
||||
name = "PXEMenuPrompt";
|
||||
code = 10;
|
||||
space = "vendor-encapsulated-options-space";
|
||||
type = "record";
|
||||
array = false;
|
||||
record-types = "uint8,string";
|
||||
} {
|
||||
name = "PXEBootMenu";
|
||||
code = 9;
|
||||
space = "vendor-encapsulated-options-space";
|
||||
type = "record";
|
||||
array = false;
|
||||
record-types = "uint16,uint8,string";
|
||||
} ];
|
||||
client-classes =
|
||||
let
|
||||
rpi4Class = {
|
||||
name = "rpi4-pxe";
|
||||
test = "option[vendor-class-identifier].text == 'PXEClient:Arch:00000:UNDI:002001'";
|
||||
option-data = [ {
|
||||
name = "boot-file-name";
|
||||
data = "bootcode.bin";
|
||||
} {
|
||||
name = "vendor-class-identifier";
|
||||
data = "PXEClient";
|
||||
} {
|
||||
name = "vendor-encapsulated-options";
|
||||
} {
|
||||
name = "PXEBootMenu";
|
||||
csv-format = true;
|
||||
data = "0,17,Raspberry Pi Boot";
|
||||
space = "vendor-encapsulated-options-space";
|
||||
} {
|
||||
name = "PXEDiscoveryControl";
|
||||
data = "3";
|
||||
space = "vendor-encapsulated-options-space";
|
||||
} {
|
||||
name = "PXEMenuPrompt";
|
||||
csv-format = true;
|
||||
data = "0,PXE";
|
||||
space = "vendor-encapsulated-options-space";
|
||||
} ];
|
||||
};
|
||||
update-static-leases on;
|
||||
|
||||
pxeClassData = {
|
||||
PXE-Legacy = {
|
||||
arch = "00000";
|
||||
boot-file-name = "netboot.xyz.kpxe";
|
||||
};
|
||||
PXE-UEFI-32-1.arch = "00002";
|
||||
PXE-UEFI-32-2.arch = "00006";
|
||||
PXE-UEFI-64-1.arch = "00007";
|
||||
PXE-UEFI-64-2.arch = "00008";
|
||||
PXE-UEFI-64-3.arch = "00009";
|
||||
};
|
||||
|
||||
makePxe = name: { boot-file-name ? "netboot.xyz.efi", arch }: {
|
||||
inherit name boot-file-name;
|
||||
test = "substring(option[60].hex,0,20) == 'PXEClient:Arch:${arch}'";
|
||||
next-server = config.site.net.serv.hosts4.nfsroot;
|
||||
};
|
||||
in
|
||||
[ rpi4Class ]
|
||||
++
|
||||
builtins.attrValues (
|
||||
builtins.mapAttrs makePxe pxeClassData
|
||||
);
|
||||
|
||||
control-socket = {
|
||||
socket-type = "unix";
|
||||
socket-name = "/run/kea/dhcp4-socket";
|
||||
};
|
||||
hooks-libraries = [ {
|
||||
library = "/run/current-system/sw/lib/kea/hooks/libdhcp_stat_cmds.so";
|
||||
} {
|
||||
library = "/run/current-system/sw/lib/kea/hooks/libdhcp_lease_cmds.so";
|
||||
} ];
|
||||
};
|
||||
${builtins.concatStringsSep "\n" (
|
||||
builtins.attrValues (
|
||||
builtins.mapAttrs (addr: hwaddr:
|
||||
''
|
||||
host ${addr} {
|
||||
hardware ethernet ${hwaddr};
|
||||
fixed-address ${addr};
|
||||
}
|
||||
''
|
||||
) dhcp.fixed-hosts
|
||||
)
|
||||
)}
|
||||
}
|
||||
''
|
||||
) dhcpNets
|
||||
)
|
||||
)}
|
||||
'';
|
||||
};
|
||||
services.kea.dhcp6 = lib.mkIf enabled {
|
||||
enable = true;
|
||||
|
||||
settings = {
|
||||
interfaces-config.interfaces = builtins.attrNames dhcpNets;
|
||||
dhcp-ddns.enable-updates = true;
|
||||
ddns-override-no-update = true;
|
||||
ddns-override-client-update = true;
|
||||
ddns-replace-client-name = "when-not-present";
|
||||
# TODO: use with kea >= 2.5.0
|
||||
# ddns-conflict-resolution-mode = "check-exists-with-dhcid";
|
||||
ddns-use-conflict-resolution = false;
|
||||
|
||||
subnet6 = concatMapDhcpNets (net: { vlan, subnets6, dhcp, domainName, ... }:
|
||||
let
|
||||
subnet = subnets6.up4 or subnets6.flpk or null;
|
||||
prefix = builtins.head (builtins.split "::/" subnet);
|
||||
in
|
||||
if subnet != null
|
||||
then {
|
||||
id = vlan;
|
||||
interface = net;
|
||||
inherit subnet;
|
||||
pools = [ {
|
||||
pool = "${prefix}:c3d2:c3d2:c3d2:1000 - ${prefix}:c3d2:c3d2:c3d2:ffff";
|
||||
#pool = subnet;
|
||||
} ];
|
||||
valid-lifetime = dhcp.time;
|
||||
max-valid-lifetime = dhcp.max-time;
|
||||
option-data = [ {
|
||||
space = "dhcp6";
|
||||
name = "domain-search";
|
||||
code = 24;
|
||||
data = domainName;
|
||||
} {
|
||||
space = "dhcp6";
|
||||
name = "dns-servers";
|
||||
code = 23;
|
||||
data = "${config.site.net.serv.hosts6.dn42.dnscache}, 2620:fe::9";
|
||||
} ];
|
||||
ddns-generated-prefix = "d";
|
||||
ddns-qualifying-suffix = domainName;
|
||||
}
|
||||
else []
|
||||
);
|
||||
|
||||
host-reservation-identifiers = [ "hw-address" ];
|
||||
#reservations = concatMapDhcpNets (net: { hosts6, dhcp, ... }:
|
||||
# builtins.filter (r: r != null) (
|
||||
# builtins.attrValues (
|
||||
# builtins.mapAttrs (name: hwaddr:
|
||||
# let
|
||||
# ip-addresses = lib.pipe hosts6 [
|
||||
# (builtins.mapAttrs (_: hosts6: hosts6.${name} or null))
|
||||
# builtins.attrValues
|
||||
# (builtins.filter (a: a != null))
|
||||
# ];
|
||||
# in
|
||||
# if builtins.trace (lib.generators.toPretty {} ip-addresses) (builtins.length ip-addresses) > 0
|
||||
# then {
|
||||
# hostname = "${name}.${net}.zentralwerk.org";
|
||||
# hw-address = hwaddr;
|
||||
# inherit ip-addresses;
|
||||
# }
|
||||
# else null
|
||||
# ) dhcp.fixed-hosts
|
||||
# )));
|
||||
control-socket = {
|
||||
socket-type = "unix";
|
||||
socket-name = "/run/kea/dhcp6.socket";
|
||||
};
|
||||
hooks-libraries = [ {
|
||||
library = "/run/current-system/sw/lib/kea/hooks/libdhcp_stat_cmds.so";
|
||||
} {
|
||||
library = "/run/current-system/sw/lib/kea/hooks/libdhcp_lease_cmds.so";
|
||||
} ];
|
||||
};
|
||||
};
|
||||
services.kea.dhcp-ddns = lib.mkIf enabled {
|
||||
enable = true;
|
||||
|
||||
settings = {
|
||||
tsig-keys = [ {
|
||||
name = "dyndns";
|
||||
algorithm = "hmac-sha256";
|
||||
secret = config.site.dyndnsKey;
|
||||
} ];
|
||||
|
||||
forward-ddns.ddns-domains = concatMapDhcpNets (net: { domainName, ... }: {
|
||||
name = "${domainName}.";
|
||||
key-name = "dyndns";
|
||||
dns-servers = [ {
|
||||
ip-address = config.site.net.serv.hosts4.dns;
|
||||
} {
|
||||
ip-address = config.site.net.serv.hosts6.dn42.dns;
|
||||
} ];
|
||||
});
|
||||
reverse-ddns.ddns-domains = map ({ name, ...}: {
|
||||
name = "${name}.";
|
||||
key-name = "dyndns";
|
||||
dns-servers = [ {
|
||||
ip-address = config.site.net.serv.hosts4.dns;
|
||||
} {
|
||||
ip-address = config.site.net.serv.hosts6.dn42.dns;
|
||||
} ];
|
||||
}) (
|
||||
builtins.filter ({ name, dynamic, ... }:
|
||||
dynamic &&
|
||||
(lib.hasSuffix ".in-addr.arpa" name ||
|
||||
lib.hasSuffix ".ip6.arpa" name)
|
||||
) config.site.dns.localZones
|
||||
);
|
||||
control-socket = {
|
||||
socket-type = "unix";
|
||||
socket-name = "/run/kea/dhcp-ddns.socket";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
services.kea.ctrl-agent = lib.mkIf enabled {
|
||||
enable = true;
|
||||
settings.control-sockets = {
|
||||
dhcp4 = {
|
||||
socket-type = "unix";
|
||||
socket-name = "/run/kea/dhcp4.socket";
|
||||
};
|
||||
dhcp6 = {
|
||||
socket-type = "unix";
|
||||
socket-name = "/run/kea/dhcp6.socket";
|
||||
};
|
||||
d2 = {
|
||||
socket-type = "unix";
|
||||
socket-name = "/run/kea/dhcp-ddns.socket";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
# Increase reliablity
|
||||
# (mostly for kea-dhcp-ddns-server.service)
|
||||
systemd.services =
|
||||
let
|
||||
restartService.serviceConfig = {
|
||||
RestartSec = 4;
|
||||
Restart = "always";
|
||||
};
|
||||
in {
|
||||
kea-dhcp4-server = restartService;
|
||||
kea-dhcp6-server = restartService;
|
||||
kea-dhcp-ddns-server = restartService;
|
||||
};
|
||||
}
|
||||
|
|
|
@ -1,26 +1,33 @@
|
|||
{ config, dns-nix, hostName, lib, pkgs, self, ... }:
|
||||
{ hostName, config, lib, pkgs, self, inputs, ... }:
|
||||
|
||||
let
|
||||
serial = builtins.substring 0 10 self.lastModifiedDate;
|
||||
serial =
|
||||
let
|
||||
timestamp = toString self.lastModified;
|
||||
datePkg = pkgs.runCommandLocal "date-${timestamp}" {} ''
|
||||
date -d @${timestamp} +%Y%m%d%H > $out
|
||||
'';
|
||||
in
|
||||
toString (import datePkg);
|
||||
|
||||
generateZoneFile = let
|
||||
util = dns-nix.util.${pkgs.system};
|
||||
in { name, ns, records, ... }: util.writeZone name {
|
||||
TTL = 60*60;
|
||||
SOA = {
|
||||
nameServer = "${lib.dns.ns}.";
|
||||
adminEmail = "astro@spaceboyz.net";
|
||||
serial = lib.toInt serial;
|
||||
refresh = 1*60*60;
|
||||
retry = 5*60;
|
||||
expire = 2*60*60;
|
||||
minimum = 1*60;
|
||||
};
|
||||
NS = map (a: a+".") ns;
|
||||
subdomains = lib.foldl (a: b: lib.recursiveUpdate a b) { } (map ({ name, type, data }: {
|
||||
${name}.${type} = [ data ];
|
||||
}) records);
|
||||
};
|
||||
generateZoneFile = { name, ns, records, dynamic }:
|
||||
builtins.toFile "${name}.zone" ''
|
||||
$ORIGIN ${name}.
|
||||
$TTL 1h
|
||||
|
||||
@ IN SOA ${lib.dns.ns}. astro.spaceboyz.net. (
|
||||
${serial} ; serial
|
||||
1h ; refresh
|
||||
1m ; retry
|
||||
2h ; expire
|
||||
1m ; minimum
|
||||
)
|
||||
${lib.concatMapStrings (ns: " IN NS ${ns}.\n") ns}
|
||||
|
||||
${lib.concatMapStrings ({ name, type, data }:
|
||||
"${name} IN ${type} ${data}\n"
|
||||
) records}
|
||||
'';
|
||||
in
|
||||
{
|
||||
options =
|
||||
|
@ -35,7 +42,7 @@ in
|
|||
type = types.enum [ "A" "AAAA" "MX" "SRV" "CNAME" "TXT" "PTR" ];
|
||||
};
|
||||
data = mkOption {
|
||||
type = types.oneOf [ types.str (types.attrsOf (types.oneOf [ types.int types.str ]))];
|
||||
type = types.str;
|
||||
};
|
||||
};
|
||||
|
||||
|
@ -69,151 +76,90 @@ in
|
|||
config = {
|
||||
site.dns.localZones = lib.dns.localZones;
|
||||
|
||||
services.knot = lib.mkIf config.site.hosts.${hostName}.services.dns.enable (
|
||||
services.bind = lib.mkIf config.site.hosts.${hostName}.services.dns.enable (
|
||||
let
|
||||
generateZone = zone@{ name, dynamic, ... }: {
|
||||
domain = name;
|
||||
template = "zentralwerk";
|
||||
acl = [ "zone_xfr" ] ++ lib.optional dynamic "dyndns";
|
||||
file = if dynamic
|
||||
then "/var/lib/knot/zones/${name}.zone"
|
||||
inherit name;
|
||||
master = true;
|
||||
# allowed for zone-transfer
|
||||
slaves = [
|
||||
# ns.c3d2.de
|
||||
"217.197.84.53" "2001:67c:1400:2240::a"
|
||||
config.site.net.serv.hosts4.bind
|
||||
config.site.net.serv.hosts6.dn42.bind
|
||||
config.site.net.serv.hosts6.up4.bind
|
||||
# ns.spaceboyz.net
|
||||
"172.22.24.4" "2a01:4f9:4b:39ec::4"
|
||||
];
|
||||
file =
|
||||
if dynamic
|
||||
then "/var/db/bind/${name}.zone"
|
||||
else generateZoneFile zone;
|
||||
notify = [ "all" ];
|
||||
extraConfig = ''
|
||||
also-notify {
|
||||
# ns.c3d2.de
|
||||
217.197.84.53;
|
||||
2001:67c:1400:2240::a;
|
||||
${config.site.net.serv.hosts4.bind};
|
||||
${config.site.net.serv.hosts6.dn42.bind};
|
||||
${config.site.net.serv.hosts6.up4.bind};
|
||||
# ns.spaceboyz.net
|
||||
172.22.24.4;
|
||||
95.217.229.209;
|
||||
2a01:4f9:4b:39ec::4;
|
||||
};
|
||||
notify-source ${config.site.net.serv.hosts4.dns};
|
||||
notify-source-v6 ${config.site.net.serv.hosts6.up4.dns};
|
||||
'' + lib.optionalString dynamic ''
|
||||
allow-update { key "dyndns"; };
|
||||
'';
|
||||
};
|
||||
|
||||
in {
|
||||
enable = true;
|
||||
settings = {
|
||||
acl = [
|
||||
{
|
||||
id = "dyndns";
|
||||
action = "update";
|
||||
key = "dyndns";
|
||||
}
|
||||
{
|
||||
id = "zone_xfr";
|
||||
address = with config.site.net.serv; [
|
||||
# ns.c3d2.de
|
||||
hosts4.knot hosts6.dn42.knot hosts6.up4.knot
|
||||
"2a00:8180:2c00:282:2041:cbff:fe0c:8516"
|
||||
"fd23:42:c3d2:582:2041:cbff:fe0c:8516"
|
||||
# ns.spaceboyz.net
|
||||
"172.22.24.4" "95.217.229.209" "2a01:4f9:4b:39ec::4"
|
||||
# ns1.supersandro.de
|
||||
"188.34.196.104" "2a01:4f8:1c1c:1d38::1"
|
||||
];
|
||||
action = "transfer";
|
||||
}
|
||||
];
|
||||
zones = map generateZone config.site.dns.localZones;
|
||||
|
||||
key = [ {
|
||||
id = "dyndns";
|
||||
algorithm = "hmac-sha256";
|
||||
secret = config.site.dyndnsKey;
|
||||
} ];
|
||||
|
||||
log = [ {
|
||||
target = "syslog";
|
||||
any = "info";
|
||||
} ];
|
||||
|
||||
mod-stats = [ {
|
||||
id = "default";
|
||||
query-type = "on";
|
||||
} ];
|
||||
|
||||
remote = let
|
||||
via = with config.site.net.serv; [ hosts4.dns hosts6.up4.dns ];
|
||||
in [
|
||||
{
|
||||
id = "ns.c3d2.de";
|
||||
address = with config.site.net.serv; [ hosts4.knot hosts6.dn42.knot hosts6.up4.knot ];
|
||||
inherit via;
|
||||
} {
|
||||
id = "ns.spaceboyz.net";
|
||||
address = [ "172.22.24.4" "95.217.229.209" "2a01:4f9:4b:39ec::4" ];
|
||||
inherit via;
|
||||
} {
|
||||
id = "ns1.supersandro.de";
|
||||
address = [ /*"188.34.196.104"*/ "2a01:4f8:1c1c:1d38::1" ];
|
||||
inherit via;
|
||||
}
|
||||
];
|
||||
|
||||
remotes = [ {
|
||||
id = "all";
|
||||
remote = [ "ns.c3d2.de" "ns.spaceboyz.net" "ns1.supersandro.de" ];
|
||||
} ];
|
||||
|
||||
server = {
|
||||
answer-rotation = true;
|
||||
automatic-acl = true;
|
||||
identity = "dns.serv.zentralwerk.org";
|
||||
listen = with config.site.net; [
|
||||
"127.0.0.1" "::1"
|
||||
serv.hosts4.dns serv.hosts6.up4.dns serv.hosts6.dn42.dns
|
||||
];
|
||||
tcp-fastopen = true;
|
||||
version = null;
|
||||
extraConfig = ''
|
||||
key "dyndns" {
|
||||
algorithm hmac-sha256;
|
||||
secret "${config.site.dyndnsKey}";
|
||||
};
|
||||
|
||||
template = [
|
||||
{
|
||||
# default is a magic name and is always loaded.
|
||||
# Because we want to use catalog-role/catalog-zone settings for all zones *except* the catalog zone itself, we must split the templates
|
||||
id = "default";
|
||||
global-module = [ "mod-stats" ];
|
||||
}
|
||||
{
|
||||
id = "zentralwerk";
|
||||
catalog-role = "member";
|
||||
catalog-zone = "zentralwerk.";
|
||||
dnssec-signing = true;
|
||||
journal-content = "all"; # required for zonefile-load=difference-no-serial and makes cold starts like zone reloads
|
||||
module = "mod-stats/default";
|
||||
semantic-checks = true;
|
||||
serial-policy = "increment";
|
||||
storage = "/var/lib/knot/zones";
|
||||
zonefile-load = "difference-no-serial";
|
||||
}
|
||||
];
|
||||
|
||||
zone = [ {
|
||||
acl = "zone_xfr";
|
||||
catalog-role = "generate";
|
||||
domain = "zentralwerk.";
|
||||
notify = [ "ns1.supersandro.de" ];
|
||||
storage = "/var/lib/knot/catalog";
|
||||
} ] ++ map generateZone config.site.dns.localZones;
|
||||
};
|
||||
'';
|
||||
extraOptions = ''
|
||||
# allow underscores in dynamic hostnames
|
||||
${lib.concatMapStringsSep "\n" (type: ''
|
||||
check-names ${type} ignore;
|
||||
'') [ "master" "slave" "response" ]}
|
||||
'';
|
||||
});
|
||||
|
||||
systemd.services = {
|
||||
create-dynamic-zones = {
|
||||
description = "Creates dynamic zone files";
|
||||
requiredBy = [ "knot.service" ];
|
||||
before = [ "knot.service" ];
|
||||
serviceConfig.Type = "oneshot";
|
||||
script = ''
|
||||
mkdir -p /var/lib/knot/zones
|
||||
systemd.services.create-dynamic-zones = {
|
||||
description = "Creates dynamic zone files";
|
||||
requiredBy = [ "bind.service" ];
|
||||
before = [ "bind.service" ];
|
||||
serviceConfig.Type = "oneshot";
|
||||
script = ''
|
||||
mkdir -p /var/db/bind
|
||||
|
||||
${lib.concatMapStringsSep "\n" (zone@{ name, ... }: ''
|
||||
[ -e /var/lib/knot/zones/${name}.zone ] || \
|
||||
cp ${generateZoneFile zone} /var/lib/knot/zones/${name}.zone
|
||||
chown -R knot /var/lib/knot/zones
|
||||
chmod -R u+rwX /var/lib/knot/zones
|
||||
'') (builtins.filter ({ dynamic, ... }: dynamic) config.site.dns.localZones)}
|
||||
'';
|
||||
};
|
||||
|
||||
update-dynamic-zones = {
|
||||
description = "Creates initial records in dynamic zone files";
|
||||
requiredBy = [ "knot.service" ];
|
||||
after = [ "knot.service" ];
|
||||
serviceConfig.Type = "oneshot";
|
||||
path = [ pkgs.dnsutils ];
|
||||
script = lib.concatMapStrings (zone: ''
|
||||
nsupdate -v -y "hmac-sha256:dyndns:${config.site.dyndnsKey}" <<EOF
|
||||
${lib.concatMapStringsSep "\n" (zone@{ name, ... }: ''
|
||||
[ -e /var/db/bind/${name}.zone ] || \
|
||||
cp ${generateZoneFile zone} /var/db/bind/${name}.zone
|
||||
chown -R named /var/db/bind
|
||||
chmod -R u+rwX /var/db/bind
|
||||
'') (
|
||||
builtins.filter ({ dynamic, ... }: dynamic) config.site.dns.localZones
|
||||
)}
|
||||
'';
|
||||
};
|
||||
systemd.services.update-dynamic-zones = {
|
||||
description = "Creates initial records in dynamic zone files";
|
||||
requiredBy = [ "bind.service" ];
|
||||
after = [ "bind.service" ];
|
||||
serviceConfig.Type = "oneshot";
|
||||
path = [ pkgs.dnsutils ];
|
||||
script = ''
|
||||
${lib.concatMapStrings (zone: ''
|
||||
nsupdate -y "hmac-sha256:dyndns:${config.site.dyndnsKey}" <<EOF
|
||||
server localhost
|
||||
|
||||
${lib.concatMapStringsSep "\n" ({ name, type, data }: ''
|
||||
|
@ -223,8 +169,10 @@ in
|
|||
|
||||
send
|
||||
EOF
|
||||
'') (builtins.filter ({ dynamic, ... }: dynamic) config.site.dns.localZones);
|
||||
};
|
||||
'') (
|
||||
builtins.filter ({ dynamic, ... }: dynamic) config.site.dns.localZones
|
||||
)}
|
||||
'';
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
|
@ -1,99 +1,105 @@
|
|||
{ hostName, config, lib, pkgs, ... }:
|
||||
|
||||
lib.mkIf config.site.hosts.${hostName}.services.dnscache.enable {
|
||||
services.kresd = {
|
||||
services.unbound = {
|
||||
enable = true;
|
||||
instances = 4;
|
||||
listenPlain = [ "0.0.0.0:53" "[::0]:53" ];
|
||||
package = pkgs.knot-resolver.override { extraFeatures = true; };
|
||||
extraConfig = /* lua */ ''
|
||||
modules = {
|
||||
'http',
|
||||
'policy',
|
||||
'predict',
|
||||
'prefill',
|
||||
'serve_stale < cache', -- servce stail records while refreshing the record
|
||||
'workarounds < iterate', -- solve problems around specific broken subdomains, mainly disables case randomization
|
||||
'view'
|
||||
}
|
||||
settings = {
|
||||
remote-control = {
|
||||
control-enable = true;
|
||||
control-use-cert = false;
|
||||
};
|
||||
server = {
|
||||
num-threads = 4;
|
||||
verbosity = 1;
|
||||
prefetch = true;
|
||||
serve-expired = true;
|
||||
cache-min-ttl = 60;
|
||||
cache-max-ttl = 3600;
|
||||
|
||||
cache.size = 500 * MB
|
||||
cache.min_ttl(60)
|
||||
interface = [ "0.0.0.0" "'::0'" ];
|
||||
# TODO: generate
|
||||
access-control = [
|
||||
"fd23:42:c3d2:500::/56 allow"
|
||||
# TODO: remove
|
||||
"2a02:8106:208:5200::/56 allow"
|
||||
# TODO: remove
|
||||
"2a02:8106:211:e900::/56 allow"
|
||||
"2a00:8180:2000:37::1/128 allow"
|
||||
"2a00:8180:2c00:200::/56 allow"
|
||||
"::172.20.72.0/117 allow"
|
||||
"::172.22.99.0/120 allow"
|
||||
"::1/128 allow"
|
||||
"172.20.72.0/21 allow"
|
||||
"10.0.0.0/24 allow"
|
||||
"10.200.0.0/15 allow"
|
||||
"172.22.99.0/24 allow"
|
||||
"127.0.0.0/8 allow"
|
||||
"0.0.0.0/0 deny"
|
||||
"::/0 deny"
|
||||
];
|
||||
# For DNS over TLS
|
||||
tls-cert-bundle = "${pkgs.cacert}/etc/ssl/certs/ca-bundle.crt";
|
||||
|
||||
net.listen('127.0.0.1', 8453, { kind = 'webmgmt' })
|
||||
http.prometheus.namespace = 'resolver_'
|
||||
# allow reverse lookup of rfc1918 space, which includes the DN42 address space
|
||||
unblock-lan-zones = true;
|
||||
insecure-lan-zones = true;
|
||||
|
||||
-- dns42
|
||||
policy.add(policy.suffix(
|
||||
policy.STUB({'fd42:d42:d42:54::1', 'fd42:d42:d42:53::1', '172.20.0.53', '172.23.0.53'}),
|
||||
policy.todnames({'dn42.', 'd.f.ip6.arpa', '20.172.in-addr.arpa', '21.172.in-addr.arpa', '22.172.in-addr.arpa', '23.172.in-addr.arpa'})
|
||||
))
|
||||
domain-insecure = [
|
||||
"dn42"
|
||||
"d.f.ip6.arpa"
|
||||
"ffdd"
|
||||
];
|
||||
};
|
||||
|
||||
-- freifunk
|
||||
policy.add(policy.suffix(
|
||||
policy.STUB({'10.200.0.4', '10.200.0.16'}),
|
||||
policy.todnames({'ffdd.', '200.10.in-addr.arpa', '201.10.in-addr.arpa'})
|
||||
))
|
||||
|
||||
-- size.dns.localZones
|
||||
policy.add(policy.suffix(
|
||||
policy.STUB({'${config.site.net.serv.hosts4.dns}', ${lib.concatStringsSep ", " (map (hosts6: "'${hosts6.dns}'") (builtins.attrValues config.site.net.serv.hosts6))}}),
|
||||
policy.todnames({${lib.concatStringsSep ", " (map (zone: "'${zone.name}'") config.site.dns.localZones)}})
|
||||
))
|
||||
|
||||
-- forward to dns caches
|
||||
policy.add(policy.slice(
|
||||
policy.slice_randomize_psl(),
|
||||
-- quad9
|
||||
policy.TLS_FORWARD({
|
||||
{'2620:fe::fe', hostname='dns.quad9.net'},
|
||||
{'2620:fe::9', hostname='dns.quad9.net'},
|
||||
{'9.9.9.9', hostname='dns.quad9.net'},
|
||||
{'149.112.112.112', hostname='dns.quad9.net'}
|
||||
}),
|
||||
-- cloudflare
|
||||
policy.TLS_FORWARD({
|
||||
{'2606:4700:4700::1111', hostname='cloudflare-dns.com'},
|
||||
{'2606:4700:4700::1001', hostname='cloudflare-dns.com'},
|
||||
{'1.1.1.1', hostname='cloudflare-dns.com'},
|
||||
{'1.0.0.1', hostname='cloudflare-dns.com'}
|
||||
})
|
||||
))
|
||||
|
||||
-- allow access from our networks
|
||||
'' + lib.concatMapStringsSep "\n" (cidr: "view:addr('${cidr}', policy.all(policy.PASS))") [
|
||||
# localhost
|
||||
"::1/128" "127.0.0.0/8"
|
||||
# mgmt
|
||||
"${config.site.net.mgmt.subnet4}"
|
||||
# dn42
|
||||
"fd23:42:c3d2:500::/56" "::172.20.72.0/117" "::172.22.99.0/120"
|
||||
"172.20.72.0/21" "172.22.99.0/24"
|
||||
# freifunk
|
||||
"10.200.0.0/15"
|
||||
# DSI
|
||||
"2a00:8180:2000:37::1/128" "2a00:8180:2c00:200::/56"
|
||||
# flpk
|
||||
"${config.site.net.flpk.subnet4}" "2a0f:5382:acab:1400::/56 allow"
|
||||
] + "\n" + /* lua */ ''
|
||||
|
||||
-- drop everything that hasn't matched
|
||||
view:addr('0.0.0.0/0', policy.all(policy.DROP))
|
||||
view:addr('::/0', policy.all(policy.DROP))
|
||||
|
||||
predict = {
|
||||
window = 15, -- sampling window
|
||||
period = 24*(60/15) -- track last X hours, divide through sampling window
|
||||
}
|
||||
|
||||
prefill.config({
|
||||
['.'] = {
|
||||
url = 'https://www.internic.net/domain/root.zone',
|
||||
interval = 86400, -- seconds
|
||||
}
|
||||
})
|
||||
|
||||
trust_anchors.set_insecure({'dn42', 'd.f.ip6.arpa', 'ffdd'})
|
||||
'';
|
||||
forward-zone = let
|
||||
mkFfddZone = name: {
|
||||
inherit name;
|
||||
forward-addr = [ "10.200.0.4" "10.200.0.16" ];
|
||||
};
|
||||
in [ {
|
||||
name = ".";
|
||||
forward-tls-upstream = true;
|
||||
forward-addr = [
|
||||
# Quad9
|
||||
"2620:fe::fe@853#dns.quad9.net"
|
||||
"9.9.9.9@853#dns.quad9.net"
|
||||
"2620:fe::9@853#dns.quad9.net"
|
||||
"149.112.112.112@853#dns.quad9.net"
|
||||
# Cloudflare DNS
|
||||
"2606:4700:4700::1111@853#cloudflare-dns.com"
|
||||
"1.1.1.1@853#cloudflare-dns.com"
|
||||
"2606:4700:4700::1001@853#cloudflare-dns.com"
|
||||
"1.0.0.1@853#cloudflare-dns.com"
|
||||
];
|
||||
} ] ++
|
||||
# Local networks
|
||||
map ({ name, ... }: {
|
||||
name = "${name}";
|
||||
forward-addr = [ "${config.site.net.serv.hosts4.dns}" ] ++
|
||||
map (hosts6: hosts6.dns)
|
||||
(builtins.attrValues config.site.net.serv.hosts6);
|
||||
}) config.site.dns.localZones
|
||||
# Freifunk
|
||||
++ (map mkFfddZone [
|
||||
"ffdd"
|
||||
"200.10.in-addr.arpa"
|
||||
"201.10.in-addr.arpa"
|
||||
]);
|
||||
# DN42
|
||||
stub-zone = let
|
||||
mkDn42Zone = name: {
|
||||
inherit name;
|
||||
stub-prime = true;
|
||||
stub-addr = [
|
||||
"172.20.0.53" "fd42:d42:d42:54::1"
|
||||
"172.23.0.53" "fd42:d42:d42:53::1"
|
||||
];
|
||||
};
|
||||
in map mkDn42Zone [
|
||||
"dn42" "d.f.ip6.arpa"
|
||||
"20.172.in-addr.arpa" "21.172.in-addr.arpa"
|
||||
"22.172.in-addr.arpa" "23.172.in-addr.arpa"
|
||||
];
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
|
@ -1,114 +0,0 @@
|
|||
{ config, lib, ... }:
|
||||
|
||||
let
|
||||
|
||||
inherit (config.networking) hostName;
|
||||
|
||||
interfaces = config.site.hosts.${hostName}.physicalInterfaces;
|
||||
|
||||
# linux iface name max length = 15
|
||||
shortenNetName = name:
|
||||
if builtins.match "priv(.*)" name != null
|
||||
then "p" + builtins.substring 4 9 name
|
||||
else if name == "coloradio"
|
||||
then "cr"
|
||||
else if name == "coloradio-gw"
|
||||
then "cr-gw"
|
||||
else name;
|
||||
|
||||
checkIfname = ifname: let
|
||||
len = builtins.stringLength ifname;
|
||||
in if len > 15
|
||||
then throw "Interface name ${ifname} is ${toString (len - 15)} chars too long."
|
||||
else ifname;
|
||||
|
||||
# `lxc.net.*` formatter for lxc.container.conf files
|
||||
netConfig =
|
||||
let
|
||||
attrNamesOrdered = attrs:
|
||||
if attrs ? type
|
||||
then [ "type" ] ++ lib.remove "type" (builtins.attrNames attrs)
|
||||
else builtins.attrNames attrs;
|
||||
|
||||
serialize = name: x:
|
||||
if builtins.isString x
|
||||
then "${name} = ${x}\n"
|
||||
else if builtins.isAttrs x
|
||||
then builtins.concatStringsSep "" (
|
||||
map (n: serialize "${name}.${n}" x.${n}) (attrNamesOrdered x)
|
||||
)
|
||||
else if builtins.isList x
|
||||
then
|
||||
let
|
||||
enumerate = xs: n:
|
||||
if xs == []
|
||||
then []
|
||||
else [ {
|
||||
e = builtins.head xs;
|
||||
i = n;
|
||||
} ] ++ enumerate (builtins.tail xs) (n + 1);
|
||||
in
|
||||
builtins.concatStringsSep "" (
|
||||
map ({ e, i }: serialize "${name}.${toString i}" e) (enumerate x 0)
|
||||
)
|
||||
else throw "Invalid data in lxc net config for ${name}: ${lib.generators.toPretty {} x}";
|
||||
|
||||
in
|
||||
serialize "lxc.net" (
|
||||
map (netName:
|
||||
let
|
||||
ifData = interfaces.${netName};
|
||||
in {
|
||||
type = ifData.type;
|
||||
name = checkIfname netName;
|
||||
flags = "up";
|
||||
hwaddr = if ifData ? hwaddr && ifData.hwaddr != null
|
||||
then ifData.hwaddr
|
||||
else "0A:14:48:xx:xx:xx";
|
||||
} // (lib.optionalAttrs (ifData.type == "veth") {
|
||||
veth.pair = checkIfname "${shortenNetName hostName}-${shortenNetName netName}";
|
||||
veth.mode = checkIfname "bridge";
|
||||
link = checkIfname netName;
|
||||
}) // (lib.optionalAttrs (ifData.type == "phys") {
|
||||
link = checkIfname "ext-${netName}";
|
||||
})
|
||||
) (builtins.attrNames interfaces)
|
||||
);
|
||||
|
||||
in
|
||||
{
|
||||
system.build.lxcConfig = builtins.toFile "${hostName}.conf" ''
|
||||
# For lxcfs and sane defaults
|
||||
lxc.include = /etc/lxc/common.conf
|
||||
|
||||
lxc.uts.name = ${hostName}
|
||||
# Handled by lxc@.service
|
||||
lxc.start.auto = 0
|
||||
lxc.rootfs.path = /var/lib/lxc/${hostName}/rootfs
|
||||
lxc.init.cmd = "/init"
|
||||
|
||||
lxc.mount.entry = /nix/store nix/store none bind,ro 0 0
|
||||
lxc.mount.entry = none tmp tmpfs defaults 0 0
|
||||
lxc.mount.auto = proc:mixed sys:ro cgroup:mixed
|
||||
|
||||
lxc.autodev = 1
|
||||
lxc.tty.max = 0
|
||||
lxc.pty.max = 8
|
||||
|
||||
lxc.cap.drop = sys_module sys_time sys_nice sys_pacct sys_rawio
|
||||
security.privileged = false
|
||||
lxc.apparmor.profile = lxc-container-default-with-mounting
|
||||
|
||||
lxc.cgroup.memory.limit_in_bytes = 1G
|
||||
lxc.cgroup.memory.kmem.tcp.limit_in_bytes = 128M
|
||||
|
||||
# tuntap
|
||||
lxc.cgroup.devices.allow = c 10:200 rw
|
||||
lxc.cgroup2.devices.allow = c 10:200 rw
|
||||
# ppp
|
||||
lxc.cgroup.devices.allow = c 108:0 rwm
|
||||
lxc.cgroup2.devices.allow = c 108:0 rwm
|
||||
|
||||
${netConfig}
|
||||
'';
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
{ lib, pkgs, ... }:
|
||||
let
|
||||
netboot_xyz_efi = pkgs.fetchurl {
|
||||
url = "https://github.com/netbootxyz/netboot.xyz/releases/download/2.0.40/netboot.xyz.efi";
|
||||
sha256 = "1gvgvlaxhjkr9i0b2bjq85h12ni9h5fn6r8nphsag3il9kificcc";
|
||||
};
|
||||
netboot_xyz_kpxe = pkgs.fetchurl {
|
||||
url = "https://github.com/netbootxyz/netboot.xyz/releases/download/2.0.40/netboot.xyz.kpxe";
|
||||
sha256 = "1crkr995i1hv3q548gx2xan1ymxmzcnr7mxaf77s2410mpqfcx82";
|
||||
};
|
||||
tftpRoot = pkgs.runCommand "tftproot" {} ''
|
||||
mkdir -p $out
|
||||
ln -s ${netboot_xyz_efi} $out/netboot.xyz.efi
|
||||
ln -s ${netboot_xyz_kpxe} $out/netboot.xyz.kpxe
|
||||
'';
|
||||
in
|
||||
{
|
||||
services.atftpd = {
|
||||
enable = true;
|
||||
root = tftpRoot;
|
||||
};
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
{ hostName, config, lib, pkgs, ... }:
|
||||
{ hostName, config, lib, ... }:
|
||||
|
||||
let
|
||||
hostConf = config.site.hosts.${hostName};
|
||||
|
@ -15,8 +15,6 @@ let
|
|||
else null;
|
||||
|
||||
enabled = firstUpstreamInterface != null;
|
||||
|
||||
inherit (upstreamInterfaces.${firstUpstreamInterface}.upstream) staticIpv4Address;
|
||||
in
|
||||
{
|
||||
systemd.network.networks = {
|
||||
|
@ -24,132 +22,64 @@ in
|
|||
# systemd-networkd only requests Prefix Delegation via DHCPv6 on
|
||||
# the upstream interface if another interface is configured for it.
|
||||
# without this, the static ipv6 subnet won't be routed to us.
|
||||
networkConfig.DHCPPrefixDelegation = true;
|
||||
networkConfig.DHCPv6PrefixDelegation = true;
|
||||
dhcpV6PrefixDelegationConfig = {
|
||||
SubnetId = "81";
|
||||
# because we have static addresses, we don't actually use this
|
||||
Assign = false;
|
||||
};
|
||||
};
|
||||
} // builtins.mapAttrs (_: { upstream, ... }:
|
||||
# DHCP
|
||||
lib.optionalAttrs (hostName != "flpk-gw") {
|
||||
DHCP = "yes";
|
||||
networkConfig.IPv6AcceptRA = true;
|
||||
dhcpV6Config.PrefixDelegationHint = "::/56";
|
||||
}
|
||||
//
|
||||
} // builtins.mapAttrs (_: { upstream, ... }: {
|
||||
DHCP = "yes";
|
||||
networkConfig.IPv6AcceptRA = true;
|
||||
dhcpV6Config.PrefixDelegationHint = "::/56";
|
||||
|
||||
# Traffic Shaping
|
||||
{
|
||||
extraConfig = ''
|
||||
[CAKE]
|
||||
Parent = root
|
||||
${lib.optionalString (upstream.provider == "vodafone") ''
|
||||
# DOCSIS overhead
|
||||
OverheadBytes = 18
|
||||
''}
|
||||
${lib.optionalString (upstream.provider == "dsi") ''
|
||||
# PPPoE overhead
|
||||
OverheadBytes = 18
|
||||
''}
|
||||
${lib.optionalString (upstream.upBandwidth != null) ''
|
||||
Bandwidth = ${toString upstream.upBandwidth}K
|
||||
''}
|
||||
'';
|
||||
}
|
||||
) upstreamInterfaces;
|
||||
extraConfig = ''
|
||||
[CAKE]
|
||||
Parent = root
|
||||
${lib.optionalString (upstream.provider == "vodafone") ''
|
||||
# DOCSIS overhead
|
||||
OverheadBytes = 18
|
||||
''}
|
||||
${lib.optionalString (upstream.provider == "dsi") ''
|
||||
# PPPoE overhead
|
||||
OverheadBytes = 18
|
||||
''}
|
||||
${lib.optionalString (upstream.upBandwidth != null) ''
|
||||
Bandwidth = ${toString upstream.upBandwidth}K
|
||||
''}
|
||||
'';
|
||||
}) upstreamInterfaces;
|
||||
|
||||
networking.nat = lib.optionalAttrs enabled {
|
||||
enable = true;
|
||||
enableIPv6 = true;
|
||||
internalInterfaces = [ "core" ];
|
||||
externalInterface = firstUpstreamInterface;
|
||||
externalIP = staticIpv4Address;
|
||||
extraCommands = ''
|
||||
# Add workaround for upstreams with wonky MTU
|
||||
iptables -t mangle -A FORWARD \
|
||||
-p tcp --tcp-flags SYN,RST SYN \
|
||||
-j TCPMSS --clamp-mss-to-pmtu
|
||||
ip6tables -t mangle -A FORWARD \
|
||||
-p tcp --tcp-flags SYN,RST SYN \
|
||||
-j TCPMSS --clamp-mss-to-pmtu
|
||||
|
||||
# Prohibit SMTP except for servers
|
||||
iptables -N fwd_smtp || \
|
||||
iptables -F fwd_smtp
|
||||
iptables -A fwd_smtp --source ${config.site.net.serv.subnet4} -j RETURN
|
||||
iptables -A fwd_smtp --dest ${config.site.net.serv.subnet4} -j RETURN
|
||||
iptables -A fwd_smtp --source ${config.site.net.flpk.subnet4} -j RETURN
|
||||
iptables -A fwd_smtp --dest ${config.site.net.flpk.subnet4} -j RETURN
|
||||
iptables -A fwd_smtp -j REJECT
|
||||
iptables -I FORWARD -p tcp --dport 25 -j fwd_smtp
|
||||
|
||||
ip6tables -N fwd_smtp || \
|
||||
ip6tables -F fwd_smtp
|
||||
${lib.concatMapStrings (subnet6: ''
|
||||
ip6tables -A fwd_smtp --source ${subnet6} -j RETURN
|
||||
ip6tables -A fwd_smtp --dest ${subnet6} -j RETURN
|
||||
'') (builtins.concatMap builtins.attrValues [
|
||||
config.site.net.serv.subnets6
|
||||
config.site.net.flpk.subnets6
|
||||
])}
|
||||
ip6tables -A fwd_smtp -j REJECT
|
||||
ip6tables -I FORWARD -p tcp --dport 25 -j fwd_smtp
|
||||
|
||||
${lib.optionalString (staticIpv4Address != null) ''
|
||||
# Allow connections to ${staticIpv4Address} from other hosts behind NAT
|
||||
${lib.concatMapStrings (fwd: let
|
||||
m = builtins.match "([0-9.]+):([0-9-]+)" fwd.destination;
|
||||
destinationIP = if m == null then throw "bad ip:ports `${fwd.destination}'" else lib.elemAt m 0;
|
||||
destinationPorts = if m == null then throw "bad ip:ports `${fwd.destination}'" else builtins.replaceStrings ["-"] [":"] (lib.elemAt m 1);
|
||||
in ''
|
||||
iptables -t nat -A nixos-nat-pre \
|
||||
-d ${staticIpv4Address} -p ${fwd.proto} \
|
||||
--dport ${builtins.toString fwd.sourcePort} \
|
||||
-j DNAT --to-destination ${fwd.destination}
|
||||
|
||||
iptables -t nat -A nixos-nat-post \
|
||||
-d ${destinationIP} -p ${fwd.proto} \
|
||||
--dport ${destinationPorts} \
|
||||
-s 172.20.72.0/21 -j MASQUERADE
|
||||
iptables -t nat -A nixos-nat-post \
|
||||
-d ${destinationIP} -p ${fwd.proto} \
|
||||
--dport ${destinationPorts} \
|
||||
-s ${config.site.net.c3d2.subnet4} -j MASQUERADE
|
||||
'') config.networking.nat.forwardPorts}
|
||||
''}
|
||||
|
||||
# Do not NAT our public IPv4 addresses
|
||||
${lib.concatMapStringsSep "\n" (net:
|
||||
lib.concatMapStrings (subnet: ''
|
||||
iptables -t nat -I nixos-nat-post \
|
||||
-o ${net} \
|
||||
-s ${subnet} \
|
||||
-j RETURN
|
||||
'') upstreamInterfaces.${net}.upstream.noNat.subnets4 or []
|
||||
) (builtins.attrNames hostConf.interfaces)}
|
||||
|
||||
externalIP = upstreamInterfaces.${firstUpstreamInterface}.upstream.staticIpv4Address;
|
||||
extraCommands =
|
||||
# Provide IPv6 upstream for everyone, using NAT66 when not from
|
||||
# our static prefixes
|
||||
${lib.concatMapStringsSep "\n" (net:
|
||||
lib.concatMapStrings (subnet: ''
|
||||
ip6tables -t nat -I nixos-nat-post \
|
||||
-o ${net} \
|
||||
-s ${subnet} \
|
||||
-j RETURN
|
||||
'') upstreamInterfaces.${net}.upstream.noNat.subnets6
|
||||
) (builtins.attrNames upstreamInterfaces)}
|
||||
lib.concatMapStringsSep "\n" (net: ''
|
||||
ip6tables -t nat -N ${net}_nat || \
|
||||
ip6tables -t nat -F ${net}_nat
|
||||
${lib.concatMapStringsSep "\n" (subnet: ''
|
||||
ip6tables -t nat -A ${net}_nat \
|
||||
-s ${subnet} \
|
||||
-j RETURN
|
||||
'') upstreamInterfaces.${net}.upstream.noNat.subnets6}
|
||||
ip6tables -t nat -A ${net}_nat -j MASQUERADE
|
||||
|
||||
# There just have been moments without a complete ruleset. Flush
|
||||
# out invalid conntrack states!
|
||||
${pkgs.conntrack-tools}/bin/conntrack -F
|
||||
'';
|
||||
extraStopCommands = ''
|
||||
iptables -F FORWARD 2>/dev/null || true
|
||||
ip6tables -F FORWARD 2>/dev/null || true
|
||||
|
||||
ip6tables -t nat -F POSTROUTING 2>/dev/null || true
|
||||
'';
|
||||
ip6tables -t nat -A POSTROUTING \
|
||||
-o ${net} \
|
||||
-j ${net}_nat
|
||||
'') (builtins.attrNames upstreamInterfaces);
|
||||
extraStopCommands =
|
||||
lib.concatMapStringsSep "\n" (net: ''
|
||||
ip6tables -t nat -F POSTROUTING 2>/dev/null || true
|
||||
ip6tables -t nat -F ${net}_nat 2>/dev/null || true
|
||||
ip6tables -t nat -X ${net}_nat 2>/dev/null || true
|
||||
'') (builtins.attrNames upstreamInterfaces);
|
||||
|
||||
forwardPorts = map ({ destination, sourcePort, reflect, ... }@forwardedPort:
|
||||
removeAttrs forwardedPort ["reflect"] // {
|
||||
|
@ -159,7 +89,11 @@ in
|
|||
else "${destination}:${toString sourcePort}";
|
||||
loopbackIPs =
|
||||
if reflect
|
||||
then [ config.site.net.core.hosts4.${hostName} ]
|
||||
then builtins.filter (ip: ip != null) (
|
||||
map (net:
|
||||
upstreamInterfaces.${net}.upstream.staticIpv4Address
|
||||
) (builtins.attrNames upstreamInterfaces)
|
||||
)
|
||||
else [];
|
||||
}
|
||||
) hostConf.forwardPorts;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
{ hostName, config, lib, ... }:
|
||||
{ hostName, inputs, config, lib, ... }:
|
||||
|
||||
let
|
||||
hostConf = config.site.hosts.${hostName};
|
||||
|
@ -26,7 +26,7 @@ in lib.mkIf (pppoeInterfaces != {}) {
|
|||
enable = true;
|
||||
autostart = true;
|
||||
config = ''
|
||||
plugin pppoe.so
|
||||
plugin rp-pppoe.so
|
||||
nic-${upstream.link}
|
||||
ifname ${ifName}
|
||||
# Login settings. (PAP)
|
||||
|
@ -39,11 +39,11 @@ in lib.mkIf (pppoeInterfaces != {}) {
|
|||
maxfail 0
|
||||
# Seconds between reconnection attempts
|
||||
holdoff 1
|
||||
|
||||
|
||||
# LCP settings.
|
||||
lcp-echo-interval 5
|
||||
lcp-echo-failure 6
|
||||
|
||||
|
||||
# PPPoE compliant settings.
|
||||
noaccomp
|
||||
default-asyncmap
|
||||
|
@ -64,17 +64,14 @@ in lib.mkIf (pppoeInterfaces != {}) {
|
|||
in networks // {
|
||||
"${ifName}" = {
|
||||
matchConfig.Name = "${ifName}";
|
||||
linkConfig = lib.optionalAttrs (ifName == "core") {
|
||||
# interface is stuck in "routable (configuring)" and blocks systemd-networkd-wait-online
|
||||
# TODO: figure out why exactly
|
||||
RequiredForOnline = false;
|
||||
};
|
||||
networkConfig = {
|
||||
DHCP = lib.mkForce "ipv6";
|
||||
DHCP = lib.mkOverride 900 "ipv6";
|
||||
# accept config set by pppd
|
||||
KeepConfiguration = "yes";
|
||||
};
|
||||
dhcpV6Config = {
|
||||
RapidCommit = true;
|
||||
ForceDHCPv6PDOtherInformation = true;
|
||||
PrefixDelegationHint = "::/56";
|
||||
};
|
||||
};
|
||||
|
@ -84,4 +81,11 @@ in lib.mkIf (pppoeInterfaces != {}) {
|
|||
};
|
||||
}) {} (builtins.attrNames pppoeInterfaces);
|
||||
|
||||
# TODO: needed?
|
||||
networking.nat.extraCommands = ''
|
||||
iptables -A FORWARD \
|
||||
-p tcp --tcp-flags SYN,RST SYN \
|
||||
-j TCPMSS --clamp-mss-to-pmtu
|
||||
'';
|
||||
|
||||
}
|
||||
|
|
|
@ -1,58 +0,0 @@
|
|||
{ config, 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 ++ [ "fe80::/64" "ff02::/16" ];
|
||||
};
|
||||
}) config.site.vpn.wireguard.peers;
|
||||
};
|
||||
|
||||
systemd.network.networks.vpn.addresses = [ {
|
||||
addressConfig = {
|
||||
Address = "fe80::1/64";
|
||||
Scope = "link";
|
||||
};
|
||||
} ];
|
||||
|
||||
environment.systemPackages = [
|
||||
pkgs.wireguard-tools
|
||||
];
|
||||
}
|
|
@ -1,7 +1,7 @@
|
|||
# wireguard upstreams (like njalla and flpk, not like vpn dialup. see vpn-gw)
|
||||
{ hostName, config, lib, pkgs, ... }:
|
||||
|
||||
let
|
||||
gateway = "upstream1";
|
||||
|
||||
tunnels = lib.filterAttrs (_: { wireguard, ... }:
|
||||
wireguard != null
|
||||
|
@ -16,7 +16,7 @@ let
|
|||
"/run/wireguard-keys/${ifName}.key";
|
||||
|
||||
wireguardMark = 3;
|
||||
vpnTable = 100;
|
||||
vpn4Table = 100;
|
||||
in
|
||||
{
|
||||
systemd.services = builtins.foldl' (services: ifName: services // {
|
||||
|
@ -52,6 +52,7 @@ in
|
|||
};
|
||||
wireguardConfig = {
|
||||
PrivateKeyFile = privateKeyFile ifName;
|
||||
# Mark for routing with another routing table
|
||||
FirewallMark = wireguardMark;
|
||||
};
|
||||
wireguardPeers = [ {
|
||||
|
@ -67,10 +68,10 @@ in
|
|||
# Wireguard transported through another routing table
|
||||
# (containing upstream by bird ospf)
|
||||
core.routingPolicyRules = [ {
|
||||
# Marked wireguard packets take the vpn routing table
|
||||
# Marked wireguard packets take the vpn4 routing table
|
||||
routingPolicyRuleConfig = {
|
||||
Table = vpn4Table;
|
||||
FirewallMark = wireguardMark;
|
||||
Table = vpnTable;
|
||||
};
|
||||
} ];
|
||||
} // builtins.mapAttrs (ifName: { wireguard, upstream, ... }: {
|
||||
|
@ -83,12 +84,12 @@ in
|
|||
|
||||
# IPv4 default route
|
||||
networkConfig.DefaultRouteOnDevice = true;
|
||||
# IPv6 default route
|
||||
routes = [ {
|
||||
# IPv6 default route
|
||||
routeConfig.Destination = "::/0";
|
||||
} ];
|
||||
|
||||
extraConfig = lib.mkIf (upstream.upBandwidth != null) ''
|
||||
extraConfig = ''
|
||||
[CAKE]
|
||||
Parent = root
|
||||
# DOCSIS overhead
|
||||
|
@ -109,7 +110,7 @@ in
|
|||
networking.iproute2 = lib.mkIf enabled {
|
||||
enable = true;
|
||||
rttablesExtraConfig = ''
|
||||
${toString vpnTable} vpn
|
||||
${toString vpn4Table} vpn4
|
||||
'';
|
||||
};
|
||||
|
||||
|
|
|
@ -0,0 +1,57 @@
|
|||
{ pkgs, lib, config, hostName, ... }:
|
||||
|
||||
let
|
||||
hostConf = config.site.hosts.${hostName};
|
||||
cfg = hostConf.services.yggdrasil;
|
||||
in lib.mkIf cfg.enable {
|
||||
networking.firewall.enable = false;
|
||||
|
||||
boot.postBootCommands = ''
|
||||
if [ ! -c /dev/net/tun ]; then
|
||||
mkdir -p /dev/net
|
||||
mknod -m 666 /dev/net/tun c 10 200
|
||||
fi
|
||||
'';
|
||||
|
||||
# Forward traffic under the prefix.
|
||||
boot.kernel.sysctl."net.ipv6.conf.all.forwarding" = 1;
|
||||
networking.nat = {
|
||||
enable = true;
|
||||
# Provide NAT66 for everyone with addresses foreign to Yggdrasil
|
||||
extraCommands = ''
|
||||
ip6tables -t nat -A POSTROUTING ! --src 200::/7 -o ygg -j MASQUERADE
|
||||
'';
|
||||
};
|
||||
|
||||
systemd.tmpfiles.rules = [
|
||||
"d /var/lib/yggdrasil 0700 root root -"
|
||||
"L+ /var/lib/yggdrasil/keys.json - - - - ${builtins.toFile "keys.json" cfg.keys}"
|
||||
];
|
||||
|
||||
services.yggdrasil = {
|
||||
enable = true;
|
||||
persistentKeys = true;
|
||||
config = {
|
||||
IfName = "ygg";
|
||||
Peers = # https://publicpeers.neilalexander.dev/
|
||||
[
|
||||
# czechia
|
||||
"tcp://[2a03:3b40:fe:ab::1]:46370" # emery vpsfree.cz
|
||||
|
||||
# poland
|
||||
"tls://[2001:41d0:601:1100::cf2]:11129"
|
||||
];
|
||||
Listen = [
|
||||
"tcp://[::]:1337"
|
||||
# Not needed as `sysctl net.ipv6.bindv6only=0` by default
|
||||
# "tcp://0.0.0.0:1337"
|
||||
];
|
||||
NodeInfo = {
|
||||
# This information is visible to the network.
|
||||
name = "y.c3d2.de";
|
||||
location = "Dresden";
|
||||
email = "ehmry@c3d2.de";
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
|
@ -1,13 +1,13 @@
|
|||
# Pulls together NixOS configuration modules according to the
|
||||
# name/role of the host to be built.
|
||||
{ hostName, lib, ... }:
|
||||
{ hostName, config, lib, pkgs, ... }:
|
||||
|
||||
let
|
||||
inherit (lib) optionals;
|
||||
|
||||
hostConfig = lib.config.site.hosts.${hostName};
|
||||
in {
|
||||
inherit (lib.config) site;
|
||||
site = lib.config.site;
|
||||
|
||||
imports = [
|
||||
../lib/config/options.nix
|
||||
|
@ -20,27 +20,24 @@ in {
|
|||
./server/default.nix
|
||||
] ++
|
||||
optionals (hostConfig.role == "container") [
|
||||
./container/lxc-config.nix
|
||||
./container/defaults.nix
|
||||
./container/dhcp-server.nix
|
||||
./container/wireguard.nix
|
||||
./container/dns.nix
|
||||
./container/dnscache.nix
|
||||
./container/yggdrasil.nix
|
||||
] ++
|
||||
optionals lib.config.site.hosts.${hostName}.isRouter [
|
||||
./container/bird.nix
|
||||
] ++
|
||||
optionals (
|
||||
builtins.match "upstream.*" hostName != null ||
|
||||
hostName == "flpk-gw"
|
||||
) [
|
||||
optionals (builtins.match "upstream.*" hostName != null) [
|
||||
./container/upstream.nix
|
||||
./container/upstream/pppoe.nix
|
||||
] ++
|
||||
optionals (hostName == "mgmt-gw") [
|
||||
./container/mgmt-gw.nix
|
||||
] ++
|
||||
optionals (hostName == "vpn-gw") [
|
||||
./container/vpn.nix
|
||||
optionals (hostName == "netboot") [
|
||||
./container/netboot.nix
|
||||
];
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
{ hostName, inputs, lib, pkgs, ... }:
|
||||
{ hostName, inputs, pkgs, config, options, lib, ... }:
|
||||
|
||||
{
|
||||
boot.kernelParams = [
|
||||
|
@ -7,9 +7,9 @@
|
|||
# Prevents automatic creation of interface bond0 by the kernel
|
||||
"bonding.max_bonds=0"
|
||||
];
|
||||
boot.tmp.useTmpfs = true;
|
||||
boot.tmpOnTmpfs = true;
|
||||
# Includes wireguard
|
||||
boot.kernelPackages = pkgs.zfsUnstable.latestCompatibleLinuxPackages;
|
||||
boot.kernelPackages = pkgs.linuxPackages_latest;
|
||||
# Keep building
|
||||
boot.zfs.enableUnstable = true;
|
||||
|
||||
|
@ -25,18 +25,11 @@
|
|||
registry = {
|
||||
nixpkgs.flake = inputs.nixpkgs;
|
||||
};
|
||||
|
||||
settings = {
|
||||
substituters = lib.mkBefore [ "https://hydra.hq.c3d2.de" ];
|
||||
trusted-public-keys = [
|
||||
"nix-serve.hq.c3d2.de:KZRGGnwOYzys6pxgM8jlur36RmkJQ/y8y62e52fj1ps=%"
|
||||
];
|
||||
};
|
||||
};
|
||||
|
||||
documentation = {
|
||||
enable = lib.mkForce false;
|
||||
nixos.enable = lib.mkForce false;
|
||||
enable = false;
|
||||
nixos.enable = false;
|
||||
};
|
||||
|
||||
environment.systemPackages = with pkgs; [
|
||||
|
@ -44,8 +37,6 @@
|
|||
bridge-utils
|
||||
conntrack-tools
|
||||
dhcpcd
|
||||
dhcpdump
|
||||
dig
|
||||
ethtool
|
||||
git
|
||||
iftop
|
||||
|
@ -58,7 +49,6 @@
|
|||
screen
|
||||
speedtest-cli
|
||||
tcpdump
|
||||
tmux
|
||||
traceroute
|
||||
vim
|
||||
wget
|
||||
|
@ -66,25 +56,6 @@
|
|||
|
||||
networking.hostName = hostName;
|
||||
|
||||
programs = {
|
||||
fzf.keybindings = true;
|
||||
git = {
|
||||
enable = true;
|
||||
config = {
|
||||
alias = {
|
||||
co = "checkout";
|
||||
lg = "log --graph --abbrev-commit --decorate --format=format:'%C(bold blue)%h%C(reset) - %C(bold green)(%ar)%C(reset) %C(white)%s%C(reset) %C(dim white)- %an%C(reset)%C(bold y
|
||||
ow)%d%C(reset)'";
|
||||
remote = "remote -v";
|
||||
st = "status";
|
||||
undo = "reset --soft HEAD^";
|
||||
};
|
||||
pull.rebase = true;
|
||||
rebase.autoStash = true;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
users.users.root.initialHashedPassword = "";
|
||||
|
||||
system.stateVersion = "20.09";
|
||||
|
|
|
@ -1,18 +1,11 @@
|
|||
{ hostName, config, lib, ... }:
|
||||
|
||||
let
|
||||
hostConfig = config.site.hosts.${hostName};
|
||||
|
||||
in {
|
||||
networking.firewall = lib.mkIf hostConfig.firewall.enable {
|
||||
lib.mkIf config.site.hosts.${hostName}.firewall.enable {
|
||||
networking.firewall = {
|
||||
enable = true;
|
||||
extraCommands = ''
|
||||
${lib.optionalString hostConfig.isRouter ''
|
||||
ip46tables -I nixos-fw -p ospfigp -j ACCEPT
|
||||
''}
|
||||
|
||||
ip46tables -A FORWARD -i core -m state --state ESTABLISHED,RELATED -j ACCEPT
|
||||
ip46tables -A FORWARD -i core -j REJECT
|
||||
ip46tables -A FORWARD -i core -j REJECT --reject-with net-unreach
|
||||
'';
|
||||
extraStopCommands = ''
|
||||
ip46tables -F FORWARD
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
{ hostName, config, lib, ... }:
|
||||
{ hostName, config, lib, pkgs, ... }:
|
||||
|
||||
let
|
||||
# pick an address for a net's gateway
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
{ pkgs, ... }:
|
||||
{ pkgs, nixpkgs-master, ... }:
|
||||
{
|
||||
boot.kernelModules = [ "kvm-intel" "pppoe" ];
|
||||
boot.kernelParams = [ "nomodeset" ];
|
||||
|
@ -8,20 +8,16 @@
|
|||
time.timeZone = "Europe/Berlin";
|
||||
|
||||
environment.systemPackages = with pkgs; [
|
||||
git
|
||||
inetutils # telnet
|
||||
wget vim git screen
|
||||
ipmitool
|
||||
liboping # noping
|
||||
screen
|
||||
vim
|
||||
wget
|
||||
];
|
||||
|
||||
services.openssh = {
|
||||
enable = true;
|
||||
settings.PermitRootLogin = "prohibit-password";
|
||||
};
|
||||
services.openssh.enable = true;
|
||||
services.openssh.permitRootLogin = "prohibit-password";
|
||||
|
||||
# additional config for bare metal
|
||||
services.collectd.plugins.ipmi = "";
|
||||
services.collectd = {
|
||||
plugins.ipmi = "";
|
||||
# FIXME: IPMI is only available with nixpkgs-21.11 onwards
|
||||
package = nixpkgs-master.legacyPackages.${pkgs.system}.collectd;
|
||||
};
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
{ self, config, lib, pkgs, ... }:
|
||||
{ hostName, self, config, lib, pkgs, ... }:
|
||||
|
||||
let
|
||||
# Containers that are run on this host
|
||||
|
@ -10,6 +10,70 @@ let
|
|||
|
||||
enabled = containers != {};
|
||||
|
||||
# linux iface name max length = 15
|
||||
shortenNetName = name:
|
||||
if builtins.match "priv(.*)" name != null
|
||||
then "p" + builtins.substring 4 9 name
|
||||
else name;
|
||||
|
||||
checkIfname = ifname: let
|
||||
len = builtins.stringLength ifname;
|
||||
in if len > 15
|
||||
then throw "Interface name ${ifname} is ${toString (len - 15)} chars too long."
|
||||
else ifname;
|
||||
|
||||
# `lxc.net.*` formatter for lxc.container.conf files
|
||||
netConfig = ctName: interfaces:
|
||||
let
|
||||
config = map (netName:
|
||||
let
|
||||
ifData = interfaces.${netName};
|
||||
in {
|
||||
type = ifData.type;
|
||||
name = checkIfname netName;
|
||||
flags = "up";
|
||||
hwaddr = if ifData ? hwaddr && ifData.hwaddr != null
|
||||
then ifData.hwaddr
|
||||
else "0A:14:48:xx:xx:xx";
|
||||
} // (lib.optionalAttrs (ifData.type == "veth") {
|
||||
veth.pair = checkIfname "${shortenNetName ctName}-${shortenNetName netName}";
|
||||
veth.mode = checkIfname "bridge";
|
||||
link = checkIfname netName;
|
||||
}) // (lib.optionalAttrs (ifData.type == "phys") {
|
||||
link = checkIfname "ext-${netName}";
|
||||
})
|
||||
) (builtins.attrNames interfaces);
|
||||
|
||||
attrNamesOrdered = attrs:
|
||||
if attrs ? type
|
||||
then [ "type" ] ++ lib.remove "type" (builtins.attrNames attrs)
|
||||
else builtins.attrNames attrs;
|
||||
|
||||
serialize = name: x:
|
||||
if builtins.isString x
|
||||
then "${name} = ${x}\n"
|
||||
else if builtins.isAttrs x
|
||||
then builtins.concatStringsSep "" (
|
||||
map (n: serialize "${name}.${n}" x.${n}) (attrNamesOrdered x)
|
||||
)
|
||||
else if builtins.isList x
|
||||
then
|
||||
let
|
||||
enumerate = xs: n:
|
||||
if xs == []
|
||||
then []
|
||||
else [ {
|
||||
e = builtins.head xs;
|
||||
i = n;
|
||||
} ] ++ enumerate (builtins.tail xs) (n + 1);
|
||||
in
|
||||
builtins.concatStringsSep "" (
|
||||
map ({ e, i }: serialize "${name}.${toString i}" e) (enumerate x 0)
|
||||
)
|
||||
else throw "Invalid data in lxc net config for ${name}: ${lib.generators.toPretty {} x}";
|
||||
in
|
||||
serialize "lxc.net" config;
|
||||
|
||||
# User-facing script to build/update container NixOS systems
|
||||
build-script = pkgs.writeScriptBin "build-container" ''
|
||||
#! ${pkgs.runtimeShell} -e
|
||||
|
@ -30,7 +94,6 @@ let
|
|||
${ctName})
|
||||
echo Using prebuilt system for container $c
|
||||
SYSTEM=${self.packages.x86_64-linux."${ctName}-rootfs"}
|
||||
CONFIG=${self.packages.x86_64-linux."${ctName}-lxc-config"}
|
||||
;;
|
||||
'') (
|
||||
builtins.attrNames (
|
||||
|
@ -42,8 +105,6 @@ let
|
|||
echo Building $c
|
||||
nix build -o /nix/var/nix/gcroots/lxc/$c zentralwerk-network#$c-rootfs
|
||||
SYSTEM=$(readlink /nix/var/nix/gcroots/lxc/$c)
|
||||
nix build -o /nix/var/nix/gcroots/lxc/$c.config zentralwerk-network#$c-lxc-config
|
||||
CONFIG=$(readlink /nix/var/nix/gcroots/lxc/$c.config)
|
||||
;;
|
||||
esac
|
||||
|
||||
|
@ -56,7 +117,6 @@ let
|
|||
mkdir -p /var/lib/lxc/$c/rootfs/$d
|
||||
done
|
||||
ln -fs $SYSTEM/init /var/lib/lxc/$c/rootfs/init
|
||||
ln -fs $CONFIG /var/lib/lxc/$c/config
|
||||
done
|
||||
|
||||
# Activate all the desired container after all of them are
|
||||
|
@ -102,8 +162,10 @@ in
|
|||
|
||||
virtualisation.lxc = lib.mkIf enabled {
|
||||
enable = true;
|
||||
# Container configs live in /etc so that they can be created
|
||||
# through `environment.etc`.
|
||||
systemConfig = ''
|
||||
lxc.lxcpath = /var/lib/lxc
|
||||
lxc.lxcpath = /etc/lxc/containers
|
||||
'';
|
||||
};
|
||||
|
||||
|
@ -114,7 +176,50 @@ in
|
|||
enable-script disable-script
|
||||
];
|
||||
|
||||
environment.etc."lxc/common.conf".source = "${pkgs.lxc}/share/lxc/config/common.conf";
|
||||
# Create lxc.container.conf files
|
||||
environment.etc =
|
||||
builtins.foldl' (etc: ctName: etc // {
|
||||
"lxc/containers/${ctName}/config" = {
|
||||
enable = true;
|
||||
source =
|
||||
builtins.toFile "${ctName}.conf" ''
|
||||
# For lxcfs and sane defaults
|
||||
lxc.include = /etc/lxc/common.conf
|
||||
|
||||
lxc.uts.name = ${ctName}
|
||||
# Handled by lxc@.service
|
||||
lxc.start.auto = 0
|
||||
lxc.rootfs.path = /var/lib/lxc/${ctName}/rootfs
|
||||
lxc.init.cmd = "/init"
|
||||
|
||||
lxc.mount.entry = /nix/store nix/store none bind,ro 0 0
|
||||
lxc.mount.entry = none tmp tmpfs defaults 0 0
|
||||
lxc,mount.auto = proc:mixed sys:ro cgroup:mixed
|
||||
|
||||
lxc.autodev = 1
|
||||
lxc.tty.max = 0
|
||||
lxc.pty.max = 8
|
||||
|
||||
lxc.cap.drop = sys_module sys_time sys_nice sys_pacct sys_rawio
|
||||
security.privileged = false
|
||||
lxc.apparmor.profile = lxc-container-default-with-mounting
|
||||
|
||||
lxc.cgroup.memory.limit_in_bytes = 1G
|
||||
lxc.cgroup.memory.kmem.tcp.limit_in_bytes = 128M
|
||||
|
||||
# tuntap
|
||||
lxc.cgroup.devices.allow = c 10:200 rw
|
||||
lxc.cgroup2.devices.allow = c 10:200 rw
|
||||
# ppp
|
||||
lxc.cgroup.devices.allow = c 108:0 rwm
|
||||
lxc.cgroup2.devices.allow = c 108:0 rwm
|
||||
|
||||
${netConfig ctName containers.${ctName}.physicalInterfaces}
|
||||
'';
|
||||
};
|
||||
}) {
|
||||
"lxc/common.conf".source = "${pkgs.lxc}/share/lxc/config/common.conf";
|
||||
} (builtins.attrNames containers);
|
||||
|
||||
# Systemd service template for LXC containers
|
||||
systemd.services."lxc@" = {
|
||||
|
@ -143,8 +248,6 @@ in
|
|||
Restart = "always";
|
||||
RestartSec = "1s";
|
||||
};
|
||||
# Prevent restart on host nixos-rebuild switch
|
||||
restartIfChanged = false;
|
||||
};
|
||||
|
||||
# Starts all the containers after boot
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
# Server network configuration
|
||||
{ config, lib, ... }:
|
||||
{ hostName, self, config, lib, pkgs, ... }:
|
||||
|
||||
let
|
||||
# LXC containers on this host
|
||||
|
@ -114,7 +114,5 @@ in
|
|||
networkConfig.Bridge = net;
|
||||
};
|
||||
}) {} ctNets;
|
||||
|
||||
wait-online.anyInterface = true;
|
||||
};
|
||||
}
|
||||
|
|
|
@ -1,12 +1,15 @@
|
|||
{ config, ... }:
|
||||
{ config, pkgs, ... }:
|
||||
|
||||
{
|
||||
# Use the systemd-boot EFI boot loader.
|
||||
boot.loader.systemd-boot.enable = true;
|
||||
boot.loader.efi.canTouchEfiVariables = true;
|
||||
boot.loader.grub.enable = true;
|
||||
boot.loader.grub.version = 2;
|
||||
boot.loader.grub.devices = [
|
||||
"/dev/disk/by-path/pci-0000:05:00.0-scsi-0:1:0:0"
|
||||
"/dev/disk/by-path/pci-0000:05:00.0-scsi-0:1:0:1"
|
||||
];
|
||||
|
||||
networking.hostName = "server1"; # Define your hostname.
|
||||
networking.hostId = "01010101";
|
||||
networking.hostId = "12345678";
|
||||
|
||||
boot.initrd.availableKernelModules = [ "uhci_hcd" "ehci_pci" "ata_piix" "hpsa" "usb_storage" "usbhid" "sd_mod" "sr_mod" ];
|
||||
boot.initrd.kernelModules = [ ];
|
||||
|
@ -44,8 +47,8 @@
|
|||
};
|
||||
|
||||
fileSystems."/boot" =
|
||||
{ device = "/dev/disk/by-label/ESP";
|
||||
fsType = "vfat";
|
||||
{ device = "/dev/disk/by-uuid/23f17e88-ab7e-4dcc-a119-2ed1b9c2c91d";
|
||||
fsType = "ext2";
|
||||
};
|
||||
|
||||
swapDevices = [ ];
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
{ ... }:
|
||||
{ pkgs, ... }:
|
||||
|
||||
{
|
||||
boot.initrd.availableKernelModules = [ "uhci_hcd" "ehci_pci" "ahci" "usbhid" "sd_mod" "sr_mod" ];
|
||||
|
@ -39,6 +39,7 @@
|
|||
};
|
||||
|
||||
boot.loader.grub.enable = true;
|
||||
boot.loader.grub.version = 2;
|
||||
boot.loader.grub.device = "/dev/sda";
|
||||
|
||||
networking.hostName = "server2"; # Define your hostname.
|
||||
|
|
|
@ -1,38 +1,31 @@
|
|||
{ self, pkgs, hostName }:
|
||||
{ self, pkgs, hostName, config, hostConfig, ... }:
|
||||
with pkgs;
|
||||
with lib;
|
||||
let
|
||||
inherit (self.lib) config;
|
||||
hostConfig = config.site.hosts.${hostName};
|
||||
|
||||
ports = self.lib.getOpenwrtPorts hostConfig.model;
|
||||
|
||||
uciDeleteAll = key: ''
|
||||
while uci -q delete ${key}[-1]; do :; done
|
||||
'';
|
||||
|
||||
# hostBridgedNets =
|
||||
# self.lib.unique (
|
||||
# builtins.concatMap ({ ssids, ... }:
|
||||
# map ({ net, ... }:
|
||||
# net
|
||||
# ) (builtins.attrValues ssids)
|
||||
# ) (builtins.attrValues hostConfig.wifi)
|
||||
# );
|
||||
|
||||
openwrtModel = self.lib.getOpenwrtModel hostConfig.model;
|
||||
|
||||
hasSwitch =
|
||||
if hostConfig.model == "ubnt_unifiac-mesh"
|
||||
if hostConfig.model == "unifiac-mesh"
|
||||
# ours don't come with a switch.
|
||||
then false
|
||||
else
|
||||
openwrtModel ? ports
|
||||
&&
|
||||
any ({ switch ? null, ... }: switch != null)
|
||||
(builtins.attrValues openwrtModel.ports);
|
||||
hasDSA = (
|
||||
all ({ switch ? null, ... }:
|
||||
switch == null
|
||||
) (builtins.attrValues openwrtModel.ports or {})
|
||||
&&
|
||||
any ({ port ? null, interface ? null, ... }:
|
||||
port != null &&
|
||||
interface != null &&
|
||||
port == interface
|
||||
) (builtins.attrValues openwrtModel.ports or {})
|
||||
) || hostConfig.model == "ubnt_unifi-usg";
|
||||
|
||||
portsDoc =
|
||||
let
|
||||
|
@ -42,7 +35,7 @@ let
|
|||
then port.index
|
||||
else if port ? interface
|
||||
then port.interface
|
||||
else "How to identify port ${generators.toPretty {} port}?";
|
||||
else "How to identify port ${lib.generators.toPretty {} port}?";
|
||||
in result // {
|
||||
"${key}" = port;
|
||||
}
|
||||
|
@ -54,7 +47,7 @@ let
|
|||
then portByIndex.${index}.port
|
||||
else if portByIndex.${index} ? interface
|
||||
then portByIndex.${index}.interface
|
||||
else throw "${hostName}: What is port ${generators.toPretty {} portByIndex.${index}.port}?"
|
||||
else throw "${hostName}: What is port ${lib.generators.toPretty {} portByIndex.${index}.port}?"
|
||||
}"
|
||||
) (
|
||||
builtins.sort builtins.lessThan (
|
||||
|
@ -112,20 +105,6 @@ let
|
|||
)
|
||||
);
|
||||
|
||||
dsaPorts = net:
|
||||
unique (
|
||||
concatMap ({ ports, ... }: ports) (
|
||||
builtins.filter ({ nets, ... }: builtins.elem net nets)
|
||||
(builtins.attrValues hostConfig.links)
|
||||
));
|
||||
|
||||
dsaPortType = net: port:
|
||||
if any ({ ports, trunk, ... }: trunk && builtins.elem port ports) (
|
||||
builtins.attrValues hostConfig.links
|
||||
) || hostConfig.links.${net}.trunk or true
|
||||
then "t"
|
||||
else "u*";
|
||||
|
||||
networkInterfaces = net:
|
||||
let
|
||||
inherit (config.site.net.${net}) vlan;
|
||||
|
@ -148,7 +127,7 @@ let
|
|||
else []
|
||||
) (builtins.attrValues openwrtModel.ports)
|
||||
++
|
||||
optionals (hostConfig.interfaces ? ${port} && vlan != null) [ "${port}.${toString vlan}" ]
|
||||
lib.optionals (hostConfig.interfaces ? ${port} && vlan != null) [ "${port}.${toString vlan}" ]
|
||||
) ports
|
||||
) (
|
||||
builtins.attrValues (
|
||||
|
@ -159,18 +138,19 @@ let
|
|||
)
|
||||
);
|
||||
|
||||
mgmtInterface =
|
||||
if hasDSA
|
||||
then "br0.${toString config.site.net.mgmt.vlan}"
|
||||
else
|
||||
let
|
||||
mgmtInterfaces = networkInterfaces "mgmt";
|
||||
in if builtins.length mgmtInterfaces == 1
|
||||
then builtins.head mgmtInterfaces
|
||||
else "br-mgmt";
|
||||
in ''
|
||||
#! ${pkgs.runtimeShell} -e
|
||||
|
||||
${if hostConfig.firstboot
|
||||
then ''
|
||||
ssh-keygen -R 192.168.1.1
|
||||
ssh root@192.168.1.1 \
|
||||
"ash -e -x" <<__SSH__
|
||||
'' else ''
|
||||
ssh root@${config.site.net.mgmt.hosts4.${hostName}} \
|
||||
"ash -e -x" <<__SSH__
|
||||
''}
|
||||
|
||||
in
|
||||
''
|
||||
# Set root password
|
||||
echo -e '${hostConfig.password}\n${hostConfig.password}' | passwd
|
||||
|
||||
|
@ -188,8 +168,8 @@ in
|
|||
uci set system.@system[0].log_ip=${config.site.net.mgmt.hosts4.logging}
|
||||
uci set system.@system[0].log_proto=udp
|
||||
|
||||
# Switch config
|
||||
${optionalString hasSwitch ''
|
||||
# Switch config
|
||||
# Ports ${portsDoc}
|
||||
${concatMapStrings (net: ''
|
||||
uci add network switch_vlan
|
||||
|
@ -198,42 +178,7 @@ in
|
|||
uci set network.@switch_vlan[-1].vlan='${toString config.site.net.${net}.vlan}'
|
||||
uci set network.@switch_vlan[-1].ports='${switchPortsConfig net}'
|
||||
uci set network.@switch_vlan[-1].comment='${net}'
|
||||
'') (
|
||||
sort (net1: net2:
|
||||
config.site.net.${net1}.vlan < config.site.net.${net2}.vlan
|
||||
) (
|
||||
unique (
|
||||
builtins.concatMap ({ nets, ... }: nets)
|
||||
(builtins.attrValues hostConfig.links)
|
||||
)
|
||||
)
|
||||
)}
|
||||
''}
|
||||
${optionalString hasDSA ''
|
||||
# DSA
|
||||
${uciDeleteAll "network.@device"}
|
||||
uci add network device
|
||||
uci set network.@device[-1].name='br0'
|
||||
uci set network.@device[-1].type='bridge'
|
||||
${concatMapStrings (port: ''
|
||||
uci add_list network.@device[-1].ports='${port}'
|
||||
'') (
|
||||
unique (
|
||||
builtins.concatMap ({ ports, ... }: ports)
|
||||
(builtins.attrValues hostConfig.links)
|
||||
)
|
||||
)}
|
||||
uci set network.br0='interface'
|
||||
uci set network.br0.proto='none'
|
||||
uci set network.br0.device='br0'
|
||||
|
||||
${concatMapStrings (net: ''
|
||||
uci add network bridge-vlan
|
||||
uci set network.@bridge-vlan[-1].device='br0'
|
||||
uci set network.@bridge-vlan[-1].vlan='${toString config.site.net.${net}.vlan}'
|
||||
${concatMapStrings (port: ''
|
||||
uci add_list network.@bridge-vlan[-1].ports='${port}:${dsaPortType net port}'
|
||||
'') (dsaPorts net)}
|
||||
'') (
|
||||
sort (net1: net2:
|
||||
config.site.net.${net1}.vlan < config.site.net.${net2}.vlan
|
||||
|
@ -248,18 +193,13 @@ in
|
|||
|
||||
# mgmt network
|
||||
uci set network.mgmt=interface
|
||||
${if hasDSA
|
||||
then ''
|
||||
uci set network.mgmt.device='br0.${toString config.site.net.mgmt.vlan}'
|
||||
'' else ''
|
||||
uci set network.mgmt.ifname='${
|
||||
if builtins.length (networkInterfaces "mgmt") > 0
|
||||
then concatStringsSep " " (networkInterfaces "mgmt")
|
||||
else throw "${hostName}: No interface for mgmt"
|
||||
}'
|
||||
''}
|
||||
uci set network.mgmt.ifname='${
|
||||
if builtins.length (networkInterfaces "mgmt") > 0
|
||||
then lib.concatStringsSep " " (networkInterfaces "mgmt")
|
||||
else throw "${hostName}: No interface for mgmt"
|
||||
}'
|
||||
uci set network.mgmt.proto=static
|
||||
${optionalString (hostConfig.interfaces.mgmt.type == "bridge") ''
|
||||
${lib.optionalString (hostConfig.interfaces.mgmt.type == "bridge") ''
|
||||
uci set network.mgmt.type=bridge
|
||||
''}
|
||||
uci set network.mgmt.ipaddr=${config.site.net.mgmt.hosts4.${hostName}}
|
||||
|
@ -274,7 +214,7 @@ in
|
|||
uci -q delete network.globals.ula_prefix || true
|
||||
# delete unused networks
|
||||
${concatMapStrings (net:
|
||||
optionalString (! hostConfig.interfaces ? ${net}) ''
|
||||
lib.optionalString (! hostConfig.interfaces ? ${net}) ''
|
||||
uci -q delete network.${net} || true
|
||||
''
|
||||
) ([ "lan" "wan" "wan6" ] ++ builtins.attrNames config.site.net)}
|
||||
|
@ -285,30 +225,22 @@ in
|
|||
iface = hostConfig.interfaces.${net};
|
||||
in optionalString (net != "mgmt" && builtins.elem iface.type ["bridge" "phys"]) ''
|
||||
uci set network.${net}=interface
|
||||
${optionalString (iface.type == "bridge") ''
|
||||
${lib.optionalString (iface.type == "bridge") ''
|
||||
uci set network.${net}.type=bridge
|
||||
uci add network device
|
||||
uci set network.@device[-1].name='${net}'
|
||||
uci set network.@device[-1].type='bridge'
|
||||
''}
|
||||
uci set network.${net}.proto=static
|
||||
${if hasDSA
|
||||
then ''
|
||||
uci set network.${net}.device='br0.${toString config.site.net.${net}.vlan}'
|
||||
'' else ''
|
||||
uci set network.${net}.ifname='${concatStringsSep " " (networkInterfaces net)}'
|
||||
''}
|
||||
${optionalString (config.site.net.${net}.mtu != null) ''
|
||||
uci set network.${net}.ifname='${concatStringsSep " " (networkInterfaces net)}'
|
||||
${lib.optionalString (config.site.net.${net}.mtu != null) ''
|
||||
uci set network.${net}.mtu=${toString config.site.net.${net}.mtu}
|
||||
''}
|
||||
|
||||
|
||||
${optionalString (config.site.net.${net}.hosts4 ? ${hostName}) ''
|
||||
${lib.optionalString (config.site.net.${net}.hosts4 ? ${hostName}) ''
|
||||
# address in net
|
||||
uci set network.${net}.ipaddr=${config.site.net.${net}.hosts4.${hostName}}
|
||||
uci set network.${net}.netmask=${self.lib.netmasks.${toString config.site.net.${net}.subnet4Len}}
|
||||
''}
|
||||
${concatMapStrings (hosts6: optionalString (hosts6 ? ${hostName}) ''
|
||||
${lib.concatMapStrings (hosts6: lib.optionalString (hosts6 ? ${hostName}) ''
|
||||
uci set network.${net}.ip6addr=${hosts6.${hostName}}/64
|
||||
'') (builtins.attrValues config.site.net.${net}.hosts6)}
|
||||
'') (builtins.attrNames hostConfig.interfaces)
|
||||
|
@ -323,13 +255,14 @@ in
|
|||
uci set network.${name}.proto=vxlan6
|
||||
uci set network.${name}.peer6addr='${iface.vxlan.peer}'
|
||||
uci set network.${name}.port=4789
|
||||
uci set network.${name}.mtu=1600
|
||||
uci set network.${name}.rxcsum=0
|
||||
uci set network.${name}.txcsum=0
|
||||
uci set network.${name}.delegate=0
|
||||
|
||||
'') (builtins.attrNames hostConfig.interfaces)
|
||||
}
|
||||
|
||||
${uciDeleteAll "wireless.radio"}
|
||||
uci -q delete wireless.default_radio0 || true
|
||||
uci -q delete wireless.default_radio1 || true
|
||||
${concatStrings (imap0 (index: path:
|
||||
|
@ -342,7 +275,6 @@ in
|
|||
uci set wireless.radio${toString index}=wifi-device
|
||||
uci set wireless.radio${toString index}.type=mac80211
|
||||
uci set wireless.radio${toString index}.country=DE
|
||||
uci set wireless.radio${toString index}.band=${radioConfig.band}
|
||||
uci set wireless.radio${toString index}.channel=${toString radioConfig.channel}
|
||||
uci set wireless.radio${toString index}.path=${path}
|
||||
uci set wireless.radio${toString index}.htmode=${radioConfig.htmode}
|
||||
|
@ -352,118 +284,34 @@ in
|
|||
${concatMapStrings (ssid:
|
||||
let
|
||||
ssidConfig = radioConfig.ssids.${ssid};
|
||||
netConfig = config.site.net.${ssidConfig.net};
|
||||
|
||||
# mapping our option to openwrt/hostapd setting
|
||||
encryption = {
|
||||
none = "none";
|
||||
owe = "owe";
|
||||
wpa2 = "psk2";
|
||||
wpa3 = "sae-mixed";
|
||||
}.${ssidConfig.encryption};
|
||||
|
||||
ifname =
|
||||
if ssidConfig.ifname != null
|
||||
then ssidConfig.ifname
|
||||
else "${ifPrefix}-${ssidConfig.net}";
|
||||
|
||||
pad = len: prefix: s:
|
||||
if builtins.stringLength s < len
|
||||
then pad len prefix "${prefix}${s}"
|
||||
else s;
|
||||
|
||||
in ''
|
||||
uci add wireless wifi-iface
|
||||
uci set wireless.@wifi-iface[-1].ifname=${ifname}
|
||||
uci set wireless.@wifi-iface[-1].ifname=${ifPrefix}-${ssidConfig.net}
|
||||
uci set wireless.@wifi-iface[-1].device=radio${toString index}
|
||||
uci set wireless.@wifi-iface[-1].ssid='${ssid}'
|
||||
uci set wireless.@wifi-iface[-1].mode=${ssidConfig.mode}
|
||||
uci set wireless.@wifi-iface[-1].network=${ssidConfig.net}
|
||||
uci set wireless.@wifi-iface[-1].mcast_rate=18000
|
||||
uci set wireless.@wifi-iface[-1].hidden=${if ssidConfig.hidden then "1" else "0"}
|
||||
uci set wireless.@wifi-iface[-1].encryption='${encryption}'
|
||||
${if (ssidConfig.psk != null)
|
||||
then ''
|
||||
uci set wireless.@wifi-iface[-1].encryption=psk2
|
||||
uci set wireless.@wifi-iface[-1].key='${ssidConfig.psk}'
|
||||
''
|
||||
else ''
|
||||
uci set wireless.@wifi-iface[-1].encryption=none
|
||||
uci -q delete wireless.@wifi-iface[-1].key || true
|
||||
''}
|
||||
${lib.optionalString (!ssidConfig.disassocLowAck) ''
|
||||
uci set wireless.@wifi-iface[-1].disassoc_low_ack='0'
|
||||
''}
|
||||
|
||||
${lib.optionalString (netConfig.wifi.ieee80211rKey != null) ''
|
||||
# for usteerd
|
||||
# see https://www.libe.net/en-wlan-roaming#client-steering
|
||||
# https://openwrt.org/docs/guide-user/network/wifi/usteer#configure_80211k_and_80211v_on_all_ap-nodes
|
||||
uci set wireless.@wifi-iface[-1].bss_transition=1
|
||||
uci set wireless.@wifi-iface[-1].wnm_sleep_mode=1
|
||||
uci set wireless.@wifi-iface[-1].time_advertisement=2
|
||||
uci set wireless.@wifi-iface[-1].time_zone=GMT0
|
||||
uci set wireless.@wifi-iface[-1].ieee80211k=1
|
||||
uci set wireless.@wifi-iface[-1].rrm_neighbor_report=1
|
||||
uci set wireless.@wifi-iface[-1].rrm_beacon_report=1
|
||||
|
||||
|
||||
# breaks Apple devices connecting to wifi when used together with wpa2/wpa3 mixed mode (sae-mixed)
|
||||
# uci set wireless.@wifi-iface[-1].ieee80211r=1
|
||||
# when unset derived from interface MAC
|
||||
uci set wireless.@wifi-iface[-1].nasid=${pad 12 "0" (toString ((lib.toInt (lib.removePrefix "ap" hostName)) * 65536 + index))}
|
||||
# when unset derived from the first 4 chars of the md5 hashed SSID
|
||||
uci set wireless.@wifi-iface[-1].mobility_domain=${pad 4 "0" (lib.toHexString (49920 + netConfig.vlan))}
|
||||
|
||||
# https://github.com/openwrt/openwrt/issues/7907
|
||||
# https://github.com/openwrt/openwrt/commit/2984a0420649733662ff95b0aff720b8c2c19f8a
|
||||
uci set wireless.@wifi-iface[-1].ft_over_ds=0
|
||||
# as recommend in 7907 and seems to fairly often trigger while testing
|
||||
uci set wireless.@wifi-iface[-1].reassociation_deadline=20000
|
||||
|
||||
# might be unused if ft_over_ds is not used
|
||||
uci set wireless.@wifi-iface[-1].ft_bridge=${mgmtInterface}
|
||||
|
||||
# otherwise the r0kh/r1kh options below are not applied
|
||||
uci set wireless.@wifi-iface[-1].ft_psk_generate_local=0
|
||||
|
||||
# do not just rely on the monility domain for increased security
|
||||
# https://forum.openwrt.org/t/802-11r-fast-transition-how-to-understand-that-ft-works/110920/81
|
||||
uci set wireless.@wifi-iface[-1].r0kh=ff:ff:ff:ff:ff:ff,\*,${netConfig.wifi.ieee80211rKey}
|
||||
uci set wireless.@wifi-iface[-1].r1kh=00:00:00:00:00:00,00:00:00:00:00:00,${netConfig.wifi.ieee80211rKey}
|
||||
uci set wireless.@wifi-iface[-1].pmk_r1_push=1
|
||||
''}
|
||||
''
|
||||
) (builtins.attrNames radioConfig.ssids)}
|
||||
'') (builtins.attrNames hostConfig.wifi))}
|
||||
|
||||
uci set usteer.@usteer[0].network=mgmt
|
||||
uci set usteer.@usteer[0].load_kick_enabled=1
|
||||
uci set usteer.@usteer[0].load_kick_threshold=67
|
||||
uci set usteer.@usteer[0].signal_diff_threshold=15
|
||||
uci set usteer.@usteer[0].load_balancing_threshold=8
|
||||
uci set usteer.@usteer[0].band_steering_threshold=16
|
||||
|
||||
uci commit
|
||||
|
||||
# Add hotfixes for MTU settings
|
||||
cat >/etc/hotplug.d/iface/99-mtu <<__MTU__
|
||||
#!/bin/sh
|
||||
|
||||
${concatMapStrings (net:
|
||||
optionalString (config.site.net ? ${net} &&
|
||||
config.site.net.${net}.mtu != null) ''
|
||||
if [ "\\\$ACTION" = ifup -a "\\\$INTERFACE" = ${net} ]; then
|
||||
ip link set \\\$DEVICE mtu ${toString config.site.net.${net}.mtu}
|
||||
fi
|
||||
'') (builtins.attrNames hostConfig.interfaces)
|
||||
}
|
||||
__MTU__
|
||||
|
||||
${optionalString hostConfig.wifiOnLink.enable ''
|
||||
${lib.optionalString hostConfig.wifiOnLink.enable ''
|
||||
# Cronjob that makes sure WiFi is only visible when server with all
|
||||
# the gateways is reachable
|
||||
cat >/etc/crontabs/root <<__CRON__
|
||||
* * * * * /usr/sbin/wifi-on-link.sh
|
||||
* * * * * /usr/sbin/usteer-info.sh
|
||||
#* * * * * /usr/sbin/wifi-on-link.sh
|
||||
__CRON__
|
||||
cat >/usr/sbin/wifi-on-link.sh <<__SH__
|
||||
#!/bin/sh
|
||||
|
@ -493,36 +341,16 @@ in
|
|||
__SH__
|
||||
chmod a+rx /usr/sbin/wifi-on-link.sh
|
||||
/etc/init.d/cron restart
|
||||
|
||||
cat > /etc/collectd.conf <<COLLECTD
|
||||
Hostname "${hostName}"
|
||||
FQDNLookup false
|
||||
Interval 10
|
||||
|
||||
BaseDir "/var/run/collectd"
|
||||
Include "/etc/collectd/conf.d"
|
||||
PIDFile "/var/run/collectd.pid"
|
||||
PluginDir "/usr/lib/collectd"
|
||||
TypesDB "/usr/share/collectd/types.db"
|
||||
|
||||
LoadPlugin cpu
|
||||
LoadPlugin load
|
||||
LoadPlugin interface
|
||||
LoadPlugin iwinfo
|
||||
LoadPlugin network
|
||||
LoadPlugin exec
|
||||
<Plugin network>
|
||||
Server "${config.site.net.serv.hosts6.dn42.stats}" "25826"
|
||||
</Plugin>
|
||||
<Plugin exec>
|
||||
Exec "nobody" "/usr/bin/usteer-stats.sh"
|
||||
</Plugin>
|
||||
COLLECTD
|
||||
''}
|
||||
chmod +x /usr/bin/usteer-stats.sh /usr/sbin/usteer-info.sh
|
||||
|
||||
for svc in dnsmasq uhttpd ; do
|
||||
rm -f /etc/rc.d/*\$svc
|
||||
/etc/init.d/\$svc stop || true
|
||||
done
|
||||
|
||||
${lib.optionalString hostConfig.firstboot "reboot"}
|
||||
__SSH__
|
||||
|
||||
echo "Base configuration done \\o/"
|
||||
echo "Later run: ap_install_collectd.sh ${config.site.net.mgmt.hosts4.${hostName}}"
|
||||
''
|
|
@ -1,20 +1,16 @@
|
|||
{ self, nixpkgs, system, openwrt-imagebuilder }:
|
||||
{ self, nixpkgs, system }:
|
||||
|
||||
let
|
||||
inherit (self.lib) config;
|
||||
|
||||
pkgs = nixpkgs.legacyPackages.${system};
|
||||
inherit (pkgs) lib;
|
||||
|
||||
export-openwrt-models = pkgs.writeText "openwrt-models.nix" (
|
||||
lib.generators.toPretty {} self.lib.openwrtModels
|
||||
nixpkgs.lib.generators.toPretty {} self.lib.openwrtModels
|
||||
);
|
||||
export-config = pkgs.writeText "config.nix" (
|
||||
lib.generators.toPretty {} (
|
||||
lib.recursiveUpdate
|
||||
config
|
||||
{ site.dns.localZones = self.lib.dns.localZones; }
|
||||
));
|
||||
nixpkgs.lib.generators.toPretty {} config
|
||||
);
|
||||
|
||||
encrypt-secrets = pkgs.writeScriptBin "encrypt-secrets" ''
|
||||
#! ${pkgs.runtimeShell} -e
|
||||
|
@ -45,7 +41,7 @@ let
|
|||
'';
|
||||
|
||||
network-cypher-graphs = import ./network-cypher-graphs.nix { inherit config pkgs; };
|
||||
network-graphs = import ./network-graphs.nix { inherit config lib pkgs; };
|
||||
network-graphs = import ./network-graphs.nix { inherit config pkgs; };
|
||||
|
||||
mkRootfs = hostName:
|
||||
self.nixosConfigurations.${hostName}.config.system.build.toplevel;
|
||||
|
@ -55,20 +51,7 @@ let
|
|||
"${hostName}-rootfs" = mkRootfs hostName;
|
||||
}) {} (
|
||||
builtins.attrNames (
|
||||
lib.filterAttrs (_: { role, ... }: builtins.elem role ["server" "container"])
|
||||
config.site.hosts
|
||||
)
|
||||
);
|
||||
|
||||
mkLxcConfig = hostName:
|
||||
self.nixosConfigurations.${hostName}.config.system.build.lxcConfig;
|
||||
|
||||
lxc-configs =
|
||||
builtins.foldl' (rootfs: hostName: rootfs // {
|
||||
"${hostName}-lxc-config" = mkLxcConfig hostName;
|
||||
}) {} (
|
||||
builtins.attrNames (
|
||||
lib.filterAttrs (_: { role, ... }: role == "container")
|
||||
nixpkgs.lib.filterAttrs (_: { role, ... }: builtins.elem role ["server" "container"])
|
||||
config.site.hosts
|
||||
)
|
||||
);
|
||||
|
@ -76,33 +59,26 @@ let
|
|||
vm-packages =
|
||||
builtins.foldl' (rootfs: hostName: rootfs // {
|
||||
"${hostName}-vm" = self.nixosConfigurations.${hostName}.config.system.build.vm
|
||||
.overrideAttrs (_oa: {
|
||||
.overrideAttrs (oa: {
|
||||
meta.mainProgram = "run-${hostName}-vm";
|
||||
});
|
||||
}) {} (
|
||||
builtins.attrNames (
|
||||
lib.filterAttrs (_: { role, ... }: role == "server")
|
||||
nixpkgs.lib.filterAttrs (_: { role, ... }: role == "server")
|
||||
config.site.hosts
|
||||
)
|
||||
);
|
||||
|
||||
openwrt = import ./openwrt { inherit self nixpkgs system openwrt-imagebuilder; };
|
||||
|
||||
openwrt-packages = builtins.foldl' (images: hostName: images // {
|
||||
${hostName} = pkgs.writeScriptBin "${hostName}.sh" (
|
||||
openwrt.sshScript hostName
|
||||
);
|
||||
"${hostName}-image" = openwrt.buildImage hostName;
|
||||
}) {} (
|
||||
builtins.attrNames (
|
||||
lib.filterAttrs (_: { role, ... }:
|
||||
role == "ap"
|
||||
) config.site.hosts
|
||||
)
|
||||
);
|
||||
all-rootfs = with pkgs;
|
||||
runCommand "all-rootfs" {} ''
|
||||
mkdir -p $out
|
||||
${lib.concatMapStrings (pkg: ''
|
||||
ln -s ${pkg} $out/${pkg.name}
|
||||
'') (builtins.attrValues rootfs-packages)}
|
||||
'';
|
||||
|
||||
device-templates = import ./device-templates.nix {
|
||||
inherit self nixpkgs system openwrt;
|
||||
inherit self nixpkgs system;
|
||||
};
|
||||
|
||||
dns-slaves = import ./dns-slaves.nix {
|
||||
|
@ -117,25 +93,13 @@ let
|
|||
inherit self nixpkgs system;
|
||||
};
|
||||
|
||||
gateway-report = import ./gateway-report.nix {
|
||||
inherit self nixpkgs system;
|
||||
};
|
||||
|
||||
switch-report = import ./switch-report.nix {
|
||||
inherit self nixpkgs system;
|
||||
};
|
||||
|
||||
vlan-report = import ./vlan-report.nix {
|
||||
inherit self nixpkgs system;
|
||||
};
|
||||
|
||||
homepage = pkgs.callPackage ./homepage {
|
||||
inherit self;
|
||||
};
|
||||
in
|
||||
rootfs-packages // lxc-configs // vm-packages // device-templates // openwrt-packages // network-graphs // network-cypher-graphs // starlink // subnetplans // {
|
||||
inherit export-openwrt-models export-config dns-slaves
|
||||
rootfs-packages // vm-packages // device-templates // network-graphs // network-cypher-graphs // starlink // subnetplans // {
|
||||
inherit all-rootfs export-openwrt-models export-config dns-slaves
|
||||
encrypt-secrets decrypt-secrets switch-to-production
|
||||
homepage gateway-report switch-report vlan-report
|
||||
vlan-report
|
||||
;
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
{ self, nixpkgs, system, openwrt }:
|
||||
{ self, nixpkgs, system }:
|
||||
with nixpkgs.lib;
|
||||
let
|
||||
pkgs = nixpkgs.legacyPackages.${system};
|
||||
|
@ -11,13 +11,18 @@ let
|
|||
args = {
|
||||
inherit self hostName config hostConfig pkgs;
|
||||
};
|
||||
in import (./switches + "/${model}.nix") (
|
||||
args // import ./switches/shared.nix args
|
||||
)
|
||||
in {
|
||||
ap = import ./ap.nix args;
|
||||
switch = import (./switches + "/${model}.nix")
|
||||
(args //
|
||||
import ./switches/shared.nix args
|
||||
);
|
||||
}.${role}
|
||||
)
|
||||
) (
|
||||
filterAttrs (_: { role, model, ... }:
|
||||
role == "switch" && model != "dumb"
|
||||
role == "ap" ||
|
||||
(role == "switch" && model != "dumb")
|
||||
) config.site.hosts
|
||||
);
|
||||
|
||||
|
|
|
@ -15,12 +15,12 @@ let
|
|||
in
|
||||
|
||||
writeText "named.slave.conf" (
|
||||
lib.concatMapStringsSep "\n" ({ name, ... }: ''
|
||||
lib.concatMapStringsSep "\n" ({ name, ns, ... }: ''
|
||||
zone "${name}" IN {
|
||||
type slave;
|
||||
masters {${mastersStr} };
|
||||
file "/var/lib/bind/slave/${name}.zone";
|
||||
allow-notify { ${mastersStr} };
|
||||
allow-notify {${mastersStr} };
|
||||
allow-query { any; };
|
||||
};
|
||||
'') (
|
||||
|
|
|
@ -1,120 +0,0 @@
|
|||
{ self, nixpkgs, system }:
|
||||
with nixpkgs.legacyPackages.${system};
|
||||
let
|
||||
config = self.lib.config;
|
||||
|
||||
in
|
||||
writeText "gateway-report.md" ''
|
||||
# Gateway Report
|
||||
|
||||
${lib.concatMapStrings (net:
|
||||
let
|
||||
netConfig = config.site.net.${net};
|
||||
|
||||
routers4 = builtins.filter (hostName:
|
||||
config.site.hosts ? ${hostName} &&
|
||||
config.site.hosts.${hostName}.isRouter
|
||||
) (
|
||||
builtins.attrNames netConfig.hosts4
|
||||
);
|
||||
|
||||
routers6 = builtins.filter (hostName:
|
||||
config.site.hosts ? ${hostName} &&
|
||||
config.site.hosts.${hostName}.isRouter
|
||||
) (lib.unique (
|
||||
builtins.concatMap builtins.attrNames (builtins.attrValues netConfig.hosts6)
|
||||
));
|
||||
|
||||
upstreamAt = l: n:
|
||||
if n < builtins.length l
|
||||
then
|
||||
let
|
||||
hostName = builtins.elemAt l n;
|
||||
hostConfig = config.site.hosts.${hostName};
|
||||
providers =
|
||||
map ({ upstream, ... }: upstream.provider) (
|
||||
builtins.filter ({ upstream, ... }:
|
||||
upstream.provider or null != null
|
||||
) (builtins.attrValues hostConfig.interfaces)
|
||||
);
|
||||
in
|
||||
"${hostName}${
|
||||
lib.optionalString (providers != []) " (${lib.concatStringsSep ", " providers})"
|
||||
}"
|
||||
else "";
|
||||
|
||||
in
|
||||
lib.optionalString (net != "core" && (routers4 != [] || routers6 != [])) ''
|
||||
## Network ${net}
|
||||
|
||||
${lib.optionalString (routers4 != []) ''
|
||||
### IPv4 `${netConfig.subnet4}`
|
||||
|
||||
| Address | Name | Primary Uplink | Fallback Uplink |
|
||||
|-|-|-|-|
|
||||
${lib.concatMapStrings (hostName:
|
||||
let
|
||||
hostConfig = config.site.hosts.${hostName};
|
||||
isDhcpDefault = hostName == netConfig.dhcp.router or null;
|
||||
emphasize = s:
|
||||
if isDhcpDefault
|
||||
then "**${s}**"
|
||||
else s;
|
||||
upstream4a = upstreamAt hostConfig.ospf.allowedUpstreams 0;
|
||||
upstream4b = upstreamAt hostConfig.ospf.allowedUpstreams 1;
|
||||
in ''
|
||||
|${
|
||||
emphasize netConfig.hosts4.${hostName}
|
||||
}|${
|
||||
emphasize hostName
|
||||
}|${
|
||||
upstream4a
|
||||
}|${
|
||||
upstream4b
|
||||
}|
|
||||
''
|
||||
) (lib.naturalSort routers4)}
|
||||
''}
|
||||
|
||||
${lib.optionalString (routers6 != {}) ''
|
||||
### IPv6 ${lib.concatStringsSep " " (
|
||||
map (s: "`${s}`") (
|
||||
builtins.attrValues netConfig.subnets6
|
||||
)
|
||||
)}
|
||||
|
||||
| Address | Name | Primary Uplink | Fallback Uplink |
|
||||
|-|-|-|-|
|
||||
${lib.concatMapStrings (hostName:
|
||||
let
|
||||
hostConfig = config.site.hosts.${hostName};
|
||||
isIpv6Router = hostName == netConfig.ipv6Router;
|
||||
emphasize = s:
|
||||
if isIpv6Router
|
||||
then "**${s}**"
|
||||
else s;
|
||||
upstream6a = upstreamAt hostConfig.ospf.allowedUpstreams6 0;
|
||||
upstream6b = upstreamAt hostConfig.ospf.allowedUpstreams6 1;
|
||||
in ''
|
||||
|${
|
||||
emphasize (
|
||||
lib.concatMapStringsSep " " (ctx:
|
||||
"`${netConfig.hosts6.${ctx}.${hostName}}`"
|
||||
) (builtins.filter (ctx:
|
||||
netConfig.hosts6.${ctx} ? ${hostName}
|
||||
) (builtins.attrNames netConfig.hosts6))
|
||||
)
|
||||
}|${
|
||||
emphasize hostName
|
||||
}|${
|
||||
upstream6a
|
||||
}|${
|
||||
upstream6b
|
||||
}|
|
||||
''
|
||||
) (lib.naturalSort routers6)}
|
||||
''}
|
||||
|
||||
''
|
||||
) (lib.naturalSort (builtins.attrNames config.site.net))}
|
||||
''
|
|
@ -1,74 +0,0 @@
|
|||
{ self
|
||||
, system
|
||||
, substituteAll
|
||||
, stdenv
|
||||
, pandoc
|
||||
, bat
|
||||
, ansi2html
|
||||
}:
|
||||
|
||||
let
|
||||
|
||||
inherit (self.packages.${system})
|
||||
export-config
|
||||
gateway-report network-graphs
|
||||
subnetplans switch-report vlan-report;
|
||||
|
||||
in
|
||||
stdenv.mkDerivation {
|
||||
pname = "zentralwerk-network-homepage";
|
||||
version = self.lastModifiedDate;
|
||||
|
||||
src = ./src;
|
||||
|
||||
nativeBuildInputs = [
|
||||
pandoc
|
||||
bat
|
||||
ansi2html
|
||||
];
|
||||
buildPhase = ''
|
||||
pandoc -t html ${../../../doc/hello.md} > index.html
|
||||
cat ${./linked-data.html} >> index.html
|
||||
pandoc -t html ${../../../doc/vpn.md} > vpn.html
|
||||
pandoc -t html ${gateway-report} > gateway-report.html
|
||||
cat ${../../../cabling.md} ${switch-report} >> switch-report.md
|
||||
pandoc -t html switch-report.md > switch-report.html
|
||||
pandoc -t html ${vlan-report} > vlan-report.html
|
||||
|
||||
echo '<pre>' > config.html
|
||||
bat --color=always --theme=GitHub -p ${export-config} | \
|
||||
ansi2html -il >> config.html
|
||||
echo '</pre>' >> config.html
|
||||
|
||||
ln -s ${substituteAll {
|
||||
src = ./figure.html;
|
||||
img = "physical.png";
|
||||
caption = "Physikalische Netzwerkstruktur";
|
||||
}} physical.html
|
||||
ln -s ${substituteAll {
|
||||
src = ./figure.html;
|
||||
img = "logical.png";
|
||||
caption = "Logische Netzwerkstruktur";
|
||||
}} logical.html
|
||||
|
||||
ln -s ${subnetplans}/share/doc/zentralwerk/* .
|
||||
for F in *.html; do
|
||||
cat ${./header.html} "$F" ${./footer.html} > "$F.new"
|
||||
rm "$F"
|
||||
mv "$F.new" "$F"
|
||||
done
|
||||
'';
|
||||
|
||||
installPhase = ''
|
||||
DIR=$out/share/doc/zentralwerk/www
|
||||
mkdir -p $DIR
|
||||
|
||||
ln -s ${network-graphs}/share/doc/zentralwerk/* $DIR/
|
||||
ln -s ${../../../doc/core.png} $DIR/core.png
|
||||
ln -s ${./security.txt} $DIR/security.txt
|
||||
cp *.{html,css,png,svg} $DIR/
|
||||
|
||||
mkdir -p $out/nix-support
|
||||
echo doc homepage $DIR index.html >> $out/nix-support/hydra-build-products
|
||||
'';
|
||||
}
|
|
@ -1,4 +0,0 @@
|
|||
<figure>
|
||||
<img src="@img@" alt="@caption@">
|
||||
<figcaption>@caption@</figcaption>
|
||||
</figure>
|
|
@ -1,14 +0,0 @@
|
|||
</main>
|
||||
|
||||
<footer>
|
||||
<p>
|
||||
<a href="https://gitea.c3d2.de/zentralwerk/network">git</a>
|
||||
vom
|
||||
<a href="https://www.c3d2.de/">C3D2</a>
|
||||
im
|
||||
<a href="https://www.zentralwerk.de/">Zentralwerk</a>
|
||||
</p>
|
||||
</footer>
|
||||
|
||||
</body>
|
||||
</html>
|
|
@ -1,35 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="de" xml:lang="de">
|
||||
<head>
|
||||
<title>zentralwerk.org</title>
|
||||
<meta charset="utf-8"/>
|
||||
<meta http-equiv="content-type" content="text/html; charset=UTF-8"/>
|
||||
<meta name="robots" content="index,follow"/>
|
||||
<meta name="description" content="zentralwerk-network"/>
|
||||
<meta name="keywords" content="c3d2 ccc zentralwerk network"/>
|
||||
<meta name="generator" content="zentralwerk-network"/>
|
||||
<meta name="language" content="de"/>
|
||||
<meta name="author" content="Astro"/>
|
||||
<link rel="icon" type="image/png" href="zw.png"/>
|
||||
<link rel="stylesheet" title="Default" type="text/css" href="style.css"/>
|
||||
</head>
|
||||
<body>
|
||||
<header>
|
||||
<h1>zentralwerk-network</h1>
|
||||
<nav>
|
||||
<ul>
|
||||
<li><a href=".">Willkommen</a></li>
|
||||
<li><a href="gateway-report.html">Router</a></li>
|
||||
<li><a href="subnetplan4.html">IPv4</a></li>
|
||||
<li><a href="subnetplan6.html">IPv6</a></li>
|
||||
<li><a href="vlan-report.html">VLAN</a></li>
|
||||
<li><a href="logical.html">Logisch</a></li>
|
||||
<li><a href="physical.html">Physisch</a></li>
|
||||
<li><a href="switch-report.html">Ports</a></li>
|
||||
<li><a href="vpn.html">VPN</a></li>
|
||||
<li><a href="config.html">Config</a></li>
|
||||
</ul>
|
||||
</nav>
|
||||
</header>
|
||||
|
||||
<main>
|
|
@ -1,30 +0,0 @@
|
|||
<script type="application/ld+json">
|
||||
{
|
||||
"@context": "https://schema.org",
|
||||
"@type": "Project",
|
||||
"name": "zentralwerk-network",
|
||||
"image": "https://www.zentralwerk.org/zw.png",
|
||||
"logo": "https://www.zentralwerk.org/zw.png",
|
||||
"@id": "https://www.zentralwerk.org/",
|
||||
"url": "https://www.zentralwerk.org/",
|
||||
"sameAs": "https://gitea.c3d2.de/zentralwerk/network",
|
||||
"address": {
|
||||
"@type": "PostalAddress",
|
||||
"streetAddress": "Riesaer Str. 32",
|
||||
"addressLocality": "Dresden",
|
||||
"postalCode": "01127",
|
||||
"addressCountry": "DE"
|
||||
},
|
||||
"geo": {
|
||||
"@type": "GeoCoordinates",
|
||||
"latitude": 51.0811716,
|
||||
"longitude": 13.7285633
|
||||
},
|
||||
"parentOrganization": {
|
||||
"@type": "NGO",
|
||||
"name": "Chaos Computer Club Dresden",
|
||||
"@id": "https://www.c3d2.de/whois.html",
|
||||
"url": "https://www.c3d2.de/whois.html"
|
||||
}
|
||||
}
|
||||
</script>
|
|
@ -1,3 +0,0 @@
|
|||
Contact: mailto:astro@spaceboyz.net
|
||||
Preferred-Languages: en, de
|
||||
Hiring: https://www.c3d2.de/space.html
|
|
@ -1,61 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
width="1920"
|
||||
height="1080"
|
||||
viewBox="0 0 507.99999 285.75"
|
||||
version="1.1"
|
||||
id="svg5"
|
||||
inkscape:version="1.2.1 (9c6d41e410, 2022-07-14)"
|
||||
sodipodi:docname="background.svg"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg">
|
||||
<sodipodi:namedview
|
||||
id="namedview7"
|
||||
pagecolor="#af1f00"
|
||||
bordercolor="#cccccc"
|
||||
borderopacity="1"
|
||||
inkscape:showpageshadow="0"
|
||||
inkscape:pageopacity="1"
|
||||
inkscape:pagecheckerboard="0"
|
||||
inkscape:deskcolor="#d1d1d1"
|
||||
inkscape:document-units="mm"
|
||||
showgrid="false"
|
||||
inkscape:zoom="0.23657384"
|
||||
inkscape:cx="1470.9995"
|
||||
inkscape:cy="762.97531"
|
||||
inkscape:window-width="1916"
|
||||
inkscape:window-height="1057"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="0"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="layer1" />
|
||||
<defs
|
||||
id="defs2" />
|
||||
<g
|
||||
inkscape:label="Layer 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1">
|
||||
<path
|
||||
sodipodi:type="star"
|
||||
style="opacity:0.349515;fill:#ffff00;fill-opacity:1;fill-rule:evenodd;stroke:#ffff00;stroke-width:1.21295;stroke-linecap:round;stroke-dasharray:none;stroke-opacity:1"
|
||||
id="path163"
|
||||
inkscape:flatsided="false"
|
||||
sodipodi:sides="48"
|
||||
sodipodi:cx="266.05429"
|
||||
sodipodi:cy="144.57217"
|
||||
sodipodi:r1="179.29391"
|
||||
sodipodi:r2="44.823479"
|
||||
sodipodi:arg1="0.36233915"
|
||||
sodipodi:arg2="0.427789"
|
||||
inkscape:rounded="-2.4286129e-17"
|
||||
inkscape:randomized="0"
|
||||
d="m 433.7067,208.12514 -126.86819,-44.95749 117.13857,66.29681 -119.91468,-61.13249 107.48296,81.01929 -110.9094,-76.26151 95.98829,94.3555 -100.00643,-90.08565 82.85123,106.07726 -87.39232,-102.36842 68.29656,115.98401 -73.28291,-112.89964 52.57333,123.90625 -57.9196,-121.4991 35.95054,129.7084 -41.56528,-128.01968 18.71264,133.29122 -24.49976,-132.34982 1.15456,134.59339 -7.01505,-134.41541 -16.42328,133.59262 10.5897,-134.18111 -33.72012,130.30605 28.01326,-131.65094 -50.43999,124.7899 44.95749,-126.86818 -66.29682,117.13856 61.1325,-119.91468 -81.01929,107.48296 76.2615,-110.9094 -94.3555,95.98829 90.08566,-100.00643 -106.07726,82.85123 102.36842,-87.39232 -115.98401,68.29657 112.89963,-73.28291 -123.90624,52.57332 121.4991,-57.9196 L 94.358103,196.21253 222.37779,154.64726 89.086568,173.35989 221.43638,148.86013 86.843,150.01469 221.2584,142.99964 87.665786,126.57636 221.8469,137.16606 91.54085,103.44594 223.19179,131.4592 98.401887,81.01921 225.27007,125.9767 108.1315,59.679885 228.04618,120.81238 120.56322,39.79309 231.47262,116.0546 135.48433,21.699094 235.49076,111.78475 152.63953,5.7074906 240.03185,108.07591 171.73529,-7.9080994 245.0182,104.99153 192.44487,-18.91471 250.36448,102.58439 214.41393,-27.124014 255.97921,100.89567 237.26657,-32.395549 261.76633,99.954267 260.61178,-34.639117 267.62682,99.776288 284.0501,-33.81633 273.4604,100.36478 307.18052,-29.941267 279.16727,101.70967 329.60725,-23.08023 284.64976,103.78795 350.94658,-13.350614 289.81408,106.56406 370.83338,-0.91889557 294.57187,109.9905 388.92737,14.002216 298.84171,114.00865 404.91897,31.157415 302.55055,118.54974 418.53456,50.253172 305.63493,123.53608 429.54117,70.962754 308.04207,128.88236 437.75048,92.931813 309.73079,134.49709 443.02201,115.78445 310.6722,140.28421 445.26558,139.12966 310.85018,146.1447 444.4428,162.56799 310.26169,151.97829 440.56773,185.6984 308.91679,157.68515 Z"
|
||||
inkscape:transform-center-x="-1.5557927e-05"
|
||||
inkscape:transform-center-y="1.8543187e-05"
|
||||
transform="matrix(3.4901017,0,0,3.4901017,-674.55653,24.83979)" />
|
||||
</g>
|
||||
</svg>
|
Before Width: | Height: | Size: 3.8 KiB |
|
@ -1,108 +0,0 @@
|
|||
body {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
background: #AF1F00 url('background.svg') fixed no-repeat center/100%;
|
||||
color: #FFEF00;
|
||||
font-family: sans-serif;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-between;
|
||||
min-height: 100vh;
|
||||
}
|
||||
|
||||
a {
|
||||
text-decoration: none;
|
||||
font-weight: bold;
|
||||
color: #CF3F1F;
|
||||
}
|
||||
|
||||
a:visited {
|
||||
color: #AF1F00;
|
||||
}
|
||||
|
||||
header, footer {
|
||||
background-color: #FFEF00;
|
||||
color: #AF1F00;
|
||||
text-align: center;
|
||||
}
|
||||
header {
|
||||
margin: 0 0 3rem;
|
||||
border-bottom: 1rem solid #DFCF00;
|
||||
}
|
||||
header h1 {
|
||||
margin: 0.5rem 0;
|
||||
padding: 0rem 2rem;
|
||||
font-family: serif;
|
||||
}
|
||||
footer {
|
||||
margin: 3rem 0 0;
|
||||
}
|
||||
footer p {
|
||||
margin: 0.3rem 0;
|
||||
}
|
||||
nav ul {
|
||||
margin: 0.3rem 0;
|
||||
padding: 0;
|
||||
list-style-type: none;
|
||||
}
|
||||
nav ul li {
|
||||
display: inline-block;
|
||||
margin: 0 2rem;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
main {
|
||||
min-width: 50vh;
|
||||
max-width: 60rem;
|
||||
margin: 1rem auto;
|
||||
padding: 1.5rem 4rem;
|
||||
background: #FFF;
|
||||
color: #111;
|
||||
border-top: 1rem solid #EFDF00;
|
||||
border-left: 1rem solid #EFDF00;
|
||||
border-right: 1.5rem solid #DFCF00;
|
||||
border-bottom: 1.5rem solid #DFCF00;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
main figure {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
main figure img {
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
main table {
|
||||
font-size: 75%;
|
||||
border-collapse: collapse;
|
||||
border: 1px solid #555;
|
||||
}
|
||||
main table th {
|
||||
background-color: #555;
|
||||
color: #FFF;
|
||||
padding: 0.4rem;
|
||||
}
|
||||
main table td {
|
||||
border: 1px solid #555;
|
||||
padding: 0.2rem 0.4rem;
|
||||
}
|
||||
|
||||
main h3 code {
|
||||
margin-left: 0.6rem;
|
||||
}
|
||||
|
||||
.sourceCode .kw {
|
||||
font-weight: bold;
|
||||
color: #1F2F6F;
|
||||
}
|
||||
.sourceCode .dt {
|
||||
font-weight: bold;
|
||||
color: #1F5F2F;
|
||||
}
|
||||
.sourceCode .ot {
|
||||
color: #666;
|
||||
}
|
||||
.sourceCode .st {
|
||||
color: #007F00;
|
||||
}
|
Binary file not shown.
Before Width: | Height: | Size: 21 KiB |
|
@ -138,7 +138,7 @@ in rec {
|
|||
logical-cypher-graph =
|
||||
let
|
||||
containers =
|
||||
lib.filterAttrs (_: { role, ... }:
|
||||
lib.filterAttrs (_: { isRouter, role, ... }:
|
||||
role == "container"
|
||||
) config.site.hosts;
|
||||
in
|
||||
|
|
|
@ -1,14 +1,12 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
{ config, pkgs, ... }:
|
||||
let
|
||||
inherit (pkgs) lib runCommand graphviz;
|
||||
|
||||
netColor = net:
|
||||
if net == "core"
|
||||
then "grey"
|
||||
else if net == "mgmt"
|
||||
then "brown"
|
||||
else if net == "roof"
|
||||
then "orange"
|
||||
else if net == "flpk"
|
||||
then "yellow"
|
||||
else if builtins.elem net [ "c3d2" "serv" "cluster" ]
|
||||
then "green"
|
||||
else if builtins.match "up.+" net != null ||
|
||||
|
@ -80,13 +78,13 @@ let
|
|||
}
|
||||
'';
|
||||
renderGraph = args@{ name, engine, ... }:
|
||||
pkgs.runCommand "${name}.png" {
|
||||
runCommand "${name}.png" {
|
||||
src = builtins.toFile "${name}.dot" (
|
||||
toDot args
|
||||
);
|
||||
} ''
|
||||
echo $src
|
||||
${pkgs.graphviz-nox}/bin/${engine} -Tpng $src > $out
|
||||
${graphviz}/bin/${engine} -Tpng $src > $out
|
||||
'';
|
||||
|
||||
in rec {
|
||||
|
@ -136,7 +134,7 @@ in rec {
|
|||
logical-graph =
|
||||
let
|
||||
containers =
|
||||
lib.filterAttrs (_: { role, ... }:
|
||||
lib.filterAttrs (_: { isRouter, role, ... }:
|
||||
role == "container"
|
||||
) config.site.hosts;
|
||||
in
|
||||
|
@ -160,7 +158,7 @@ in rec {
|
|||
) (builtins.attrNames containers);
|
||||
};
|
||||
|
||||
network-graphs = pkgs.runCommand "network-graphs" {} ''
|
||||
network-graphs = runCommand "network-graphs" {} ''
|
||||
DIR=$out/share/doc/zentralwerk
|
||||
mkdir -p $DIR
|
||||
ln -s ${physical-graph} $DIR/physical.png
|
||||
|
|
|
@ -1,144 +0,0 @@
|
|||
{ self, nixpkgs, system, openwrt-imagebuilder }:
|
||||
|
||||
let
|
||||
inherit (self.lib) config;
|
||||
pkgs = nixpkgs.legacyPackages.${system};
|
||||
uciConfig = hostName: import ./uci-config.nix { inherit self pkgs hostName; };
|
||||
|
||||
modelPackages = {
|
||||
"tplink_archer-c7-v2" = [
|
||||
"-kmod-ath10k-ct" "-ath10k-firmware-qca988x-ct-full-htt" "-ath10k-firmware-qca988x-ct"
|
||||
"kmod-ath10k" "ath10k-firmware-qca988x"
|
||||
];
|
||||
"tplink_archer-c7-v5" = [
|
||||
"-kmod-ath10k-ct" "-ath10k-firmware-qca988x-ct" "-ath10k-firmware-qca988x-ct-full-htt"
|
||||
"kmod-ath10k" "ath10k-firmware-qca988x"
|
||||
];
|
||||
"ubnt_unifiac-lite" = [
|
||||
"-kmod-ath10k-ct" "-ath10k-firmware-qca988x-ct"
|
||||
"kmod-ath10k" "ath10k-firmware-qca988x"
|
||||
];
|
||||
"ubnt_unifiac-mesh" = [
|
||||
"-kmod-ath10k-ct" "-ath10k-firmware-qca988x-ct"
|
||||
"kmod-ath10k" "ath10k-firmware-qca988x"
|
||||
];
|
||||
"dir-615-d" = [
|
||||
# flash size reasons
|
||||
"-wpad-openssl"
|
||||
"-tcpdump"
|
||||
"wpad-wolfssl"
|
||||
];
|
||||
};
|
||||
in rec {
|
||||
sshScript = hostName:
|
||||
let
|
||||
address = config.site.net.mgmt.hosts4.${hostName};
|
||||
in ''
|
||||
#! ${pkgs.runtimeShell} -e
|
||||
|
||||
ssh root@${address} "cat > /tmp/openwrt-image" < ${buildImage hostName}/openwrt-*-${hostName}-*-sysupgrade.bin
|
||||
ssh root@${address} "sysupgrade -n /tmp/openwrt-image" || true
|
||||
|
||||
# ssh hostkey will have changed after boot
|
||||
ssh-keygen -R ${address}
|
||||
'';
|
||||
|
||||
buildImage = hostName:
|
||||
let
|
||||
hostConfig = config.site.hosts.${hostName};
|
||||
|
||||
hasVxlan = builtins.any ({ type, ... }:
|
||||
type == "vxlan"
|
||||
) (builtins.attrValues hostConfig.interfaces);
|
||||
|
||||
inherit (hostConfig) model;
|
||||
|
||||
matches = (openwrt-imagebuilder.lib.profiles {
|
||||
inherit pkgs;
|
||||
}).identifyProfiles model;
|
||||
|
||||
fallbackProfile =
|
||||
if model == "dir-615-d"
|
||||
then (openwrt-imagebuilder.lib.profiles {
|
||||
inherit pkgs;
|
||||
release = "19.07.10";
|
||||
}).identifyProfile model
|
||||
else if builtins.match "tl-wr[78].*" model != null
|
||||
then {
|
||||
release = "18.06.9";
|
||||
packagesArch = "mips_24kc";
|
||||
target = "ar71xx";
|
||||
variant = "tiny";
|
||||
profile = model;
|
||||
sha256 = "sha256-P7BJI6n6s53szYXKshnJRKL2fLIYgJLPiq/yd0oRKoE=";
|
||||
feedsSha256 = {
|
||||
base.sha256 = "sha256-IbND2snJ1UrDRhvGQIRxzGuSpftQ+AyiWqaVZqbGdHY=";
|
||||
packages.sha256 = "sha256-18UvzdUL98CranBtzAY7hoUlEvafUdssAQOuqDQi4BU=";
|
||||
};
|
||||
}
|
||||
else null;
|
||||
|
||||
build = args:
|
||||
openwrt-imagebuilder.lib.build (args // {
|
||||
extraImageName = "zw-${hostName}";
|
||||
packages = [
|
||||
# remove unused default .ipk
|
||||
"-dnsmasq" "-firewall" "-firewall4"
|
||||
"-ppp" "-ppp-mod-pppoe" "-kmod-ppp" "-kmod-pppoe" "-kmod-pppox"
|
||||
"-iptables" "-ip6tables" "-kmod-ipt-offload"
|
||||
"-odhcp6c" "-odhcpd-ipv6only"
|
||||
"-wpad-basic-mbedtls"
|
||||
# monitoring
|
||||
"collectd"
|
||||
"collectd-mod-iwinfo" "collectd-mod-network"
|
||||
"collectd-mod-interface" "collectd-mod-load" "collectd-mod-cpu"
|
||||
"collectd-mod-exec"
|
||||
] ++ (
|
||||
if args.variant != "tiny"
|
||||
then [
|
||||
# debugging
|
||||
"htop"
|
||||
"tcpdump"
|
||||
# wpa3
|
||||
"-wpad-basic-wolfssl" "-wpad-mini"
|
||||
"wpad-openssl"
|
||||
"usteer"
|
||||
] else [
|
||||
# debugging
|
||||
"tcpdump-mini"
|
||||
# wpa3
|
||||
"-wpad-openssl" "-wpad-mini"
|
||||
"wpad-wolfssl"
|
||||
]
|
||||
) ++ nixpkgs.lib.optionals hasVxlan [
|
||||
"vxlan" "kmod-vxlan"
|
||||
] ++ modelPackages.${model} or [];
|
||||
disabledServices = [ "dnsmasq" "uhttpd" ];
|
||||
files = pkgs.runCommandNoCC "image-files" {} ''
|
||||
mkdir -p $out/etc/uci-defaults
|
||||
cat > $out/etc/uci-defaults/99-zentralwerk <<EOF
|
||||
${uciConfig hostName}
|
||||
EOF
|
||||
mkdir -p $out/usr/{bin,sbin}
|
||||
cp ${./usteer-info.sh} $out/usr/sbin/usteer-info.sh
|
||||
cp ${./usteer-stats.sh} $out/usr/bin/usteer-stats.sh
|
||||
chmod +x $out/usr/bin/*.sh $out/usr/sbin/*.sh
|
||||
'';
|
||||
});
|
||||
|
||||
in
|
||||
if matches == [] && fallbackProfile != null
|
||||
then build fallbackProfile
|
||||
|
||||
else if matches == []
|
||||
then builtins.trace "${hostName} (${model}) not supported by OpenWRT"
|
||||
null
|
||||
|
||||
else if builtins.length matches == 1
|
||||
then build (builtins.elemAt matches 0)
|
||||
|
||||
else builtins.trace "${hostName} (${model}) has multiple models!" (
|
||||
build (builtins.elemAt matches 0)
|
||||
);
|
||||
|
||||
}
|
|
@ -1,3 +0,0 @@
|
|||
#! /bin/sh
|
||||
[ -p /tmp/usteer-info ] || exit 0
|
||||
exec /bin/ubus call usteer local_info > /tmp/usteer-info
|
|
@ -1,32 +0,0 @@
|
|||
#! /bin/sh
|
||||
|
||||
HOSTNAME=`cat /proc/sys/kernel/hostname`
|
||||
INTERVAL=60
|
||||
|
||||
[ -p /tmp/usteer-info ] || mkfifo /tmp/usteer-info
|
||||
|
||||
while true; do
|
||||
if [ ! -p /tmp/usteer-info ]; then
|
||||
echo "/tmp/usteer-info went missing!"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
DATA="$(cat /tmp/usteer-info)"
|
||||
cd /sys/class/net
|
||||
for iface in wlan*; do
|
||||
eval $( echo "$DATA" | jsonfilter \
|
||||
-e 'LOAD=@["hostapd.'$iface'"].load' \
|
||||
-e 'NOISE=@["hostapd.'$iface'"].noise' \
|
||||
-e 'N_ASSOC=@["hostapd.'$iface'"].n_assoc' \
|
||||
-e 'FREQ=@["hostapd.'$iface'"].freq' \
|
||||
-e 'ROAM_SOURCE=@["hostapd.'$iface'"].roam_events.source' \
|
||||
-e 'ROAM_TARGET=@["hostapd.'$iface'"].roam_events.target'
|
||||
)
|
||||
echo "PUTVAL \"$HOSTNAME/usteer_local_info-$iface/stations-load\" interval=$INTERVAL N:$LOAD"
|
||||
echo "PUTVAL \"$HOSTNAME/usteer_local_info-$iface/signal_noise-noise\" interval=$INTERVAL N:$NOISE"
|
||||
echo "PUTVAL \"$HOSTNAME/usteer_local_info-$iface/stations-n_assoc\" interval=$INTERVAL N:$N_ASSOC"
|
||||
echo "PUTVAL \"$HOSTNAME/usteer_local_info-$iface/frequency-freq\" interval=$INTERVAL N:$FREQ"
|
||||
echo "PUTVAL \"$HOSTNAME/usteer_local_info-$iface/transitions-roam_source\" interval=$INTERVAL N:$ROAM_SOURCE"
|
||||
echo "PUTVAL \"$HOSTNAME/usteer_local_info-$iface/transitions-roam_target\" interval=$INTERVAL N:$ROAM_TARGET"
|
||||
done
|
||||
done
|
|
@ -57,14 +57,10 @@ nets.each do |net|
|
|||
end
|
||||
exit 1 if collisions > 0
|
||||
|
||||
GROUP_PREFIX = 19
|
||||
GROUP_PREFIX = 16
|
||||
groups = {}
|
||||
nets.each do |net|
|
||||
if net.addr.prefix > GROUP_PREFIX
|
||||
group = net.addr.supernet(GROUP_PREFIX).to_s
|
||||
else
|
||||
group = net.addr.to_s
|
||||
end
|
||||
group = net.addr.supernet(GROUP_PREFIX).to_s
|
||||
(groups[group] ||= []) << net
|
||||
end
|
||||
|
||||
|
@ -105,9 +101,7 @@ def background_color desc
|
|||
"#9F9F9F"
|
||||
when "mgmt"
|
||||
"#FF3F3F"
|
||||
when "roof"
|
||||
"#FF4F2F"
|
||||
when "c3d2", "flpk"
|
||||
when "c3d2"
|
||||
"yellow"
|
||||
when "serv", "cluster"
|
||||
"orange"
|
||||
|
|
|
@ -1,97 +0,0 @@
|
|||
{ self, nixpkgs, system }:
|
||||
with nixpkgs.legacyPackages.${system};
|
||||
let
|
||||
config = self.lib.config;
|
||||
|
||||
reportHosts = lib.concatMapStrings (hostName:
|
||||
let
|
||||
inherit (config.site.hosts.${hostName}) links model location;
|
||||
|
||||
linksByPorts = builtins.foldl' (linksByPorts: linkName:
|
||||
if links.${linkName}.group != null
|
||||
then
|
||||
# group ports
|
||||
linksByPorts // {
|
||||
${lib.concatMapStringsSep "<br>" (port:
|
||||
"`${port}`"
|
||||
) links.${linkName}.ports} = linkName;
|
||||
}
|
||||
else
|
||||
# expand lists of access ports to seperate rows
|
||||
builtins.foldl' (linksByPorts': port:
|
||||
linksByPorts' // {
|
||||
"`${port}`" = linkName;
|
||||
}
|
||||
) linksByPorts links.${linkName}.ports
|
||||
) {} (builtins.attrNames links);
|
||||
|
||||
in ''
|
||||
## ${hostName}
|
||||
|
||||
`${model}` @ **${location}**
|
||||
|
||||
|Ports|Target|Networks|
|
||||
|-:|:-:|:-|
|
||||
${lib.concatMapStrings (ports:
|
||||
let
|
||||
linkName = linksByPorts.${ports};
|
||||
link = links.${linkName};
|
||||
in ''
|
||||
|${
|
||||
lib.optionalString (link.group != null)
|
||||
"**Group ${toString link.group}**<br>"
|
||||
}${
|
||||
ports
|
||||
}|**${
|
||||
linkName
|
||||
}**|${
|
||||
if link.trunk
|
||||
then "**Trunk:** "
|
||||
else "**Access:** "
|
||||
}${
|
||||
lib.concatStringsSep ", " (
|
||||
map (net:
|
||||
if config.site.net.${net}.vlan != null
|
||||
then "${net} (`${toString config.site.net.${net}.vlan}`)"
|
||||
else net
|
||||
) (builtins.sort (a: b:
|
||||
let
|
||||
vlanA = config.site.net.${a}.vlan;
|
||||
vlanB = config.site.net.${b}.vlan;
|
||||
in
|
||||
(
|
||||
if vlanA == null
|
||||
then 4096
|
||||
else vlanA
|
||||
) < (
|
||||
if vlanB == null
|
||||
then 4096
|
||||
else vlanB
|
||||
)
|
||||
) link.nets)
|
||||
)
|
||||
}|
|
||||
'') (lib.naturalSort (
|
||||
builtins.attrNames linksByPorts
|
||||
))}
|
||||
|
||||
'');
|
||||
|
||||
reportRole = role:
|
||||
reportHosts (
|
||||
lib.naturalSort (
|
||||
builtins.filter (hostName:
|
||||
config.site.hosts.${hostName}.role == role
|
||||
) (builtins.attrNames config.site.hosts)
|
||||
)
|
||||
);
|
||||
in
|
||||
writeText "switch-report.md" ''
|
||||
# Switch Report
|
||||
|
||||
${reportRole "switch"}
|
||||
|
||||
# Access Point Report
|
||||
|
||||
${reportRole "ap"}
|
||||
''
|
|
@ -1,180 +0,0 @@
|
|||
{ self, pkgs, hostName, config, hostConfig
|
||||
, sort, sortBy, sortNetsByVlan
|
||||
, ... }:
|
||||
|
||||
with pkgs;
|
||||
with lib;
|
||||
|
||||
''
|
||||
#! ${expect}/bin/expect -f
|
||||
|
||||
${if hostConfig.firstboot
|
||||
then ''
|
||||
spawn sudo ${uucp}/bin/cu -s 19200 -l /dev/ttyUSB0
|
||||
send "\r"
|
||||
''
|
||||
else ''
|
||||
spawn ${inetutils}/bin/telnet ${config.site.net.mgmt.hosts4.${hostName}}
|
||||
|
||||
expect "Password:"
|
||||
send "${hostConfig.password}\r"
|
||||
''
|
||||
}
|
||||
expect ">"
|
||||
send "system-view\r"
|
||||
expect "]"
|
||||
|
||||
send "sysname ${hostName}\r"
|
||||
expect "]"
|
||||
|
||||
send "user-interface vty 0 4\r"
|
||||
expect "ui-vty0-4]"
|
||||
send "screen-length 0\r"
|
||||
expect "ui-vty0-4]"
|
||||
send "user privilege level 3\r"
|
||||
expect "ui-vty0-4]"
|
||||
send "set authentication password simple ${hostConfig.password}\r"
|
||||
expect "ui-vty0-4]"
|
||||
send "quit\r"
|
||||
expect "${hostName}]"
|
||||
|
||||
send "local-user admin\r"
|
||||
expect -- "-luser-admin]"
|
||||
send "password simple ${hostConfig.password}\r"
|
||||
expect -- "-luser-admin]"
|
||||
send "quit\r"
|
||||
expect "${hostName}]"
|
||||
|
||||
# Enable logging
|
||||
send "info-center enable\r"
|
||||
expect "]"
|
||||
send "info-center loghost ${config.site.net.mgmt.hosts4.logging} channel loghost facility local6\r"
|
||||
expect "]"
|
||||
send "info-center source default channel loghost log level informational\r"
|
||||
expect "]"
|
||||
|
||||
${concatMapStrings (net:
|
||||
let
|
||||
netConfig = config.site.net.${net};
|
||||
vlan = toString netConfig.vlan;
|
||||
inherit (config.site.net.${net}) hosts4;
|
||||
hostAddr4 = hosts4.${hostName};
|
||||
prefixLength = elemAt (
|
||||
builtins.split "/" netConfig.subnet4
|
||||
) 2;
|
||||
netmask = self.lib.netmasks.${prefixLength};
|
||||
in
|
||||
if netConfig.vlan != null
|
||||
then ''
|
||||
send "vlan ${vlan}\r"
|
||||
expect -- "-vlan${vlan}]"
|
||||
send "name ${net}\r"
|
||||
expect -- "-vlan${vlan}]"
|
||||
${optionalString (net == "mgmt") ''
|
||||
# Actually only used for mgmt_vlan, switches are not routers
|
||||
send "interface Vlan-interface ${vlan}\r"
|
||||
expect "]"
|
||||
${optionalString (hosts4 ? ${hostName}) ''
|
||||
send "ip address ${hostAddr4} ${netmask}\r"
|
||||
expect "]"
|
||||
''}
|
||||
''}
|
||||
send "quit\r"
|
||||
expect "${hostName}]"
|
||||
''
|
||||
else ""
|
||||
) (sortNetsByVlan (builtins.attrNames config.site.net))
|
||||
}
|
||||
|
||||
${concatMapStrings (name:
|
||||
let
|
||||
linkConfig = hostConfig.links.${name};
|
||||
isAccess = config.site.net ? ${name};
|
||||
netConfig = config.site.net.${name};
|
||||
isTrunk = !isAccess;
|
||||
isBond = isTrunk && builtins.length linkConfig.ports > 1;
|
||||
in
|
||||
if isTrunk
|
||||
then ''
|
||||
${optionalString isBond ''
|
||||
send "link-aggregation group ${linkConfig.group} mode static\r"
|
||||
expect {
|
||||
"This aggregation will be modified to static mode. Continue ?" {
|
||||
send "Y\r"
|
||||
}
|
||||
"]" {}
|
||||
}
|
||||
send "link-aggregation group ${linkConfig.group} description ${name}\r"
|
||||
expect "]"
|
||||
''}
|
||||
${concatMapStrings (port: ''
|
||||
send "interface ${port}\r"
|
||||
expect "]"
|
||||
send "undo stp edged-port\r"
|
||||
expect "]"
|
||||
${if isBond
|
||||
then ''
|
||||
send "lacp enable\r"
|
||||
expect "]"
|
||||
send "undo port link-aggregation group\r"
|
||||
expect "]"
|
||||
send "port link-aggregation group ${linkConfig.group}\r"
|
||||
'' else ''
|
||||
send "undo lacp enable\r"
|
||||
''}
|
||||
expect "]"
|
||||
send "jumboframe enable\r"
|
||||
expect "]"
|
||||
|
||||
send "port link-type trunk\r"
|
||||
expect "]"
|
||||
# Set dummy default vlan
|
||||
send "port trunk pvid vlan 4094\r"
|
||||
expect "]"
|
||||
# Deconfigure all but mgmt vlan
|
||||
send "undo port trunk permit vlan 2 to 4094\r"
|
||||
expect "]"
|
||||
${concatMapStrings (vlan: ''
|
||||
send "port trunk permit vlan ${toString vlan}\r"
|
||||
expect "]"
|
||||
'') (sort linkConfig.vlans)}
|
||||
send "undo shutdown\r"
|
||||
expect "]"
|
||||
send "quit\r"
|
||||
expect "${hostName}]"
|
||||
'') (sort linkConfig.ports)}
|
||||
'' else
|
||||
concatMapStrings (port: ''
|
||||
send "interface ${port}\r"
|
||||
expect "]"
|
||||
send "undo port link-aggregation group\r"
|
||||
expect "]"
|
||||
send "port link-type access\r"
|
||||
expect "]"
|
||||
${if name == "mgmt"
|
||||
then ''
|
||||
send "undo port access vlan\r"
|
||||
expect "]"
|
||||
'' else ''
|
||||
send "port access vlan ${toString netConfig.vlan}\r"
|
||||
expect "]"
|
||||
''}
|
||||
send "undo shutdown\r"
|
||||
expect "]"
|
||||
send "quit\r"
|
||||
expect "${hostName}]"
|
||||
'') (sort linkConfig.ports)
|
||||
) (sortBy (link: hostConfig.links.${link}.ports)
|
||||
(builtins.attrNames hostConfig.links)
|
||||
)}
|
||||
|
||||
send "save main\r"
|
||||
expect "Y/N]"
|
||||
send "YES\r"
|
||||
expect "press the enter key):"
|
||||
send "\r"
|
||||
expect "]"
|
||||
send "quit\r"
|
||||
expect ">"
|
||||
send "quit\r"
|
||||
''
|
|
@ -122,7 +122,7 @@ with lib;
|
|||
send "exit\r"
|
||||
expect "(config)#"
|
||||
'' else ''
|
||||
send "interface range gigabitEthernet ${ports}\r"
|
||||
send "interface range gigabitEthernet 1/0/${ports}\r"
|
||||
expect "(config-if-range)#"
|
||||
send "switchport mode access\r"
|
||||
expect "(config-if-range)#"
|
||||
|
|
|
@ -1,134 +0,0 @@
|
|||
{ pkgs, hostName, config, hostConfig
|
||||
, sortBy, sortNetsByVlan
|
||||
, ... }:
|
||||
with pkgs;
|
||||
with lib;
|
||||
let
|
||||
configFile = builtins.toFile "junos.config" ''
|
||||
system {
|
||||
host-name ${hostName};
|
||||
time-zone Europe/Berlin;
|
||||
root-authentication {
|
||||
encrypted-password "%%HASH%%"; ## SECRET-DATA
|
||||
ssh-ed25519 "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIHGgoLzQMeyX1wjsX/hgVkN//zyfOQPiBRYgO2ajEGH6 root@server2";
|
||||
}
|
||||
services {
|
||||
ssh {
|
||||
root-login allow;
|
||||
}
|
||||
netconf {
|
||||
ssh;
|
||||
}
|
||||
web-management {
|
||||
http {
|
||||
interface [ vme.0 vlan.1 ];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
protocols {
|
||||
lldp {
|
||||
interface all;
|
||||
}
|
||||
}
|
||||
virtual-chassis {
|
||||
no-split-detection;
|
||||
member 0 {
|
||||
mastership-priority 255;
|
||||
}
|
||||
member 1 {
|
||||
mastership-priority 255;
|
||||
}
|
||||
}
|
||||
chassis { aggregated-devices { ethernet { device-count 32; } } }
|
||||
|
||||
vlans {
|
||||
${concatMapStrings (net:
|
||||
let
|
||||
netName = if net == "mgmt"
|
||||
then "mgmt-vlan"
|
||||
else net;
|
||||
netConfig = config.site.net.${net};
|
||||
vlan = toString netConfig.vlan;
|
||||
in
|
||||
lib.optionalString (netConfig.vlan != null) ''
|
||||
${netName} {
|
||||
vlan-id ${vlan};
|
||||
${lib.optionalString (net == "mgmt") ''
|
||||
l3-interface vlan.${vlan};
|
||||
''}
|
||||
}
|
||||
''
|
||||
) (sortNetsByVlan (builtins.attrNames config.site.net))}
|
||||
}
|
||||
|
||||
interfaces {
|
||||
vlan {
|
||||
unit ${toString config.site.net.mgmt.vlan} {
|
||||
family inet {
|
||||
address ${mgmtAddress}/${toString config.site.net.mgmt.subnet4Len};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
${concatMapStrings (name:
|
||||
let
|
||||
linkConfig = hostConfig.links.${name};
|
||||
group = linkConfig.group;
|
||||
isBond = linkConfig.group != null &&
|
||||
builtins.length linkConfig.ports > 1;
|
||||
nets = map (net:
|
||||
if net == "mgmt"
|
||||
then "mgmt-vlan"
|
||||
else net
|
||||
) linkConfig.nets;
|
||||
vlanConfig = ''
|
||||
unit 0 {
|
||||
family ethernet-switching {
|
||||
port-mode ${if linkConfig.trunk then "trunk" else "access"};
|
||||
vlan { members [ ${concatStringsSep " " nets} ]; }
|
||||
}
|
||||
}
|
||||
'';
|
||||
in
|
||||
if isBond
|
||||
then concatMapStrings (port: ''
|
||||
${port} {
|
||||
ether-options { 802.3ad ae${group}; }
|
||||
}
|
||||
'') (linkConfig.ports) + ''
|
||||
ae${group} {
|
||||
aggregated-ether-options { lacp { active; } }
|
||||
${vlanConfig}
|
||||
}
|
||||
''
|
||||
else concatMapStrings (port: ''
|
||||
${port} {
|
||||
${vlanConfig}
|
||||
}
|
||||
'') (linkConfig.ports)
|
||||
) (sortBy (link: hostConfig.links.${link}.ports)
|
||||
(builtins.attrNames hostConfig.links)
|
||||
)}
|
||||
}
|
||||
'';
|
||||
|
||||
configFileWithHash = runCommand "junos.config" {
|
||||
nativeBuildInputs = [ mkpasswd ];
|
||||
} ''
|
||||
HASH=$(echo "${hostConfig.password}" | mkpasswd --method=SHA-512 --stdin)
|
||||
substitute ${configFile} $out \
|
||||
--replace "%%HASH%%" "$HASH"
|
||||
'';
|
||||
|
||||
mgmtAddress = config.site.net.mgmt.hosts4.${hostName};
|
||||
in ''
|
||||
#! ${runtimeShell} -e
|
||||
|
||||
scp ${configFileWithHash} root@${mgmtAddress}:/tmp/junos.config
|
||||
ssh root@${mgmtAddress} cli <<EOF
|
||||
configure
|
||||
load override /tmp/junos.config
|
||||
commit
|
||||
EOF
|
||||
''
|
|
@ -1,5 +1,5 @@
|
|||
# https://www.crc.id.au/real-console-on-linksys-srw2024-switch/
|
||||
{ pkgs, hostName, config, hostConfig
|
||||
{ self, pkgs, hostName, config, hostConfig
|
||||
, sort, sortBy, sortNetsByVlan
|
||||
, ... }:
|
||||
with pkgs;
|
||||
|
@ -66,11 +66,10 @@ with lib;
|
|||
${concatMapStrings (name:
|
||||
let
|
||||
linkConfig = hostConfig.links.${name};
|
||||
isAccess = config.site.net ? ${name};
|
||||
netConfig = config.site.net.${name};
|
||||
isTrunk = linkConfig.trunk;
|
||||
isBond = builtins.length linkConfig.ports > 1 &&
|
||||
# not named like a net
|
||||
(!config.site.net ? ${name});
|
||||
isTrunk = !isAccess;
|
||||
isBond = isTrunk && builtins.length linkConfig.ports > 1;
|
||||
vlans = concatStringsSep "," (map toString (sort linkConfig.vlans));
|
||||
ports = concatStringsSep "," linkConfig.ports;
|
||||
in
|
||||
|
@ -109,31 +108,6 @@ with lib;
|
|||
send "exit\r"
|
||||
expect "(config)#"
|
||||
'') linkConfig.ports
|
||||
else if isBond
|
||||
then
|
||||
if builtins.length linkConfig.vlans != 1
|
||||
then throw "Cannot configure non-trunked port with multiple vlans"
|
||||
else ''
|
||||
send "interface range ethernet ${ports}\r"
|
||||
expect "(config-if)#"
|
||||
send "channel-group ${linkConfig.group} mode auto\r"
|
||||
expect "(config-if)#"
|
||||
send "interface port-channel ${linkConfig.group}\r"
|
||||
expect "(config-if)#"
|
||||
send "exit\r"
|
||||
|
||||
send "interface port-channel ${linkConfig.group}\r"
|
||||
expect "(config-if)#"
|
||||
send "switchport trunk allowed vlan remove all\r"
|
||||
expect "(config-if)#"
|
||||
send "switchport mode access\r"
|
||||
expect "(config-if)#"
|
||||
send "switchport access vlan ${toString (builtins.head linkConfig.vlans)}\r"
|
||||
expect "(config-if)#"
|
||||
|
||||
send "exit\r"
|
||||
expect "(config)#"
|
||||
''
|
||||
else concatMapStrings (port: ''
|
||||
send "interface ethernet ${port}\r"
|
||||
expect "(config-if)#"
|
||||
|
|
|
@ -3,10 +3,8 @@ with nixpkgs.legacyPackages.${system};
|
|||
let
|
||||
config = self.lib.config;
|
||||
in
|
||||
writeText "vlan-report.md" ''
|
||||
# VLAN Report
|
||||
|
||||
${lib.concatMapStrings (net: ''
|
||||
writeText "vlan-report.txt" (
|
||||
lib.concatMapStrings (net: ''
|
||||
## ${net}${lib.optionalString (config.site.net.${net}.vlan != null) " (VLAN ${toString config.site.net.${net}.vlan})"}
|
||||
${lib.concatStringsSep "\n" (
|
||||
lib.concatMap (host:
|
||||
|
@ -20,5 +18,5 @@ writeText "vlan-report.md" ''
|
|||
) (lib.attrNames config.site.hosts)
|
||||
)}
|
||||
|
||||
'') (lib.attrNames config.site.net)}
|
||||
''
|
||||
'') (lib.attrNames config.site.net)
|
||||
)
|
||||
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue