Compare commits
1 Commits
Author | SHA1 | Date | |
---|---|---|---|
ca5b0c2d6c |
|
@ -78,10 +78,6 @@ ausgeführt.
|
||||||
|
|
||||||
### LXC-Containers auf Server
|
### 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
|
Ein Server erwartet die für ihn (`location = hostName`) konfigurierten
|
||||||
Container. systemd versucht sie zu starten. Das wird erst nach
|
Container. systemd versucht sie zu starten. Das wird erst nach
|
||||||
`build-container` funktionieren, welches das Rootfs anlegt.
|
`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 |
|
| | ![][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.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.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.04.01 *v* | ![][gi] B 2.05.07 *v* | | | 18 |
|
||||||
| ![][ri] B 4.05.02 *v* | ![][gi] B 2.06 | | | 19 |
|
| ![][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.06.01 | ![][ri] B 2.07 | | | 20 |
|
||||||
| ![][ri] B 4.07.05 *v* | | | | 21 |
|
| ![][ri] B 4.07.05 | | | | 21 |
|
||||||
| ![][ri] B 4.08.01 | | | | 22 |
|
| ![][ri] B 4.08.01 | | | | 22 |
|
||||||
| ![][ri] B 4.09.01 *v* | | | | 23 |
|
| ![][ri] B 4.09.01 *v* | | | | 23 |
|
||||||
| ![][ri] B 4.10.01 *v* | | | | 24 |
|
| ![][ri] B 4.10.01 *v* | | | | 24 |
|
||||||
|
|
1083
config/ap.nix
1083
config/ap.nix
File diff suppressed because it is too large
Load Diff
|
@ -1,9 +1,4 @@
|
||||||
{ config, lib, ... }:
|
{ lib, ... }:
|
||||||
|
|
||||||
let
|
|
||||||
# https://github.com/NixOS/nixpkgs/pull/206965
|
|
||||||
concatMapAttrsRecursive = with lib; f: flip pipe [ (mapAttrs f) attrValues (foldl' recursiveUpdate { }) ];
|
|
||||||
in
|
|
||||||
{
|
{
|
||||||
imports = [
|
imports = [
|
||||||
# Secrets
|
# Secrets
|
||||||
|
@ -14,8 +9,7 @@ in
|
||||||
./switch.nix
|
./switch.nix
|
||||||
./ap.nix
|
./ap.nix
|
||||||
./server.nix
|
./server.nix
|
||||||
]
|
] ++
|
||||||
# IP networks
|
# IP networks
|
||||||
++ lib.filesystem.listFilesRecursive ./net;
|
lib.filesystem.listFilesRecursive ./net;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,74 +8,65 @@
|
||||||
fixed-hosts = {
|
fixed-hosts = {
|
||||||
"172.22.99.96" = "08:00:27:bb:8c:b3";
|
"172.22.99.96" = "08:00:27:bb:8c:b3";
|
||||||
"172.22.99.98" = "08:00:27:aa:90:e2";
|
"172.22.99.98" = "08:00:27:aa:90:e2";
|
||||||
# "astrom" = "aa:00:5b:08:f0:5c";
|
"astrom.hq.c3d2.de" = "aa:00:5b:08:f0:5c";
|
||||||
# "astron" = "aa:00:5b:08:f0:5b";
|
"astron.hq.c3d2.de" = "aa:00:5b:08:f0:5b";
|
||||||
# "batman" = "5c:cf:7f:c0:05:28";
|
"batman.hq.c3d2.de" = "5c:cf:7f:c0:05:28";
|
||||||
# "beere" = "b8:27:eb:ac:65:d2";
|
"beere.hq.c3d2.de" = "b8:27:eb:ac:65:d2";
|
||||||
# "beere2" = "b8:27:eb:53:0b:27";
|
"beere2.hq.c3d2.de" = "b8:27:eb:53:0b:27";
|
||||||
# "bender.hq.c3de.de" = "00:23:df:7e:c8:0a";
|
"bender.hq.c3de.de" = "00:23:df:7e:c8:0a";
|
||||||
# "cider" = "00:0d:93:75:ee:fa";
|
"cider.hq.c3d2.de" = "00:0d:93:75:ee:fa";
|
||||||
"dacbert" = "dc:a6:32:e0:46:bf";
|
"dacbert.hq.c3d2.de" = "dc:a6:32:31:b6:32";
|
||||||
"dn42" = "aa:00:42:7a:32:46";
|
"dn42.hq.c3d2.de" = "aa:00:42:7a:32:46";
|
||||||
# "drucker" = "00:23:c3:d2:12:0f";
|
"drucker.hq.c3d2.de" = "00:23:c3:d2:12:0f";
|
||||||
# "feile" = "aa:00:5b:12:c1:f7";
|
"feile.hq.c3d2.de" = "aa:00:5b:12:c1:f7";
|
||||||
# "fernandopoo" = "aa:00:f7:52:85:27";
|
"fernandopoo.hq.c3d2.de" = "aa:00:f7:52:85:27";
|
||||||
# "fhem" = "b8:27:eb:9e:8b:db";
|
"fhem.hq.c3d2.de" = "b8:27:eb:9e:8b:db";
|
||||||
# "git" = "aa:00:47:d8:57:10";
|
"git.hq.c3d2.de" = "aa:00:47:d8:57:10";
|
||||||
"glotzbert" = "90:1b:0e:88:da:0a";
|
"glotzbert.hq.c3d2.de" = "ec:a8:6b:fe:b4:cb";
|
||||||
# "wled-nix-snowflake" = "44:17:93:10:77:e8";
|
"icq.hq.c3d2.de" = "aa:00:30:f6:27:89";
|
||||||
# "wled-fairy-dust" = "3c:61:05:e3:2f:ad";
|
"jabber1.hq.c3d2.de" = "aa:00:0b:19:8f:14";
|
||||||
# "wled-warnbert" = "3c:61:05:fc:21:37";
|
"jabber2.hq.c3d2.de" = "aa:00:3d:6a:23:b8";
|
||||||
# "wled-matrix" = "e8:db:84:e4:f4:30";
|
"knot.hq.c3d2.de" = "52:54:cf:fd:ce:3f";
|
||||||
# "ledball1" = "b8:27:eb:53:0b:27";
|
"ledball1.hq.c3d2.de" = "b8:27:eb:53:0b:27";
|
||||||
# Beleuchtungskiste auf Traverse über Fernseher
|
"ledbeere.hq.c3d2.de" = "b8:27:eb:60:99:59";
|
||||||
# "ledbeere" = "b8:27:eb:60:99:59";
|
"leviathan.hq.c3d2.de" = "00:ff:08:31:db:e5";
|
||||||
# "leviathan" = "00:ff:08:31:db:e5";
|
"lisbeth.hq.c3d2.de" = "b8:27:eb:a5:ee:5c";
|
||||||
# "lisbeth" = "b8:27:eb:a5:ee:5c";
|
"marenz-build.hq.c3d2.de" = "44:1e:a1:59:2e:e8";
|
||||||
# "marenz-build" = "44:1e:a1:59:2e:e8";
|
"matemat.hq.c3d2.de" = "a2:1b:7c:e8:19:72";
|
||||||
# "matemat" = "a2:1b:7c:e8:19:72";
|
"minecraft.hq.c3d2.de" = "4a:57:d3:64:fe:e9";
|
||||||
# "minecraft" = "4a:57:d3:64:fe:e9";
|
"moleflap.hq.c3d2.de" = "aa:00:0d:b1:6c:67";
|
||||||
# "moleflap" = "aa:00:0d:b1:6c:67";
|
"monit.hq.c3d2.de" = "00:23:ae:94:e7:19";
|
||||||
# "monit" = "00:23:ae:94:e7:19";
|
"public-access-proxy.hq.c3d2.de" = "12:24:5f:bd:9b:e7";
|
||||||
"pipebert" = "ec:a8:6b:fe:b4:cb";
|
"pulsebert.hq.c3d2.de" = "b8:27:eb:16:31:61";
|
||||||
# "public-access-proxy" = "12:24:5f:bd:9b:e7";
|
"ruststripe1.hq.c3d2.de" = "06:32:0e:39:21:69";
|
||||||
"pulsebert" = "b8:27:eb:16:31:61";
|
"schalter.hq.c3d2.de" = "b8:27:eb:4c:be:ff";
|
||||||
# "ruststripe1" = "06:32:0e:39:21:69";
|
"semanta.hq.c3d2.de" = "00:ff:e4:bb:ea:2a";
|
||||||
"schalter" = "b8:27:eb:ac:65:d2";
|
"server2.hq.c3d2.de" = "d0:67:e5:f3:57:10";
|
||||||
# "semanta" = "00:ff:e4:bb:ea:2a";
|
"server3.hq.c3d2.de" = "e4:1f:13:2e:4f:c0";
|
||||||
# "server2" = "d0:67:e5:f3:57:10";
|
"server4.hq.c3d2.de" = "00:9c:02:a9:26:01";
|
||||||
# "server3" = "e4:1f:13:2e:4f:c0";
|
"sharing.hq.c3d2.de" = "00:23:c3:d2:75:18";
|
||||||
# "server4" = "00:9c:02:a9:26:01";
|
"sofafon.hq.c3d2.de" = "b8:27:eb:23:8d:01";
|
||||||
# "sharing" = "00:23:c3:d2:75:18";
|
"storage2.hq.c3d2.de" = "42:5e:0f:4e:f3:cc";
|
||||||
# "sofafon" = "b8:27:eb:23:8d:01";
|
"ustriper.hq.c3d2.de" = "aa:bb:95:33:bb:aa";
|
||||||
# "storage2" = "42:5e:0f:4e:f3:cc";
|
"wiefelspuetz.hq.c3d2.de" = "aa:00:7f:01:8a:d0";
|
||||||
# "ustriper" = "aa:bb:95:33:bb:aa";
|
"wormhole.hq.c3d2.de" = "00:23:c3:d2:00:76";
|
||||||
# "wiefelspuetz" = "aa:00:7f:01:8a:d0";
|
"www1.hq.c3d2.de" = "aa:00:13:8b:03:47";
|
||||||
# "wormhole" = "00:23:c3:d2:00:76";
|
|
||||||
# "www1" = "aa:00:13:8b:03:47";
|
|
||||||
# "riscbert" = "6c:cf:39:00:05:95";
|
|
||||||
};
|
};
|
||||||
time = 300;
|
time = 86400;
|
||||||
max-time = 30 * 24 * 3600;
|
max-time = 2592000;
|
||||||
router = "c3d2-gw3";
|
router = "c3d2-anon";
|
||||||
};
|
};
|
||||||
domainName = "c3d2.zentralwerk.org";
|
domainName = "c3d2.zentralwerk.org";
|
||||||
dynamicDomain = true;
|
dynamicDomain = true;
|
||||||
subnet4 = "172.22.99.0/24";
|
subnet4 = "172.22.99.0/24";
|
||||||
hosts4 = {
|
hosts4 = {
|
||||||
|
bgp = "172.22.99.250";
|
||||||
c3d2-anon = "172.22.99.1";
|
c3d2-anon = "172.22.99.1";
|
||||||
c3d2-gw1 = "172.22.99.2";
|
c3d2-gw1 = "172.22.99.2";
|
||||||
c3d2-gw2 = "172.22.99.3";
|
c3d2-gw2 = "172.22.99.3";
|
||||||
c3d2-gw3 = "172.22.99.4";
|
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";
|
dn42 = "172.22.99.253";
|
||||||
};
|
};
|
||||||
ipv6Router = "c3d2-gw3";
|
|
||||||
hosts6.dn42 = {
|
hosts6.dn42 = {
|
||||||
bgp = "fd23:42:c3d2:523::c3d2:ff0b";
|
bgp = "fd23:42:c3d2:523::c3d2:ff0b";
|
||||||
c3d2-anon = "fd23:42:c3d2:523::c3d2:1";
|
c3d2-anon = "fd23:42:c3d2:523::c3d2:1";
|
||||||
|
@ -89,12 +80,12 @@
|
||||||
c3d2-gw1 = "2a00:8180:2c00:223::c3d2:2";
|
c3d2-gw1 = "2a00:8180:2c00:223::c3d2:2";
|
||||||
c3d2-gw2 = "2a00:8180:2c00:223::c3d2:3";
|
c3d2-gw2 = "2a00:8180:2c00:223::c3d2:3";
|
||||||
c3d2-gw3 = "2a00:8180:2c00:223::c3d2:4";
|
c3d2-gw3 = "2a00:8180:2c00:223::c3d2:4";
|
||||||
glotzbert = "2a00:8180:2c00:223:e1ad:6c2b:af9f:2d13";
|
|
||||||
pipebert = "2a00:8180:2c00:223:eea8:6bff:fefe:b4cb";
|
|
||||||
};
|
};
|
||||||
|
hosts6.yggdrasil.c3d2-gw3 = "30c:c3d2:b946:76d0::1";
|
||||||
subnets6 = {
|
subnets6 = {
|
||||||
dn42 = "fd23:42:c3d2:523::/64";
|
dn42 = "fd23:42:c3d2:523::/64";
|
||||||
up4 = "2a00:8180:2c00:223::/64";
|
up4 = "2a00:8180:2c00:223::/64";
|
||||||
|
yggdrasil = "30c:c3d2:b946:76d0::/64";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -121,21 +112,21 @@
|
||||||
c3d2.hwaddr = "0A:14:48:01:21:01";
|
c3d2.hwaddr = "0A:14:48:01:21:01";
|
||||||
core.hwaddr = "0A:14:48:01:21:00";
|
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 {
|
c3d2-gw2 = makeGateway {
|
||||||
interfaces = {
|
interfaces = {
|
||||||
c3d2.hwaddr = "0A:14:48:01:21:03";
|
c3d2.hwaddr = "0A:14:48:01:21:03";
|
||||||
core.hwaddr = "0A:14:48:01:21:02";
|
core.hwaddr = "0A:14:48:01:21:02";
|
||||||
};
|
};
|
||||||
ospf.allowedUpstreams = [ "upstream3" "upstream4" "anon1" "freifunk" ];
|
ospf.allowedUpstreams = [ "upstream1" "upstream3" "upstream4" "anon1" "freifunk" ];
|
||||||
};
|
};
|
||||||
c3d2-gw3 = makeGateway {
|
c3d2-gw3 = makeGateway {
|
||||||
interfaces = {
|
interfaces = {
|
||||||
c3d2.hwaddr = "0A:14:48:01:21:05";
|
c3d2.hwaddr = "0A:14:48:01:21:05";
|
||||||
core.hwaddr = "0A:14:48:01:21:04";
|
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
|
in
|
||||||
{
|
{
|
||||||
site.net.cluster = {
|
site.net.cluster = {
|
||||||
ipv6Router = "cls-gw";
|
|
||||||
domainName = "cluster.zentralwerk.org";
|
domainName = "cluster.zentralwerk.org";
|
||||||
extraRecords = map (host: {
|
extraRecords = map (host: {
|
||||||
data = {
|
data = "1 1 6789 ${host}";
|
||||||
service = "ceph-mon";
|
name = "_ceph-mon._tcp";
|
||||||
proto = "tcp";
|
|
||||||
priority = 1;
|
|
||||||
weight = 1;
|
|
||||||
port = 6789;
|
|
||||||
target = host;
|
|
||||||
};
|
|
||||||
name = "@";
|
|
||||||
type = "SRV";
|
type = "SRV";
|
||||||
}) cephMonServers
|
}) cephMonServers
|
||||||
++
|
++
|
||||||
|
@ -133,7 +125,7 @@ in
|
||||||
let
|
let
|
||||||
makeServer = {
|
makeServer = {
|
||||||
role = "client";
|
role = "client";
|
||||||
model = "nixos";
|
model = "proxmox";
|
||||||
interfaces = builtins.foldl' (interfaces: net:
|
interfaces = builtins.foldl' (interfaces: net:
|
||||||
interfaces // {
|
interfaces // {
|
||||||
"${net}".type = "bridge";
|
"${net}".type = "bridge";
|
||||||
|
@ -144,13 +136,10 @@ in
|
||||||
"mgmt"
|
"mgmt"
|
||||||
"serv"
|
"serv"
|
||||||
"c3d2"
|
"c3d2"
|
||||||
"c3d2iot"
|
|
||||||
"pub"
|
"pub"
|
||||||
"priv23"
|
"priv23"
|
||||||
"priv31"
|
"priv31"
|
||||||
"priv45"
|
|
||||||
"bmx"
|
"bmx"
|
||||||
"flpk"
|
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
in {
|
in {
|
||||||
|
@ -166,7 +155,7 @@ in
|
||||||
type = "veth";
|
type = "veth";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
ospf.allowedUpstreams = [ "upstream4" "upstream3" "anon1" "freifunk" ];
|
ospf.allowedUpstreams = [ "upstream4" "upstream1" "upstream3" "anon1" "freifunk" ];
|
||||||
};
|
};
|
||||||
server3 = makeServer;
|
server3 = makeServer;
|
||||||
server5 = makeServer;
|
server5 = makeServer;
|
||||||
|
@ -174,6 +163,5 @@ in
|
||||||
server7 = makeServer;
|
server7 = makeServer;
|
||||||
server8 = makeServer;
|
server8 = makeServer;
|
||||||
server9 = 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" ];
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
|
@ -49,13 +49,6 @@
|
||||||
priv40-gw = "172.20.72.61";
|
priv40-gw = "172.20.72.61";
|
||||||
priv41-gw = "172.20.72.65";
|
priv41-gw = "172.20.72.65";
|
||||||
priv42-gw = "172.20.72.67";
|
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";
|
priv5-gw = "172.20.72.15";
|
||||||
priv6-gw = "172.20.72.16";
|
priv6-gw = "172.20.72.16";
|
||||||
priv7-gw = "172.20.72.17";
|
priv7-gw = "172.20.72.17";
|
||||||
|
@ -69,12 +62,12 @@
|
||||||
server6 = "172.20.72.56";
|
server6 = "172.20.72.56";
|
||||||
server7 = "172.20.72.57";
|
server7 = "172.20.72.57";
|
||||||
server8 = "172.20.72.58";
|
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";
|
upstream3 = "172.20.72.11";
|
||||||
upstream4 = "172.20.72.12";
|
upstream4 = "172.20.72.12";
|
||||||
coloradio-gw = "172.20.72.62";
|
yggdrasil = "172.20.72.62";
|
||||||
vpn-gw = "172.20.72.69";
|
|
||||||
flpk-gw = "172.20.72.71";
|
|
||||||
iot-gw = "172.20.72.77";
|
|
||||||
};
|
};
|
||||||
hosts6 = {
|
hosts6 = {
|
||||||
dn42 = {
|
dn42 = {
|
||||||
|
@ -84,10 +77,8 @@
|
||||||
c3d2-gw1 = "fd23:42:c3d2:581::c3d2:1";
|
c3d2-gw1 = "fd23:42:c3d2:581::c3d2:1";
|
||||||
c3d2-gw2 = "fd23:42:c3d2:581::c3d2:2";
|
c3d2-gw2 = "fd23:42:c3d2:581::c3d2:2";
|
||||||
c3d2-gw3 = "fd23:42:c3d2:581::c3d2:3";
|
c3d2-gw3 = "fd23:42:c3d2:581::c3d2:3";
|
||||||
cls-gw = "fd23:42:c3d2:581::c3d2:4";
|
|
||||||
freifunk = "fd23:42:c3d2:581:8000::1";
|
freifunk = "fd23:42:c3d2:581:8000::1";
|
||||||
mgmt-gw = "fd23:42:c3d2:581::8:3";
|
mgmt-gw = "fd23:42:c3d2:581::8:3";
|
||||||
iot-gw = "fd23:42:c3d2:581::8:7";
|
|
||||||
priv1-gw = "fd23:42:c3d2:581::c:0";
|
priv1-gw = "fd23:42:c3d2:581::c:0";
|
||||||
priv10-gw = "fd23:42:c3d2:581::c:9";
|
priv10-gw = "fd23:42:c3d2:581::c:9";
|
||||||
priv11-gw = "fd23:42:c3d2:581::c:a";
|
priv11-gw = "fd23:42:c3d2:581::c:a";
|
||||||
|
@ -125,13 +116,6 @@
|
||||||
priv40-gw = "fd23:42:c3d2:581::c:27";
|
priv40-gw = "fd23:42:c3d2:581::c:27";
|
||||||
priv41-gw = "fd23:42:c3d2:581::c:28";
|
priv41-gw = "fd23:42:c3d2:581::c:28";
|
||||||
priv42-gw = "fd23:42:c3d2:581::c:29";
|
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";
|
|
||||||
priv5-gw = "fd23:42:c3d2:581::c:4";
|
priv5-gw = "fd23:42:c3d2:581::c:4";
|
||||||
priv6-gw = "fd23:42:c3d2:581::c:5";
|
priv6-gw = "fd23:42:c3d2:581::c:5";
|
||||||
priv7-gw = "fd23:42:c3d2:581::c:6";
|
priv7-gw = "fd23:42:c3d2:581::c:6";
|
||||||
|
@ -139,10 +123,11 @@
|
||||||
priv9-gw = "fd23:42:c3d2:581::c:8";
|
priv9-gw = "fd23:42:c3d2:581::c:8";
|
||||||
pub-gw = "fd23:42:c3d2:581::8:2";
|
pub-gw = "fd23:42:c3d2:581::8:2";
|
||||||
serv-gw = "fd23:42:c3d2:581::8:1";
|
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";
|
upstream3 = "fd23:42:c3d2:581::b:2";
|
||||||
upstream4 = "fd23:42:c3d2:581::b:3";
|
upstream4 = "fd23:42:c3d2:581::b:3";
|
||||||
vpn-gw = "fd23:42:c3d2:581:9001::1";
|
yggdrasil = "fd23:42:c3d2:581:9000::1";
|
||||||
coloradio-gw = "fd23:42:c3d2:581:9009::1";
|
|
||||||
};
|
};
|
||||||
up4 = {
|
up4 = {
|
||||||
anon1 = "2a00:8180:2c00:281::9:1";
|
anon1 = "2a00:8180:2c00:281::9:1";
|
||||||
|
@ -154,7 +139,6 @@
|
||||||
cls-gw = "2a00:8180:2c00:281::8:4";
|
cls-gw = "2a00:8180:2c00:281::8:4";
|
||||||
freifunk = "2a00:8180:2c00:281:8000::1";
|
freifunk = "2a00:8180:2c00:281:8000::1";
|
||||||
mgmt-gw = "2a00:8180:2c00:281::8:3";
|
mgmt-gw = "2a00:8180:2c00:281::8:3";
|
||||||
iot-gw = "2a00:8180:2c00:281::8:7";
|
|
||||||
priv1-gw = "2a00:8180:2c00:281::c:0";
|
priv1-gw = "2a00:8180:2c00:281::c:0";
|
||||||
priv10-gw = "2a00:8180:2c00:281::c:9";
|
priv10-gw = "2a00:8180:2c00:281::c:9";
|
||||||
priv11-gw = "2a00:8180:2c00:281::c:a";
|
priv11-gw = "2a00:8180:2c00:281::c:a";
|
||||||
|
@ -192,22 +176,15 @@
|
||||||
priv40-gw = "2a00:8180:2c00:281::c:27";
|
priv40-gw = "2a00:8180:2c00:281::c:27";
|
||||||
priv41-gw = "2a00:8180:2c00:281::c:28";
|
priv41-gw = "2a00:8180:2c00:281::c:28";
|
||||||
priv42-gw = "2a00:8180:2c00:281::c:29";
|
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";
|
|
||||||
priv5-gw = "2a00:8180:2c00:281::c:4";
|
priv5-gw = "2a00:8180:2c00:281::c:4";
|
||||||
priv6-gw = "2a00:8180:2c00:281::c:5";
|
priv6-gw = "2a00:8180:2c00:281::c:5";
|
||||||
priv7-gw = "2a00:8180:2c00:281::c:6";
|
priv7-gw = "2a00:8180:2c00:281::c:6";
|
||||||
priv8-gw = "2a00:8180:2c00:281::c:7";
|
priv8-gw = "2a00:8180:2c00:281::c:7";
|
||||||
priv9-gw = "2a00:8180:2c00:281::c:8";
|
priv9-gw = "2a00:8180:2c00:281::c:8";
|
||||||
serv-gw = "2a00:8180:2c00:281::8:1";
|
serv-gw = "2a00:8180:2c00:281::8:1";
|
||||||
|
upstream1 = "2a00:8180:2c00:281::b:0";
|
||||||
upstream4 = "2a00:8180:2c00:281::b:1";
|
upstream4 = "2a00:8180:2c00:281::b:1";
|
||||||
vpn-gw = "2a00:8180:2c00:281:9001::1";
|
yggdrasil = "2a00:8180:2c00:281:9000::1";
|
||||||
coloradio-gw = "2a00:8180:2c00:281:9009::1";
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
subnet4 = "172.20.72.0/25";
|
subnet4 = "172.20.72.0/25";
|
||||||
|
@ -238,10 +215,10 @@
|
||||||
};
|
};
|
||||||
ospf = {
|
ospf = {
|
||||||
allowedUpstreams =
|
allowedUpstreams =
|
||||||
[ "upstream4" "upstream3" "anon1" "freifunk" ];
|
[ "upstream4" "upstream1" "upstream3" "anon1" "freifunk" ];
|
||||||
stubNets4 = [ "172.20.0.0/14" "10.0.0.0/8" ];
|
stubNets4 = [ "172.20.0.0/14" "10.0.0.0/8" ];
|
||||||
stubNets6 =
|
stubNets6 =
|
||||||
[ "fd00::/8" "2a00:8180:2c00:200::/56" ];
|
[ "fd00::/8" "2a02:8106:208:5200::/56" "2a02:8106:211:e900::/56" ];
|
||||||
};
|
};
|
||||||
role = "container";
|
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,16 +63,7 @@
|
||||||
ap62 = "10.0.0.102";
|
ap62 = "10.0.0.102";
|
||||||
ap63 = "10.0.0.103";
|
ap63 = "10.0.0.103";
|
||||||
ap64 = "10.0.0.104";
|
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";
|
ap7 = "10.0.0.47";
|
||||||
ap70 = "10.0.0.110";
|
|
||||||
ap71 = "10.0.0.111";
|
|
||||||
ap72 = "10.0.0.112";
|
|
||||||
ap73 = "10.0.0.113";
|
|
||||||
ap8 = "10.0.0.48";
|
ap8 = "10.0.0.48";
|
||||||
ap9 = "10.0.0.49";
|
ap9 = "10.0.0.49";
|
||||||
logging = "10.0.0.251";
|
logging = "10.0.0.251";
|
||||||
|
@ -104,10 +95,6 @@
|
||||||
switch-c3d2-main = "10.0.0.14";
|
switch-c3d2-main = "10.0.0.14";
|
||||||
switch-d1 = "10.0.0.13";
|
switch-d1 = "10.0.0.13";
|
||||||
switch-dach = "10.0.0.17";
|
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 = {
|
hosts6 = {
|
||||||
dn42 = {
|
dn42 = {
|
||||||
|
@ -172,16 +159,7 @@
|
||||||
ap62 = "fd23:42:c3d2:580::4:3e";
|
ap62 = "fd23:42:c3d2:580::4:3e";
|
||||||
ap63 = "fd23:42:c3d2:580::4:3f";
|
ap63 = "fd23:42:c3d2:580::4:3f";
|
||||||
ap64 = "fd23:42:c3d2:580::4:40";
|
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";
|
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";
|
|
||||||
ap73 = "fd23:42:c3d2:580::4:49";
|
|
||||||
ap8 = "fd23:42:c3d2:580::4:8";
|
ap8 = "fd23:42:c3d2:580::4:8";
|
||||||
ap9 = "fd23:42:c3d2:580::4:9";
|
ap9 = "fd23:42:c3d2:580::4:9";
|
||||||
mgmt-gw = "fd23:42:c3d2:580:ffff:ffff:ffff:ffff";
|
mgmt-gw = "fd23:42:c3d2:580:ffff:ffff:ffff:ffff";
|
||||||
|
@ -213,7 +191,7 @@
|
||||||
};
|
};
|
||||||
ospf = {
|
ospf = {
|
||||||
allowedUpstreams =
|
allowedUpstreams =
|
||||||
[ "upstream4" "upstream3" "anon1" "freifunk" ];
|
[ "upstream4" "upstream1" "upstream3" "anon1" "freifunk" ];
|
||||||
};
|
};
|
||||||
role = "container";
|
role = "container";
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{ lib, ... }:
|
{ lib, ... }:
|
||||||
let
|
let
|
||||||
privCount = 49;
|
privCount = 42;
|
||||||
seq = n: max:
|
seq = n: max:
|
||||||
if n <= max
|
if n <= max
|
||||||
then [ n ] ++ seq (n + 1) max
|
then [ n ] ++ seq (n + 1) max
|
||||||
|
@ -16,9 +16,9 @@ lib.mkMerge (
|
||||||
site.net."priv${toString n}" = {
|
site.net."priv${toString n}" = {
|
||||||
dhcp = {
|
dhcp = {
|
||||||
server = "priv${toString n}-gw";
|
server = "priv${toString n}-gw";
|
||||||
time = 300;
|
time = 120;
|
||||||
max-time = 60 * 24 * 3600;
|
max-time = 86400;
|
||||||
router = "priv${toString n}-gw";
|
router = "priv${toString n}-gw.priv${toString n}";
|
||||||
};
|
};
|
||||||
domainName = "priv${toString n}.zentralwerk.org";
|
domainName = "priv${toString n}.zentralwerk.org";
|
||||||
dynamicDomain = true;
|
dynamicDomain = true;
|
||||||
|
@ -38,7 +38,7 @@ lib.mkMerge (
|
||||||
core.type = "veth";
|
core.type = "veth";
|
||||||
"priv${toString n}".type = "veth";
|
"priv${toString n}".type = "veth";
|
||||||
};
|
};
|
||||||
ospf.allowedUpstreams = [ "upstream4" "upstream3" "anon1" "freifunk" ];
|
ospf.allowedUpstreams = [ "upstream4" "upstream3" "upstream1" "anon1" "freifunk" ];
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
) (seq 1 privCount)
|
) (seq 1 privCount)
|
||||||
|
@ -58,12 +58,10 @@ lib.mkMerge (
|
||||||
subnet4 = "172.20.75.0/27";
|
subnet4 = "172.20.75.0/27";
|
||||||
dhcp = {
|
dhcp = {
|
||||||
start = "172.20.75.2";
|
start = "172.20.75.2";
|
||||||
end = "172.20.75.30";
|
end = "172.20.75.31";
|
||||||
fixed-hosts = {
|
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.7" = "60:33:4b:0b:cd:fc";
|
||||||
|
"172.20.75.9" = "00:11:32:22:95:79";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
@ -204,6 +202,7 @@ lib.mkMerge (
|
||||||
dhcp = {
|
dhcp = {
|
||||||
start = "172.20.73.194";
|
start = "172.20.73.194";
|
||||||
end = "172.20.73.254";
|
end = "172.20.73.254";
|
||||||
|
max-time = lib.mkForce 2592000;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
priv20 = {
|
priv20 = {
|
||||||
|
@ -238,10 +237,9 @@ lib.mkMerge (
|
||||||
end = "172.20.73.190";
|
end = "172.20.73.190";
|
||||||
fixed-hosts = {
|
fixed-hosts = {
|
||||||
"172.20.73.162" = "da:2c:3a:2c:87:22";
|
"172.20.73.162" = "da:2c:3a:2c:87:22";
|
||||||
"172.20.73.163" = "b8:27:eb:16:31:61";
|
"172.20.73.163" = "ca:9f:27:b2:bf:6d";
|
||||||
"172.20.73.164" = "ca:71:c4:90:3e:c7";
|
"172.20.73.164" = "60:01:94:6f:81:a6";
|
||||||
};
|
};
|
||||||
time = lib.mkForce 900;
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
priv24 = {
|
priv24 = {
|
||||||
|
@ -305,11 +303,7 @@ lib.mkMerge (
|
||||||
subnet4 = "172.20.75.208/28";
|
subnet4 = "172.20.75.208/28";
|
||||||
dhcp = {
|
dhcp = {
|
||||||
start = "172.20.75.210";
|
start = "172.20.75.210";
|
||||||
end = "172.20.75.221";
|
end = "172.20.75.222";
|
||||||
fixed-hosts = {
|
|
||||||
# zw-ev-vm
|
|
||||||
"172.20.75.222" = "92:a8:00:49:a6:61";
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
priv32 = {
|
priv32 = {
|
||||||
|
@ -400,62 +394,6 @@ lib.mkMerge (
|
||||||
end = "172.20.76.46";
|
end = "172.20.76.46";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
priv43 = {
|
|
||||||
hosts4 = { priv43-gw = "172.20.76.97"; };
|
|
||||||
subnet4 = "172.20.76.96/28";
|
|
||||||
dhcp = {
|
|
||||||
start = "172.20.76.98";
|
|
||||||
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 = {
|
site.hosts = {
|
||||||
|
@ -574,7 +512,7 @@ lib.mkMerge (
|
||||||
hwaddr = "0A:14:47:02:2A:19";
|
hwaddr = "0A:14:47:02:2A:19";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
ospf.allowedUpstreams = [ "upstream3" "upstream4" "anon1" "freifunk" ];
|
ospf.allowedUpstreams = [ "upstream3" "upstream4" "upstream1" "anon1" "freifunk" ];
|
||||||
};
|
};
|
||||||
priv18-gw = {
|
priv18-gw = {
|
||||||
interfaces = {
|
interfaces = {
|
||||||
|
@ -726,48 +664,6 @@ lib.mkMerge (
|
||||||
priv42.hwaddr = "0A:14:48:01:2A:51";
|
priv42.hwaddr = "0A:14:48:01:2A:51";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
priv43-gw = {
|
|
||||||
interfaces = {
|
|
||||||
core.hwaddr = "0A:14:48:01:2A:52";
|
|
||||||
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 = {
|
site.net.pub = {
|
||||||
dhcp = {
|
dhcp = {
|
||||||
start = "172.20.78.2";
|
end = "172.20.79.254";
|
||||||
end = "172.20.79.253";
|
max-time = 3600;
|
||||||
router = "pub-gw";
|
router = "pub-gw.pub";
|
||||||
server = "pub-gw";
|
server = "pub-gw";
|
||||||
time = 120;
|
start = "172.20.78.2";
|
||||||
max-time = 12 * 3600;
|
time = 300;
|
||||||
};
|
};
|
||||||
domainName = "pub.zentralwerk.org";
|
domainName = "pub.zentralwerk.org";
|
||||||
dynamicDomain = true;
|
dynamicDomain = true;
|
||||||
hosts4 = {
|
hosts4 = { pub-gw = "172.20.78.1"; };
|
||||||
pub-gw = "172.20.78.1";
|
hosts6 = { dn42 = { pub-gw = "fd23:42:c3d2:583::1"; }; };
|
||||||
};
|
|
||||||
hosts6 = {
|
|
||||||
dn42 = {
|
|
||||||
pub-gw = "fd23:42:c3d2:583::1";
|
|
||||||
};
|
|
||||||
flpk = {
|
|
||||||
pub-gw = "2a0f:5382:acab:1403::1";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
subnet4 = "172.20.78.0/23";
|
subnet4 = "172.20.78.0/23";
|
||||||
subnets6 = {
|
subnets6 = { dn42 = "fd23:42:c3d2:583::/64"; };
|
||||||
dn42 = "fd23:42:c3d2:583::/64";
|
|
||||||
flpk = "2a0f:5382:acab:1403::/64";
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
site.hosts.pub-gw = {
|
site.hosts.pub-gw = {
|
||||||
|
@ -41,7 +29,6 @@
|
||||||
};
|
};
|
||||||
ospf = {
|
ospf = {
|
||||||
allowedUpstreams = [ "anon1" "freifunk" ];
|
allowedUpstreams = [ "anon1" "freifunk" ];
|
||||||
allowedUpstreams6 = [ "flpk-gw" "anon1" "freifunk" ];
|
|
||||||
};
|
};
|
||||||
role = "container";
|
role = "container";
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,18 +0,0 @@
|
||||||
{
|
|
||||||
site.net.roof = {
|
|
||||||
# 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";
|
|
||||||
};
|
|
||||||
hosts6.dn42 = {
|
|
||||||
ap57 = "fd23:42:c3d2:584::39";
|
|
||||||
ap58 = "fd23:42:c3d2:584::40";
|
|
||||||
};
|
|
||||||
subnets6.dn42 = "fd23:42:c3d2:584::/64";
|
|
||||||
};
|
|
||||||
}
|
|
|
@ -7,136 +7,123 @@
|
||||||
serv-gw = "172.20.73.1";
|
serv-gw = "172.20.73.1";
|
||||||
dns = "172.20.73.2";
|
dns = "172.20.73.2";
|
||||||
stats = "172.20.73.3";
|
stats = "172.20.73.3";
|
||||||
dresden-zone = "172.20.73.4";
|
radius = "172.20.73.4";
|
||||||
tlms-elastic = "172.20.73.7"; # tlms
|
zeit = "172.20.73.5";
|
||||||
|
minecraft = "172.20.73.6";
|
||||||
|
used1 = "172.20.73.7";
|
||||||
dnscache = "172.20.73.8";
|
dnscache = "172.20.73.8";
|
||||||
tlms-ctfd = "172.20.73.9"; # tlms
|
used2 = "172.20.73.9";
|
||||||
buzzrelay = "172.20.73.15";
|
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";
|
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";
|
spaceapi = "172.20.73.25";
|
||||||
|
used13 = "172.20.73.26";
|
||||||
mucbot = "172.20.73.27";
|
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";
|
scrape = "172.20.73.32";
|
||||||
pretalx = "172.20.73.33";
|
used19 = "172.20.73.33";
|
||||||
vaultwarden = "172.20.73.34";
|
used20 = "172.20.73.34";
|
||||||
uranus = "172.20.73.37"; # tlms
|
used21 = "172.20.73.35";
|
||||||
tram-borzoi = "172.20.73.38"; # tlms
|
used22 = "172.20.73.36";
|
||||||
borken-data-hoarder = "172.20.73.39"; # tlms
|
used23 = "172.20.73.37";
|
||||||
matrix = "172.20.73.40";
|
used24 = "172.20.73.38";
|
||||||
activity-relay = "172.20.73.41";
|
used25 = "172.20.73.39";
|
||||||
luulaatsch-asterisk = "172.20.73.42";
|
used26 = "172.20.73.40";
|
||||||
|
# unused = "172.22.73.41";
|
||||||
|
# unused = "172.22.73.42";
|
||||||
grafana = "172.20.73.43";
|
grafana = "172.20.73.43";
|
||||||
|
kibana = "172.20.73.44";
|
||||||
public-access-proxy = "172.20.73.45";
|
public-access-proxy = "172.20.73.45";
|
||||||
marenz = "172.20.73.46";
|
marenz = "172.20.73.46";
|
||||||
network-homepage = "172.20.73.47";
|
leonos = "172.20.73.47";
|
||||||
home-assistant = "172.20.73.48";
|
minetest = "172.20.73.48";
|
||||||
hydra = "172.20.73.49";
|
hydra = "172.20.73.49";
|
||||||
owncast = "172.20.73.50";
|
netboot = "172.20.73.50";
|
||||||
nfsroot = "172.20.73.51";
|
vps1 = "172.20.73.51";
|
||||||
ticker = "172.20.73.52";
|
ticker = "172.20.73.52";
|
||||||
gitea = "172.20.73.53";
|
gitea = "172.20.73.53";
|
||||||
stream = "172.20.73.54";
|
stream = "172.20.73.54";
|
||||||
jabber = "172.20.73.55";
|
jabber = "172.20.73.55";
|
||||||
mobilizon = "172.20.73.56";
|
mobilizon = "172.20.73.56";
|
||||||
radiobert = "172.20.73.57";
|
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";
|
sdrweb = "172.20.73.60";
|
||||||
knot = "172.20.73.61";
|
bind = "172.20.73.61";
|
||||||
blogs = "172.20.73.62";
|
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.dn42 = "fd23:42:c3d2:582::/64";
|
||||||
subnets6.up4 = "2a00:8180:2c00:282::/64";
|
subnets6.up4 = "2a00:8180:2c00:282::/64";
|
||||||
hosts6.dn42 = {
|
hosts6.dn42 = {
|
||||||
knot = "fd23:42:c3d2:582:cd7:56ff:fe69:6366";
|
bind = "fd23:42:c3d2:582:cd7:56ff:fe69:6366";
|
||||||
blogs = "fd23:42:c3d2:582:b8a8:7dff:fee8:5ac2";
|
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";
|
dns = "fd23:42:c3d2:582:2:0:0:2";
|
||||||
dnscache = "fd23:42:c3d2:582:f096:dbff:fee8:427d";
|
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";
|
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";
|
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";
|
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";
|
mobilizon = "fd23:42:c3d2:582:48d1:5cff:fea7:1676";
|
||||||
mongo = "fd23:42:c3d2:582:14ec:c8ff:fe0a:fc5c";
|
mongo = "fd23:42:c3d2:582:14ec:c8ff:fe0a:fc5c";
|
||||||
mucbot = "fd23:42:c3d2:582:28db:dff:fe6b:e89a";
|
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";
|
radiobert = "fd23:42:c3d2:582:e65f:1ff:fe5d:1679";
|
||||||
radius = "fd23:42:c3d2:582:2:0:0:4";
|
radius = "fd23:42:c3d2:582:2:0:0:4";
|
||||||
sdrweb = "fd23:42:c3d2:582:3078:bbff:fe76:e9ef";
|
sdrweb = "fd23:42:c3d2:582:3078:bbff:fe76:e9ef";
|
||||||
serv-gw = "fd23:42:c3d2:582::1";
|
serv-gw = "fd23:42:c3d2:582::1";
|
||||||
spaceapi = "fd23:42:c3d2:582:1457:adff:fe93:62e9";
|
spaceapi = "fd23:42:c3d2:582:1457:adff:fe93:62e9";
|
||||||
stats = "fd23:42:c3d2:582:2:0:0:3";
|
stats = "fd23:42:c3d2:582:2:0:0:3";
|
||||||
staging-data-hoarder = "fd23:42:c3d2:582:2de:5bff:fef9:e23d";
|
zeit = "fd23:42:c3d2:582:2:0:0:5";
|
||||||
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";
|
|
||||||
};
|
};
|
||||||
hosts6.up4 = {
|
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";
|
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";
|
dns = "2a00:8180:2c00:282:2:0:0:2";
|
||||||
dnscache = "2a00:8180:2c00:282:f096:dbff:fee8:427d";
|
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";
|
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";
|
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";
|
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";
|
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";
|
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";
|
public-access-proxy = "2a00:8180:2c00:282:1024:5fff:febd:9be7";
|
||||||
radiobert = "2a00:8180:2c00:282:e65f:1ff:fe5d:1679";
|
radiobert = "2a00:8180:2c00:282:e65f:1ff:fe5d:1679";
|
||||||
radius = "2a00:8180:2c00:282:2:0:0:4";
|
radius = "2a00:8180:2c00:282:2:0:0:4";
|
||||||
scrape = "2a00:8180:2c00:282:e073:50ff:fef5:eb6e";
|
scrape = "2a00:8180:2c00:282:e073:50ff:fef5:eb6e";
|
||||||
sdrweb = "2a00:8180:2c00:282:3078:bbff:fe76:e9ef";
|
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";
|
spaceapi = "2a00:8180:2c00:282:1457:adff:fe93:62e9";
|
||||||
stats = "2a00:8180:2c00:282:2:0:0:3";
|
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";
|
ticker = "2a00:8180:2c00:282:b407:40ff:fec1:81f2";
|
||||||
staging-data-hoarder = "2a00:8180:2c00:282:2de:5bff:fef9:e23d";
|
zeit = "2a00:8180:2c00:282:2:0:0:5";
|
||||||
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";
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -160,6 +147,9 @@
|
||||||
dnscache = makeContainer {
|
dnscache = makeContainer {
|
||||||
services.dnscache.enable = true;
|
services.dnscache.enable = true;
|
||||||
};
|
};
|
||||||
|
netboot = makeContainer {
|
||||||
|
interfaces.serv.hwaddr = "0A:14:48:01:15:01";
|
||||||
|
};
|
||||||
serv-gw = makeContainer {
|
serv-gw = makeContainer {
|
||||||
interfaces = {
|
interfaces = {
|
||||||
core = {
|
core = {
|
||||||
|
@ -175,16 +165,10 @@
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
ospf.allowedUpstreams =
|
ospf.allowedUpstreams =
|
||||||
[ "upstream4" "upstream3" "anon1" "freifunk" ];
|
[ "upstream4" "upstream1" "upstream3" "anon1" "freifunk" ];
|
||||||
};
|
};
|
||||||
stats = makeContainer {
|
stats = makeContainer {
|
||||||
interfaces.serv.hwaddr = "0A:14:48:01:15:00";
|
interfaces.serv.hwaddr = "0A:14:48:01:15:00";
|
||||||
};
|
};
|
||||||
|
|
||||||
hydra = {
|
|
||||||
role = "client";
|
|
||||||
model = "nixos";
|
|
||||||
interfaces.serv.type = "phys";
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,10 +2,153 @@
|
||||||
let
|
let
|
||||||
servHosts = config.site.net.serv.hosts4;
|
servHosts = config.site.net.serv.hosts4;
|
||||||
inherit (config.site.net.c3d2.hosts4) dn42;
|
inherit (config.site.net.c3d2.hosts4) dn42;
|
||||||
inherit (config.site.net.flpk.hosts4) c3d2-web;
|
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
site.hosts = {
|
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;
|
||||||
|
}
|
||||||
|
];
|
||||||
|
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 = {
|
upstream3 = {
|
||||||
interfaces = {
|
interfaces = {
|
||||||
core = {
|
core = {
|
||||||
|
@ -28,191 +171,203 @@ in
|
||||||
role = "container";
|
role = "container";
|
||||||
};
|
};
|
||||||
|
|
||||||
upstream4 = rec {
|
upstream4 = {
|
||||||
forwardPorts = [
|
forwardPorts = [
|
||||||
{ # http
|
{
|
||||||
destination = servHosts.public-access-proxy;
|
destination = "172.20.73.45";
|
||||||
proto = "tcp";
|
proto = "tcp";
|
||||||
|
reflect = true;
|
||||||
sourcePort = 80;
|
sourcePort = 80;
|
||||||
}
|
}
|
||||||
{ # https
|
{
|
||||||
destination = servHosts.public-access-proxy;
|
destination = "172.20.73.45";
|
||||||
proto = "tcp";
|
proto = "tcp";
|
||||||
|
reflect = true;
|
||||||
sourcePort = 443;
|
sourcePort = 443;
|
||||||
}
|
}
|
||||||
{ # gemini
|
|
||||||
destination = "${c3d2-web}:1965";
|
|
||||||
proto = "tcp";
|
|
||||||
sourcePort = 1965;
|
|
||||||
}
|
|
||||||
{
|
{
|
||||||
destination = servHosts.knot;
|
destination = "172.20.73.61";
|
||||||
proto = "tcp";
|
proto = "tcp";
|
||||||
|
reflect = false;
|
||||||
sourcePort = 53;
|
sourcePort = 53;
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
destination = servHosts.knot;
|
destination = "172.20.73.61";
|
||||||
proto = "udp";
|
proto = "udp";
|
||||||
|
reflect = false;
|
||||||
sourcePort = 53;
|
sourcePort = 53;
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
destination = dn42;
|
destination = dn42;
|
||||||
proto = "udp";
|
proto = "udp";
|
||||||
|
reflect = true;
|
||||||
sourcePort = 2325;
|
sourcePort = 2325;
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
destination = dn42;
|
destination = dn42;
|
||||||
proto = "udp";
|
proto = "udp";
|
||||||
sourcePort = 2327;
|
reflect = true;
|
||||||
}
|
|
||||||
{
|
|
||||||
destination = dn42;
|
|
||||||
proto = "udp";
|
|
||||||
sourcePort = 2337;
|
|
||||||
}
|
|
||||||
{
|
|
||||||
destination = dn42;
|
|
||||||
proto = "udp";
|
|
||||||
sourcePort = 2338;
|
|
||||||
}
|
|
||||||
{
|
|
||||||
destination = dn42;
|
|
||||||
proto = "udp";
|
|
||||||
sourcePort = 2339;
|
|
||||||
}
|
|
||||||
{
|
|
||||||
destination = dn42;
|
|
||||||
proto = "udp";
|
|
||||||
sourcePort = 2340;
|
|
||||||
}
|
|
||||||
{
|
|
||||||
destination = dn42;
|
|
||||||
proto = "udp";
|
|
||||||
sourcePort = 2342;
|
|
||||||
}
|
|
||||||
{
|
|
||||||
destination = dn42;
|
|
||||||
proto = "udp";
|
|
||||||
sourcePort = 2399;
|
sourcePort = 2399;
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
destination = dn42;
|
destination = dn42;
|
||||||
proto = "udp";
|
proto = "udp";
|
||||||
sourcePort = 24699;
|
reflect = true;
|
||||||
|
sourcePort = 2327;
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
destination = dn42;
|
destination = dn42;
|
||||||
proto = "udp";
|
proto = "udp";
|
||||||
sourcePort = 64699;
|
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 = "${servHosts.leonos}:22";
|
||||||
|
proto = "tcp";
|
||||||
|
reflect = true;
|
||||||
|
sourcePort = 2223;
|
||||||
|
}
|
||||||
|
{
|
||||||
|
destination = servHosts.minetest;
|
||||||
|
proto = "udp";
|
||||||
|
reflect = true;
|
||||||
|
sourcePort = 30000;
|
||||||
}
|
}
|
||||||
# ?
|
# ?
|
||||||
{
|
{
|
||||||
destination = "172.22.99.175:22";
|
destination = "172.22.99.175:22";
|
||||||
proto = "tcp";
|
proto = "tcp";
|
||||||
|
reflect = true;
|
||||||
sourcePort = 2224;
|
sourcePort = 2224;
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
destination = servHosts.gitea;
|
destination = servHosts.gitea;
|
||||||
proto = "tcp";
|
proto = "tcp";
|
||||||
|
reflect = true;
|
||||||
sourcePort = 22;
|
sourcePort = 22;
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
destination = servHosts.jabber;
|
destination = servHosts.jabber;
|
||||||
proto = "tcp";
|
proto = "tcp";
|
||||||
|
reflect = true;
|
||||||
sourcePort = 5222;
|
sourcePort = 5222;
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
destination = servHosts.jabber;
|
destination = servHosts.jabber;
|
||||||
proto = "tcp";
|
proto = "tcp";
|
||||||
|
reflect = true;
|
||||||
sourcePort = 5223;
|
sourcePort = 5223;
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
destination = servHosts.jabber;
|
destination = servHosts.jabber;
|
||||||
proto = "tcp";
|
proto = "tcp";
|
||||||
|
reflect = true;
|
||||||
sourcePort = 5269;
|
sourcePort = 5269;
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
destination = servHosts.jabber;
|
destination = servHosts.jabber;
|
||||||
proto = "tcp";
|
proto = "tcp";
|
||||||
|
reflect = true;
|
||||||
sourcePort = 3478;
|
sourcePort = 3478;
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
destination = servHosts.jabber;
|
destination = servHosts.jabber;
|
||||||
proto = "tcp";
|
proto = "tcp";
|
||||||
|
reflect = true;
|
||||||
sourcePort = 3479;
|
sourcePort = 3479;
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
destination = servHosts.jabber;
|
destination = servHosts.jabber;
|
||||||
proto = "udp";
|
proto = "udp";
|
||||||
|
reflect = true;
|
||||||
sourcePort = 3478;
|
sourcePort = 3478;
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
destination = servHosts.jabber;
|
destination = servHosts.jabber;
|
||||||
proto = "udp";
|
proto = "udp";
|
||||||
|
reflect = true;
|
||||||
sourcePort = 3479;
|
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
|
# poelzi
|
||||||
{
|
{
|
||||||
destination = "172.20.73.162:22";
|
destination = "172.20.73.162:22";
|
||||||
proto = "tcp";
|
proto = "tcp";
|
||||||
|
reflect = true;
|
||||||
sourcePort = 2323;
|
sourcePort = 2323;
|
||||||
}
|
}
|
||||||
# jan
|
|
||||||
{
|
|
||||||
destination = "172.20.75.3:51820";
|
|
||||||
proto = "udp";
|
|
||||||
sourcePort = 30057;
|
|
||||||
}
|
|
||||||
# zw-ev RDP
|
# zw-ev RDP
|
||||||
{
|
{
|
||||||
destination = "172.20.75.222:3389";
|
destination = "172.20.75.222:3389";
|
||||||
proto = "tcp";
|
proto = "tcp";
|
||||||
sourcePort = 45000;
|
|
||||||
}
|
|
||||||
{
|
|
||||||
destination = config.site.net.core.hosts4.vpn-gw;
|
|
||||||
proto = "udp";
|
|
||||||
sourcePort = config.site.vpn.wireguard.port;
|
|
||||||
reflect = true;
|
reflect = true;
|
||||||
}
|
sourcePort = 45000;
|
||||||
{
|
|
||||||
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";
|
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
interfaces = {
|
interfaces = {
|
||||||
|
@ -238,12 +393,7 @@ in
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
ospf = {
|
ospf.upstreamInstance = 8;
|
||||||
upstreamInstance = 8;
|
|
||||||
stubNets4 = [
|
|
||||||
"${interfaces.up4-pppoe.upstream.staticIpv4Address}/32"
|
|
||||||
];
|
|
||||||
};
|
|
||||||
role = "container";
|
role = "container";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -264,7 +414,7 @@ in
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
ospf = {
|
ospf = {
|
||||||
allowedUpstreams = [ "upstream3" "upstream4" "freifunk" ];
|
allowedUpstreams = [ "upstream1" "upstream3" "upstream4" "freifunk" ];
|
||||||
upstreamInstance = 5;
|
upstreamInstance = 5;
|
||||||
};
|
};
|
||||||
role = "container";
|
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" ];
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
18
config/net/yggdrasil.nix
Normal file
18
config/net/yggdrasil.nix
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
{
|
||||||
|
site.hosts.yggdrasil = {
|
||||||
|
role = "container";
|
||||||
|
interfaces = {
|
||||||
|
core = {
|
||||||
|
hwaddr = "0A:14:48:01:26:ff";
|
||||||
|
type = "veth";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
ospf = {
|
||||||
|
allowedUpstreams =
|
||||||
|
[ "upstream3" "upstream1" "upstream4" "anon1" "freifunk" ];
|
||||||
|
stubNets6 = [ "200::/7" ];
|
||||||
|
};
|
||||||
|
|
||||||
|
services.yggdrasil.enable = true;
|
||||||
|
};
|
||||||
|
}
|
|
@ -1,85 +1,62 @@
|
||||||
-----BEGIN PGP MESSAGE-----
|
-----BEGIN PGP MESSAGE-----
|
||||||
|
|
||||||
hQEMA2PKcvDMvlKLAQgAjGer7r8wCoigtDTS5zzUnJI02b3RQvhbqjv4a6RD52ry
|
hQEMA2PKcvDMvlKLAQf/VrM3oRXn8dHbFyxWAps/OAhk83HD4RCIlSQUcEHYHi9i
|
||||||
NzqqX7yIVyOEP2SnqoBpmWHYFJ3WcRb5Io3DXBLjgVHZbWJMP/DtVzHN+1ix3A5T
|
hMr44NqNVms4/E02bWMKlkUZmeEaVo92QmTUYyDF8hZUgZ59Kh0gQoXbSukA+8Kn
|
||||||
ZjxROLc/EDyd+prSvbol5UJkHJeoH7PWwPmO1VPOVZwAV+NGJS/qKXz/wUGFA6y5
|
lJ0HWg3HuAr/XqCDm3AWBzHAhuL8rYg8tKxwbvKNjk5uKd3VhpyEHYapBKmPgP5D
|
||||||
iH6vzetTvxSBt08dYVulzmI/B6MwHUz8W7YTTal7QTKftlyzXWZHydbj1AWJjGoR
|
yeP+OoMwHxm9ltCrNKehWJavGpI0NolcLqoaOVrltwwlLCC6cWxH0SWnM1NUigJ5
|
||||||
qadxsH4ZlqdHJrP/j5Yvw72XgdzAN7MQrofslqFI9ro9nccLQ7Q3B7kzt/EvoOPm
|
3FfakgI2uD4wsfUB2DsIfP5rraCmC/K7PFSRxJ8z4LRDAG1WNxK7CA9oYFSqEIo7
|
||||||
obPHW1I0UFoFXhfTujROXwVlernk6qmxO/oNr5UZB9LqAaroXhliddAzPZPT5qcK
|
axMDZvRfFViqs1grXruTQzI2GAodvMt4Sqw9TXGi4tLrAU8a+GvXDcoIYHe2MmUP
|
||||||
szctWSv1eNlGO44iwIJyrh/Yetmrhll8flPl9URWIi9r383xkawhxG52alUVjRIz
|
dxN/tq8nJUE+PEq6RtdIcuOv1yhkgXHAfzcf7gWIugREglGywfX0Ops9+Mp8UQnz
|
||||||
u2BC3vdrt5o0GfEpZlDo23UbIxLIFbMg2xTXcFBq5TJEw0+owwhz+m+JRrXY9h1+
|
kRbPI4m7zkzIozsq0Q7CSrKVAwT/CC+gpMFtOx+uZOPC02p4za6yL5GMgPBKHmr8
|
||||||
SVlMX0PcUUg4vmX+7/KVIwrSECFpfPcBTSyMafUT6SfxG02/WmvzcEXk8E8hK+a3
|
qbMujryv30Ua48SeVRhgI+ScnUxXBau6VGWOPX4U7v6Y5jtJkea9lFHurNpByAaf
|
||||||
VzolJIqirrv1CRwm60xOucytFI5OnxYI3kV9saiLwB6i9KI8Hw91pM7T+kQmXbbl
|
4y12GFlePqbcVrGdcfCL15fDkhfi5ba1nlpi+dILJYegttis5iNMyueKb2jDzFjk
|
||||||
etRddcQLXdhjRB/bCUJbQeEKZx0gjVAQkTFtdz6tp2vc9u/WS6UMrrQIkzdwLIOg
|
vpY9PG0Npxa9YCq1IPawTEwU4/sFh00psM9jdXBNne33FNyYcpy+gF0+fCU6Y0o6
|
||||||
AXa8JmCtlTcN1uVVDlmQqba5li6ObqM4dtyOwHkXmpwBLObtoSg2yxTExxVwtAxz
|
qXB2V1iSaVLxW1te5UQV2rn0QAKwpbE+c7IL2oEizktBzNEDB94ls0hdzo8j1Umd
|
||||||
CgNcPZ9snnht8MpXGrrzQUsdGfBY4gZ8Hgh1oScqW9b8o5XtT74hdtWXFMv6tE2F
|
wCk6x7UGU0iJCZtg/a6THmDEoa7ib7U4qeBB8XoJYW6VA113ROc+VFbdl1aDyA3o
|
||||||
8bco4QBt6q95aYSi/wcyLwIyhUI+PEh2m5UM7KjYs2xxWbzU7Q0nj70VI9x+0Y+U
|
jCB5zQR0/RI+xrvc9Vn57bmlrOsTVkG0kf17a3MWVfYobpHCg2OBTLlaGEfvdcZ1
|
||||||
Apez4mYlqiep5l94E4Q4wb3rizYeXFAzZDe5FXfcpRgVPHGSq6XWUYSgyQENuRTB
|
EwMGTJhnakJIkbKJdO1b2ljp6NaJMxJdQLVHjyFB6JjDRosZPeW4qO5jRgShMaVL
|
||||||
Ll8usdYLgT3Y7ULxT4O/8OKkDFMyfmTIdSiJRUJ8izMTm0yq5lKrSsqYTZVNOF6v
|
4ZZb3XORms679ItX19DanCEP2ouo8MP9Fbt3y6C/s0YqOOAOOa5o4Wb04098Upod
|
||||||
NDEolddj4DOaRV07DkrQRMpukrTCauZdC/c/hwmr3+ZcaMi33ZKHIbCXex/34D9z
|
7TH70faAtzgcx9nZ4aoPsXWgbvoEGWyJZvoRxF/6X887z+cLYtY+6K709TSsYc+F
|
||||||
0CH3fA0nn/w3jh9CwOKBrT+cbOlMF3gVJbQU8xGgf7QHyaf8dEoayiInk9wKfUJd
|
3TGt8gpt+kzfwuGv9QUQ/tDAdvR3LPQ4zKJ4COJ89ybuop4+GlrQC2v/FvE58LJ+
|
||||||
BQ6YGukQBb6KDDNuDq0r9UYeRPjWc/mGSZkluoEl1GVFkFNpxlKStB68hNRJg63i
|
q1yS/kim+/FsvmwAM+7vYj/wn6hXAWn2rleWTcFgmu4MwIyxfwjUcTXRrUptvnRS
|
||||||
gS/l6jSkj1IKmsnbkJVtC+YwH/Pkx6+fcisXmUGPZ9KUiw2qiCGLFbHm5Shc7YBW
|
juY71sqQMe/44QB2KZNDvNX6efj2ay0Uvx6MXBN2Wfkn0lFrlspcgP1eDdQZDgDU
|
||||||
BpiZzCEjRrp71lB5URbbY+zhf+lcAdxewbw8v0R0tJP2hzmXCqsvJnB4jcEc1YD5
|
HyemCXAYmylUYXVNgwENksKpaV5vbSZSuN0QHzzcpNR/ur3Jne9uPe2AqzXanep9
|
||||||
lFD/4ivgZ95pVaoV+WsjETZZd3pkvo2PQC0f/2momT+KwYAdwcPfwJH8S9FLBjKE
|
ozQoz7YCOlXxqqWzI2dV0JqszoLQA0OarFlGAmR1eA2tfxnUayMjHl85LEk2PGI6
|
||||||
nQRlYRjiUUEMO7TZ9J7a8onyFxozVwH7IJMz/L2wEs0u8dPr3Rj3kpCbHD8tNCE4
|
IMyKIyB28tkue1ualu/deq+3CHBdJmWLUeC7DSSUH8NLzChcnJDZA+Vyiic4Ovdr
|
||||||
BP5s1d+S18vSKNRBYY2z7t1eyBZ+9hu1vgWR7GsAcgwCv6YTfVT8VE9RBdkglwP2
|
N+hTeUQM6BHIGNtgX7LtH+2phdA4Mc9Vl2b7AtDghZmz5IcBA90G8PVkhSBY0I/j
|
||||||
Me6G1Af5KMNyQq0GDaKT/pPlS3WCdjpkOHCpw+2HfSjPVDAvWbBkrB8xQrQp8kwg
|
ssphtIroQwfC9Z8vQmmQkwAv/VgHIstp8UM51K1c24ckCFduu2Vo6SOaDUwV2efF
|
||||||
mHMD9udGsfpUSQVoNxIjIeK9EfFEjgXA+53/BVuCbSL5bWQXnKCMba656z7UrWqo
|
x/F4RPHr/A2TzdAZj3cIe5S4Gkc9D/5p8PJ2w2MuP+fKWTE9Z3IM7BlbO6VlLbxq
|
||||||
NqVdJ7c8N7/U9fxaUaagDoziBUsV+eT58eGFRZJJHkbDZvmRthYOQnR82KSQz2cx
|
VZTIzjtivJKaD7B0hpyWcjqI6GU3o3FvMyOLCFTJvrXpWfCAErsHf1I8vtPI2T7I
|
||||||
Neo9z3mSVA8FVRnwNaSNZiHRRKoFY+6HfDOmP5PzAIrW1/TBVYR6+5gmqou3KPqY
|
eBYl85LNOiqPTDkjqQHFe/BahPzNS8c1tdfdCmY1ILRdYCN2DM9RVZmbyypyt49z
|
||||||
1I8DKkVYqlRSve+GXeFIEkeiJ8N5BZ4WZw3EglWSrP+uG7zywJ1pWNja5WNKSzX4
|
K3IHMi3G4RizGXQ+tdfmsqO/n7TInY9p3td2RcYcUT1AfQOkiMV9jBrBuylPcsvh
|
||||||
mXPdI6KxTL40V06SraUqAOhd8uqH4fEhaBJVCqtm9cdXar7dqAbkaX5RARDb/BNg
|
q7AlmlIEPikhlXCxFIkt/zQPy6qyka2GS1n5yl0MyqE40e5pSZkkvBN1dt6+Kvxw
|
||||||
K4m8iDRkrFCO6JYMmwWJz+q/HxY5u71szxFKUiYREeP0udxapekx6IELMwnMrdUT
|
EIUyxRPlFjoQXtDgtAA8vEgl5feNkD1QviM+72dvPOo4lszHLHxdI87hqYCysRCA
|
||||||
GCryJs0VJuRDsOxSyuGprz+UnhY/K7NXRmE6hIrXJQ5mjsHtyjd2vk+OzJY6mL7S
|
XGaCa/qExxuG0Hl+6X7iI9adGlFz9iiQrVYjZoGOXC2z7Vkd8Dr4LY2xSyVHZDaQ
|
||||||
vRZw5FUqRvFsXXLNq/+YtRZSSZChMX0BM42prcC61PIm8qiVLs2199hKWmJmBill
|
W4h7PJ5OPGKhwUY9V8ZDgSdiwLa0Bgoc+fSf/mDZhzOjV34tDh8G4gU3GaZGjG4Z
|
||||||
DZnTJzvm38EWBPkm5JGh4tJ9VN769kyhDtWKtZ4aEuykcPJor+Did+oYuMadKUCN
|
8J2Hj1H4At4McETx+Tg5aqJfFM71EG8no5PNBaKXQ5lInMR5dFh+OUVizGmLDQmi
|
||||||
0NAuKxXAUHc/TfnSxBZxRdHWZo9vyYhiIWNoy5724yWfBH+STgNy3c+Z/JeKXvVB
|
a2aK6SzvwEegijKQWMyHTvPEzJAg/mghM2s1EN4kg12VvO9LEMC7F65YWkpGktg3
|
||||||
YUM4J7ys2TEnTmcoR43MPrF2+bdDsgsItQjtLlBmRvRItdswFYkunuQRBYmXoNBb
|
Zch0J4b5z+QMMDOC/gAkYfalRvraV6rDRzhbrLsQe870zqvdyArurHbmpBpvE1Sv
|
||||||
2MTTxHSU4jyM5FUxBi9XAk0mnWgo/aK/FhfE73VxvVXwfwpEkomL/TFexGzfFx7d
|
sDgcYKWwZ4w8gcxaju4qk9NNkFkPaZP/Cz346HWUDWPr8SbZGZ3O7WNm0JvFy9oS
|
||||||
70T8RWCYgFHOuoe+O04wo2qyvCZZittRQGlInNztDCQI6lqa8TSILVgIRMgvnrcR
|
HwOm32yc8RT2dfzRIj4faGMrGUsXG5dULoyrYfatxDM3ohMt8BvvqJ8i2EVHpZI2
|
||||||
P9BUixDlFfl8x4g0lacxZm9nN5XNgnI1RTiXNXeigIciRydyeAKoV3gxY54i5jOm
|
ZElpBo7qM08+9VpwBpBseBxjE3uAkqBAaBBwRfecJvQuFjgQowk8uOmhGvvPQ+v3
|
||||||
VFUClFfQFz+nBStRQumqxMXKa433J1l8NENmZmkc+D2TeLt8kbgNN4Zg7zKiNRFt
|
lcTIErizNHDyKhbwMvzURNELa6TqThaeHQi3X9djiSvl+uUgu1nGnCZwK/ApYa0a
|
||||||
UvFEtqPxQSiFgLCjrMH2wLkq79EtP/Zfpok/1iGbKfT+/bhDFB0iWE0AdIAa0oiu
|
Z0BvM7sap63DTdete3iWo/OKKTL+yU6QpmV69wUNmVn867E+naX7GeqgMS2PcwdI
|
||||||
1JDsSFmoMTtMHgywSvVxaDVE4/0C81D3foLERbc+dwo00+YyROrQ74+mNoFrY4vd
|
kFmWFzKf4m4BpodfJ8II0M3tE3nWYwGRKy72DjrP1TittRyhTIRMKh0N4jnYlh+g
|
||||||
xcDKxgkcZeZXxsUlox0F26OVZ3B7krUQC7EbBBVvdimJk7S0WXTHfR5ENz7lp1C2
|
TeTodvcZL5xL2lwLvxBbULtz0wRVcloB1BPla2LiBlclpdKvKmgRk36gvq3E5N6/
|
||||||
2gRL8Pdj9I4VsOmGAfcNPV2J5RVdRwyL9dSxCPVQ4ECrBqHSPqGbQoT7aHX9b+6A
|
CJ+BQ94QjLa1EcEBjYtK557nyFW2s3Km8tD1+FAO+uj2X9BLq9Qyax/FMteiSwF5
|
||||||
LKCWUqC18NxrRr4dbSxcjkE4w+vPmENrDh+yR7zDgdWY03rGN/jT2CV1le69AAaq
|
rPEfy9OhZH2v2jkYCfc9scFA69PkskfJQ6ZfnJT4mYMmn1UEN3L+Q2b66hdaeIbo
|
||||||
RTf5n+skzsWz+u09bW7b43gpwhh7YeSFKpogNZ8z2ujEr0fkrGsOWWba9z620Xls
|
SmH7Es9xofBN+2MYOYPTg5ptyYUAlLVdnJrgAnKIylPr3iedBLJ2mYK6aDoj3PWT
|
||||||
f/4dPKcNiJLOIOXT555xZSpsgzAtPO1g9QM+l8Q6PZjqAvGjbHsYMw5ao+iwL0qt
|
7klVaCJfxNxb7siiwKJjTvs7Y/7eI1mN5dsPW0OWCWONzR+XGu4wwT+CcZURB086
|
||||||
M93Uj47PxD4qqz4MwYQw8S/dtrUkvBDEoA2fVU/00Fb9XzrECDUffDxHEUmDIcJQ
|
yD4DyFOpZb42RN8NBTwyiKOYVsd/7jUKXat0HQswRy7hDW3qs5aIkLJCaX1vd9an
|
||||||
h/q7ZntcVp//Gy4DeEiqp63s6poWGdbDmccN3hWmzWHEI0HR7pNS/FHEzESCw9oh
|
56b1Fwu9FMhIzEdLPPrJQMLA3xYDh4NiOwO0oy370Pdoy1aPa6lMA7QrQrZXfpsz
|
||||||
PkZzOa76GmyDqbopneVUmtfCuBjahTjVSAv4YlAsqQMI5wUgV+bwlfB7Rm2v8X4R
|
eFpgRSEkzJFlDRTSYsdczx3Kdpe8L9Ha3KJ3m261mQIUucnIFQlES1tfv2au87x6
|
||||||
cyka3F9xWxuC3/5vxuPyyxA1YZc/fzpOqafFCU3mGF2byOKCL0YNuoqUbQBtagHZ
|
48dZRT8EyAoTQiCH8e7sRpZUYllgM71peyQNWSnqoNERp9PL3eRTWzfa9xn9IglD
|
||||||
6rrmGqNjyVuUG15KLBF29sYlJTBYF7tAeyVx2vLJqzKPRMGL2Ph8wg8Rg58eqKgU
|
CyuSAuRgivvSanVqNOX3xFQ1doAT4mfJ2HyA1IZOPXOxSGiueyAAOeUbQOsl7xHv
|
||||||
gUIlCGzxGoqK1fVlrvvRATHplO77s+W/dA0svfSeD3xrtEd5oF9oQeI78A71Vmrw
|
7L7UdvHpVta2Rn1I8kuPrvAGiFkM5ROyMF6bBqkwu+cZ+oNdP8xwZ6ovxOBNeAwV
|
||||||
ZsMech54mketddbn9t2MID8rVWxTtX5xIAxnW5TBfO8DucsqbxsJNm7Edzue0C2L
|
Fx/ZEJZpnU2BAjkZrHA/OLJ7sgFo+Pqo0BpnDaZVO0xtVLYHUMBTqt4uGaHJ/qIJ
|
||||||
i7tDKM5ZSbkivh0C7G1w7cu9SAv7gHStu+3DKGlW7MmCfLSEGk34jRdTRUu/2KAh
|
3KPJDjHq1CRyLFwQ+HKT3QYu9IsvJ33PQGwFcqP8pyuhXX0z3QaLUs9tZ93jW4d3
|
||||||
cbHxHj25mDC6ZPz54FX6iDA0epm0ILVXZa75gjlfq4o9ldjKbR6yueIuc2hy7H1b
|
70XDQ0udMjazKHQnpLpqleVqvG6vDI5KcXRn8GzMyDHsSObak+pKNIm01TjYmDEj
|
||||||
QFlmx415H5TGTpjSJdjXCqvbbwphOIqsN0Qh3ZqUdaboVGipZdlFv3FH/2uxAFKW
|
cDk7a+5d5DNA4ELExj0Py/C3D8JtcQzycnZv6EwGsyLsDTtQhSkGHcvfK6u0SfvD
|
||||||
VMJ1CpFAWe2iLtQEgrxJ15xpsLx+zcFUfftR8vXNRwMcEffV7xQguTugGic5O0DB
|
aWg=
|
||||||
m5Oopo6bB9wMU4tvDRosjnvMEkuwbSPLSA/8JeZFO1zCK8Pa2znYNEwHNxeHiTCT
|
=2R32
|
||||||
+oouXDqdcT9dnH4cg4GeHjVDZO0I9yZL/cMDUPtqN0XySXe8Zj7VxtpQmcePklV/
|
|
||||||
RDoGKHxEVz2a16foONjtVfsoheFHLWAI47IOTFDHA/CSQLCmCqwpfZQIuX2oWRwc
|
|
||||||
aPN4t5Qkx5TllLzL6keXkDV43/yw0dnXBQQDQ/Z4DP5GShwahyFggA/XonKYb9F0
|
|
||||||
B+pz+NOOkZjcFrcFeMr4cMdffc2ACxDJZWH4BHcwM9WICqoefJHlUu65ZTBBlisJ
|
|
||||||
mwP4Xapx8khsln2xXDUfhsoXu5+FHBexyVP1OUmZZ+zO3UEXPa+OwpglqrYGMueE
|
|
||||||
iXEO2lCOi6HrQCd7cvONPEwLaqavojMhsP42ywirWK7J9XuCoaEWtZjlA/Sq2D2B
|
|
||||||
upK6WuFMr+eE5lhrp5LFCRMJoiiwJb/bA7sMdZhg6HjIZNoNkrCvdgvLScbKxHM8
|
|
||||||
4G82FAafs/fbel5mdUNEe3nOXhQX2KH1MkUhnKGv5hi9gsXLaJlQTZBFsjoT8MUX
|
|
||||||
XUNdEWQ/xtGjs7eNBn/MzpP3JeByrDG0u0Tbt2whOkwhKQt+odph7sMRxwtvvniu
|
|
||||||
ij9nA3OlSGpTEItmC1jls29sJy5/0Ojp6Y3v/ZBfG6xh0xhhjpZIoOGQoK1wdG4m
|
|
||||||
m0j6TZqRKwX9FqQ9aCVY65lp/MsdXehe6/EShyT4K56KuGbpDuzoeZRshDPOvcjU
|
|
||||||
A1t44vBp3aYH9gE6QfM/dg8akN+LXOM7komveAbFvcvE8KFVdfHOUJIjPyy+saX0
|
|
||||||
ZHWLrH/SU+vUuFUw9VSuEavar95l9pRyWCeV67DWN2+FY8HESlfltjwiswActvrt
|
|
||||||
uDeIdtd42y4yA5u3BFCGEAWgZm+aVkQxuMN4OynTHM3NGJ6NUOeL8cGMA02KE65v
|
|
||||||
8pg4o3sIjfmsD76srDx7hKIpIe+K4QpAIxxL21HPZuXhE3ksNHh3x5x7hjkvNAUi
|
|
||||||
z3xbaR03avMeSle1LvUH/A88Fn+/0ataHYiQiIM95RXvMdKAk6SNNsN7rp1RZNhV
|
|
||||||
X6cNTBz2uUVbAXMUgbbBc9O2AVMR0pbfAYBKHPm24b+tWMShG/DR9f/mFFdUznEX
|
|
||||||
9+ydjRh9Mh9ZYgzKXqA9SZ/4Zhqn2Mve3r3Rii4K2w6KUbxRHev7FpV/KGgYsMmw
|
|
||||||
bLjSgS/cwQ7Ky9yRM12EmoAcimy/7vpyPRBM1tWnPBKhZf1xq15UM/lf53OcBjxb
|
|
||||||
ezeETqSQc6flKtEAxRv6nWSuormgn6JbClMjhII3velUKyfPCe29HNtFQ3LWJu4R
|
|
||||||
WLMH7A2qx0cIuyOuoFXefWh/9C3fiO72hqI5yQ2x4dxtEutUNTmByxZxTxJD/tSN
|
|
||||||
BI3ZmHeysFpUVdfDdt3Nc/Jw3lQCuBk=
|
|
||||||
=sq5B
|
|
||||||
-----END PGP MESSAGE-----
|
-----END PGP MESSAGE-----
|
||||||
|
|
|
@ -2,8 +2,6 @@
|
||||||
{
|
{
|
||||||
site.net = {
|
site.net = {
|
||||||
core.ospf.secret = "encrypted";
|
core.ospf.secret = "encrypted";
|
||||||
pub.wifi.ieee80211rKey = "2dc40abba46da9490ea0e00f93f18ce5";
|
|
||||||
c3d2.wifi.ieee80211rKey = "d1b1fa2461efc0df9e2d96579607b7f6";
|
|
||||||
};
|
};
|
||||||
|
|
||||||
site.hosts = {
|
site.hosts = {
|
||||||
|
@ -45,6 +43,7 @@
|
||||||
ap40.password = "encrypted";
|
ap40.password = "encrypted";
|
||||||
ap41.password = "encrypted";
|
ap41.password = "encrypted";
|
||||||
ap42.password = "encrypted";
|
ap42.password = "encrypted";
|
||||||
|
ap43.password = "encrypted";
|
||||||
ap44.password = "encrypted";
|
ap44.password = "encrypted";
|
||||||
ap45.password = "encrypted";
|
ap45.password = "encrypted";
|
||||||
ap46.password = "encrypted";
|
ap46.password = "encrypted";
|
||||||
|
@ -58,33 +57,13 @@
|
||||||
ap54.password = "encrypted";
|
ap54.password = "encrypted";
|
||||||
ap55.password = "encrypted";
|
ap55.password = "encrypted";
|
||||||
ap56.password = "encrypted";
|
ap56.password = "encrypted";
|
||||||
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";
|
|
||||||
ap73.password = "encrypted";
|
|
||||||
switch-a1.password = "encrypted";
|
switch-a1.password = "encrypted";
|
||||||
switch-b1.password = "encrypted";
|
switch-b1.password = "encrypted";
|
||||||
switch-b2.password = "encrypted";
|
switch-b2.password = "encrypted";
|
||||||
switch-b3.password = "encrypted";
|
|
||||||
switch-c1.password = "encrypted";
|
switch-c1.password = "encrypted";
|
||||||
switch-c3d2-main.password = "encrypted";
|
switch-c3d2-main.password = "encrypted";
|
||||||
switch-d1.password = "encrypted";
|
switch-d1.password = "encrypted";
|
||||||
switch-dach.password = "encrypted";
|
switch-dach.password = "encrypted";
|
||||||
switch-ds1.password = "encrypted";
|
|
||||||
switch-ds2.password = "encrypted";
|
|
||||||
switch-ds3.password = "encrypted";
|
|
||||||
|
|
||||||
upstream4.interfaces.up4-pppoe.upstream = {
|
upstream4.interfaces.up4-pppoe.upstream = {
|
||||||
user = "encrypted";
|
user = "encrypted";
|
||||||
|
@ -97,75 +76,75 @@
|
||||||
privateKey = "encrypted";
|
privateKey = "encrypted";
|
||||||
publicKey = "encrypted";
|
publicKey = "encrypted";
|
||||||
};
|
};
|
||||||
flpk-gw.interfaces.up-flpk.wireguard = {
|
|
||||||
addresses = [ "fec0::1/64" "192.168.0.1/24" ];
|
yggdrasil.services.yggdrasil.keys = ''
|
||||||
endpoint = "0.0.0.1";
|
{
|
||||||
privateKey = "encrypted";
|
"PublicKey": "0000000000000000000000000000000000000000000000000000000000000000",
|
||||||
publicKey = "encrypted";
|
"PrivateKey": "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
|
||||||
};
|
}
|
||||||
|
'';
|
||||||
|
|
||||||
ap1.wifi."platform/qca953x_wmac".ssids."uebergangsnetz".psk = "encrypted";
|
ap1.wifi."platform/qca953x_wmac".ssids."uebergangsnetz".psk = "encrypted";
|
||||||
ap10.wifi."platform/qca953x_wmac".ssids = {
|
ap10.wifi."platform/qca953x_wmac".ssids = {
|
||||||
|
"Ebs 2000".psk = "encrypted";
|
||||||
"iz-dresden.org".psk = "encrypted";
|
"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 = {
|
ap12.wifi."platform/ar934x_wmac".ssids = {
|
||||||
"IrèneMélix".psk = "encrypted";
|
"IrèneMélix".psk = "encrypted";
|
||||||
"paperheart".psk = "encrypted";
|
"paperheart".psk = "encrypted";
|
||||||
};
|
};
|
||||||
ap15.wifi."platform/ahb/18100000.wmac".ssids."etz250".psk = "encrypted";
|
ap15.wifi."platform/qca955x_wmac".ssids."etz250".psk = "encrypted";
|
||||||
ap17.wifi."platform/ahb/18100000.wmac".ssids = {
|
ap17.wifi."platform/qca955x_wmac".ssids = {
|
||||||
"EDUB".psk = "encrypted";
|
"EDUB".psk = "encrypted";
|
||||||
"Zweitwohnsitz".psk = "encrypted";
|
"Zweitwohnsitz".psk = "encrypted";
|
||||||
"e-Stuetzpunkt".psk = "encrypted";
|
"e-Stuetzpunkt".psk = "encrypted";
|
||||||
};
|
};
|
||||||
ap18.wifi."platform/qca953x_wmac".ssids."Restaurierung Wolff/Kober".psk = "encrypted";
|
ap18.wifi."platform/qca953x_wmac".ssids."Restaurierung Wolff/Kober".psk = "encrypted";
|
||||||
ap19.wifi."platform/qca953x_wmac".ssids = {
|
ap19.wifi."platform/qca953x_wmac".ssids = {
|
||||||
"Bockwurst".psk = "encrypted";
|
"Studio 01127".psk = "encrypted";
|
||||||
"Walter".psk = "encrypted";
|
"Walter".psk = "encrypted";
|
||||||
};
|
};
|
||||||
ap2.wifi = {
|
ap2.wifi = {
|
||||||
"pci0000:00/0000:00:00.0".ssids."C3D2".psk = "encrypted";
|
"pci0000:01/0000:01:00.0".ssids."C3D2".psk = "encrypted";
|
||||||
"platform/ahb/18100000.wmac".ssids = {
|
"platform/qca955x_wmac".ssids."C3D2 legacy".psk = "encrypted";
|
||||||
"C3D2 legacy".psk = "encrypted";
|
|
||||||
"C3D2 IoT".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 = {
|
ap23.wifi = {
|
||||||
"pci0000:00/0000:00:00.0".ssids."LBK Network".psk = "encrypted";
|
"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";
|
ap24.wifi."platform/ar933x_wmac".ssids."farbwerk".psk = "encrypted";
|
||||||
ap25.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";
|
ap26.wifi."pci0000:00/0000:00:00.0".ssids."Dezember".psk = "encrypted";
|
||||||
ap29.wifi = {
|
ap29.wifi = {
|
||||||
"pci0000:00/0000:00:00.0".ssids."jungnickel-fotografie".psk = "encrypted";
|
"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 = {
|
ap3.wifi = {
|
||||||
"pci0000:00/0000:00:00.0".ssids."C3D2".psk = "encrypted";
|
"pci0000:00/0000:00:00.0".ssids."C3D2".psk = "encrypted";
|
||||||
"platform/ar934x_wmac".ssids."C3D2 legacy".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 = {
|
ap31.wifi = {
|
||||||
"pci0000:00/0000:00:00.0".ssids."C3D2".psk = "encrypted";
|
"pci0000:00/0000:00:00.0".ssids."C3D2".psk = "encrypted";
|
||||||
"platform/ahb/18100000.wmac".ssids = {
|
"platform/qca956x_wmac".ssids = {
|
||||||
"C3D2 legacy" = { "psk" = "encrypted"; };
|
"C3D2 legacy" = { "psk" = "encrypted"; };
|
||||||
"C3D2 IoT" = { "psk" = "encrypted"; };
|
|
||||||
"FOTOAKADEMIEdd" = { "psk" = "encrypted"; };
|
"FOTOAKADEMIEdd" = { "psk" = "encrypted"; };
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
ap32.wifi = {
|
ap32.wifi = {
|
||||||
"pci0000:00/0000:00:00.0".ssids."ZW stage".psk = "encrypted";
|
"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 = {
|
ap33.wifi = {
|
||||||
"pci0000:00/0000:00:00.0".ssids."C3D2".psk = "encrypted";
|
"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";
|
ap35.wifi."platform/qca956x_wmac".ssids."Koch".psk = "encrypted";
|
||||||
ap34.wifi."platform/ahb/18100000.wmac".ssids."etz250".psk = "encrypted";
|
|
||||||
ap35.wifi."platform/ahb/18100000.wmac".ssids."Koch".psk = "encrypted";
|
|
||||||
ap36.wifi."platform/ar933x_wmac".ssids."C3D2 legacy".psk = "encrypted";
|
ap36.wifi."platform/ar933x_wmac".ssids."C3D2 legacy".psk = "encrypted";
|
||||||
ap37.wifi = {
|
ap37.wifi = {
|
||||||
"pci0000:00/0000:00:00.0".ssids."hechtfilm.de".psk = "encrypted";
|
"pci0000:00/0000:00:00.0".ssids."hechtfilm.de".psk = "encrypted";
|
||||||
|
@ -176,26 +155,26 @@
|
||||||
"ZW heinrichsgarten" = { "psk" = "encrypted"; };
|
"ZW heinrichsgarten" = { "psk" = "encrypted"; };
|
||||||
"plop" = { "psk" = "encrypted"; };
|
"plop" = { "psk" = "encrypted"; };
|
||||||
};
|
};
|
||||||
"platform/ahb/18100000.wmac".ssids = {
|
"platform/qca956x_wmac".ssids = {
|
||||||
"ZW heinrichsgarten" = { "psk" = "encrypted"; };
|
"ZW heinrichsgarten" = { "psk" = "encrypted"; };
|
||||||
"plop" = { "psk" = "encrypted"; };
|
"plop" = { "psk" = "encrypted"; };
|
||||||
"millimeter" = { "psk" = "encrypted"; };
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
ap39.wifi."platform/10180000.wmac".ssids."EckiTino".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 = {
|
ap40.wifi = {
|
||||||
"pci0000:00/0000:00:00.0".ssids."M".psk = "encrypted";
|
"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 = {
|
ap41.wifi = {
|
||||||
"pci0000:00/0000:00:00.0".ssids."Walter".psk = "encrypted";
|
"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 = {
|
ap42.wifi = {
|
||||||
"pci0000:00/0000:00:00.0".ssids."jam-circle.de".psk = "encrypted";
|
"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 = {
|
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: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";
|
"1e140000.pcie/pci0000:00/0000:00:01.0/0000:02:00.0".ssids."ZW stage".psk = "encrypted";
|
||||||
|
@ -226,7 +205,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: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";
|
"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 = {
|
ap50.wifi = {
|
||||||
"1e140000.pcie/pci0000:00/0000:00:00.0/0000:01:00.0".ssids = {
|
"1e140000.pcie/pci0000:00/0000:00:00.0/0000:01:00.0".ssids = {
|
||||||
"ZW stage legacy".psk = "encrypted";
|
"ZW stage legacy".psk = "encrypted";
|
||||||
|
@ -236,7 +215,7 @@
|
||||||
};
|
};
|
||||||
ap51.wifi = {
|
ap51.wifi = {
|
||||||
"pci0000:01/0000:01:00.0".ssids."antrares".psk = "encrypted";
|
"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 = {
|
ap52.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:00.0/0000:01:00.0".ssids."ZW stage legacy".psk = "encrypted";
|
||||||
|
@ -245,82 +224,17 @@
|
||||||
ap53.wifi."platform/qca953x_wmac".ssids."Karen Koschnick".psk = "encrypted";
|
ap53.wifi."platform/qca953x_wmac".ssids."Karen Koschnick".psk = "encrypted";
|
||||||
ap54.wifi = {
|
ap54.wifi = {
|
||||||
"pci0000:00/0000:00:00.0".ssids."Abyssinia".psk = "encrypted";
|
"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 = {
|
ap55.wifi = {
|
||||||
"pci0000:00/0000:00:00.0".ssids."MagLAN".psk = "encrypted";
|
"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 = {
|
ap56.wifi = {
|
||||||
"pci0000:00/0000:00:00.0".ssids."MagLAN".psk = "encrypted";
|
"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";
|
|
||||||
};
|
|
||||||
ap58.wifi = {
|
|
||||||
"pci0000:00/0000:00:00.0".ssids."Zentralwerk".psk = "encrypted";
|
|
||||||
"platform/ahb/18100000.wmac".ssids."LIZA".psk = "encrypted";
|
|
||||||
};
|
|
||||||
ap59.wifi = {
|
|
||||||
"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";
|
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";
|
|
||||||
};
|
|
||||||
ap73.wifi = {
|
|
||||||
"1e140000.pcie/pci0000:00/0000:00:01.0/0000:02:00.0".ssids."Princess Castle".psk = "encrypted";
|
|
||||||
"1e140000.pcie/pci0000:00/0000:00:01.0/0000:02:00.0+1".ssids."Princess Castle".psk = "encrypted";
|
|
||||||
};
|
|
||||||
ap8.wifi = {
|
ap8.wifi = {
|
||||||
"pci0000:00/0000:00:00.0".ssids."C3D2".psk = "encrypted";
|
"pci0000:00/0000:00:00.0".ssids."C3D2".psk = "encrypted";
|
||||||
"platform/ar934x_wmac".ssids = {
|
"platform/ar934x_wmac".ssids = {
|
||||||
|
@ -331,18 +245,5 @@
|
||||||
ap9.wifi."platform/qca953x_wmac".ssids."Herzzbuehne".psk = "encrypted";
|
ap9.wifi."platform/qca953x_wmac".ssids."Herzzbuehne".psk = "encrypted";
|
||||||
};
|
};
|
||||||
|
|
||||||
site.dyndnsKey = "oYmxXCIa0nArp0679L6v+y/UfnhripOudLv+R5Cop8I=";
|
site.dyndnsKey = "SECRET";
|
||||||
|
|
||||||
site.vpn.wireguard = {
|
|
||||||
privateKey = "wPNXY4ED3Jz3Kz0KOmvfQOou6/wHrgqSsykaMYrtb28=";
|
|
||||||
peers = [ {
|
|
||||||
# privateKey: GOdfeizQZjPmyYnh3LMI3LrYeEtqYMyOvK8KASVgI1Q=
|
|
||||||
publicKey = "4aTjdm/APMTERczvtnLXRFYjSWYsmwPFTumjyno4nx4=";
|
|
||||||
allowedIPs = [
|
|
||||||
"172.20.76.226"
|
|
||||||
"fd23:42:c3d2:585::/64"
|
|
||||||
"2a00:8180:2c00:285::/64"
|
|
||||||
];
|
|
||||||
} ];
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,7 +14,7 @@ let
|
||||||
)
|
)
|
||||||
) {} (builtins.attrValues containers);
|
) {} (builtins.attrValues containers);
|
||||||
|
|
||||||
makeServer = _name: {
|
makeServer = name: {
|
||||||
role = "server";
|
role = "server";
|
||||||
model = "pc";
|
model = "pc";
|
||||||
interfaces = bridgeInterfaces // {
|
interfaces = bridgeInterfaces // {
|
||||||
|
|
|
@ -7,58 +7,16 @@
|
||||||
interfaces = { mgmt.type = "phys"; };
|
interfaces = { mgmt.type = "phys"; };
|
||||||
|
|
||||||
links = {
|
links = {
|
||||||
switch-a2.ports = [ "7" ];
|
switch-c1.ports = [ "7" ];
|
||||||
priv25.ports = [
|
priv25.ports = [ "2" "3" "4" "5" ];
|
||||||
# A6: Kleiner Saal Schaltschrank
|
priv31.ports = [ "6" ];
|
||||||
"1"
|
pub.ports = [ "8" ];
|
||||||
# Kabinett A10
|
iso4.ports = [ "1" ];
|
||||||
"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
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
switch-a2 = {
|
switch-b1 = {
|
||||||
role = "switch";
|
role = "switch";
|
||||||
model = "dumb";
|
model = "linksys-srw2048";
|
||||||
location = "Saal A";
|
|
||||||
|
|
||||||
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" ];
|
|
||||||
ap47.ports = [ "13" ];
|
|
||||||
ap48.ports = [ "14" ];
|
|
||||||
ap49.ports = [ "15" ];
|
|
||||||
ap50.ports = [ "16" ];
|
|
||||||
ap52.ports = [ "17" ];
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
switch-b3 = {
|
|
||||||
role = "switch";
|
|
||||||
model = "junos";
|
|
||||||
location = "Haus B Souterrain";
|
location = "Haus B Souterrain";
|
||||||
interfaces = { mgmt.type = "phys"; };
|
interfaces = { mgmt.type = "phys"; };
|
||||||
|
|
||||||
|
@ -68,144 +26,127 @@
|
||||||
# Ports 21-24 unten seitlich (optional optisch)
|
# Ports 21-24 unten seitlich (optional optisch)
|
||||||
# Port 7 geht aktuell nach Turm C Erdgeschoss und dadurch zur Ecce
|
# Port 7 geht aktuell nach Turm C Erdgeschoss und dadurch zur Ecce
|
||||||
links = {
|
links = {
|
||||||
ap23.ports = [ "ge-0/0/10" ];
|
ap23.ports = [ "g10" ];
|
||||||
ap8.ports = [ "ge-0/0/16" ];
|
ap8.ports = [ "g16" ];
|
||||||
iso1.ports = [ "ge-0/0/2" ];
|
c3d2.ports = [ "g23" ];
|
||||||
iso2.ports = [ "ge-0/0/3" ];
|
iso1.ports = [ "g2" ];
|
||||||
iso3.ports = [ "ge-0/0/4" ];
|
iso2.ports = [ "g3" ];
|
||||||
coloradio.ports = [
|
iso3.ports = [ "g4" ];
|
||||||
# Patchpanel C8
|
mgmt.ports = [ "g1" ];
|
||||||
"ge-0/0/22"
|
serv.ports = [ "g22" ];
|
||||||
];
|
# server1 had g46,g47,g48 too but this switch has too few
|
||||||
c3d2.ports = [
|
# port-channel groups
|
||||||
"ge-0/0/5"
|
server1.ports = [ "g24" ];
|
||||||
"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"
|
|
||||||
];
|
|
||||||
};
|
|
||||||
server2 = {
|
server2 = {
|
||||||
group = "1";
|
group = "1";
|
||||||
ports = [
|
ports = [ "g12" "g38" "g39" "g40" ];
|
||||||
"ge-0/0/38" "ge-0/0/39"
|
|
||||||
"ge-1/0/32" "ge-1/0/33"
|
|
||||||
];
|
|
||||||
};
|
};
|
||||||
hydra = {
|
server5 = {
|
||||||
|
group = "6";
|
||||||
|
ports = [ "g17" "g18" "g19" "g20" ];
|
||||||
|
};
|
||||||
|
server6 = {
|
||||||
|
group = "8";
|
||||||
|
ports = [ "g5" "g6" "g7" "g8" ];
|
||||||
|
};
|
||||||
|
server7 = {
|
||||||
group = "7";
|
group = "7";
|
||||||
trunk = false;
|
ports = [ "g9" "g11" "g14" "g15" ];
|
||||||
ports = [
|
|
||||||
"ge-0/0/14" "ge-0/0/15"
|
|
||||||
"ge-1/0/14" "ge-1/0/15"
|
|
||||||
];
|
|
||||||
};
|
};
|
||||||
server10 = {
|
server8 = {
|
||||||
group = "5";
|
group = "5";
|
||||||
ports = [
|
ports = [ "g35" "g36" "g37" "g13" ];
|
||||||
"ge-0/0/36" "ge-0/0/37"
|
};
|
||||||
"ge-1/0/36" "ge-1/0/37"
|
switch-b2 = {
|
||||||
];
|
group = "3";
|
||||||
|
ports = [ "g25" "g26" "g27" "g28" ];
|
||||||
};
|
};
|
||||||
switch-c1 = {
|
switch-c1 = {
|
||||||
group = "2";
|
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 = {
|
switch-c3d2-main = {
|
||||||
group = "4";
|
group = "4";
|
||||||
ports = [
|
ports = [ "g41" "g42" "g43" "g44" ];
|
||||||
"ge-0/0/26"
|
|
||||||
"ge-0/0/27"
|
|
||||||
"ge-1/0/26"
|
|
||||||
"ge-1/0/27"
|
|
||||||
];
|
|
||||||
};
|
};
|
||||||
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" ];
|
links = {
|
||||||
ap11.ports = [ "ge-1/0/10" ];
|
ap1.ports = [ "GigabitEthernet 1/0/8" ];
|
||||||
ap34.ports = [ "ge-1/0/12" ];
|
ap11.ports = [ "GigabitEthernet 1/0/10" ];
|
||||||
ap18.ports = [ "ge-1/0/18" ];
|
ap15.ports = [ "GigabitEthernet 1/0/12" ];
|
||||||
ap29.ports = [ "ge-0/0/46" ];
|
ap18.ports = [ "GigabitEthernet 1/0/18" ];
|
||||||
ap30.ports = [ "ge-1/0/22" ];
|
ap24.ports = [ "GigabitEthernet 1/0/34" ];
|
||||||
ap35.ports = [ "ge-1/0/23" ];
|
ap25.ports = [ "GigabitEthernet 1/0/35" ];
|
||||||
ap37.ports = [ "ge-1/0/39" ];
|
ap29.ports = [ "GigabitEthernet 1/0/36" ];
|
||||||
ap63.ports = [ "ge-1/0/17" ];
|
ap30.ports = [ "GigabitEthernet 1/0/22" ];
|
||||||
ap40.ports = [ "ge-1/0/21" ];
|
ap35.ports = [ "GigabitEthernet 1/0/23" ];
|
||||||
ap41.ports = [ "ge-0/0/47" ];
|
ap37.ports = [ "GigabitEthernet 1/0/39" ];
|
||||||
ap42.ports = [ "ge-1/0/6" ];
|
ap39.ports = [ "GigabitEthernet 1/0/17" ];
|
||||||
ap5.ports = [ "ge-1/0/7" ];
|
ap40.ports = [ "GigabitEthernet 1/0/21" ];
|
||||||
ap51.ports = [ "ge-1/0/13" ];
|
ap41.ports = [ "GigabitEthernet 1/0/37" ];
|
||||||
ap53.ports = [ "ge-0/0/7" ];
|
ap42.ports = [ "GigabitEthernet 1/0/6" ];
|
||||||
ap72.ports = [ "ge-1/0/38" ];
|
ap5.ports = [ "GigabitEthernet 1/0/7" ];
|
||||||
ap55.ports = [ "ge-1/0/19" ];
|
ap51.ports = [ "GigabitEthernet 1/0/13" ];
|
||||||
ap56.ports = [ "ge-1/0/9" ];
|
ap53.ports = [ "GigabitEthernet 1/0/15" ];
|
||||||
ap60.ports = [ "ge-1/0/20" ];
|
ap54.ports = [ "GigabitEthernet 1/0/38" ];
|
||||||
ap62.ports = [ "ge-0/0/11" ];
|
ap55.ports = [ "GigabitEthernet 1/0/19" ];
|
||||||
ap65.ports = [ "ge-0/0/9" ];
|
ap56.ports = [ "GigabitEthernet 1/0/9" ];
|
||||||
ap66.ports = [ "ge-1/0/43" ];
|
|
||||||
mgmt.ports = [
|
mgmt.ports = [
|
||||||
"ge-0/0/0"
|
"GigabitEthernet1/0/1"
|
||||||
"ge-0/0/1"
|
# server3
|
||||||
"ge-1/0/44"
|
"GigabitEthernet1/0/41"
|
||||||
|
# server1
|
||||||
|
"GigabitEthernet1/0/42"
|
||||||
|
"GigabitEthernet1/0/43"
|
||||||
|
# server5
|
||||||
|
"GigabitEthernet1/0/44"
|
||||||
|
# server6
|
||||||
|
"GigabitEthernet1/0/45"
|
||||||
# server7
|
# server7
|
||||||
"ge-1/0/45"
|
"GigabitEthernet1/0/46"
|
||||||
"ge-1/0/46"
|
|
||||||
# server8
|
# server8
|
||||||
"ge-1/0/47"
|
"GigabitEthernet1/0/47"
|
||||||
# server9
|
# server9
|
||||||
"ge-1/0/48"
|
"GigabitEthernet1/0/48"
|
||||||
];
|
];
|
||||||
flpk.ports = [
|
priv1.ports = [ "GigabitEthernet 1/0/3" ];
|
||||||
# server7
|
priv19.ports = [ "GigabitEthernet 1/0/40" ];
|
||||||
"ge-0/0/40"
|
priv2.ports = [ "GigabitEthernet 1/0/4" ];
|
||||||
];
|
priv24.ports = [ "GigabitEthernet 1/0/14" "GigabitEthernet 1/0/16" ];
|
||||||
priv1.ports = [ "ge-1/0/3" ];
|
priv3.ports = [ "GigabitEthernet 1/0/5" ];
|
||||||
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" ];
|
|
||||||
ap73.ports = [ "ge-0/0/45" ];
|
|
||||||
pub.ports = [
|
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 = {
|
server9 = {
|
||||||
group = "10";
|
group = "3";
|
||||||
ports = [
|
ports = [
|
||||||
"ge-0/0/28"
|
"GigabitEthernet1/0/2"
|
||||||
"ge-0/0/29"
|
"GigabitEthernet1/0/29"
|
||||||
"ge-1/0/28"
|
"GigabitEthernet1/0/32"
|
||||||
"ge-1/0/29"
|
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
server8 = {
|
switch-b1 = {
|
||||||
group = "6";
|
group = "2";
|
||||||
ports = [
|
ports = [
|
||||||
"ge-0/0/41"
|
"TenGigabitEthernet 1/1/1"
|
||||||
"ge-0/0/42"
|
"GigabitEthernet 1/0/25"
|
||||||
"ge-1/0/41"
|
"GigabitEthernet 1/0/26"
|
||||||
"ge-1/0/42"
|
"GigabitEthernet 1/0/27"
|
||||||
];
|
"GigabitEthernet 1/0/28"
|
||||||
};
|
|
||||||
server6 = {
|
|
||||||
group = "9";
|
|
||||||
ports = [
|
|
||||||
"ge-0/0/18"
|
|
||||||
"ge-0/0/19"
|
|
||||||
"ge-1/0/0"
|
|
||||||
"ge-1/0/2"
|
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
@ -219,11 +160,11 @@
|
||||||
|
|
||||||
links = {
|
links = {
|
||||||
# Saal A: durch dummen PoE-Switch mit Aggregation an ap44-50,52 + switch-a1
|
# Saal A: durch dummen PoE-Switch mit Aggregation an ap44-50,52 + switch-a1
|
||||||
switch-a2 = {
|
switch-a1 = {
|
||||||
group = "1";
|
group = "1";
|
||||||
ports = [ "15-16" ];
|
ports = [ "15-16" ];
|
||||||
};
|
};
|
||||||
switch-b3 = {
|
switch-b1 = {
|
||||||
group = "2";
|
group = "2";
|
||||||
ports = [ "21-24" ];
|
ports = [ "21-24" ];
|
||||||
};
|
};
|
||||||
|
@ -238,15 +179,13 @@
|
||||||
ap19.ports = [ "17" ];
|
ap19.ports = [ "17" ];
|
||||||
ap26.ports = [ "18" ];
|
ap26.ports = [ "18" ];
|
||||||
ap38.ports = [ "7" ];
|
ap38.ports = [ "7" ];
|
||||||
ap61.ports = [ "13" ];
|
|
||||||
# Iso nets
|
# Iso nets
|
||||||
iso1.ports = [ "9" ];
|
iso1.ports = [ "9" ];
|
||||||
iso2.ports = [ "10" ];
|
iso2.ports = [ "10" ];
|
||||||
iso3.ports = [ "11" ];
|
iso3.ports = [ "11" ];
|
||||||
iso4.ports = [ "12" ];
|
iso4.ports = [ "12" ];
|
||||||
|
iso5.ports = [ "13" ];
|
||||||
iso6.ports = [ "14" ];
|
iso6.ports = [ "14" ];
|
||||||
# Saal Foyer
|
|
||||||
priv25.ports = [ "20" ];
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -258,7 +197,7 @@
|
||||||
|
|
||||||
links = {
|
links = {
|
||||||
mgmt.ports = [ "1" ];
|
mgmt.ports = [ "1" ];
|
||||||
switch-b3 = {
|
switch-b1 = {
|
||||||
group = "1";
|
group = "1";
|
||||||
ports = [ "21-24" ];
|
ports = [ "21-24" ];
|
||||||
};
|
};
|
||||||
|
@ -269,8 +208,11 @@
|
||||||
# Fenster
|
# Fenster
|
||||||
ap33.ports = [ "5" ];
|
ap33.ports = [ "5" ];
|
||||||
c3d2.ports = [ "8-20" ];
|
c3d2.ports = [ "8-20" ];
|
||||||
|
# Testing
|
||||||
|
ap-test1.ports = [ "4" ];
|
||||||
|
bmx.ports = [ "7" ];
|
||||||
# tmp Datenspuren: VOC
|
# tmp Datenspuren: VOC
|
||||||
iso4.ports = [ "4" "6" "7" ];
|
iso4.ports = [ "6" ];
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -281,13 +223,12 @@
|
||||||
interfaces = { mgmt.type = "phys"; };
|
interfaces = { mgmt.type = "phys"; };
|
||||||
|
|
||||||
links = {
|
links = {
|
||||||
switch-b3 = {
|
switch-b1 = {
|
||||||
group = "1";
|
group = "1";
|
||||||
ports = [ "1" ];
|
ports = [ "1" ];
|
||||||
};
|
};
|
||||||
switch-d2.ports = [ "3" ];
|
|
||||||
|
|
||||||
# Turm D APs
|
# Turm D APs
|
||||||
|
ap3.ports = [ "3" ];
|
||||||
ap7.ports = [ "8" ];
|
ap7.ports = [ "8" ];
|
||||||
ap9.ports = [ "5" ];
|
ap9.ports = [ "5" ];
|
||||||
ap10.ports = [ "4" ];
|
ap10.ports = [ "4" ];
|
||||||
|
@ -296,21 +237,6 @@
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
switch-d2 = {
|
|
||||||
role = "switch";
|
|
||||||
model = "dumb";
|
|
||||||
location = "Turm D Durchgang 1. Etage";
|
|
||||||
|
|
||||||
links = {
|
|
||||||
switch-d1 = {
|
|
||||||
group = "1";
|
|
||||||
ports = [ "12" ];
|
|
||||||
};
|
|
||||||
ap3.ports = [ "1" ];
|
|
||||||
ap59.ports = [ "2" ];
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
switch-dach = {
|
switch-dach = {
|
||||||
role = "switch";
|
role = "switch";
|
||||||
model = "HP-procurve-2824";
|
model = "HP-procurve-2824";
|
||||||
|
@ -321,149 +247,13 @@
|
||||||
mgmt.ports = [ "1" ];
|
mgmt.ports = [ "1" ];
|
||||||
switch-c1.ports = [ "24" ];
|
switch-c1.ports = [ "24" ];
|
||||||
# Freifunk nodes
|
# Freifunk nodes
|
||||||
bmx.ports = [ "12,14,16" ];
|
bmx.ports = [ "10-19" ];
|
||||||
# radiobert
|
# radiobert
|
||||||
serv.ports = [ "7" ];
|
serv.ports = [ "6-9" ];
|
||||||
# Starlink
|
# Starlink
|
||||||
up3.ports = [ "3" ];
|
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;
|
c3d2 = 5;
|
||||||
cluster = 6;
|
cluster = 6;
|
||||||
bmx = 7;
|
bmx = 7;
|
||||||
flpk = 8;
|
|
||||||
coloradio = 9;
|
|
||||||
# Modems
|
# Modems
|
||||||
up1 = 10;
|
up1 = 10;
|
||||||
up2 = 11;
|
up2 = 11;
|
||||||
up3 = 12;
|
up3 = 12;
|
||||||
up4 = 13;
|
up4 = 13;
|
||||||
# Isolated other stuff
|
|
||||||
c3d2iot = 20;
|
|
||||||
# Isolated neighbors directly connectied with their modems
|
# Isolated neighbors directly connectied with their modems
|
||||||
iso1 = 101;
|
iso1 = 101;
|
||||||
iso2 = 102;
|
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
|
gemeinsam kaufen und bezahlen müssen. Such dir einen aus, dann
|
||||||
bestellen und konfigurieren wir ihn.
|
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))
|
* 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)
|
* [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)
|
![WLAN-Router](https://upload.wikimedia.org/wikipedia/commons/thumb/3/34/Linksys-Wireless-G-Router.jpg/280px-Linksys-Wireless-G-Router.jpg)
|
||||||
|
|
||||||
### Netzverteilung
|
### 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.
|
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
|
[C3D2](https://www.c3d2.de/space.html), Haus B Souterrain, genau in der Mitte
|
||||||
|
|
||||||
|
|
||||||
![Kernnetz visualisiert von eri!](core.png)
|
![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": {
|
"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": {
|
"nixpkgs": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1717104653,
|
"lastModified": 1641924320,
|
||||||
"narHash": "sha256-0ZkToL+IOOP3xw0JPgTj8WP8aeKwxNNiG3gr6prfnig=",
|
"narHash": "sha256-DuOpJqoMmQ3Yk4C64QQHFaByhbSIi872He6z5BXY1YM=",
|
||||||
"owner": "SuperSandro2000",
|
"owner": "NixOS",
|
||||||
"repo": "nixpkgs",
|
"repo": "nixpkgs",
|
||||||
"rev": "b15c037e83ebf28278abc1769df8792ea30a223f",
|
"rev": "05f3de54d568dba52efaad966f0e09bfea796dcb",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
"owner": "SuperSandro2000",
|
"owner": "NixOS",
|
||||||
"ref": "nixos-24.05",
|
"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",
|
"repo": "nixpkgs",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
|
@ -55,46 +34,25 @@
|
||||||
"openwrt": {
|
"openwrt": {
|
||||||
"flake": false,
|
"flake": false,
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1713442482,
|
"lastModified": 1641673875,
|
||||||
"narHash": "sha256-OAcv1qiM2V6wPQm4Tz2QnnDpw34pifG6QRDZea7AP9o=",
|
"narHash": "sha256-Eb9tVxE9Pmob/xWZ6wRt95cTycPeyPkyyaaWaz6cWtA=",
|
||||||
"ref": "openwrt-23.05",
|
"ref": "openwrt-21.02",
|
||||||
"rev": "9b33b74ef71225442361d5192d3a727be212c3cd",
|
"rev": "6ced8cad8edd2a04fc6bb914c333c8aac9a1c825",
|
||||||
"revCount": 58296,
|
"revCount": 50927,
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://git.openwrt.org/openwrt/openwrt.git"
|
"url": "https://git.openwrt.org/openwrt/openwrt.git"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
"ref": "openwrt-23.05",
|
"ref": "openwrt-21.02",
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://git.openwrt.org/openwrt/openwrt.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": {
|
"root": {
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"dns-nix": "dns-nix",
|
|
||||||
"nixpkgs": "nixpkgs",
|
"nixpkgs": "nixpkgs",
|
||||||
"openwrt": "openwrt",
|
"nixpkgs-master": "nixpkgs-master",
|
||||||
"openwrt-imagebuilder": "openwrt-imagebuilder"
|
"openwrt": "openwrt"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
44
flake.nix
44
flake.nix
|
@ -2,22 +2,13 @@
|
||||||
description = "Zentralwerk network";
|
description = "Zentralwerk network";
|
||||||
|
|
||||||
inputs = {
|
inputs = {
|
||||||
dns-nix = {
|
nixpkgs.url = "github:NixOS/nixpkgs/release-21.11";
|
||||||
url = "github:SuperSandro2000/dns.nix";
|
nixpkgs-master.url = "github:NixOS/nixpkgs";
|
||||||
inputs.nixpkgs.follows = "nixpkgs";
|
openwrt.url = "git+https://git.openwrt.org/openwrt/openwrt.git?ref=openwrt-21.02";
|
||||||
};
|
openwrt.flake = false;
|
||||||
nixpkgs.url = "github:SuperSandro2000/nixpkgs/nixos-24.05";
|
|
||||||
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";
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
outputs = inputs@{ self, dns-nix, nixpkgs, openwrt, openwrt-imagebuilder }:
|
outputs = inputs@{ self, nixpkgs, nixpkgs-master, openwrt }:
|
||||||
let
|
let
|
||||||
system = "x86_64-linux";
|
system = "x86_64-linux";
|
||||||
systems = [ system ];
|
systems = [ system ];
|
||||||
|
@ -27,23 +18,24 @@
|
||||||
self.lib.nixosSystem {
|
self.lib.nixosSystem {
|
||||||
inherit system;
|
inherit system;
|
||||||
modules = [ self.nixosModule ];
|
modules = [ self.nixosModule ];
|
||||||
specialArgs = {
|
specialArgs.hostName = name;
|
||||||
hostName = name;
|
specialArgs.lib = self.lib;
|
||||||
inherit (self) lib;
|
specialArgs.self = self;
|
||||||
inherit inputs dns-nix self;
|
specialArgs.inputs = inputs;
|
||||||
};
|
specialArgs.nixpkgs-master = nixpkgs-master;
|
||||||
};
|
};
|
||||||
in {
|
in {
|
||||||
# Config, and utilities
|
# Config, and utilities
|
||||||
lib = nixpkgs.lib.extend (_final: _prev:
|
lib = nixpkgs.lib.extend (final: prev:
|
||||||
import ./nix/lib {
|
import ./nix/lib {
|
||||||
inherit self openwrt;
|
inherit self;
|
||||||
inherit (nixpkgs.legacyPackages.x86_64-linux) lib pkgs;
|
inherit openwrt;
|
||||||
|
pkgs = nixpkgs.legacyPackages.x86_64-linux;
|
||||||
});
|
});
|
||||||
|
|
||||||
# Everything that can be built locally outside of NixOS
|
# Everything that can be built locally outside of NixOS
|
||||||
packages = forAllSystems (system:
|
packages = forAllSystems (system:
|
||||||
import ./nix/pkgs { inherit self nixpkgs system openwrt-imagebuilder; }
|
import ./nix/pkgs { inherit self nixpkgs system; }
|
||||||
);
|
);
|
||||||
|
|
||||||
# Configuration for nixosConfigurations
|
# Configuration for nixosConfigurations
|
||||||
|
@ -76,10 +68,12 @@
|
||||||
''
|
''
|
||||||
);
|
);
|
||||||
wrappers = {
|
wrappers = {
|
||||||
"all-device-scripts" = hydraJob;
|
"all-device-scripts" = pkg:
|
||||||
|
hydraJob pkg;
|
||||||
|
|
||||||
"export-config" = exportFileWrapper;
|
"export-config" = exportFileWrapper;
|
||||||
"switch-.*" = exportFileWrapper;
|
"switch-.*" = exportFileWrapper;
|
||||||
"ap.*-image" = exportFileWrapper;
|
"ap.*" = exportFileWrapper;
|
||||||
};
|
};
|
||||||
in
|
in
|
||||||
builtins.mapAttrs (name: pkg:
|
builtins.mapAttrs (name: pkg:
|
||||||
|
|
|
@ -4,14 +4,14 @@
|
||||||
|
|
||||||
let
|
let
|
||||||
result = pkgs.lib.evalModules {
|
result = pkgs.lib.evalModules {
|
||||||
|
args = {
|
||||||
|
inherit self pkgs;
|
||||||
|
};
|
||||||
modules = [
|
modules = [
|
||||||
(
|
(
|
||||||
{ lib, ... }:
|
{ lib, ... }:
|
||||||
with lib;
|
with lib;
|
||||||
{
|
{
|
||||||
config._module.args = {
|
|
||||||
inherit self pkgs;
|
|
||||||
};
|
|
||||||
options.assertions = mkOption {
|
options.assertions = mkOption {
|
||||||
type = with types; listOf unspecified;
|
type = with types; listOf unspecified;
|
||||||
internal = true;
|
internal = true;
|
||||||
|
|
|
@ -55,13 +55,13 @@ let
|
||||||
links' = builtins.tail links;
|
links' = builtins.tail links;
|
||||||
in
|
in
|
||||||
if config.site.hosts ? ${link}
|
if config.site.hosts ? ${link}
|
||||||
then networksBehindLink' seen' (builtins.filter (link: ! seen' ? ${link}) (
|
then networksBehindLink' seen' (
|
||||||
links' ++ (
|
links' ++ (
|
||||||
builtins.attrNames config.site.hosts.${link}.interfaces
|
builtins.attrNames config.site.hosts.${link}.interfaces
|
||||||
) ++ (
|
) ++ (
|
||||||
onlyUnseen (builtins.attrNames config.site.hosts.${link}.links)
|
onlyUnseen (builtins.attrNames config.site.hosts.${link}.links)
|
||||||
)
|
)
|
||||||
))
|
)
|
||||||
else if config.site.net ? ${link}
|
else if config.site.net ? ${link}
|
||||||
then networksBehindLink' seen' links'
|
then networksBehindLink' seen' links'
|
||||||
|
|
||||||
|
@ -102,7 +102,7 @@ let
|
||||||
options = {
|
options = {
|
||||||
vlan = mkOption {
|
vlan = mkOption {
|
||||||
description = "VLAN tag number";
|
description = "VLAN tag number";
|
||||||
type = with types; nullOr int;
|
type = types.int;
|
||||||
};
|
};
|
||||||
subnet4 = mkOption {
|
subnet4 = mkOption {
|
||||||
description = "v.w.x.y/z";
|
description = "v.w.x.y/z";
|
||||||
|
@ -158,11 +158,6 @@ let
|
||||||
type = with types; nullOr (submodule { options = dhcpOpts; });
|
type = with types; nullOr (submodule { options = dhcpOpts; });
|
||||||
default = null;
|
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 {
|
domainName = mkOption {
|
||||||
description = "Domain name option";
|
description = "Domain name option";
|
||||||
type = types.str;
|
type = types.str;
|
||||||
|
@ -178,7 +173,7 @@ let
|
||||||
type = enum [ "A" "AAAA" "MX" "SRV" "CNAME" "TXT" ];
|
type = enum [ "A" "AAAA" "MX" "SRV" "CNAME" "TXT" ];
|
||||||
};
|
};
|
||||||
data = mkOption {
|
data = mkOption {
|
||||||
type = oneOf [ str (attrsOf (oneOf [ int str ])) ];
|
type = str;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
@ -190,26 +185,6 @@ let
|
||||||
default = false;
|
default = false;
|
||||||
description = "Domain updated by DHCP server?";
|
description = "Domain updated by DHCP server?";
|
||||||
};
|
};
|
||||||
mtu = mkOption {
|
|
||||||
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
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
captiveJson = mkOption {
|
|
||||||
type = with types; nullOr str;
|
|
||||||
default = null;
|
|
||||||
description = ''
|
|
||||||
Optional URL to Captive Portal JSON file.
|
|
||||||
|
|
||||||
See: <https://datatracker.ietf.org/doc/html/draft-ietf-capport-api>
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -230,11 +205,6 @@ let
|
||||||
type = with types; nullOr int;
|
type = with types; nullOr int;
|
||||||
default = null;
|
default = null;
|
||||||
};
|
};
|
||||||
noNat.subnets4 = mkOption {
|
|
||||||
type = with types; listOf str;
|
|
||||||
default = [];
|
|
||||||
description = "Do not NAT traffic from these public static subnets";
|
|
||||||
};
|
|
||||||
noNat.subnets6 = mkOption {
|
noNat.subnets6 = mkOption {
|
||||||
type = with types; listOf str;
|
type = with types; listOf str;
|
||||||
default = [];
|
default = [];
|
||||||
|
@ -250,7 +220,7 @@ let
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
interfaceOpts = { ... }: {
|
interfaceOpts = { name, ... }: {
|
||||||
options = {
|
options = {
|
||||||
hwaddr = mkOption {
|
hwaddr = mkOption {
|
||||||
type = with types; nullOr str;
|
type = with types; nullOr str;
|
||||||
|
@ -258,7 +228,7 @@ let
|
||||||
description = "Static MAC address";
|
description = "Static MAC address";
|
||||||
};
|
};
|
||||||
type = mkOption {
|
type = mkOption {
|
||||||
type = types.enum [ "phys" "veth" "pppoe" "bridge" "wireguard" "vxlan" ];
|
type = types.enum [ "phys" "veth" "pppoe" "bridge" "wireguard" ];
|
||||||
description = ''
|
description = ''
|
||||||
veth: Virtual ethernet to be attached to a bridge.
|
veth: Virtual ethernet to be attached to a bridge.
|
||||||
|
|
||||||
|
@ -301,16 +271,6 @@ let
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
vxlan = mkOption {
|
|
||||||
default = null;
|
|
||||||
type = with types; nullOr (submodule {
|
|
||||||
options = {
|
|
||||||
peer = mkOption {
|
|
||||||
type = str;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
});
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -369,8 +329,7 @@ let
|
||||||
# isRouter = Part of the core network?
|
# isRouter = Part of the core network?
|
||||||
default =
|
default =
|
||||||
config.site.hosts.${name}.interfaces ? core &&
|
config.site.hosts.${name}.interfaces ? core &&
|
||||||
config.site.net.core.hosts4 ? ${name} &&
|
config.site.net.core.hosts4 ? ${name};
|
||||||
config.site.hosts.${name}.role == "container";
|
|
||||||
description = "Should this host route?";
|
description = "Should this host route?";
|
||||||
};
|
};
|
||||||
firewall.enable = mkOption {
|
firewall.enable = mkOption {
|
||||||
|
@ -421,11 +380,6 @@ let
|
||||||
default = [];
|
default = [];
|
||||||
description = "Accept default routes from these OSPF routers, in order of preference";
|
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 {
|
ospf.upstreamInstance = mkOption {
|
||||||
type = with types; nullOr int;
|
type = with types; nullOr int;
|
||||||
default = null;
|
default = null;
|
||||||
|
@ -447,6 +401,16 @@ let
|
||||||
type = types.bool;
|
type = types.bool;
|
||||||
default = false;
|
default = false;
|
||||||
};
|
};
|
||||||
|
services.yggdrasil = {
|
||||||
|
enable = mkOption {
|
||||||
|
type = types.bool;
|
||||||
|
default = false;
|
||||||
|
};
|
||||||
|
keys = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
default = "";
|
||||||
|
};
|
||||||
|
};
|
||||||
links = mkOption {
|
links = mkOption {
|
||||||
description = "Which port is connected to what other device? Keys are either network names or known hostnames.";
|
description = "Which port is connected to what other device? Keys are either network names or known hostnames.";
|
||||||
default = {};
|
default = {};
|
||||||
|
@ -455,25 +419,17 @@ let
|
||||||
wifi = mkOption {
|
wifi = mkOption {
|
||||||
default = {};
|
default = {};
|
||||||
type = with types; attrsOf (submodule (
|
type = with types; attrsOf (submodule (
|
||||||
{ config, ... }: {
|
{ name, ... }: {
|
||||||
options = {
|
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 {
|
htmode = mkOption {
|
||||||
type = enum [ "HT20" "HT40-" "HT40+" "HT40" "VHT80" ];
|
type = enum [ "HT20" "HT40-" "HT40+" "VHT80" ];
|
||||||
};
|
};
|
||||||
channel = mkOption {
|
channel = mkOption {
|
||||||
type = int;
|
type = int;
|
||||||
};
|
};
|
||||||
ssids = mkOption {
|
ssids = mkOption {
|
||||||
type = attrsOf (submodule ({ config, ... }: {
|
type = attrsOf (submodule (
|
||||||
|
{ name, ... }: {
|
||||||
options = {
|
options = {
|
||||||
net = mkOption {
|
net = mkOption {
|
||||||
type = str;
|
type = str;
|
||||||
|
@ -482,45 +438,13 @@ let
|
||||||
type = nullOr str;
|
type = nullOr str;
|
||||||
default = null;
|
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.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}));
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
));
|
));
|
||||||
};
|
};
|
||||||
wifiOnLink.enable = mkOption {
|
};
|
||||||
type = types.bool;
|
}
|
||||||
default = true;
|
));
|
||||||
description = ''
|
|
||||||
Install the wifi-on-link.sh script on OpenWRT devices.
|
|
||||||
'';
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
@ -530,7 +454,7 @@ let
|
||||||
type = types.int;
|
type = types.int;
|
||||||
};
|
};
|
||||||
peers = mkOption {
|
peers = mkOption {
|
||||||
type = with types; attrsOf (submodule ({ ... }: {
|
type = with types; attrsOf (submodule ({ name, ... }: {
|
||||||
options = {
|
options = {
|
||||||
asn = mkOption {
|
asn = mkOption {
|
||||||
type = types.int;
|
type = types.int;
|
||||||
|
@ -560,12 +484,8 @@ let
|
||||||
vlans = mkOption {
|
vlans = mkOption {
|
||||||
type = with types; listOf int;
|
type = with types; listOf int;
|
||||||
description = "Automatically generated, do not set";
|
description = "Automatically generated, do not set";
|
||||||
default = builtins.concatMap (net:
|
default = map (net:
|
||||||
let
|
config.site.net.${net}.vlan
|
||||||
inherit (config.site.net.${net}) vlan;
|
|
||||||
in if vlan != null
|
|
||||||
then [ vlan ]
|
|
||||||
else []
|
|
||||||
) config.site.hosts.${hostName}.links.${name}.nets;
|
) config.site.hosts.${hostName}.links.${name}.nets;
|
||||||
};
|
};
|
||||||
trunk = mkOption {
|
trunk = mkOption {
|
||||||
|
@ -580,30 +500,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
|
in
|
||||||
{
|
{
|
||||||
options.site = {
|
options.site = {
|
||||||
|
@ -613,7 +509,6 @@ in
|
||||||
type = with types; attrsOf (submodule netOpts);
|
type = with types; attrsOf (submodule netOpts);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
hosts = mkOption {
|
hosts = mkOption {
|
||||||
description = "All the static hosts";
|
description = "All the static hosts";
|
||||||
default = {};
|
default = {};
|
||||||
|
@ -627,23 +522,6 @@ in
|
||||||
dyndnsKey = mkOption {
|
dyndnsKey = mkOption {
|
||||||
type = types.str;
|
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 =
|
config.warnings =
|
||||||
|
@ -678,7 +556,7 @@ in
|
||||||
else []
|
else []
|
||||||
) (builtins.attrNames config.site.hosts);
|
) (builtins.attrNames config.site.hosts);
|
||||||
in
|
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 "IPv4 subnet" (x: if x.subnet4 == null then [] else [x.subnet4]) config.site.net) ++
|
||||||
(reportCollisions "IPv6 subnet" (x: builtins.attrValues x.subnets6) config.site.net) ++
|
(reportCollisions "IPv6 subnet" (x: builtins.attrValues x.subnets6) config.site.net) ++
|
||||||
ospfUpstreamXorGw;
|
ospfUpstreamXorGw;
|
||||||
|
@ -736,7 +614,7 @@ in
|
||||||
let
|
let
|
||||||
vlan = toString config.site.net.${net}.vlan;
|
vlan = toString config.site.net.${net}.vlan;
|
||||||
in
|
in
|
||||||
if config.site.net.${net}.vlan != null && result ? ${vlan}
|
if result ? ${vlan}
|
||||||
then result // {
|
then result // {
|
||||||
"${vlan}" = result.${vlan} ++ [ net ];
|
"${vlan}" = result.${vlan} ++ [ net ];
|
||||||
}
|
}
|
||||||
|
@ -747,67 +625,5 @@ in
|
||||||
in map (vlan: {
|
in map (vlan: {
|
||||||
assertion = builtins.length vlanNets.${vlan} == 1;
|
assertion = builtins.length vlanNets.${vlan} == 1;
|
||||||
message = "VLAN ${vlan} is used by more than one network: ${lib.concatStringsSep " " vlanNets.${vlan}}";
|
message = "VLAN ${vlan} is used by more than one network: ${lib.concatStringsSep " " vlanNets.${vlan}}";
|
||||||
}) (builtins.attrNames vlanNets))
|
}) (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);
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,13 +1,13 @@
|
||||||
{ self, lib, openwrt, pkgs }:
|
{ self, pkgs, openwrt }:
|
||||||
|
|
||||||
rec {
|
rec {
|
||||||
inherit (import ./config { inherit self pkgs; }) config;
|
config = (import ./config { inherit self pkgs; }).config;
|
||||||
|
|
||||||
netmasks = import ./netmasks.nix;
|
netmasks = import ./netmasks.nix;
|
||||||
|
|
||||||
subnet = import ./subnet { inherit pkgs; };
|
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; };
|
openwrtModels = import ./openwrt-models.nix { inherit self openwrt; };
|
||||||
|
|
||||||
|
@ -15,9 +15,8 @@ rec {
|
||||||
let
|
let
|
||||||
models =
|
models =
|
||||||
builtins.filter ({ models, ... }:
|
builtins.filter ({ models, ... }:
|
||||||
self.lib.any ({ model, vendor, ... }:
|
self.lib.any ({ model, ... }:
|
||||||
model == wantedModel ||
|
model == wantedModel
|
||||||
"${vendor}_${model}" == wantedModel
|
|
||||||
) models
|
) models
|
||||||
) openwrtModels;
|
) openwrtModels;
|
||||||
result =
|
result =
|
||||||
|
|
107
nix/lib/dns.nix
107
nix/lib/dns.nix
|
@ -1,18 +1,15 @@
|
||||||
{ config, lib }:
|
{ pkgs, config }:
|
||||||
|
|
||||||
|
let
|
||||||
|
lib = pkgs.lib;
|
||||||
|
in
|
||||||
rec {
|
rec {
|
||||||
ns = "dns.serv.zentralwerk.org";
|
ns = "dns.serv.zentralwerk.org";
|
||||||
internalNS = [ ns ];
|
internalNS = [ ns ];
|
||||||
# public servers (slaves)
|
# public servers (slaves)
|
||||||
publicNS = [
|
publicNS = [ "ns.c3d2.de" "ns.spaceboyz.net" ];
|
||||||
"ns.c3d2.de"
|
|
||||||
"ns.spaceboyz.net"
|
|
||||||
"ns1.supersandro.de"
|
|
||||||
];
|
|
||||||
|
|
||||||
publicIPv4 = config.site.hosts.upstream4.interfaces.up4-pppoe.upstream.staticIpv4Address;
|
dynamicReverseZones = [
|
||||||
|
|
||||||
dynamicReverseZones4 = [
|
|
||||||
"73.20.172.in-addr.arpa"
|
"73.20.172.in-addr.arpa"
|
||||||
"74.20.172.in-addr.arpa"
|
"74.20.172.in-addr.arpa"
|
||||||
"75.20.172.in-addr.arpa"
|
"75.20.172.in-addr.arpa"
|
||||||
|
@ -21,25 +18,7 @@ rec {
|
||||||
"78.20.172.in-addr.arpa"
|
"78.20.172.in-addr.arpa"
|
||||||
"79.20.172.in-addr.arpa"
|
"79.20.172.in-addr.arpa"
|
||||||
"99.22.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 =
|
localZones =
|
||||||
let
|
let
|
||||||
|
@ -64,9 +43,8 @@ rec {
|
||||||
);
|
);
|
||||||
|
|
||||||
# generate zones only for nets with hosts
|
# generate zones only for nets with hosts
|
||||||
namedNets = lib.filterAttrs (_name: { hosts4, hosts6, dynamicDomain, ... }:
|
namedNets = lib.filterAttrs (name: { hosts4, hosts6, dynamicDomain, ... }:
|
||||||
hosts4 != {} ||
|
(hosts4 != [] && hosts6 != []) ||
|
||||||
hosts6 != {} ||
|
|
||||||
dynamicDomain
|
dynamicDomain
|
||||||
) config.site.net;
|
) config.site.net;
|
||||||
|
|
||||||
|
@ -99,7 +77,7 @@ rec {
|
||||||
"${zone}" = true;
|
"${zone}" = true;
|
||||||
}
|
}
|
||||||
) {} (builtins.attrNames reverseHosts4)
|
) {} (builtins.attrNames reverseHosts4)
|
||||||
) ++ dynamicReverseZones4
|
) ++ dynamicReverseZones
|
||||||
);
|
);
|
||||||
|
|
||||||
# turns `::` into `0000:0000:0000:0000:0000:0000:0000:0000`
|
# turns `::` into `0000:0000:0000:0000:0000:0000:0000:0000`
|
||||||
|
@ -149,8 +127,10 @@ rec {
|
||||||
let
|
let
|
||||||
domain =
|
domain =
|
||||||
if ctx == "dn42"
|
if ctx == "dn42"
|
||||||
then "${net}.zentralwerk.dn42"
|
then namedNets.${net}.domainName
|
||||||
else namedNets.${net}.domainName;
|
else if builtins.match "up.*" ctx != null
|
||||||
|
then "${net}.zentralwerk.org"
|
||||||
|
else throw "Invalid IPv6 context: ${ctx}";
|
||||||
in
|
in
|
||||||
lib.recursiveUpdate result {
|
lib.recursiveUpdate result {
|
||||||
"${ipv6ToReverse hosts.${host}}" = "${host}.${domain}";
|
"${ipv6ToReverse hosts.${host}}" = "${host}.${domain}";
|
||||||
|
@ -160,10 +140,9 @@ rec {
|
||||||
)) {} (builtins.attrNames namedNets);
|
)) {} (builtins.attrNames namedNets);
|
||||||
|
|
||||||
# `{ dn42 = [ "....ip6.arpa" ]; }`
|
# `{ dn42 = [ "....ip6.arpa" ]; }`
|
||||||
reverseZones6 = builtins.mapAttrs (_ctx: reverseHosts6ctx:
|
reverseZones6 = builtins.mapAttrs (ctx: reverseHosts6ctx:
|
||||||
builtins.attrNames (
|
builtins.attrNames (
|
||||||
builtins.foldl' (result: rname:
|
builtins.foldl' (result: rname: result // {
|
||||||
result // {
|
|
||||||
"${builtins.substring ((128 - reverseZone6Size) / 2) (72 - ((128 - reverseZone6Size) / 2)) rname}" = true;
|
"${builtins.substring ((128 - reverseZone6Size) / 2) (72 - ((128 - reverseZone6Size) / 2)) rname}" = true;
|
||||||
}) {} (builtins.attrNames reverseHosts6ctx)
|
}) {} (builtins.attrNames reverseHosts6ctx)
|
||||||
)
|
)
|
||||||
|
@ -172,38 +151,28 @@ rec {
|
||||||
in [ {
|
in [ {
|
||||||
name = "zentralwerk.org";
|
name = "zentralwerk.org";
|
||||||
ns = publicNS;
|
ns = publicNS;
|
||||||
records = [ {
|
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;
|
|
||||||
} ];
|
|
||||||
} {
|
} {
|
||||||
name = "zentralwerk.dn42";
|
name = "zentralwerk.dn42";
|
||||||
ns = internalNS;
|
ns = internalNS;
|
||||||
records = [ ];
|
records = [ {
|
||||||
|
name = "ipa";
|
||||||
|
type = "A";
|
||||||
|
data = config.site.net.serv.hosts4.ipa;
|
||||||
|
} ];
|
||||||
} {
|
} {
|
||||||
name = "dyn.zentralwerk.org";
|
name = "dyn.zentralwerk.org";
|
||||||
ns = publicNS;
|
ns = publicNS;
|
||||||
records = [ {
|
records = [ {
|
||||||
name = "upstream4";
|
name = "upstream1";
|
||||||
type = "A";
|
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.attrValues (
|
||||||
builtins.mapAttrs (net: { dynamicDomain, hosts4, hosts6, extraRecords, ... }: [
|
builtins.mapAttrs (net: { dynamicDomain, hosts4, hosts6, extraRecords, ... }: [
|
||||||
{
|
{
|
||||||
|
@ -219,20 +188,14 @@ rec {
|
||||||
records =
|
records =
|
||||||
hosts4Records hosts4 ++
|
hosts4Records hosts4 ++
|
||||||
lib.optionals (hosts6 ? up4) (hosts6Records hosts6.up4) ++
|
lib.optionals (hosts6 ? up4) (hosts6Records hosts6.up4) ++
|
||||||
lib.optionals (hosts6 ? flpk) (hosts6Records hosts6.flpk) ++
|
|
||||||
extraRecords;
|
extraRecords;
|
||||||
dynamic = dynamicDomain;
|
dynamic = dynamicDomain;
|
||||||
}
|
}
|
||||||
]) namedNets
|
]) namedNets
|
||||||
)
|
)
|
||||||
)
|
) ++ map (zone: {
|
||||||
++
|
|
||||||
map (zone: {
|
|
||||||
name = zone;
|
name = zone;
|
||||||
ns =
|
ns = internalNS;
|
||||||
if isRfc1918Reverse zone
|
|
||||||
then internalNS
|
|
||||||
else publicNS;
|
|
||||||
records =
|
records =
|
||||||
map (reverse: {
|
map (reverse: {
|
||||||
name = builtins.head (
|
name = builtins.head (
|
||||||
|
@ -244,16 +207,17 @@ rec {
|
||||||
builtins.filter (lib.hasSuffix ".${zone}")
|
builtins.filter (lib.hasSuffix ".${zone}")
|
||||||
(builtins.attrNames reverseHosts4)
|
(builtins.attrNames reverseHosts4)
|
||||||
);
|
);
|
||||||
dynamic = builtins.elem zone dynamicReverseZones4;
|
dynamic = builtins.elem zone dynamicReverseZones;
|
||||||
}) reverseZones4
|
}) reverseZones4
|
||||||
++
|
++ builtins.concatMap (ctx:
|
||||||
builtins.concatMap (ctx:
|
|
||||||
map (zone: {
|
map (zone: {
|
||||||
name = zone;
|
name = zone;
|
||||||
ns =
|
ns =
|
||||||
if ctx == "dn42"
|
if ctx == "dn42"
|
||||||
then internalNS
|
then internalNS
|
||||||
else publicNS;
|
else if builtins.match "up.*" ctx != null
|
||||||
|
then publicNS
|
||||||
|
else throw "Invalid IPv6 context: ${ctx}";
|
||||||
records =
|
records =
|
||||||
map (reverse: {
|
map (reverse: {
|
||||||
name = builtins.substring 0 ((128 - reverseZone6Size) / 2 - 1) reverse;
|
name = builtins.substring 0 ((128 - reverseZone6Size) / 2 - 1) reverse;
|
||||||
|
@ -263,7 +227,6 @@ rec {
|
||||||
builtins.filter (lib.hasSuffix ".${zone}")
|
builtins.filter (lib.hasSuffix ".${zone}")
|
||||||
(builtins.attrNames reverseHosts6.${ctx})
|
(builtins.attrNames reverseHosts6.${ctx})
|
||||||
);
|
);
|
||||||
dynamic = builtins.elem zone dynamicReverseZones6;
|
|
||||||
}) reverseZones6.${ctx}
|
}) reverseZones6.${ctx}
|
||||||
) (builtins.attrNames reverseZones6);
|
) (builtins.attrNames reverseZones6);
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,14 +28,8 @@ let
|
||||||
builtins.filter (word:
|
builtins.filter (word:
|
||||||
word != [] && word != ""
|
word != [] && word != ""
|
||||||
) tokens;
|
) tokens;
|
||||||
command =
|
command = builtins.head words;
|
||||||
if words != []
|
args = builtins.tail words;
|
||||||
then builtins.head words
|
|
||||||
else "-";
|
|
||||||
args =
|
|
||||||
if words != []
|
|
||||||
then builtins.tail words
|
|
||||||
else [];
|
|
||||||
|
|
||||||
makeLinkFromArg = port: arg:
|
makeLinkFromArg = port: arg:
|
||||||
builtins.foldl' (result: interface:
|
builtins.foldl' (result: interface:
|
||||||
|
@ -95,9 +89,7 @@ let
|
||||||
|
|
||||||
ucidef_set_interfaces_lan_wan.ports =
|
ucidef_set_interfaces_lan_wan.ports =
|
||||||
makeLinkFromArg "lan" (builtins.elemAt args 0) //
|
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
|
in
|
||||||
if commands ? ${command}
|
if commands ? ${command}
|
||||||
|
|
|
@ -47,15 +47,6 @@ in
|
||||||
Forward true
|
Forward true
|
||||||
Server "${config.site.net.serv.hosts4.spaceapi}" "${toString networkPort}"
|
Server "${config.site.net.serv.hosts4.spaceapi}" "${toString networkPort}"
|
||||||
Server "${config.site.net.serv.hosts4.grafana}" "${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") {
|
}) (lib.optionalAttrs (hostName != "stats") {
|
||||||
plugins.network = ''
|
plugins.network = ''
|
||||||
|
@ -90,7 +81,7 @@ in
|
||||||
Host "inbert.c3d2.de"
|
Host "inbert.c3d2.de"
|
||||||
Host "heise.de"
|
Host "heise.de"
|
||||||
'';
|
'';
|
||||||
}) (lib.optionalAttrs config.services.kea.dhcp4.enable {
|
}) (lib.optionalAttrs config.services.dhcpd4.enable {
|
||||||
plugins.exec =
|
plugins.exec =
|
||||||
let
|
let
|
||||||
maxTimeout = builtins.foldl' (maxTimeout: net:
|
maxTimeout = builtins.foldl' (maxTimeout: net:
|
||||||
|
@ -104,7 +95,7 @@ in
|
||||||
else maxTimeout
|
else maxTimeout
|
||||||
) 180 (builtins.attrNames config.site.net);
|
) 180 (builtins.attrNames config.site.net);
|
||||||
in ''
|
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 {
|
}) (lib.optionalAttrs config.services.unbound.enable {
|
||||||
plugins.exec = ''
|
plugins.exec = ''
|
||||||
|
@ -115,29 +106,4 @@ in
|
||||||
Exec "nobody" "${self.packages.${system}.starlink-stats}/bin/starlink-stats" "192.168.100.1:9200"
|
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";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
32
nix/nixos-module/collectd/dhcpcount.rb
Executable file → Normal file
32
nix/nixos-module/collectd/dhcpcount.rb
Executable file → Normal file
|
@ -1,30 +1,38 @@
|
||||||
#!/usr/bin/env ruby
|
#!/usr/bin/env ruby
|
||||||
|
|
||||||
require 'csv'
|
require 'date'
|
||||||
|
|
||||||
INTERVAL = 60
|
INTERVAL = 10
|
||||||
TIMEOUT = ARGV[0].to_i # TODO: now unused
|
TIMEOUT = ARGV[0].to_i
|
||||||
hostname = CSV::readlines("/proc/sys/kernel/hostname").join.strip
|
hostname = IO::readlines("/proc/sys/kernel/hostname").join.strip
|
||||||
STDOUT.sync = true
|
STDOUT.sync = true
|
||||||
|
|
||||||
loop do
|
loop do
|
||||||
seen = {}
|
seen = {}
|
||||||
count = 0
|
count = 0
|
||||||
now = Time.now.to_i
|
|
||||||
|
|
||||||
CSV::readlines("/var/lib/kea/kea-leases4.csv", headers: true).each do |rec|
|
addr = nil
|
||||||
h = rec.to_h
|
starts = nil
|
||||||
addr = h["hwaddr"]
|
|
||||||
next unless addr
|
IO::readlines("/var/lib/dhcp/dhcpd.leases").each do |line|
|
||||||
last = h["expire"].to_i
|
if line =~ /^lease (.+) \{/
|
||||||
elapsed = now - last
|
addr = $1
|
||||||
next if elapsed >= TIMEOUT
|
|
||||||
|
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]
|
unless seen[addr]
|
||||||
count += 1
|
count += 1
|
||||||
seen[addr] = true
|
seen[addr] = true
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
puts "PUTVAL \"#{hostname}/exec-dhcpd/current_sessions-leases\" interval=#{INTERVAL} N:#{count}"
|
puts "PUTVAL \"#{hostname}/exec-dhcpd/current_sessions-leases\" interval=#{INTERVAL} N:#{count}"
|
||||||
|
|
||||||
sleep INTERVAL
|
sleep INTERVAL
|
||||||
|
|
0
nix/nixos-module/collectd/unbound.rb
Executable file → Normal file
0
nix/nixos-module/collectd/unbound.rb
Executable file → Normal file
|
@ -1,9 +1,7 @@
|
||||||
# Routing daemon configuration
|
# Routing daemon configuration
|
||||||
{ hostName, config, lib, pkgs, ... }:
|
{ hostName, config, options, lib, pkgs, ... }:
|
||||||
|
|
||||||
let
|
let
|
||||||
hostNameEscaped = builtins.replaceStrings [ "-" ] [ "_" ] hostName;
|
|
||||||
|
|
||||||
hostConf = config.site.hosts.${hostName};
|
hostConf = config.site.hosts.${hostName};
|
||||||
|
|
||||||
upstreamInterfaces = lib.filterAttrs (_: { upstream, ... }:
|
upstreamInterfaces = lib.filterAttrs (_: { upstream, ... }:
|
||||||
|
@ -12,11 +10,17 @@ let
|
||||||
|
|
||||||
isUpstream = upstreamInterfaces != {};
|
isUpstream = upstreamInterfaces != {};
|
||||||
|
|
||||||
ipv6RouterNets = builtins.attrNames (
|
# Configuring a gateway? If so, this is the associated net.
|
||||||
lib.filterAttrs (net: { ipv6Router, ... }:
|
gatewayNet =
|
||||||
ipv6Router == hostName
|
let
|
||||||
) config.site.net
|
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:
|
enumerate = n: list:
|
||||||
if list == []
|
if list == []
|
||||||
|
@ -65,61 +69,50 @@ in
|
||||||
protocol device {
|
protocol device {
|
||||||
scan time 10;
|
scan time 10;
|
||||||
}
|
}
|
||||||
|
${lib.optionalString isUpstream ''
|
||||||
# Import address ranges of upstream interfaces so that
|
# Import address ranges of upstream interfaces so that
|
||||||
# internal traffic to local public services take no detours
|
# internal traffic to local public services take no detours
|
||||||
# if the default router takes another upstream gateway.
|
# if the default router takes another upstream gateway.
|
||||||
protocol direct {
|
protocol direct {
|
||||||
ipv4 {
|
ipv4 {
|
||||||
${if isUpstream
|
# No RFC6598
|
||||||
then ''
|
import where net !~ 100.64.0.0/10
|
||||||
# No RFC1918, RFC6598
|
# No RFC1918
|
||||||
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 ];
|
&& net !~ 10.0.0.0/8
|
||||||
''
|
&& net !~ 172.16.0.0/12
|
||||||
else ""}
|
&& net !~ 192.168.0.0/16;
|
||||||
};
|
};
|
||||||
ipv6;
|
ipv6;
|
||||||
interface ${lib.concatMapStringsSep ", " (iface:
|
interface ${lib.concatMapStringsSep ", " (iface:
|
||||||
''"${iface}"''
|
''"${iface}"''
|
||||||
)(builtins.attrNames hostConf.interfaces)};
|
)(builtins.attrNames upstreamInterfaces)};
|
||||||
check link yes;
|
check link yes;
|
||||||
}
|
}
|
||||||
|
''}
|
||||||
|
|
||||||
${lib.optionalString (
|
${lib.optionalString (builtins.match "anon.*" hostName != null) ''
|
||||||
builtins.match "anon.*" hostName != null ||
|
|
||||||
hostName == "flpk-gw"
|
|
||||||
) ''
|
|
||||||
# BIRD routing table for Wireguard transport
|
# BIRD routing table for Wireguard transport
|
||||||
ipv4 table vpn_table;
|
ipv4 table vpn4_table;
|
||||||
|
|
||||||
# Kernel routing table for Wireguard transport
|
# Kernel routing table for Wireguard transport
|
||||||
protocol kernel VPN {
|
protocol kernel VPN4 {
|
||||||
# "vpn_table" configured on anon routers
|
# "vpn4_table" configured on anon routers
|
||||||
kernel table 100;
|
kernel table 100;
|
||||||
ipv4 {
|
ipv4 {
|
||||||
export all;
|
export all;
|
||||||
table vpn_table;
|
table vpn4_table;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
''}
|
''}
|
||||||
|
|
||||||
${lib.optionalString (ipv6RouterNets != []) ''
|
${lib.optionalString (gatewayNet != null) ''
|
||||||
# Router advertisements
|
# Router advertisements
|
||||||
protocol radv {
|
protocol radv {
|
||||||
rdnss ${config.site.net.serv.hosts6.dn42.dnscache};
|
rdnss ${config.site.net.serv.hosts6.dn42.dnscache};
|
||||||
|
|
||||||
${lib.concatMapStrings (net: ''
|
interface "${gatewayNet}" {
|
||||||
interface "${net}" {
|
|
||||||
min ra interval 10;
|
min ra interval 10;
|
||||||
max ra interval 60;
|
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;
|
|
||||||
''}
|
|
||||||
|
|
||||||
${builtins.concatStringsSep "\n" (
|
${builtins.concatStringsSep "\n" (
|
||||||
map (subnet6: ''
|
map (subnet6: ''
|
||||||
|
@ -127,27 +120,26 @@ in
|
||||||
preferred lifetime 600;
|
preferred lifetime 600;
|
||||||
valid lifetime 1800;
|
valid lifetime 1800;
|
||||||
};
|
};
|
||||||
'') (builtins.attrValues config.site.net.${net}.subnets6)
|
'') (builtins.attrValues config.site.net.${gatewayNet}.subnets6)
|
||||||
)}
|
)}
|
||||||
|
|
||||||
dnssl "${config.site.net.${net}.domainName}";
|
dnssl "${config.site.net.${gatewayNet}.domainName}";
|
||||||
};
|
};
|
||||||
'') ipv6RouterNets}
|
|
||||||
}
|
}
|
||||||
''}
|
''}
|
||||||
|
|
||||||
# OSPFv2 for site-local IPv4
|
# OSPFv2 for site-local IPv4
|
||||||
protocol ospf v2 ZW4 {
|
protocol ospf v2 ZW4 {
|
||||||
ipv4 {
|
ipv4 {
|
||||||
import all;
|
export where net != 0.0.0.0/0 && source != RTS_BGP;
|
||||||
# OSPF is self-contained
|
|
||||||
export none;
|
|
||||||
};
|
};
|
||||||
area 0 {
|
area 0 {
|
||||||
${builtins.concatStringsSep "\n" (
|
${builtins.concatStringsSep "\n" (
|
||||||
builtins.attrValues (
|
builtins.attrValues (
|
||||||
builtins.mapAttrs (net: _:
|
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
|
if config.site.net ? "${net}" && config.site.net.${net}.ospf.secret != null
|
||||||
then ''
|
then ''
|
||||||
interface "${net}" {
|
interface "${net}" {
|
||||||
|
@ -158,12 +150,12 @@ in
|
||||||
password "${config.site.net.${net}.ospf.secret}";
|
password "${config.site.net.${net}.ospf.secret}";
|
||||||
};
|
};
|
||||||
''
|
''
|
||||||
else ''
|
else if config.site.net ? "${net}" && config.site.net.${net}.subnet4 != null
|
||||||
interface "${net}" {
|
then ''
|
||||||
stub yes;
|
# Advertise route of network ${net}
|
||||||
cost 10;
|
stubnet ${config.site.net.${net}.subnet4} {};
|
||||||
};
|
|
||||||
''
|
''
|
||||||
|
else ""
|
||||||
) hostConf.interfaces
|
) hostConf.interfaces
|
||||||
)
|
)
|
||||||
)}
|
)}
|
||||||
|
@ -178,7 +170,7 @@ in
|
||||||
|
|
||||||
${lib.optionalString isUpstream ''
|
${lib.optionalString isUpstream ''
|
||||||
# OSPFv2 to advertise my default route
|
# OSPFv2 to advertise my default route
|
||||||
protocol ospf v2 ZW4_${hostNameEscaped} {
|
protocol ospf v2 ZW4_${hostName} {
|
||||||
ipv4 {
|
ipv4 {
|
||||||
export where net = 0.0.0.0/0;
|
export where net = 0.0.0.0/0;
|
||||||
};
|
};
|
||||||
|
@ -211,19 +203,14 @@ in
|
||||||
${text}
|
${text}
|
||||||
|
|
||||||
# OSPFv2 to receive a default route from ${upstream}
|
# OSPFv2 to receive a default route from ${upstream}
|
||||||
protocol ospf v2 ZW4_${
|
protocol ospf v2 ZW4_${upstream} {
|
||||||
builtins.replaceStrings [ "-" ] [ "_" ] upstream
|
|
||||||
} {
|
|
||||||
ipv4 {
|
ipv4 {
|
||||||
import filter {
|
import filter {
|
||||||
preference = preference + ${toString (100 - n)};
|
preference = preference + ${toString (100 - n)};
|
||||||
accept;
|
accept;
|
||||||
};
|
};
|
||||||
${lib.optionalString (
|
${lib.optionalString (builtins.match "anon.*" hostName != null) ''
|
||||||
builtins.match "anon.*" hostName != null ||
|
table vpn4_table;
|
||||||
hostName == "flpk-gw"
|
|
||||||
) ''
|
|
||||||
table vpn_table;
|
|
||||||
''}
|
''}
|
||||||
};
|
};
|
||||||
area 0 {
|
area 0 {
|
||||||
|
@ -232,11 +219,7 @@ in
|
||||||
builtins.mapAttrs (net: _:
|
builtins.mapAttrs (net: _:
|
||||||
# Enable OSPF only on interfaces with a secret.
|
# Enable OSPF only on interfaces with a secret.
|
||||||
lib.optionalString (config.site.net.${net}.ospf.secret != null) ''
|
lib.optionalString (config.site.net.${net}.ospf.secret != null) ''
|
||||||
interface "${net}" instance ${
|
interface "${net}" instance ${toString config.site.hosts.${upstream}.ospf.upstreamInstance} {
|
||||||
builtins.replaceStrings [ "-" ] [ "_" ] (
|
|
||||||
toString config.site.hosts.${upstream}.ospf.upstreamInstance
|
|
||||||
)
|
|
||||||
} {
|
|
||||||
hello 10;
|
hello 10;
|
||||||
wait 20;
|
wait 20;
|
||||||
authentication cryptographic;
|
authentication cryptographic;
|
||||||
|
@ -256,15 +239,15 @@ in
|
||||||
# OSPFv3 for site-local IPv6
|
# OSPFv3 for site-local IPv6
|
||||||
protocol ospf v3 ZW6 {
|
protocol ospf v3 ZW6 {
|
||||||
ipv6 {
|
ipv6 {
|
||||||
import all;
|
export where net != ::/0 && source != RTS_BGP;
|
||||||
# OSPF is self-contained
|
|
||||||
export none;
|
|
||||||
};
|
};
|
||||||
area 0 {
|
area 0 {
|
||||||
${builtins.concatStringsSep "\n" (
|
${builtins.concatStringsSep "\n" (
|
||||||
builtins.attrValues (
|
builtins.attrValues (
|
||||||
builtins.mapAttrs (net: _:
|
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
|
if config.site.net.${net}.ospf.secret != null
|
||||||
then ''
|
then ''
|
||||||
interface "${net}" {
|
interface "${net}" {
|
||||||
|
@ -275,12 +258,12 @@ in
|
||||||
password "${config.site.net.${net}.ospf.secret}";
|
password "${config.site.net.${net}.ospf.secret}";
|
||||||
};
|
};
|
||||||
''
|
''
|
||||||
else ''
|
else builtins.concatStringsSep "\n" (
|
||||||
interface "${net}" {
|
map (subnet6: ''
|
||||||
stub yes;
|
# Advertise route of network ${net}
|
||||||
cost 10;
|
stubnet ${subnet6} {};
|
||||||
};
|
'') (builtins.attrValues config.site.net.${net}.subnets6)
|
||||||
''
|
)
|
||||||
) hostConf.physicalInterfaces
|
) hostConf.physicalInterfaces
|
||||||
)
|
)
|
||||||
)}
|
)}
|
||||||
|
@ -296,7 +279,7 @@ in
|
||||||
|
|
||||||
${lib.optionalString isUpstream ''
|
${lib.optionalString isUpstream ''
|
||||||
# OSPFv3 to advertise my default route
|
# OSPFv3 to advertise my default route
|
||||||
protocol ospf v3 ZW6_${hostNameEscaped} {
|
protocol ospf v3 ZW6_${hostName} {
|
||||||
ipv6 {
|
ipv6 {
|
||||||
export where net = ::/0;
|
export where net = ::/0;
|
||||||
};
|
};
|
||||||
|
@ -329,9 +312,7 @@ in
|
||||||
${text}
|
${text}
|
||||||
|
|
||||||
# OSPFv3 to receive a default route from ${upstream}
|
# OSPFv3 to receive a default route from ${upstream}
|
||||||
protocol ospf v3 ZW6_${
|
protocol ospf v3 ZW6_${upstream} {
|
||||||
builtins.replaceStrings [ "-" ] [ "_" ] upstream
|
|
||||||
} {
|
|
||||||
ipv6 {
|
ipv6 {
|
||||||
import filter {
|
import filter {
|
||||||
preference = preference + ${toString (100 - n)};
|
preference = preference + ${toString (100 - n)};
|
||||||
|
@ -344,11 +325,7 @@ in
|
||||||
builtins.mapAttrs (net: _:
|
builtins.mapAttrs (net: _:
|
||||||
# Enable OSPF only on interfaces with a secret.
|
# Enable OSPF only on interfaces with a secret.
|
||||||
lib.optionalString (config.site.net.${net}.ospf.secret != null) ''
|
lib.optionalString (config.site.net.${net}.ospf.secret != null) ''
|
||||||
interface "${net}" instance ${
|
interface "${net}" instance ${toString config.site.hosts.${upstream}.ospf.upstreamInstance} {
|
||||||
builtins.replaceStrings [ "-" ] [ "_" ] (
|
|
||||||
toString config.site.hosts.${upstream}.ospf.upstreamInstance
|
|
||||||
)
|
|
||||||
} {
|
|
||||||
hello 10;
|
hello 10;
|
||||||
wait 20;
|
wait 20;
|
||||||
authentication cryptographic;
|
authentication cryptographic;
|
||||||
|
@ -362,7 +339,7 @@ in
|
||||||
}
|
}
|
||||||
'';
|
'';
|
||||||
n = n + 1;
|
n = n + 1;
|
||||||
}) { text = ""; n = 0; } hostConf.ospf.allowedUpstreams6
|
}) { text = ""; n = 0; } hostConf.ospf.allowedUpstreams
|
||||||
).text}
|
).text}
|
||||||
|
|
||||||
# Zentralwerk DN42
|
# Zentralwerk DN42
|
||||||
|
@ -373,8 +350,11 @@ in
|
||||||
protocol static {
|
protocol static {
|
||||||
ipv6;
|
ipv6;
|
||||||
route fd23:42:c3d2:580::/57 unreachable;
|
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 2a00:8180:2c00:200::/56 unreachable;
|
||||||
route 2a0f:5382:acab:1400::/56 unreachable;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
${lib.optionalString (hostConf.bgp != null) ''
|
${lib.optionalString (hostConf.bgp != null) ''
|
||||||
|
@ -436,8 +416,8 @@ in
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
instance = {
|
instance = {
|
||||||
ipv4 = "ZW4_${hostNameEscaped}";
|
ipv4 = "ZW4_${hostName}";
|
||||||
ipv6 = "ZW6_${hostNameEscaped}";
|
ipv6 = "ZW6_${hostName}";
|
||||||
};
|
};
|
||||||
checkService = addressFamily: {
|
checkService = addressFamily: {
|
||||||
description = "Check connectivity for ${addressFamily}";
|
description = "Check connectivity for ${addressFamily}";
|
||||||
|
@ -447,7 +427,7 @@ in
|
||||||
User = "bird2";
|
User = "bird2";
|
||||||
Group = "bird2";
|
Group = "bird2";
|
||||||
};
|
};
|
||||||
path = with pkgs; [ bird2 iputils ];
|
path = [ pkgs.bird2 "/run/wrappers" ];
|
||||||
script = ''
|
script = ''
|
||||||
STATE=unknown
|
STATE=unknown
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
{ config, lib, modulesPath, pkgs, ... }:
|
{ config, lib, modulesPath, ... }:
|
||||||
|
|
||||||
{
|
{
|
||||||
imports = [
|
imports = [
|
||||||
|
@ -6,19 +6,22 @@
|
||||||
(modulesPath + "/virtualisation/lxc-container.nix")
|
(modulesPath + "/virtualisation/lxc-container.nix")
|
||||||
];
|
];
|
||||||
|
|
||||||
environment = {
|
boot = {
|
||||||
etc."machine-id".text = builtins.substring 0 8 (builtins.hashString "sha256" config.networking.hostName);
|
isContainer = true;
|
||||||
systemPackages = with pkgs; [
|
loader = {
|
||||||
ripgrep
|
initScript.enable = true;
|
||||||
];
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
environment.etc."machine-id".text =
|
||||||
|
builtins.substring 0 8 (
|
||||||
|
builtins.hashString "sha256" config.networking.hostName
|
||||||
|
);
|
||||||
|
|
||||||
nix = {
|
nix = {
|
||||||
settings = {
|
useSandbox = false;
|
||||||
sandbox = false;
|
maxJobs = lib.mkDefault 1;
|
||||||
max-jobs = lib.mkDefault 4;
|
buildCores = lib.mkDefault 1;
|
||||||
cores = lib.mkDefault 4;
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
systemd.services =
|
systemd.services =
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
# ISC DHCP/IPv4 server configuration
|
# ISC DHCP/IPv4 server configuration
|
||||||
{ hostName, config, lib, ... }:
|
{ hostName, inputs, config, lib, ... }:
|
||||||
|
|
||||||
let
|
let
|
||||||
dhcpNets =
|
dhcpNets =
|
||||||
|
@ -8,341 +8,81 @@ let
|
||||||
dhcp.server == hostName
|
dhcp.server == hostName
|
||||||
) config.site.net;
|
) 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;
|
enabled = builtins.length (builtins.attrNames dhcpNets) > 0;
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
services.kea.dhcp4 = lib.mkIf enabled {
|
services.dhcpd4 = lib.optionalAttrs enabled {
|
||||||
enable = true;
|
enable = true;
|
||||||
|
|
||||||
settings = {
|
interfaces = builtins.attrNames dhcpNets;
|
||||||
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));
|
|
||||||
|
|
||||||
subnet4 = concatMapDhcpNets (net: { vlan, subnet4, hosts4, dhcp, domainName, captiveJson, ... }: {
|
extraConfig = ''
|
||||||
id = vlan;
|
${builtins.concatStringsSep "\n" (
|
||||||
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";
|
|
||||||
} ] ++ lib.optional (captiveJson != null) {
|
|
||||||
space = "dhcp4";
|
|
||||||
name = "v4-captive-portal";
|
|
||||||
code = 114;
|
|
||||||
data = captiveJson;
|
|
||||||
};
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
))
|
|
||||||
builtins.attrValues
|
|
||||||
(builtins.filter (r: r != null))
|
|
||||||
];
|
|
||||||
});
|
|
||||||
|
|
||||||
match-client-id = false;
|
|
||||||
host-reservation-identifiers = [ "hw-address" ];
|
|
||||||
|
|
||||||
# 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";
|
|
||||||
} ];
|
|
||||||
};
|
|
||||||
|
|
||||||
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.attrValues (
|
||||||
builtins.mapAttrs makePxe pxeClassData
|
builtins.mapAttrs (net: { dhcp, subnet4Net, subnet4Len, domainName, ...}:
|
||||||
);
|
''
|
||||||
|
ddns-update-style standard;
|
||||||
control-socket = {
|
key dyndns {
|
||||||
socket-type = "unix";
|
algorithm hmac-sha256;
|
||||||
socket-name = "/run/kea/dhcp4-socket";
|
secret ${config.site.dyndnsKey};
|
||||||
};
|
};
|
||||||
hooks-libraries = [ {
|
zone ${domainName}. {
|
||||||
library = "/run/current-system/sw/lib/kea/hooks/libdhcp_stat_cmds.so";
|
primary ${config.site.net.serv.hosts4.dns};
|
||||||
} {
|
primary6 ${config.site.net.serv.hosts6.dn42.dns};
|
||||||
library = "/run/current-system/sw/lib/kea/hooks/libdhcp_lease_cmds.so";
|
key dyndns;
|
||||||
} ];
|
|
||||||
};
|
|
||||||
};
|
|
||||||
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, captiveJson, ... }:
|
|
||||||
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";
|
|
||||||
} ] ++ lib.optional (captiveJson != null) {
|
|
||||||
space = "dhcp6";
|
|
||||||
name = "v6-captive-portal";
|
|
||||||
code = 103;
|
|
||||||
data = captiveJson;
|
|
||||||
};
|
|
||||||
ddns-generated-prefix = "d";
|
|
||||||
ddns-qualifying-suffix = domainName;
|
|
||||||
}
|
}
|
||||||
else []
|
${lib.concatMapStrings ({ name, dynamic, ... }:
|
||||||
);
|
lib.optionalString (
|
||||||
|
|
||||||
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 &&
|
dynamic &&
|
||||||
(lib.hasSuffix ".in-addr.arpa" name ||
|
lib.hasSuffix ".in-addr.arpa" name
|
||||||
lib.hasSuffix ".ip6.arpa" name)
|
) ''
|
||||||
) config.site.dns.localZones
|
zone ${name}. {
|
||||||
);
|
primary ${config.site.net.serv.hosts4.dns};
|
||||||
control-socket = {
|
primary6 ${config.site.net.serv.hosts6.dn42.dns};
|
||||||
socket-type = "unix";
|
key dyndns;
|
||||||
socket-name = "/run/kea/dhcp-ddns.socket";
|
}
|
||||||
};
|
''
|
||||||
};
|
) config.site.dns.localZones}
|
||||||
};
|
|
||||||
|
|
||||||
services.kea.ctrl-agent = lib.mkIf enabled {
|
option arch code 93 = unsigned integer 16;
|
||||||
enable = true;
|
group {
|
||||||
settings.control-sockets = {
|
default-lease-time ${toString dhcp.time};
|
||||||
dhcp4 = {
|
max-lease-time ${toString dhcp.max-time};
|
||||||
socket-type = "unix";
|
option routers ${config.site.net.${net}.hosts4.${builtins.replaceStrings [".${net}"] [""] dhcp.router}};
|
||||||
socket-name = "/run/kea/dhcp4.socket";
|
option domain-name "${domainName}";
|
||||||
};
|
option domain-name-servers 172.20.73.8, 9.9.9.9;
|
||||||
dhcp6 = {
|
ddns-domainname "${domainName}";
|
||||||
socket-type = "unix";
|
|
||||||
socket-name = "/run/kea/dhcp6.socket";
|
|
||||||
};
|
|
||||||
d2 = {
|
|
||||||
socket-type = "unix";
|
|
||||||
socket-name = "/run/kea/dhcp-ddns.socket";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
# Increase reliablity
|
next-server ${config.site.net.serv.hosts4.netboot};
|
||||||
# (mostly for kea-dhcp-ddns-server.service)
|
if option arch = 00:00 {
|
||||||
systemd.services =
|
filename "netboot.xyz.kpxe";
|
||||||
let
|
} else {
|
||||||
restartService.serviceConfig = {
|
filename "netboot.xyz.efi";
|
||||||
RestartSec = 4;
|
}
|
||||||
Restart = "always";
|
|
||||||
};
|
subnet ${subnet4Net} netmask ${lib.netmasks.${toString subnet4Len}} {
|
||||||
in {
|
range ${dhcp.start} ${dhcp.end};
|
||||||
kea-dhcp4-server = restartService;
|
}
|
||||||
kea-dhcp6-server = restartService;
|
|
||||||
kea-dhcp-ddns-server = restartService;
|
update-static-leases on;
|
||||||
|
|
||||||
|
${builtins.concatStringsSep "\n" (
|
||||||
|
builtins.attrValues (
|
||||||
|
builtins.mapAttrs (addr: hwaddr:
|
||||||
|
''
|
||||||
|
host ${addr} {
|
||||||
|
hardware ethernet ${hwaddr};
|
||||||
|
fixed-address ${addr};
|
||||||
|
}
|
||||||
|
''
|
||||||
|
) dhcp.fixed-hosts
|
||||||
|
)
|
||||||
|
)}
|
||||||
|
}
|
||||||
|
''
|
||||||
|
) dhcpNets
|
||||||
|
)
|
||||||
|
)}
|
||||||
|
'';
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,30 +1,33 @@
|
||||||
{ config, dns-nix, hostName, lib, pkgs, self, ... }:
|
{ hostName, config, lib, pkgs, self, inputs, ... }:
|
||||||
|
|
||||||
let
|
let
|
||||||
serial = builtins.substring 0 10 self.lastModifiedDate;
|
serial =
|
||||||
|
let
|
||||||
generateZoneFile = let
|
timestamp = toString self.lastModified;
|
||||||
util = dns-nix.util.${pkgs.system};
|
datePkg = pkgs.runCommandLocal "date-${timestamp}" {} ''
|
||||||
in { name, ns, records, ... }: (util.writeZone name {
|
date -d @${timestamp} +%Y%m%d%H > $out
|
||||||
TTL = 60*60;
|
'';
|
||||||
SOA = {
|
in
|
||||||
nameServer = "${lib.dns.ns}.";
|
toString (import datePkg);
|
||||||
adminEmail = "astro@spaceboyz.net";
|
|
||||||
serial = lib.toInt serial;
|
generateZoneFile = { name, ns, records, dynamic }:
|
||||||
refresh = 1*60*60;
|
builtins.toFile "${name}.zone" ''
|
||||||
retry = 5*60;
|
$ORIGIN ${name}.
|
||||||
expire = 2*60*60;
|
$TTL 1h
|
||||||
minimum = 1*60;
|
|
||||||
};
|
@ IN SOA ${lib.dns.ns}. astro.spaceboyz.net. (
|
||||||
NS = map (a: a+".") ns;
|
${serial} ; serial
|
||||||
subdomains = lib.foldl (a: b: lib.recursiveUpdate a b) { } (map ({ name, type, data }: {
|
1h ; refresh
|
||||||
${name}.${type} = [ data ];
|
1m ; retry
|
||||||
}) records);
|
2h ; expire
|
||||||
}).overrideAttrs (_: {
|
1m ; minimum
|
||||||
checkPhase = ''
|
)
|
||||||
${pkgs.knot-dns}/bin/kzonecheck "$target"
|
${lib.concatMapStrings (ns: " IN NS ${ns}.\n") ns}
|
||||||
|
|
||||||
|
${lib.concatMapStrings ({ name, type, data }:
|
||||||
|
"${name} IN ${type} ${data}\n"
|
||||||
|
) records}
|
||||||
'';
|
'';
|
||||||
});
|
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
options =
|
options =
|
||||||
|
@ -39,7 +42,7 @@ in
|
||||||
type = types.enum [ "A" "AAAA" "MX" "SRV" "CNAME" "TXT" "PTR" ];
|
type = types.enum [ "A" "AAAA" "MX" "SRV" "CNAME" "TXT" "PTR" ];
|
||||||
};
|
};
|
||||||
data = mkOption {
|
data = mkOption {
|
||||||
type = types.oneOf [ types.str (types.attrsOf (types.oneOf [ types.int types.str ]))];
|
type = types.str;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -73,169 +76,90 @@ in
|
||||||
config = {
|
config = {
|
||||||
site.dns.localZones = lib.dns.localZones;
|
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
|
let
|
||||||
generateZone = zone@{ name, dynamic, ... }: {
|
generateZone = zone@{ name, dynamic, ... }: {
|
||||||
domain = name;
|
inherit name;
|
||||||
template = "zentralwerk";
|
master = true;
|
||||||
acl = [ "zone_xfr" ]
|
# allowed for zone-transfer
|
||||||
++ lib.optional (lib.hasSuffix ".arpa" name) "dn42"
|
slaves = [
|
||||||
++ lib.optional dynamic "dyndns";
|
# ns.c3d2.de
|
||||||
file = if dynamic
|
"217.197.84.53" "2001:67c:1400:2240::a"
|
||||||
then "/var/lib/knot/zones/${name}.zone"
|
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;
|
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 {
|
in {
|
||||||
enable = true;
|
enable = true;
|
||||||
settings = {
|
zones = map generateZone config.site.dns.localZones;
|
||||||
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" "37.27.116.148" "2a01:4f9:3070:2728::4"
|
|
||||||
# ns1.supersandro.de
|
|
||||||
"188.34.196.104" "2a01:4f8:1c1c:1d38::1"
|
|
||||||
];
|
|
||||||
action = "transfer";
|
|
||||||
}
|
|
||||||
{
|
|
||||||
id = "dn42";
|
|
||||||
address = [ "172.22.24.4" "fd42:180:3de0:30::1" ];
|
|
||||||
}
|
|
||||||
];
|
|
||||||
|
|
||||||
key = [ {
|
extraConfig = ''
|
||||||
id = "dyndns";
|
key "dyndns" {
|
||||||
algorithm = "hmac-sha256";
|
algorithm hmac-sha256;
|
||||||
secret = config.site.dyndnsKey;
|
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"
|
|
||||||
"37.27.116.148" "2a01:4f9:3070:2728::4"
|
|
||||||
];
|
|
||||||
inherit via;
|
|
||||||
} {
|
|
||||||
id = "ns1.supersandro.de";
|
|
||||||
address = [ /*"188.34.196.104"*/ "2a01:4f8:1c1c:1d38::1" ];
|
|
||||||
inherit via;
|
|
||||||
} {
|
|
||||||
id = "b.master.delegation-servers.dn42";
|
|
||||||
address = [ "172.22.24.4" "fd42:180:3de0:30::1" ];
|
|
||||||
}
|
|
||||||
];
|
|
||||||
|
|
||||||
remotes = [
|
|
||||||
{
|
|
||||||
id = "all";
|
|
||||||
remote = [ "ns.c3d2.de" "ns.spaceboyz.net" "ns1.supersandro.de" ];
|
|
||||||
}
|
|
||||||
{
|
|
||||||
id = "dn42";
|
|
||||||
remote = [ "b.master.delegation-servers.dn42" ];
|
|
||||||
}
|
|
||||||
];
|
|
||||||
|
|
||||||
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;
|
|
||||||
};
|
|
||||||
|
|
||||||
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" "ns.spaceboyz.net" ];
|
|
||||||
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 = {
|
systemd.services.create-dynamic-zones = {
|
||||||
create-dynamic-zones = {
|
|
||||||
description = "Creates dynamic zone files";
|
description = "Creates dynamic zone files";
|
||||||
requiredBy = [ "knot.service" ];
|
requiredBy = [ "bind.service" ];
|
||||||
before = [ "knot.service" ];
|
before = [ "bind.service" ];
|
||||||
serviceConfig.Type = "oneshot";
|
serviceConfig.Type = "oneshot";
|
||||||
script = ''
|
script = ''
|
||||||
mkdir -p /var/lib/knot/zones
|
mkdir -p /var/db/bind
|
||||||
|
|
||||||
${lib.concatMapStringsSep "\n" (zone@{ name, ... }: ''
|
${lib.concatMapStringsSep "\n" (zone@{ name, ... }: ''
|
||||||
[ -e /var/lib/knot/zones/${name}.zone ] || \
|
[ -e /var/db/bind/${name}.zone ] || \
|
||||||
cp ${generateZoneFile zone} /var/lib/knot/zones/${name}.zone
|
cp ${generateZoneFile zone} /var/db/bind/${name}.zone
|
||||||
chown -R knot /var/lib/knot/zones
|
chown -R named /var/db/bind
|
||||||
chmod -R u+rwX /var/lib/knot/zones
|
chmod -R u+rwX /var/db/bind
|
||||||
'') (builtins.filter ({ dynamic, ... }: dynamic) config.site.dns.localZones)}
|
'') (
|
||||||
|
builtins.filter ({ dynamic, ... }: dynamic) config.site.dns.localZones
|
||||||
|
)}
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
systemd.services.update-dynamic-zones = {
|
||||||
update-dynamic-zones = {
|
|
||||||
description = "Creates initial records in dynamic zone files";
|
description = "Creates initial records in dynamic zone files";
|
||||||
requiredBy = [ "knot.service" ];
|
requiredBy = [ "bind.service" ];
|
||||||
after = [ "knot.service" ];
|
after = [ "bind.service" ];
|
||||||
serviceConfig.Type = "oneshot";
|
serviceConfig.Type = "oneshot";
|
||||||
path = [ pkgs.dnsutils ];
|
path = [ pkgs.dnsutils ];
|
||||||
script = lib.concatMapStrings (zone: ''
|
script = ''
|
||||||
nsupdate -v -y "hmac-sha256:dyndns:${config.site.dyndnsKey}" <<EOF
|
${lib.concatMapStrings (zone: ''
|
||||||
|
nsupdate -y "hmac-sha256:dyndns:${config.site.dyndnsKey}" <<EOF
|
||||||
server localhost
|
server localhost
|
||||||
|
|
||||||
${lib.concatMapStringsSep "\n" ({ name, type, data }: ''
|
${lib.concatMapStringsSep "\n" ({ name, type, data }: ''
|
||||||
|
@ -245,8 +169,10 @@ in
|
||||||
|
|
||||||
send
|
send
|
||||||
EOF
|
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, ... }:
|
{ hostName, config, lib, pkgs, ... }:
|
||||||
|
|
||||||
lib.mkIf config.site.hosts.${hostName}.services.dnscache.enable {
|
lib.mkIf config.site.hosts.${hostName}.services.dnscache.enable {
|
||||||
services.kresd = {
|
services.unbound = {
|
||||||
enable = true;
|
enable = true;
|
||||||
instances = 4;
|
settings = {
|
||||||
listenPlain = [ "0.0.0.0:53" "[::0]:53" ];
|
remote-control = {
|
||||||
package = pkgs.knot-resolver.override { extraFeatures = true; };
|
control-enable = true;
|
||||||
extraConfig = /* lua */ ''
|
control-use-cert = false;
|
||||||
modules = {
|
};
|
||||||
'http',
|
server = {
|
||||||
'policy',
|
num-threads = 4;
|
||||||
'predict',
|
verbosity = 1;
|
||||||
'prefill',
|
prefetch = true;
|
||||||
'serve_stale < cache', -- servce stail records while refreshing the record
|
serve-expired = true;
|
||||||
'workarounds < iterate', -- solve problems around specific broken subdomains, mainly disables case randomization
|
cache-min-ttl = 60;
|
||||||
'view'
|
cache-max-ttl = 3600;
|
||||||
}
|
|
||||||
|
|
||||||
cache.size = 500 * MB
|
interface = [ "0.0.0.0" "'::0'" ];
|
||||||
cache.min_ttl(60)
|
# 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' })
|
# allow reverse lookup of rfc1918 space, which includes the DN42 address space
|
||||||
http.prometheus.namespace = 'resolver_'
|
unblock-lan-zones = true;
|
||||||
|
insecure-lan-zones = true;
|
||||||
|
|
||||||
-- dns42
|
domain-insecure = [
|
||||||
policy.add(policy.suffix(
|
"dn42"
|
||||||
policy.STUB({'fd42:d42:d42:54::1', 'fd42:d42:d42:53::1', '172.20.0.53', '172.23.0.53'}),
|
"d.f.ip6.arpa"
|
||||||
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'})
|
"ffdd"
|
||||||
))
|
];
|
||||||
|
};
|
||||||
|
|
||||||
-- freifunk
|
forward-zone = let
|
||||||
policy.add(policy.suffix(
|
mkFfddZone = name: {
|
||||||
policy.STUB({'10.200.0.4', '10.200.0.16'}),
|
inherit name;
|
||||||
policy.todnames({'ffdd.', '200.10.in-addr.arpa', '201.10.in-addr.arpa'})
|
forward-addr = [ "10.200.0.4" "10.200.0.16" ];
|
||||||
))
|
};
|
||||||
|
in [ {
|
||||||
-- size.dns.localZones
|
name = ".";
|
||||||
policy.add(policy.suffix(
|
forward-tls-upstream = true;
|
||||||
policy.STUB({'${config.site.net.serv.hosts4.dns}', ${lib.concatStringsSep ", " (map (hosts6: "'${hosts6.dns}'") (builtins.attrValues config.site.net.serv.hosts6))}}),
|
forward-addr = [
|
||||||
policy.todnames({${lib.concatStringsSep ", " (map (zone: "'${zone.name}'") config.site.dns.localZones)}})
|
# Quad9
|
||||||
))
|
"2620:fe::fe@853#dns.quad9.net"
|
||||||
|
"9.9.9.9@853#dns.quad9.net"
|
||||||
-- forward to dns caches
|
"2620:fe::9@853#dns.quad9.net"
|
||||||
policy.add(policy.slice(
|
"149.112.112.112@853#dns.quad9.net"
|
||||||
policy.slice_randomize_psl(),
|
# Cloudflare DNS
|
||||||
-- quad9
|
"2606:4700:4700::1111@853#cloudflare-dns.com"
|
||||||
policy.TLS_FORWARD({
|
"1.1.1.1@853#cloudflare-dns.com"
|
||||||
{'2620:fe::fe', hostname='dns.quad9.net'},
|
"2606:4700:4700::1001@853#cloudflare-dns.com"
|
||||||
{'2620:fe::9', hostname='dns.quad9.net'},
|
"1.0.0.1@853#cloudflare-dns.com"
|
||||||
{'9.9.9.9', hostname='dns.quad9.net'},
|
];
|
||||||
{'149.112.112.112', hostname='dns.quad9.net'}
|
} ] ++
|
||||||
}),
|
# Local networks
|
||||||
-- cloudflare
|
map ({ name, ... }: {
|
||||||
policy.TLS_FORWARD({
|
name = "${name}";
|
||||||
{'2606:4700:4700::1111', hostname='cloudflare-dns.com'},
|
forward-addr = [ "${config.site.net.serv.hosts4.dns}" ] ++
|
||||||
{'2606:4700:4700::1001', hostname='cloudflare-dns.com'},
|
map (hosts6: hosts6.dns)
|
||||||
{'1.1.1.1', hostname='cloudflare-dns.com'},
|
(builtins.attrValues config.site.net.serv.hosts6);
|
||||||
{'1.0.0.1', hostname='cloudflare-dns.com'}
|
}) config.site.dns.localZones
|
||||||
})
|
# Freifunk
|
||||||
))
|
++ (map mkFfddZone [
|
||||||
|
"ffdd"
|
||||||
-- allow access from our networks
|
"200.10.in-addr.arpa"
|
||||||
'' + lib.concatMapStringsSep "\n" (cidr: "view:addr('${cidr}', policy.all(policy.PASS))") [
|
"201.10.in-addr.arpa"
|
||||||
# localhost
|
]);
|
||||||
"::1/128" "127.0.0.0/8"
|
# DN42
|
||||||
# mgmt
|
stub-zone = let
|
||||||
"${config.site.net.mgmt.subnet4}"
|
mkDn42Zone = name: {
|
||||||
# dn42
|
inherit name;
|
||||||
"fd23:42:c3d2:500::/56" "::172.20.72.0/117" "::172.22.99.0/120"
|
stub-prime = true;
|
||||||
"172.20.72.0/21" "172.22.99.0/24"
|
stub-addr = [
|
||||||
# freifunk
|
"172.20.0.53" "fd42:d42:d42:54::1"
|
||||||
"10.200.0.0/15"
|
"172.23.0.53" "fd42:d42:d42:53::1"
|
||||||
# DSI
|
];
|
||||||
"2a00:8180:2000:37::1/128" "2a00:8180:2c00:200::/56"
|
};
|
||||||
# flpk
|
in map mkDn42Zone [
|
||||||
"${config.site.net.flpk.subnet4}" "2a0f:5382:acab:1400::/56 allow"
|
"dn42" "d.f.ip6.arpa"
|
||||||
] + "\n" + /* lua */ ''
|
"20.172.in-addr.arpa" "21.172.in-addr.arpa"
|
||||||
|
"22.172.in-addr.arpa" "23.172.in-addr.arpa"
|
||||||
-- 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'})
|
|
||||||
'';
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -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}
|
|
||||||
'';
|
|
||||||
}
|
|
22
nix/nixos-module/container/netboot.nix
Normal file
22
nix/nixos-module/container/netboot.nix
Normal file
|
@ -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
|
let
|
||||||
hostConf = config.site.hosts.${hostName};
|
hostConf = config.site.hosts.${hostName};
|
||||||
|
@ -15,8 +15,6 @@ let
|
||||||
else null;
|
else null;
|
||||||
|
|
||||||
enabled = firstUpstreamInterface != null;
|
enabled = firstUpstreamInterface != null;
|
||||||
|
|
||||||
inherit (upstreamInterfaces.${firstUpstreamInterface}.upstream) staticIpv4Address;
|
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
systemd.network.networks = {
|
systemd.network.networks = {
|
||||||
|
@ -24,23 +22,19 @@ in
|
||||||
# systemd-networkd only requests Prefix Delegation via DHCPv6 on
|
# systemd-networkd only requests Prefix Delegation via DHCPv6 on
|
||||||
# the upstream interface if another interface is configured for it.
|
# the upstream interface if another interface is configured for it.
|
||||||
# without this, the static ipv6 subnet won't be routed to us.
|
# without this, the static ipv6 subnet won't be routed to us.
|
||||||
networkConfig.DHCPPrefixDelegation = true;
|
networkConfig.DHCPv6PrefixDelegation = true;
|
||||||
dhcpV6PrefixDelegationConfig = {
|
dhcpV6PrefixDelegationConfig = {
|
||||||
SubnetId = "81";
|
SubnetId = "81";
|
||||||
# because we have static addresses, we don't actually use this
|
# because we have static addresses, we don't actually use this
|
||||||
Assign = false;
|
Assign = false;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
} // builtins.mapAttrs (_: { upstream, ... }:
|
} // builtins.mapAttrs (_: { upstream, ... }: {
|
||||||
# DHCP
|
|
||||||
lib.optionalAttrs (hostName != "flpk-gw") {
|
|
||||||
DHCP = "yes";
|
DHCP = "yes";
|
||||||
networkConfig.IPv6AcceptRA = true;
|
networkConfig.IPv6AcceptRA = true;
|
||||||
dhcpV6Config.PrefixDelegationHint = "::/56";
|
dhcpV6Config.PrefixDelegationHint = "::/56";
|
||||||
}
|
|
||||||
//
|
|
||||||
# Traffic Shaping
|
# Traffic Shaping
|
||||||
{
|
|
||||||
extraConfig = ''
|
extraConfig = ''
|
||||||
[CAKE]
|
[CAKE]
|
||||||
Parent = root
|
Parent = root
|
||||||
|
@ -56,100 +50,36 @@ in
|
||||||
Bandwidth = ${toString upstream.upBandwidth}K
|
Bandwidth = ${toString upstream.upBandwidth}K
|
||||||
''}
|
''}
|
||||||
'';
|
'';
|
||||||
}
|
}) upstreamInterfaces;
|
||||||
) upstreamInterfaces;
|
|
||||||
|
|
||||||
networking.nat = lib.optionalAttrs enabled {
|
networking.nat = lib.optionalAttrs enabled {
|
||||||
enable = true;
|
enable = true;
|
||||||
enableIPv6 = true;
|
|
||||||
internalInterfaces = [ "core" ];
|
internalInterfaces = [ "core" ];
|
||||||
externalInterface = firstUpstreamInterface;
|
externalInterface = firstUpstreamInterface;
|
||||||
externalIP = staticIpv4Address;
|
externalIP = upstreamInterfaces.${firstUpstreamInterface}.upstream.staticIpv4Address;
|
||||||
extraCommands = ''
|
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)}
|
|
||||||
|
|
||||||
# Provide IPv6 upstream for everyone, using NAT66 when not from
|
# Provide IPv6 upstream for everyone, using NAT66 when not from
|
||||||
# our static prefixes
|
# our static prefixes
|
||||||
${lib.concatMapStringsSep "\n" (net:
|
lib.concatMapStringsSep "\n" (net: ''
|
||||||
lib.concatMapStrings (subnet: ''
|
ip6tables -t nat -N ${net}_nat || \
|
||||||
ip6tables -t nat -I nixos-nat-post \
|
ip6tables -t nat -F ${net}_nat
|
||||||
-o ${net} \
|
${lib.concatMapStringsSep "\n" (subnet: ''
|
||||||
|
ip6tables -t nat -A ${net}_nat \
|
||||||
-s ${subnet} \
|
-s ${subnet} \
|
||||||
-j RETURN
|
-j RETURN
|
||||||
'') upstreamInterfaces.${net}.upstream.noNat.subnets6
|
'') upstreamInterfaces.${net}.upstream.noNat.subnets6}
|
||||||
) (builtins.attrNames upstreamInterfaces)}
|
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 -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 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:
|
forwardPorts = map ({ destination, sourcePort, reflect, ... }@forwardedPort:
|
||||||
removeAttrs forwardedPort ["reflect"] // {
|
removeAttrs forwardedPort ["reflect"] // {
|
||||||
|
@ -159,7 +89,11 @@ in
|
||||||
else "${destination}:${toString sourcePort}";
|
else "${destination}:${toString sourcePort}";
|
||||||
loopbackIPs =
|
loopbackIPs =
|
||||||
if reflect
|
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 [];
|
else [];
|
||||||
}
|
}
|
||||||
) hostConf.forwardPorts;
|
) hostConf.forwardPorts;
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
{ hostName, config, lib, ... }:
|
{ hostName, inputs, config, lib, ... }:
|
||||||
|
|
||||||
let
|
let
|
||||||
hostConf = config.site.hosts.${hostName};
|
hostConf = config.site.hosts.${hostName};
|
||||||
|
@ -26,7 +26,7 @@ in lib.mkIf (pppoeInterfaces != {}) {
|
||||||
enable = true;
|
enable = true;
|
||||||
autostart = true;
|
autostart = true;
|
||||||
config = ''
|
config = ''
|
||||||
plugin pppoe.so
|
plugin rp-pppoe.so
|
||||||
nic-${upstream.link}
|
nic-${upstream.link}
|
||||||
ifname ${ifName}
|
ifname ${ifName}
|
||||||
# Login settings. (PAP)
|
# Login settings. (PAP)
|
||||||
|
@ -64,17 +64,14 @@ in lib.mkIf (pppoeInterfaces != {}) {
|
||||||
in networks // {
|
in networks // {
|
||||||
"${ifName}" = {
|
"${ifName}" = {
|
||||||
matchConfig.Name = "${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 = {
|
networkConfig = {
|
||||||
DHCP = lib.mkForce "ipv6";
|
DHCP = lib.mkOverride 900 "ipv6";
|
||||||
# accept config set by pppd
|
# accept config set by pppd
|
||||||
KeepConfiguration = "yes";
|
KeepConfiguration = "yes";
|
||||||
};
|
};
|
||||||
dhcpV6Config = {
|
dhcpV6Config = {
|
||||||
|
RapidCommit = true;
|
||||||
|
ForceDHCPv6PDOtherInformation = true;
|
||||||
PrefixDelegationHint = "::/56";
|
PrefixDelegationHint = "::/56";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
@ -84,4 +81,11 @@ in lib.mkIf (pppoeInterfaces != {}) {
|
||||||
};
|
};
|
||||||
}) {} (builtins.attrNames 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, ... }:
|
{ hostName, config, lib, pkgs, ... }:
|
||||||
|
|
||||||
let
|
let
|
||||||
|
gateway = "upstream1";
|
||||||
|
|
||||||
tunnels = lib.filterAttrs (_: { wireguard, ... }:
|
tunnels = lib.filterAttrs (_: { wireguard, ... }:
|
||||||
wireguard != null
|
wireguard != null
|
||||||
|
@ -16,7 +16,7 @@ let
|
||||||
"/run/wireguard-keys/${ifName}.key";
|
"/run/wireguard-keys/${ifName}.key";
|
||||||
|
|
||||||
wireguardMark = 3;
|
wireguardMark = 3;
|
||||||
vpnTable = 100;
|
vpn4Table = 100;
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
systemd.services = builtins.foldl' (services: ifName: services // {
|
systemd.services = builtins.foldl' (services: ifName: services // {
|
||||||
|
@ -52,6 +52,7 @@ in
|
||||||
};
|
};
|
||||||
wireguardConfig = {
|
wireguardConfig = {
|
||||||
PrivateKeyFile = privateKeyFile ifName;
|
PrivateKeyFile = privateKeyFile ifName;
|
||||||
|
# Mark for routing with another routing table
|
||||||
FirewallMark = wireguardMark;
|
FirewallMark = wireguardMark;
|
||||||
};
|
};
|
||||||
wireguardPeers = [ {
|
wireguardPeers = [ {
|
||||||
|
@ -67,10 +68,10 @@ in
|
||||||
# Wireguard transported through another routing table
|
# Wireguard transported through another routing table
|
||||||
# (containing upstream by bird ospf)
|
# (containing upstream by bird ospf)
|
||||||
core.routingPolicyRules = [ {
|
core.routingPolicyRules = [ {
|
||||||
# Marked wireguard packets take the vpn routing table
|
# Marked wireguard packets take the vpn4 routing table
|
||||||
routingPolicyRuleConfig = {
|
routingPolicyRuleConfig = {
|
||||||
|
Table = vpn4Table;
|
||||||
FirewallMark = wireguardMark;
|
FirewallMark = wireguardMark;
|
||||||
Table = vpnTable;
|
|
||||||
};
|
};
|
||||||
} ];
|
} ];
|
||||||
} // builtins.mapAttrs (ifName: { wireguard, upstream, ... }: {
|
} // builtins.mapAttrs (ifName: { wireguard, upstream, ... }: {
|
||||||
|
@ -83,12 +84,12 @@ in
|
||||||
|
|
||||||
# IPv4 default route
|
# IPv4 default route
|
||||||
networkConfig.DefaultRouteOnDevice = true;
|
networkConfig.DefaultRouteOnDevice = true;
|
||||||
routes = [ {
|
|
||||||
# IPv6 default route
|
# IPv6 default route
|
||||||
|
routes = [ {
|
||||||
routeConfig.Destination = "::/0";
|
routeConfig.Destination = "::/0";
|
||||||
} ];
|
} ];
|
||||||
|
|
||||||
extraConfig = lib.mkIf (upstream.upBandwidth != null) ''
|
extraConfig = ''
|
||||||
[CAKE]
|
[CAKE]
|
||||||
Parent = root
|
Parent = root
|
||||||
# DOCSIS overhead
|
# DOCSIS overhead
|
||||||
|
@ -109,7 +110,7 @@ in
|
||||||
networking.iproute2 = lib.mkIf enabled {
|
networking.iproute2 = lib.mkIf enabled {
|
||||||
enable = true;
|
enable = true;
|
||||||
rttablesExtraConfig = ''
|
rttablesExtraConfig = ''
|
||||||
${toString vpnTable} vpn
|
${toString vpn4Table} vpn4
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
55
nix/nixos-module/container/yggdrasil.nix
Normal file
55
nix/nixos-module/container/yggdrasil.nix
Normal file
|
@ -0,0 +1,55 @@
|
||||||
|
{ 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/
|
||||||
|
[
|
||||||
|
# deutschland
|
||||||
|
"tcp://[2a01:4f8:172:9ce::2]:1194" # janastu
|
||||||
|
|
||||||
|
# czechia
|
||||||
|
"tcp://[2a03:3b40:fe:ab::1]:46370" # emery vpsfree.cz
|
||||||
|
|
||||||
|
# poland
|
||||||
|
"tls://[2001:41d0:601:1100::cf2]:11129"
|
||||||
|
];
|
||||||
|
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
|
# Pulls together NixOS configuration modules according to the
|
||||||
# name/role of the host to be built.
|
# name/role of the host to be built.
|
||||||
{ hostName, lib, ... }:
|
{ hostName, config, lib, pkgs, ... }:
|
||||||
|
|
||||||
let
|
let
|
||||||
inherit (lib) optionals;
|
inherit (lib) optionals;
|
||||||
|
|
||||||
hostConfig = lib.config.site.hosts.${hostName};
|
hostConfig = lib.config.site.hosts.${hostName};
|
||||||
in {
|
in {
|
||||||
inherit (lib.config) site;
|
site = lib.config.site;
|
||||||
|
|
||||||
imports = [
|
imports = [
|
||||||
../lib/config/options.nix
|
../lib/config/options.nix
|
||||||
|
@ -20,27 +20,24 @@ in {
|
||||||
./server/default.nix
|
./server/default.nix
|
||||||
] ++
|
] ++
|
||||||
optionals (hostConfig.role == "container") [
|
optionals (hostConfig.role == "container") [
|
||||||
./container/lxc-config.nix
|
|
||||||
./container/defaults.nix
|
./container/defaults.nix
|
||||||
./container/dhcp-server.nix
|
./container/dhcp-server.nix
|
||||||
./container/wireguard.nix
|
./container/wireguard.nix
|
||||||
./container/dns.nix
|
./container/dns.nix
|
||||||
./container/dnscache.nix
|
./container/dnscache.nix
|
||||||
|
./container/yggdrasil.nix
|
||||||
] ++
|
] ++
|
||||||
optionals lib.config.site.hosts.${hostName}.isRouter [
|
optionals lib.config.site.hosts.${hostName}.isRouter [
|
||||||
./container/bird.nix
|
./container/bird.nix
|
||||||
] ++
|
] ++
|
||||||
optionals (
|
optionals (builtins.match "upstream.*" hostName != null) [
|
||||||
builtins.match "upstream.*" hostName != null ||
|
|
||||||
hostName == "flpk-gw"
|
|
||||||
) [
|
|
||||||
./container/upstream.nix
|
./container/upstream.nix
|
||||||
./container/upstream/pppoe.nix
|
./container/upstream/pppoe.nix
|
||||||
] ++
|
] ++
|
||||||
optionals (hostName == "mgmt-gw") [
|
optionals (hostName == "mgmt-gw") [
|
||||||
./container/mgmt-gw.nix
|
./container/mgmt-gw.nix
|
||||||
] ++
|
] ++
|
||||||
optionals (hostName == "vpn-gw") [
|
optionals (hostName == "netboot") [
|
||||||
./container/vpn.nix
|
./container/netboot.nix
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
{ hostName, inputs, config, lib, pkgs, ... }:
|
{ hostName, inputs, pkgs, config, options, lib, ... }:
|
||||||
|
|
||||||
{
|
{
|
||||||
boot.kernelParams = [
|
boot.kernelParams = [
|
||||||
|
@ -7,9 +7,11 @@
|
||||||
# Prevents automatic creation of interface bond0 by the kernel
|
# Prevents automatic creation of interface bond0 by the kernel
|
||||||
"bonding.max_bonds=0"
|
"bonding.max_bonds=0"
|
||||||
];
|
];
|
||||||
boot.tmp.useTmpfs = true;
|
boot.tmpOnTmpfs = true;
|
||||||
# Includes wireguard
|
# Includes wireguard
|
||||||
boot.kernelPackages = config.boot.zfs.package.latestCompatibleLinuxPackages;
|
boot.kernelPackages = pkgs.linuxPackages_latest;
|
||||||
|
# Keep building
|
||||||
|
boot.zfs.enableUnstable = true;
|
||||||
|
|
||||||
# no persistent logs
|
# no persistent logs
|
||||||
services.journald.extraConfig = ''
|
services.journald.extraConfig = ''
|
||||||
|
@ -23,18 +25,11 @@
|
||||||
registry = {
|
registry = {
|
||||||
nixpkgs.flake = inputs.nixpkgs;
|
nixpkgs.flake = inputs.nixpkgs;
|
||||||
};
|
};
|
||||||
|
|
||||||
settings = {
|
|
||||||
substituters = lib.mkBefore [ "https://hydra.hq.c3d2.de" ];
|
|
||||||
trusted-public-keys = [
|
|
||||||
"nix-serve.hq.c3d2.de:KZRGGnwOYzys6pxgM8jlur36RmkJQ/y8y62e52fj1ps=%"
|
|
||||||
];
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
documentation = {
|
documentation = {
|
||||||
enable = lib.mkForce false;
|
enable = false;
|
||||||
nixos.enable = lib.mkForce false;
|
nixos.enable = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
environment.systemPackages = with pkgs; [
|
environment.systemPackages = with pkgs; [
|
||||||
|
@ -42,8 +37,6 @@
|
||||||
bridge-utils
|
bridge-utils
|
||||||
conntrack-tools
|
conntrack-tools
|
||||||
dhcpcd
|
dhcpcd
|
||||||
dhcpdump
|
|
||||||
dig
|
|
||||||
ethtool
|
ethtool
|
||||||
git
|
git
|
||||||
iftop
|
iftop
|
||||||
|
@ -56,7 +49,6 @@
|
||||||
screen
|
screen
|
||||||
speedtest-cli
|
speedtest-cli
|
||||||
tcpdump
|
tcpdump
|
||||||
tmux
|
|
||||||
traceroute
|
traceroute
|
||||||
vim
|
vim
|
||||||
wget
|
wget
|
||||||
|
@ -64,25 +56,6 @@
|
||||||
|
|
||||||
networking.hostName = hostName;
|
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 = "";
|
users.users.root.initialHashedPassword = "";
|
||||||
|
|
||||||
system.stateVersion = "20.09";
|
system.stateVersion = "20.09";
|
||||||
|
|
|
@ -1,18 +1,11 @@
|
||||||
{ hostName, config, lib, ... }:
|
{ hostName, config, lib, ... }:
|
||||||
|
|
||||||
let
|
lib.mkIf config.site.hosts.${hostName}.firewall.enable {
|
||||||
hostConfig = config.site.hosts.${hostName};
|
networking.firewall = {
|
||||||
|
|
||||||
in {
|
|
||||||
networking.firewall = lib.mkIf hostConfig.firewall.enable {
|
|
||||||
enable = true;
|
enable = true;
|
||||||
extraCommands = ''
|
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 -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 = ''
|
extraStopCommands = ''
|
||||||
ip46tables -F FORWARD
|
ip46tables -F FORWARD
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
{ hostName, config, lib, ... }:
|
{ hostName, config, lib, pkgs, ... }:
|
||||||
|
|
||||||
let
|
let
|
||||||
# pick an address for a net's gateway
|
# pick an address for a net's gateway
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
{ pkgs, ... }:
|
{ pkgs, nixpkgs-master, ... }:
|
||||||
{
|
{
|
||||||
boot.kernelModules = [ "kvm-intel" "pppoe" ];
|
boot.kernelModules = [ "kvm-intel" "pppoe" ];
|
||||||
boot.kernelParams = [ "nomodeset" ];
|
boot.kernelParams = [ "nomodeset" ];
|
||||||
|
@ -8,20 +8,16 @@
|
||||||
time.timeZone = "Europe/Berlin";
|
time.timeZone = "Europe/Berlin";
|
||||||
|
|
||||||
environment.systemPackages = with pkgs; [
|
environment.systemPackages = with pkgs; [
|
||||||
git
|
wget vim git screen
|
||||||
inetutils # telnet
|
|
||||||
ipmitool
|
ipmitool
|
||||||
liboping # noping
|
|
||||||
screen
|
|
||||||
vim
|
|
||||||
wget
|
|
||||||
];
|
];
|
||||||
|
services.openssh.enable = true;
|
||||||
services.openssh = {
|
services.openssh.permitRootLogin = "prohibit-password";
|
||||||
enable = true;
|
|
||||||
settings.PermitRootLogin = "prohibit-password";
|
|
||||||
};
|
|
||||||
|
|
||||||
# additional config for bare metal
|
# 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
|
let
|
||||||
# Containers that are run on this host
|
# Containers that are run on this host
|
||||||
|
@ -10,6 +10,70 @@ let
|
||||||
|
|
||||||
enabled = containers != {};
|
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
|
# User-facing script to build/update container NixOS systems
|
||||||
build-script = pkgs.writeScriptBin "build-container" ''
|
build-script = pkgs.writeScriptBin "build-container" ''
|
||||||
#! ${pkgs.runtimeShell} -e
|
#! ${pkgs.runtimeShell} -e
|
||||||
|
@ -30,7 +94,6 @@ let
|
||||||
${ctName})
|
${ctName})
|
||||||
echo Using prebuilt system for container $c
|
echo Using prebuilt system for container $c
|
||||||
SYSTEM=${self.packages.x86_64-linux."${ctName}-rootfs"}
|
SYSTEM=${self.packages.x86_64-linux."${ctName}-rootfs"}
|
||||||
CONFIG=${self.packages.x86_64-linux."${ctName}-lxc-config"}
|
|
||||||
;;
|
;;
|
||||||
'') (
|
'') (
|
||||||
builtins.attrNames (
|
builtins.attrNames (
|
||||||
|
@ -42,8 +105,6 @@ let
|
||||||
echo Building $c
|
echo Building $c
|
||||||
nix build -o /nix/var/nix/gcroots/lxc/$c zentralwerk-network#$c-rootfs
|
nix build -o /nix/var/nix/gcroots/lxc/$c zentralwerk-network#$c-rootfs
|
||||||
SYSTEM=$(readlink /nix/var/nix/gcroots/lxc/$c)
|
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
|
esac
|
||||||
|
|
||||||
|
@ -56,7 +117,6 @@ let
|
||||||
mkdir -p /var/lib/lxc/$c/rootfs/$d
|
mkdir -p /var/lib/lxc/$c/rootfs/$d
|
||||||
done
|
done
|
||||||
ln -fs $SYSTEM/init /var/lib/lxc/$c/rootfs/init
|
ln -fs $SYSTEM/init /var/lib/lxc/$c/rootfs/init
|
||||||
ln -fs $CONFIG /var/lib/lxc/$c/config
|
|
||||||
done
|
done
|
||||||
|
|
||||||
# Activate all the desired container after all of them are
|
# Activate all the desired container after all of them are
|
||||||
|
@ -102,8 +162,10 @@ in
|
||||||
|
|
||||||
virtualisation.lxc = lib.mkIf enabled {
|
virtualisation.lxc = lib.mkIf enabled {
|
||||||
enable = true;
|
enable = true;
|
||||||
|
# Container configs live in /etc so that they can be created
|
||||||
|
# through `environment.etc`.
|
||||||
systemConfig = ''
|
systemConfig = ''
|
||||||
lxc.lxcpath = /var/lib/lxc
|
lxc.lxcpath = /etc/lxc/containers
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -114,7 +176,50 @@ in
|
||||||
enable-script disable-script
|
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 service template for LXC containers
|
||||||
systemd.services."lxc@" = {
|
systemd.services."lxc@" = {
|
||||||
|
@ -143,8 +248,6 @@ in
|
||||||
Restart = "always";
|
Restart = "always";
|
||||||
RestartSec = "1s";
|
RestartSec = "1s";
|
||||||
};
|
};
|
||||||
# Prevent restart on host nixos-rebuild switch
|
|
||||||
restartIfChanged = false;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
# Starts all the containers after boot
|
# Starts all the containers after boot
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
# Server network configuration
|
# Server network configuration
|
||||||
{ config, lib, ... }:
|
{ hostName, self, config, lib, pkgs, ... }:
|
||||||
|
|
||||||
let
|
let
|
||||||
# LXC containers on this host
|
# LXC containers on this host
|
||||||
|
@ -114,7 +114,5 @@ in
|
||||||
networkConfig.Bridge = net;
|
networkConfig.Bridge = net;
|
||||||
};
|
};
|
||||||
}) {} ctNets;
|
}) {} ctNets;
|
||||||
|
|
||||||
wait-online.anyInterface = true;
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,17 +1,21 @@
|
||||||
{ config, ... }:
|
{ config, pkgs, ... }:
|
||||||
|
|
||||||
{
|
{
|
||||||
# Use the systemd-boot EFI boot loader.
|
boot.loader.grub.enable = true;
|
||||||
boot.loader.systemd-boot.enable = true;
|
boot.loader.grub.version = 2;
|
||||||
boot.loader.efi.canTouchEfiVariables = true;
|
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.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.availableKernelModules = [ "uhci_hcd" "ehci_pci" "ata_piix" "hpsa" "usb_storage" "usbhid" "sd_mod" "sr_mod" ];
|
||||||
boot.initrd.kernelModules = [ ];
|
boot.initrd.kernelModules = [ ];
|
||||||
boot.extraModulePackages = [ ];
|
boot.extraModulePackages = [ ];
|
||||||
nixpkgs.config.allowBroken = true;
|
nixpkgs.config.allowBroken = true;
|
||||||
|
boot.zfs.enableUnstable = true;
|
||||||
boot.supportedFilesystems = [ "zfs" ];
|
boot.supportedFilesystems = [ "zfs" ];
|
||||||
boot.initrd.supportedFilesystems = [ "zfs" ];
|
boot.initrd.supportedFilesystems = [ "zfs" ];
|
||||||
# Required for Broadcom NICs
|
# Required for Broadcom NICs
|
||||||
|
@ -43,8 +47,8 @@
|
||||||
};
|
};
|
||||||
|
|
||||||
fileSystems."/boot" =
|
fileSystems."/boot" =
|
||||||
{ device = "/dev/disk/by-label/ESP";
|
{ device = "/dev/disk/by-uuid/23f17e88-ab7e-4dcc-a119-2ed1b9c2c91d";
|
||||||
fsType = "vfat";
|
fsType = "ext2";
|
||||||
};
|
};
|
||||||
|
|
||||||
swapDevices = [ ];
|
swapDevices = [ ];
|
||||||
|
|
|
@ -1,9 +1,10 @@
|
||||||
{ ... }:
|
{ pkgs, ... }:
|
||||||
|
|
||||||
{
|
{
|
||||||
boot.initrd.availableKernelModules = [ "uhci_hcd" "ehci_pci" "ahci" "usbhid" "sd_mod" "sr_mod" ];
|
boot.initrd.availableKernelModules = [ "uhci_hcd" "ehci_pci" "ahci" "usbhid" "sd_mod" "sr_mod" ];
|
||||||
boot.initrd.kernelModules = [ ];
|
boot.initrd.kernelModules = [ ];
|
||||||
nixpkgs.config.allowBroken = true;
|
nixpkgs.config.allowBroken = true;
|
||||||
|
boot.zfs.enableUnstable = true;
|
||||||
boot.supportedFilesystems = [ "zfs" ];
|
boot.supportedFilesystems = [ "zfs" ];
|
||||||
boot.initrd.supportedFilesystems = [ "zfs" ];
|
boot.initrd.supportedFilesystems = [ "zfs" ];
|
||||||
boot.extraModulePackages = [ ];
|
boot.extraModulePackages = [ ];
|
||||||
|
@ -38,6 +39,7 @@
|
||||||
};
|
};
|
||||||
|
|
||||||
boot.loader.grub.enable = true;
|
boot.loader.grub.enable = true;
|
||||||
|
boot.loader.grub.version = 2;
|
||||||
boot.loader.grub.device = "/dev/sda";
|
boot.loader.grub.device = "/dev/sda";
|
||||||
|
|
||||||
networking.hostName = "server2"; # Define your hostname.
|
networking.hostName = "server2"; # Define your hostname.
|
||||||
|
|
319
nix/pkgs/ap.nix
Normal file
319
nix/pkgs/ap.nix
Normal file
|
@ -0,0 +1,319 @@
|
||||||
|
{ self, pkgs, hostName, config, hostConfig, ... }:
|
||||||
|
with pkgs;
|
||||||
|
with lib;
|
||||||
|
let
|
||||||
|
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 =
|
||||||
|
any ({ switch ? null, ... }: switch != null)
|
||||||
|
(builtins.attrValues openwrtModel.ports);
|
||||||
|
|
||||||
|
portsDoc =
|
||||||
|
let
|
||||||
|
portByIndex = builtins.foldl' (result: port:
|
||||||
|
let
|
||||||
|
key = if port ? index
|
||||||
|
then port.index
|
||||||
|
else if port ? interface
|
||||||
|
then port.interface
|
||||||
|
else "How to identify port ${lib.generators.toPretty {} port}?";
|
||||||
|
in result // {
|
||||||
|
"${key}" = port;
|
||||||
|
}
|
||||||
|
) {} (builtins.attrValues openwrtModel.ports);
|
||||||
|
in
|
||||||
|
concatMapStringsSep ", " (index:
|
||||||
|
"${index}:${
|
||||||
|
if portByIndex.${index} ? port
|
||||||
|
then portByIndex.${index}.port
|
||||||
|
else if portByIndex.${index} ? interface
|
||||||
|
then portByIndex.${index}.interface
|
||||||
|
else throw "What is port ${lib.generators.toPretty {} portByIndex.${index}.port}?"
|
||||||
|
}"
|
||||||
|
) (
|
||||||
|
builtins.sort builtins.lessThan (
|
||||||
|
builtins.attrNames portByIndex
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
switchHostInterface =
|
||||||
|
let
|
||||||
|
hostPorts = sort builtins.lessThan (
|
||||||
|
map ({ interface, ... }: interface) (
|
||||||
|
builtins.attrValues (
|
||||||
|
filterAttrs (_: { type, ... }: type == "host")
|
||||||
|
openwrtModel.ports
|
||||||
|
)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
in if hostPorts == []
|
||||||
|
then throw "No host ports found for OpenWRT model ${hostConfig.model}"
|
||||||
|
else builtins.head hostPorts;
|
||||||
|
|
||||||
|
switchPortIndices = f:
|
||||||
|
map ({ index, ... }: index) (
|
||||||
|
builtins.attrValues (
|
||||||
|
filterAttrs (_: port: port ? index && f port)
|
||||||
|
openwrtModel.ports
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
trunked = map (index: "${index}t");
|
||||||
|
|
||||||
|
# OpenWRT switch ports string ("0t 1t 2 3 4") for a network (VLAN)
|
||||||
|
switchPortsConfig = net:
|
||||||
|
concatStringsSep " " (
|
||||||
|
# Host interface
|
||||||
|
trunked (switchPortIndices ({ interface ? null, ... }: interface == switchHostInterface))
|
||||||
|
++
|
||||||
|
# Access networks
|
||||||
|
optionals (hostConfig.links ? ${net}) (
|
||||||
|
builtins.concatMap (port':
|
||||||
|
switchPortIndices ({ port ? null, ... }: port == port')
|
||||||
|
) hostConfig.links.${net}.ports
|
||||||
|
)
|
||||||
|
++
|
||||||
|
# Trunk ports
|
||||||
|
builtins.concatMap (port':
|
||||||
|
trunked (switchPortIndices ({ port ? null, ... }: port == port'))
|
||||||
|
) (
|
||||||
|
builtins.concatMap ({ ports, ... }: ports) (
|
||||||
|
builtins.attrValues (
|
||||||
|
filterAttrs (_: { trunk, ... }:
|
||||||
|
trunk
|
||||||
|
) hostConfig.links
|
||||||
|
))
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
networkInterfaces = net:
|
||||||
|
let
|
||||||
|
inherit (config.site.net.${net}) vlan;
|
||||||
|
|
||||||
|
ifaces =
|
||||||
|
unique (
|
||||||
|
builtins.concatMap ({ trunk, ports, switch ? null, ... }:
|
||||||
|
builtins.concatMap (port:
|
||||||
|
builtins.concatMap (portData:
|
||||||
|
if portData ? port && port == portData.port
|
||||||
|
then [ ((
|
||||||
|
if portData ? switch
|
||||||
|
then switchHostInterface
|
||||||
|
else if portData ? interface
|
||||||
|
then portData.interface
|
||||||
|
else throw "Cannot find interface for ${port} on OpenWRT model ${hostConfig.model}"
|
||||||
|
) + (
|
||||||
|
if trunk || switch != null
|
||||||
|
then ".${toString vlan}"
|
||||||
|
else ""
|
||||||
|
)) ]
|
||||||
|
else []
|
||||||
|
) (builtins.attrValues openwrtModel.ports)
|
||||||
|
) ports
|
||||||
|
) (
|
||||||
|
builtins.attrValues (
|
||||||
|
filterAttrs (link: { nets, ... }:
|
||||||
|
link == net || builtins.elem net nets
|
||||||
|
) hostConfig.links
|
||||||
|
)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
in
|
||||||
|
if ifaces == []
|
||||||
|
then throw "No interfaces found for ${net} on ${hostName}"
|
||||||
|
else ifaces;
|
||||||
|
|
||||||
|
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__
|
||||||
|
''}
|
||||||
|
|
||||||
|
# Set root password
|
||||||
|
echo -e '${hostConfig.password}\n${hostConfig.password}' | passwd
|
||||||
|
|
||||||
|
# add ssh pubkeys
|
||||||
|
${concatMapStrings (sshPubKey: ''
|
||||||
|
echo "${sshPubKey}" > /etc/dropbear/authorized_keys
|
||||||
|
'') config.site.sshPubKeys}
|
||||||
|
|
||||||
|
# System configuration
|
||||||
|
${uciDeleteAll "network.@switch_vlan"}
|
||||||
|
${uciDeleteAll "wireless.@wifi"}
|
||||||
|
|
||||||
|
uci set system.@system[0].hostname=${hostName}
|
||||||
|
uci set dhcp.@dnsmasq[0].enabled=0
|
||||||
|
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 ''
|
||||||
|
# Ports ${portsDoc}
|
||||||
|
${concatMapStrings (net: ''
|
||||||
|
uci add network switch_vlan
|
||||||
|
uci set network.@switch_vlan[-1]=switch_vlan
|
||||||
|
uci set network.@switch_vlan[-1].device='switch0'
|
||||||
|
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)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)}
|
||||||
|
''}
|
||||||
|
|
||||||
|
# mgmt network
|
||||||
|
uci set network.mgmt=interface
|
||||||
|
uci set network.mgmt.ifname=${if builtins.length (networkInterfaces "mgmt") == 1 then builtins.head (networkInterfaces "mgmt") else throw "No interface for mgmt"}
|
||||||
|
uci set network.mgmt.proto=static
|
||||||
|
uci set network.mgmt.ipaddr=${config.site.net.mgmt.hosts4.${hostName}}
|
||||||
|
uci set network.mgmt.netmask=${self.lib.netmasks.${elemAt (
|
||||||
|
builtins.split "/" config.site.net.mgmt.subnet4
|
||||||
|
) 2}}
|
||||||
|
uci set network.mgmt.gateway=${config.site.net.mgmt.hosts4.mgmt-gw}
|
||||||
|
uci set network.mgmt.ip6addr=${config.site.net.mgmt.hosts6.dn42.${hostName}}/64
|
||||||
|
uci set network.mgmt.ip6gw=${config.site.net.mgmt.hosts6.dn42.mgmt-gw}
|
||||||
|
uci -q delete network.mgmt.dns || true
|
||||||
|
uci add_list network.mgmt.dns=${config.site.net.serv.hosts4.dnscache}
|
||||||
|
uci add_list network.mgmt.dns=${config.site.net.serv.hosts6.dn42.dnscache}
|
||||||
|
|
||||||
|
uci -q delete network.globals.ula_prefix || true
|
||||||
|
# delete unused networks
|
||||||
|
${concatMapStrings (net:
|
||||||
|
lib.optionalString (! hostConfig.interfaces ? ${net}) ''
|
||||||
|
uci -q delete network.${net} || true
|
||||||
|
''
|
||||||
|
) ([ "lan" "wan" "wan6" ] ++ builtins.attrNames config.site.net)}
|
||||||
|
|
||||||
|
# bridged networks
|
||||||
|
${concatMapStrings (net:
|
||||||
|
let
|
||||||
|
iface = hostConfig.interfaces.${net};
|
||||||
|
in optionalString (net != "mgmt" && iface.type == "bridge") ''
|
||||||
|
uci set network.${net}=interface
|
||||||
|
uci set network.${net}.type=bridge
|
||||||
|
uci set network.${net}.proto=static
|
||||||
|
uci set network.${net}.ifname='${concatStringsSep " " (networkInterfaces net)}'
|
||||||
|
|
||||||
|
'') (builtins.attrNames hostConfig.interfaces)
|
||||||
|
}
|
||||||
|
|
||||||
|
uci -q delete wireless.default_radio0 || true
|
||||||
|
uci -q delete wireless.default_radio1 || true
|
||||||
|
${concatStrings (imap0 (index: path:
|
||||||
|
let
|
||||||
|
radioConfig = hostConfig.wifi.${path};
|
||||||
|
ifPrefix = if radioConfig.channel < 15
|
||||||
|
then "wlan2"
|
||||||
|
else "wlan5";
|
||||||
|
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}.channel=${toString radioConfig.channel}
|
||||||
|
uci set wireless.radio${toString index}.path=${path}
|
||||||
|
uci set wireless.radio${toString index}.htmode=${radioConfig.htmode}
|
||||||
|
uci set wireless.radio${toString index}.noscan=1
|
||||||
|
uci -q delete wireless.radio${toString index}.disabled || true
|
||||||
|
|
||||||
|
${concatMapStrings (ssid:
|
||||||
|
let
|
||||||
|
ssidConfig = radioConfig.ssids.${ssid};
|
||||||
|
in ''
|
||||||
|
uci add wireless wifi-iface
|
||||||
|
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=ap
|
||||||
|
uci set wireless.@wifi-iface[-1].network=${ssidConfig.net}
|
||||||
|
uci set wireless.@wifi-iface[-1].mcast_rate=18000
|
||||||
|
${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
|
||||||
|
''}
|
||||||
|
|
||||||
|
''
|
||||||
|
) (builtins.attrNames radioConfig.ssids)}
|
||||||
|
'') (builtins.attrNames hostConfig.wifi))}
|
||||||
|
|
||||||
|
uci commit
|
||||||
|
|
||||||
|
# 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
|
||||||
|
__CRON__
|
||||||
|
cat >/usr/sbin/wifi-on-link.sh <<__SH__
|
||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
if (ping -c 1 -W 3 ${config.site.net.mgmt.hosts4.mgmt-gw}) ; then
|
||||||
|
REACHABLE=y
|
||||||
|
else
|
||||||
|
REACHABLE=n
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "\\\$(cat /sys/class/net/wlan2-pub/operstate)" == "up" ] ; then
|
||||||
|
UP=y
|
||||||
|
else
|
||||||
|
UP=n
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -e /sys/class/leds/blue:dome ] ; then
|
||||||
|
ERROR_LED=/sys/class/leds/blue:dome/brightness
|
||||||
|
[ \\\$REACHABLE = y ] && echo 0 > \\\$ERROR_LED
|
||||||
|
[ \\\$REACHABLE = n ] && echo 1 > \\\$ERROR_LED
|
||||||
|
fi
|
||||||
|
|
||||||
|
[ \\\$REACHABLE = y ] && [ \\\$UP = n ] && wifi up
|
||||||
|
[ \\\$REACHABLE = n ] && [ \\\$UP = y ] && wifi down
|
||||||
|
|
||||||
|
exit 0
|
||||||
|
__SH__
|
||||||
|
chmod a+rx /usr/sbin/wifi-on-link.sh
|
||||||
|
/etc/init.d/cron restart
|
||||||
|
|
||||||
|
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,4 +1,4 @@
|
||||||
#!/usr/bin/env bash
|
#!/bin/bash
|
||||||
|
|
||||||
for HOST in $@ ; do
|
for HOST in $@ ; do
|
||||||
ssh root@$HOST \
|
ssh root@$HOST \
|
||||||
|
|
|
@ -1,20 +1,16 @@
|
||||||
{ self, nixpkgs, system, openwrt-imagebuilder }:
|
{ self, nixpkgs, system }:
|
||||||
|
|
||||||
let
|
let
|
||||||
inherit (self.lib) config;
|
inherit (self.lib) config;
|
||||||
|
|
||||||
pkgs = nixpkgs.legacyPackages.${system};
|
pkgs = nixpkgs.legacyPackages.${system};
|
||||||
inherit (pkgs) lib;
|
|
||||||
|
|
||||||
export-openwrt-models = pkgs.writeText "openwrt-models.nix" (
|
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" (
|
export-config = pkgs.writeText "config.nix" (
|
||||||
lib.generators.toPretty {} (
|
nixpkgs.lib.generators.toPretty {} config
|
||||||
lib.recursiveUpdate
|
);
|
||||||
config
|
|
||||||
{ site.dns.localZones = self.lib.dns.localZones; }
|
|
||||||
));
|
|
||||||
|
|
||||||
encrypt-secrets = pkgs.writeScriptBin "encrypt-secrets" ''
|
encrypt-secrets = pkgs.writeScriptBin "encrypt-secrets" ''
|
||||||
#! ${pkgs.runtimeShell} -e
|
#! ${pkgs.runtimeShell} -e
|
||||||
|
@ -45,7 +41,7 @@ let
|
||||||
'';
|
'';
|
||||||
|
|
||||||
network-cypher-graphs = import ./network-cypher-graphs.nix { inherit config pkgs; };
|
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:
|
mkRootfs = hostName:
|
||||||
self.nixosConfigurations.${hostName}.config.system.build.toplevel;
|
self.nixosConfigurations.${hostName}.config.system.build.toplevel;
|
||||||
|
@ -55,20 +51,7 @@ let
|
||||||
"${hostName}-rootfs" = mkRootfs hostName;
|
"${hostName}-rootfs" = mkRootfs hostName;
|
||||||
}) {} (
|
}) {} (
|
||||||
builtins.attrNames (
|
builtins.attrNames (
|
||||||
lib.filterAttrs (_: { role, ... }: builtins.elem role ["server" "container"])
|
nixpkgs.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")
|
|
||||||
config.site.hosts
|
config.site.hosts
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
@ -76,33 +59,26 @@ let
|
||||||
vm-packages =
|
vm-packages =
|
||||||
builtins.foldl' (rootfs: hostName: rootfs // {
|
builtins.foldl' (rootfs: hostName: rootfs // {
|
||||||
"${hostName}-vm" = self.nixosConfigurations.${hostName}.config.system.build.vm
|
"${hostName}-vm" = self.nixosConfigurations.${hostName}.config.system.build.vm
|
||||||
.overrideAttrs (_oa: {
|
.overrideAttrs (oa: {
|
||||||
meta.mainProgram = "run-${hostName}-vm";
|
meta.mainProgram = "run-${hostName}-vm";
|
||||||
});
|
});
|
||||||
}) {} (
|
}) {} (
|
||||||
builtins.attrNames (
|
builtins.attrNames (
|
||||||
lib.filterAttrs (_: { role, ... }: role == "server")
|
nixpkgs.lib.filterAttrs (_: { role, ... }: role == "server")
|
||||||
config.site.hosts
|
config.site.hosts
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
openwrt = import ./openwrt { inherit self nixpkgs system openwrt-imagebuilder; };
|
all-rootfs = with pkgs;
|
||||||
|
runCommand "all-rootfs" {} ''
|
||||||
openwrt-packages = builtins.foldl' (images: hostName: images // {
|
mkdir -p $out
|
||||||
${hostName} = pkgs.writeScriptBin "${hostName}.sh" (
|
${lib.concatMapStrings (pkg: ''
|
||||||
openwrt.sshScript hostName
|
ln -s ${pkg} $out/${pkg.name}
|
||||||
);
|
'') (builtins.attrValues rootfs-packages)}
|
||||||
"${hostName}-image" = openwrt.buildImage hostName;
|
'';
|
||||||
}) {} (
|
|
||||||
builtins.attrNames (
|
|
||||||
lib.filterAttrs (_: { role, ... }:
|
|
||||||
role == "ap"
|
|
||||||
) config.site.hosts
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
device-templates = import ./device-templates.nix {
|
device-templates = import ./device-templates.nix {
|
||||||
inherit self nixpkgs system openwrt;
|
inherit self nixpkgs system;
|
||||||
};
|
};
|
||||||
|
|
||||||
dns-slaves = import ./dns-slaves.nix {
|
dns-slaves = import ./dns-slaves.nix {
|
||||||
|
@ -116,26 +92,9 @@ let
|
||||||
subnetplans = import ./subnetplans.nix {
|
subnetplans = import ./subnetplans.nix {
|
||||||
inherit self nixpkgs system;
|
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
|
in
|
||||||
rootfs-packages // lxc-configs // vm-packages // device-templates // openwrt-packages // network-graphs // network-cypher-graphs // starlink // subnetplans // {
|
rootfs-packages // vm-packages // device-templates // network-graphs // network-cypher-graphs // starlink // subnetplans // {
|
||||||
inherit export-openwrt-models export-config dns-slaves
|
inherit all-rootfs export-openwrt-models export-config dns-slaves
|
||||||
encrypt-secrets decrypt-secrets switch-to-production
|
encrypt-secrets decrypt-secrets switch-to-production
|
||||||
homepage gateway-report switch-report vlan-report
|
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
{ self, nixpkgs, system, openwrt }:
|
{ self, nixpkgs, system }:
|
||||||
with nixpkgs.lib;
|
with nixpkgs.lib;
|
||||||
let
|
let
|
||||||
pkgs = nixpkgs.legacyPackages.${system};
|
pkgs = nixpkgs.legacyPackages.${system};
|
||||||
|
@ -11,13 +11,17 @@ let
|
||||||
args = {
|
args = {
|
||||||
inherit self hostName config hostConfig pkgs;
|
inherit self hostName config hostConfig pkgs;
|
||||||
};
|
};
|
||||||
in import (./switches + "/${model}.nix") (
|
in {
|
||||||
args // import ./switches/shared.nix args
|
ap = import ./ap.nix args;
|
||||||
)
|
switch = import (./switches + "/${model}.nix")
|
||||||
|
(args //
|
||||||
|
import ./switches/shared.nix args
|
||||||
|
);
|
||||||
|
}.${role}
|
||||||
)
|
)
|
||||||
) (
|
) (
|
||||||
filterAttrs (_: { role, model, ... }:
|
filterAttrs (_: { role, ... }:
|
||||||
role == "switch" && model != "dumb"
|
role == "ap" || role == "switch"
|
||||||
) config.site.hosts
|
) config.site.hosts
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
@ -15,13 +15,13 @@ let
|
||||||
in
|
in
|
||||||
|
|
||||||
writeText "named.slave.conf" (
|
writeText "named.slave.conf" (
|
||||||
lib.concatMapStringsSep "\n" ({ name, ... }: ''
|
lib.concatMapStringsSep "\n" ({ name, ns, ... }: ''
|
||||||
zone "${name}" IN {
|
zone "${name}" IN {
|
||||||
type slave;
|
type slave;
|
||||||
masters {${mastersStr} };
|
masters {${mastersStr} };
|
||||||
file "/var/lib/bind/slave/${name}.zone";
|
file "/var/lib/bind/slave/${name}.zone";
|
||||||
allow-notify {${mastersStr} };
|
allow-notify {${mastersStr} };
|
||||||
allow-query { any; };
|
allow-query { all; };
|
||||||
};
|
};
|
||||||
'') (
|
'') (
|
||||||
# public zones only
|
# public zones only
|
||||||
|
|
|
@ -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,5 +0,0 @@
|
||||||
{
|
|
||||||
"captive": false,
|
|
||||||
"user-portal-url": "https://zentralwerk.org/",
|
|
||||||
"venue-info-url": "https://zentralwerk.org/"
|
|
||||||
}
|
|
|
@ -1,75 +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
|
|
||||||
ln -s ${./captive.json} $DIR/captive.json
|
|
||||||
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 =
|
logical-cypher-graph =
|
||||||
let
|
let
|
||||||
containers =
|
containers =
|
||||||
lib.filterAttrs (_: { role, ... }:
|
lib.filterAttrs (_: { isRouter, role, ... }:
|
||||||
role == "container"
|
role == "container"
|
||||||
) config.site.hosts;
|
) config.site.hosts;
|
||||||
in
|
in
|
||||||
|
|
|
@ -1,14 +1,12 @@
|
||||||
{ config, lib, pkgs, ... }:
|
{ config, pkgs, ... }:
|
||||||
let
|
let
|
||||||
|
inherit (pkgs) lib runCommand graphviz;
|
||||||
|
|
||||||
netColor = net:
|
netColor = net:
|
||||||
if net == "core"
|
if net == "core"
|
||||||
then "grey"
|
then "grey"
|
||||||
else if net == "mgmt"
|
else if net == "mgmt"
|
||||||
then "brown"
|
then "brown"
|
||||||
else if net == "roof"
|
|
||||||
then "orange"
|
|
||||||
else if net == "flpk"
|
|
||||||
then "yellow"
|
|
||||||
else if builtins.elem net [ "c3d2" "serv" "cluster" ]
|
else if builtins.elem net [ "c3d2" "serv" "cluster" ]
|
||||||
then "green"
|
then "green"
|
||||||
else if builtins.match "up.+" net != null ||
|
else if builtins.match "up.+" net != null ||
|
||||||
|
@ -80,13 +78,13 @@ let
|
||||||
}
|
}
|
||||||
'';
|
'';
|
||||||
renderGraph = args@{ name, engine, ... }:
|
renderGraph = args@{ name, engine, ... }:
|
||||||
pkgs.runCommand "${name}.png" {
|
runCommand "${name}.png" {
|
||||||
src = builtins.toFile "${name}.dot" (
|
src = builtins.toFile "${name}.dot" (
|
||||||
toDot args
|
toDot args
|
||||||
);
|
);
|
||||||
} ''
|
} ''
|
||||||
echo $src
|
echo $src
|
||||||
${pkgs.graphviz-nox}/bin/${engine} -Tpng $src > $out
|
${graphviz}/bin/${engine} -Tpng $src > $out
|
||||||
'';
|
'';
|
||||||
|
|
||||||
in rec {
|
in rec {
|
||||||
|
@ -136,7 +134,7 @@ in rec {
|
||||||
logical-graph =
|
logical-graph =
|
||||||
let
|
let
|
||||||
containers =
|
containers =
|
||||||
lib.filterAttrs (_: { role, ... }:
|
lib.filterAttrs (_: { isRouter, role, ... }:
|
||||||
role == "container"
|
role == "container"
|
||||||
) config.site.hosts;
|
) config.site.hosts;
|
||||||
in
|
in
|
||||||
|
@ -160,7 +158,7 @@ in rec {
|
||||||
) (builtins.attrNames containers);
|
) (builtins.attrNames containers);
|
||||||
};
|
};
|
||||||
|
|
||||||
network-graphs = pkgs.runCommand "network-graphs" {} ''
|
network-graphs = runCommand "network-graphs" {} ''
|
||||||
DIR=$out/share/doc/zentralwerk
|
DIR=$out/share/doc/zentralwerk
|
||||||
mkdir -p $DIR
|
mkdir -p $DIR
|
||||||
ln -s ${physical-graph} $DIR/physical.png
|
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,528 +0,0 @@
|
||||||
{ self, pkgs, hostName }:
|
|
||||||
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
|
|
||||||
'';
|
|
||||||
|
|
||||||
openwrtModel = self.lib.getOpenwrtModel hostConfig.model;
|
|
||||||
|
|
||||||
hasSwitch =
|
|
||||||
if hostConfig.model == "ubnt_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
|
|
||||||
portByIndex = builtins.foldl' (result: port:
|
|
||||||
let
|
|
||||||
key = if port ? index
|
|
||||||
then port.index
|
|
||||||
else if port ? interface
|
|
||||||
then port.interface
|
|
||||||
else "How to identify port ${generators.toPretty {} port}?";
|
|
||||||
in result // {
|
|
||||||
"${key}" = port;
|
|
||||||
}
|
|
||||||
) {} (builtins.attrValues openwrtModel.ports);
|
|
||||||
in
|
|
||||||
concatMapStringsSep ", " (index:
|
|
||||||
"${index}:${
|
|
||||||
if portByIndex.${index} ? port
|
|
||||||
then portByIndex.${index}.port
|
|
||||||
else if portByIndex.${index} ? interface
|
|
||||||
then portByIndex.${index}.interface
|
|
||||||
else throw "${hostName}: What is port ${generators.toPretty {} portByIndex.${index}.port}?"
|
|
||||||
}"
|
|
||||||
) (
|
|
||||||
builtins.sort builtins.lessThan (
|
|
||||||
builtins.attrNames portByIndex
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
switchHostInterface =
|
|
||||||
let
|
|
||||||
hostPorts = sort builtins.lessThan (
|
|
||||||
map ({ interface, ... }: interface) (
|
|
||||||
builtins.attrValues (
|
|
||||||
filterAttrs (_: { type, ... }: type == "host")
|
|
||||||
openwrtModel.ports
|
|
||||||
)
|
|
||||||
)
|
|
||||||
);
|
|
||||||
in if hostPorts == []
|
|
||||||
then throw "${hostName}: No host ports found for OpenWRT model ${hostConfig.model}"
|
|
||||||
else builtins.head hostPorts;
|
|
||||||
|
|
||||||
switchPortIndices = f:
|
|
||||||
map ({ index, ... }: index) (
|
|
||||||
builtins.attrValues (
|
|
||||||
filterAttrs (_: port: port ? index && f port)
|
|
||||||
openwrtModel.ports
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
trunked = map (index: "${index}t");
|
|
||||||
|
|
||||||
# OpenWRT switch ports string ("0t 1t 2 3 4") for a network (VLAN)
|
|
||||||
switchPortsConfig = net:
|
|
||||||
concatStringsSep " " (
|
|
||||||
# Host interface
|
|
||||||
trunked (switchPortIndices ({ interface ? null, ... }: interface == switchHostInterface))
|
|
||||||
++
|
|
||||||
# Access networks
|
|
||||||
optionals (hostConfig.links ? ${net}) (
|
|
||||||
builtins.concatMap (port':
|
|
||||||
switchPortIndices ({ port ? null, ... }: port == port')
|
|
||||||
) hostConfig.links.${net}.ports
|
|
||||||
)
|
|
||||||
++
|
|
||||||
# Trunk ports
|
|
||||||
builtins.concatMap (port':
|
|
||||||
trunked (switchPortIndices ({ port ? null, ... }: port == port'))
|
|
||||||
) (
|
|
||||||
builtins.concatMap ({ ports, ... }: ports) (
|
|
||||||
builtins.attrValues (
|
|
||||||
filterAttrs (_: { trunk, ... }:
|
|
||||||
trunk
|
|
||||||
) hostConfig.links
|
|
||||||
))
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
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;
|
|
||||||
in unique (
|
|
||||||
builtins.concatMap ({ trunk, ports, switch ? null, ... }:
|
|
||||||
builtins.concatMap (port:
|
|
||||||
builtins.concatMap (portData:
|
|
||||||
if portData ? port && port == portData.port
|
|
||||||
then [ ((
|
|
||||||
if portData ? switch
|
|
||||||
then switchHostInterface
|
|
||||||
else if portData ? interface
|
|
||||||
then portData.interface
|
|
||||||
else throw "${hostName}: Cannot find interface for ${port} on OpenWRT model ${hostConfig.model}"
|
|
||||||
) + (
|
|
||||||
if trunk || switch != null
|
|
||||||
then ".${toString vlan}"
|
|
||||||
else ""
|
|
||||||
)) ]
|
|
||||||
else []
|
|
||||||
) (builtins.attrValues openwrtModel.ports)
|
|
||||||
++
|
|
||||||
optionals (hostConfig.interfaces ? ${port} && vlan != null) [ "${port}.${toString vlan}" ]
|
|
||||||
) ports
|
|
||||||
) (
|
|
||||||
builtins.attrValues (
|
|
||||||
filterAttrs (link: { nets, ... }:
|
|
||||||
link == net || builtins.elem net nets
|
|
||||||
) hostConfig.links
|
|
||||||
)
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
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
|
|
||||||
''
|
|
||||||
# Set root password
|
|
||||||
echo -e '${hostConfig.password}\n${hostConfig.password}' | passwd
|
|
||||||
|
|
||||||
# add ssh pubkeys
|
|
||||||
${concatMapStrings (sshPubKey: ''
|
|
||||||
echo "${sshPubKey}" > /etc/dropbear/authorized_keys
|
|
||||||
'') config.site.sshPubKeys}
|
|
||||||
|
|
||||||
# System configuration
|
|
||||||
${uciDeleteAll "network.@switch_vlan"}
|
|
||||||
${uciDeleteAll "wireless.@wifi-iface"}
|
|
||||||
|
|
||||||
uci set system.@system[0].hostname=${hostName}
|
|
||||||
uci set dhcp.@dnsmasq[0].enabled=0
|
|
||||||
uci set system.@system[0].log_ip=${config.site.net.mgmt.hosts4.logging}
|
|
||||||
uci set system.@system[0].log_proto=udp
|
|
||||||
|
|
||||||
${optionalString hasSwitch ''
|
|
||||||
# Switch config
|
|
||||||
# Ports ${portsDoc}
|
|
||||||
${concatMapStrings (net: ''
|
|
||||||
uci add network switch_vlan
|
|
||||||
uci set network.@switch_vlan[-1]=switch_vlan
|
|
||||||
uci set network.@switch_vlan[-1].device='switch0'
|
|
||||||
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
|
|
||||||
) (
|
|
||||||
unique (
|
|
||||||
builtins.concatMap ({ nets, ... }: nets)
|
|
||||||
(builtins.attrValues hostConfig.links)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)}
|
|
||||||
''}
|
|
||||||
|
|
||||||
# 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.proto=static
|
|
||||||
${optionalString (hostConfig.interfaces.mgmt.type == "bridge") ''
|
|
||||||
uci set network.mgmt.type=bridge
|
|
||||||
''}
|
|
||||||
uci set network.mgmt.ipaddr=${config.site.net.mgmt.hosts4.${hostName}}
|
|
||||||
uci set network.mgmt.netmask=${self.lib.netmasks.${toString config.site.net.mgmt.subnet4Len}}
|
|
||||||
uci set network.mgmt.gateway=${config.site.net.mgmt.hosts4.mgmt-gw}
|
|
||||||
uci set network.mgmt.ip6addr=${config.site.net.mgmt.hosts6.dn42.${hostName}}/64
|
|
||||||
uci set network.mgmt.ip6gw=${config.site.net.mgmt.hosts6.dn42.mgmt-gw}
|
|
||||||
uci -q delete network.mgmt.dns || true
|
|
||||||
uci add_list network.mgmt.dns=${config.site.net.serv.hosts4.dnscache}
|
|
||||||
uci add_list network.mgmt.dns=${config.site.net.serv.hosts6.dn42.dnscache}
|
|
||||||
|
|
||||||
uci -q delete network.globals.ula_prefix || true
|
|
||||||
# delete unused networks
|
|
||||||
${concatMapStrings (net:
|
|
||||||
optionalString (! hostConfig.interfaces ? ${net}) ''
|
|
||||||
uci -q delete network.${net} || true
|
|
||||||
''
|
|
||||||
) ([ "lan" "wan" "wan6" ] ++ builtins.attrNames config.site.net)}
|
|
||||||
|
|
||||||
# bridged and static networks
|
|
||||||
${concatMapStrings (net:
|
|
||||||
let
|
|
||||||
iface = hostConfig.interfaces.${net};
|
|
||||||
in optionalString (net != "mgmt" && builtins.elem iface.type ["bridge" "phys"]) ''
|
|
||||||
uci set network.${net}=interface
|
|
||||||
${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}.mtu=${toString config.site.net.${net}.mtu}
|
|
||||||
''}
|
|
||||||
|
|
||||||
|
|
||||||
${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}) ''
|
|
||||||
uci set network.${net}.ip6addr=${hosts6.${hostName}}/64
|
|
||||||
'') (builtins.attrValues config.site.net.${net}.hosts6)}
|
|
||||||
'') (builtins.attrNames hostConfig.interfaces)
|
|
||||||
}
|
|
||||||
|
|
||||||
# vxlan trunks
|
|
||||||
${concatMapStrings (name:
|
|
||||||
let
|
|
||||||
iface = hostConfig.interfaces.${name};
|
|
||||||
in optionalString (iface.type == "vxlan") ''
|
|
||||||
uci set network.${name}=interface
|
|
||||||
uci set network.${name}.proto=vxlan6
|
|
||||||
uci set network.${name}.peer6addr='${iface.vxlan.peer}'
|
|
||||||
uci set network.${name}.port=4789
|
|
||||||
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:
|
|
||||||
let
|
|
||||||
radioConfig = hostConfig.wifi.${path};
|
|
||||||
ifPrefix = if radioConfig.channel < 15
|
|
||||||
then "wlan2"
|
|
||||||
else "wlan5";
|
|
||||||
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}
|
|
||||||
uci set wireless.radio${toString index}.noscan=1
|
|
||||||
uci -q delete wireless.radio${toString index}.disabled || true
|
|
||||||
|
|
||||||
${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].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].key='${ssidConfig.psk}'
|
|
||||||
''
|
|
||||||
else ''
|
|
||||||
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 ''
|
|
||||||
# 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
|
|
||||||
__CRON__
|
|
||||||
cat >/usr/sbin/wifi-on-link.sh <<__SH__
|
|
||||||
#!/bin/sh
|
|
||||||
|
|
||||||
if (ping -c 1 -W 3 ${config.site.net.mgmt.hosts4.mgmt-gw}) ; then
|
|
||||||
REACHABLE=y
|
|
||||||
else
|
|
||||||
REACHABLE=n
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ "\\\$(cat /sys/class/net/wlan2-pub/operstate)" == "up" ] ; then
|
|
||||||
UP=y
|
|
||||||
else
|
|
||||||
UP=n
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ -e /sys/class/leds/blue:dome ] ; then
|
|
||||||
ERROR_LED=/sys/class/leds/blue:dome/brightness
|
|
||||||
[ \\\$REACHABLE = y ] && echo 0 > \\\$ERROR_LED
|
|
||||||
[ \\\$REACHABLE = n ] && echo 1 > \\\$ERROR_LED
|
|
||||||
fi
|
|
||||||
|
|
||||||
[ \\\$REACHABLE = y ] && [ \\\$UP = n ] && wifi up
|
|
||||||
[ \\\$REACHABLE = n ] && [ \\\$UP = y ] && wifi down
|
|
||||||
|
|
||||||
exit 0
|
|
||||||
__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
|
|
||||||
''
|
|
|
@ -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
|
end
|
||||||
exit 1 if collisions > 0
|
exit 1 if collisions > 0
|
||||||
|
|
||||||
GROUP_PREFIX = 19
|
GROUP_PREFIX = 16
|
||||||
groups = {}
|
groups = {}
|
||||||
nets.each do |net|
|
nets.each do |net|
|
||||||
if net.addr.prefix > GROUP_PREFIX
|
|
||||||
group = net.addr.supernet(GROUP_PREFIX).to_s
|
group = net.addr.supernet(GROUP_PREFIX).to_s
|
||||||
else
|
|
||||||
group = net.addr.to_s
|
|
||||||
end
|
|
||||||
(groups[group] ||= []) << net
|
(groups[group] ||= []) << net
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -105,9 +101,7 @@ def background_color desc
|
||||||
"#9F9F9F"
|
"#9F9F9F"
|
||||||
when "mgmt"
|
when "mgmt"
|
||||||
"#FF3F3F"
|
"#FF3F3F"
|
||||||
when "roof"
|
when "c3d2"
|
||||||
"#FF4F2F"
|
|
||||||
when "c3d2", "flpk"
|
|
||||||
"yellow"
|
"yellow"
|
||||||
when "serv", "cluster"
|
when "serv", "cluster"
|
||||||
"orange"
|
"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"}
|
|
||||||
''
|
|
|
@ -54,9 +54,7 @@ with lib;
|
||||||
builtins.split "/" netConfig.subnet4
|
builtins.split "/" netConfig.subnet4
|
||||||
) 2;
|
) 2;
|
||||||
netmask = self.lib.netmasks.${prefixLength};
|
netmask = self.lib.netmasks.${prefixLength};
|
||||||
in
|
in ''
|
||||||
if netConfig.vlan != null
|
|
||||||
then ''
|
|
||||||
send "vlan ${vlan}\r"
|
send "vlan ${vlan}\r"
|
||||||
expect -- "-vlan${vlan}]"
|
expect -- "-vlan${vlan}]"
|
||||||
send "name ${net}\r"
|
send "name ${net}\r"
|
||||||
|
@ -72,9 +70,7 @@ with lib;
|
||||||
''}
|
''}
|
||||||
send "quit\r"
|
send "quit\r"
|
||||||
expect "${hostName}]"
|
expect "${hostName}]"
|
||||||
''
|
'') (sortNetsByVlan (builtins.attrNames config.site.net))
|
||||||
else ""
|
|
||||||
) (sortNetsByVlan (builtins.attrNames config.site.net))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
${concatMapStrings (name:
|
${concatMapStrings (name:
|
||||||
|
|
|
@ -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"
|
|
||||||
''
|
|
|
@ -37,7 +37,7 @@ with lib;
|
||||||
send "logging facility local6\r"
|
send "logging facility local6\r"
|
||||||
expect "(config)# "
|
expect "(config)# "
|
||||||
|
|
||||||
# TODO ntp
|
# todo ntp
|
||||||
# timesync sntp
|
# timesync sntp
|
||||||
# ip timep manual {#ntp#} interval 10
|
# ip timep manual {#ntp#} interval 10
|
||||||
|
|
||||||
|
@ -51,9 +51,7 @@ with lib;
|
||||||
builtins.split "/" netConfig.subnet4
|
builtins.split "/" netConfig.subnet4
|
||||||
) 2;
|
) 2;
|
||||||
netmask = self.lib.netmasks.${prefixLength};
|
netmask = self.lib.netmasks.${prefixLength};
|
||||||
in
|
in ''
|
||||||
if netConfig.vlan != null
|
|
||||||
then ''
|
|
||||||
send "vlan ${vlan}\r"
|
send "vlan ${vlan}\r"
|
||||||
expect "(vlan-${vlan})#"
|
expect "(vlan-${vlan})#"
|
||||||
|
|
||||||
|
@ -83,9 +81,7 @@ with lib;
|
||||||
send "no vlan ${vlan} untagged all\r"
|
send "no vlan ${vlan} untagged all\r"
|
||||||
expect "(config)# "
|
expect "(config)# "
|
||||||
''}
|
''}
|
||||||
''
|
'') (sortNetsByVlan (builtins.attrNames config.site.net))
|
||||||
else ""
|
|
||||||
) (sortNetsByVlan (builtins.attrNames config.site.net))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
${concatMapStrings (name:
|
${concatMapStrings (name:
|
||||||
|
|
|
@ -60,9 +60,7 @@ with lib;
|
||||||
builtins.split "/" netConfig.subnet4
|
builtins.split "/" netConfig.subnet4
|
||||||
) 2;
|
) 2;
|
||||||
netmask = self.lib.netmasks.${prefixLength};
|
netmask = self.lib.netmasks.${prefixLength};
|
||||||
in
|
in ''
|
||||||
if netConfig.vlan != null
|
|
||||||
then ''
|
|
||||||
${optionalString (net != "mgmt") ''
|
${optionalString (net != "mgmt") ''
|
||||||
send "vlan ${vlan}\r"
|
send "vlan ${vlan}\r"
|
||||||
expect "(config-vlan)#"
|
expect "(config-vlan)#"
|
||||||
|
@ -82,7 +80,6 @@ with lib;
|
||||||
send "exit\r"
|
send "exit\r"
|
||||||
expect "(config)#"
|
expect "(config)#"
|
||||||
''
|
''
|
||||||
else ""
|
|
||||||
) (sortNetsByVlan (builtins.attrNames config.site.net))}
|
) (sortNetsByVlan (builtins.attrNames config.site.net))}
|
||||||
|
|
||||||
${concatMapStrings (name:
|
${concatMapStrings (name:
|
||||||
|
@ -122,7 +119,7 @@ with lib;
|
||||||
send "exit\r"
|
send "exit\r"
|
||||||
expect "(config)#"
|
expect "(config)#"
|
||||||
'' else ''
|
'' else ''
|
||||||
send "interface range gigabitEthernet ${ports}\r"
|
send "interface range gigabitEthernet 1/0/${ports}\r"
|
||||||
expect "(config-if-range)#"
|
expect "(config-if-range)#"
|
||||||
send "switchport mode access\r"
|
send "switchport mode access\r"
|
||||||
expect "(config-if-range)#"
|
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/
|
# https://www.crc.id.au/real-console-on-linksys-srw2024-switch/
|
||||||
{ pkgs, hostName, config, hostConfig
|
{ self, pkgs, hostName, config, hostConfig
|
||||||
, sort, sortBy, sortNetsByVlan
|
, sort, sortBy, sortNetsByVlan
|
||||||
, ... }:
|
, ... }:
|
||||||
with pkgs;
|
with pkgs;
|
||||||
|
@ -33,44 +33,29 @@ with lib;
|
||||||
send "vlan database\r"
|
send "vlan database\r"
|
||||||
expect "(config-vlan)# "
|
expect "(config-vlan)# "
|
||||||
|
|
||||||
${concatMapStrings (net:
|
${concatMapStrings (net: ''
|
||||||
let
|
send "vlan ${toString config.site.net.${net}.vlan}\r"
|
||||||
netConfig = config.site.net.${net};
|
|
||||||
in
|
|
||||||
if netConfig.vlan != null
|
|
||||||
then ''
|
|
||||||
send "vlan ${toString netConfig.vlan}\r"
|
|
||||||
expect "(config-vlan)#"
|
expect "(config-vlan)#"
|
||||||
''
|
'') (sortNetsByVlan (builtins.attrNames config.site.net))}
|
||||||
else ""
|
|
||||||
) (sortNetsByVlan (builtins.attrNames config.site.net))}
|
|
||||||
send "exit\r"
|
send "exit\r"
|
||||||
expect "(config)#"
|
expect "(config)#"
|
||||||
|
|
||||||
${concatMapStrings (net:
|
${concatMapStrings (net: ''
|
||||||
let
|
|
||||||
netConfig = config.site.net.${net};
|
|
||||||
in
|
|
||||||
if netConfig.vlan != null
|
|
||||||
then ''
|
|
||||||
send "interface vlan ${toString config.site.net.${net}.vlan}\r"
|
send "interface vlan ${toString config.site.net.${net}.vlan}\r"
|
||||||
expect "(config-if)#"
|
expect "(config-if)#"
|
||||||
send "name ${net}\r"
|
send "name ${net}\r"
|
||||||
expect "(config-if)#"
|
expect "(config-if)#"
|
||||||
send "exit\r"
|
send "exit\r"
|
||||||
expect "(config)#"
|
expect "(config)#"
|
||||||
''
|
'') (sortNetsByVlan (builtins.attrNames config.site.net))}
|
||||||
else ""
|
|
||||||
) (sortNetsByVlan (builtins.attrNames config.site.net))}
|
|
||||||
|
|
||||||
${concatMapStrings (name:
|
${concatMapStrings (name:
|
||||||
let
|
let
|
||||||
linkConfig = hostConfig.links.${name};
|
linkConfig = hostConfig.links.${name};
|
||||||
|
isAccess = config.site.net ? ${name};
|
||||||
netConfig = config.site.net.${name};
|
netConfig = config.site.net.${name};
|
||||||
isTrunk = linkConfig.trunk;
|
isTrunk = !isAccess;
|
||||||
isBond = builtins.length linkConfig.ports > 1 &&
|
isBond = isTrunk && builtins.length linkConfig.ports > 1;
|
||||||
# not named like a net
|
|
||||||
(!config.site.net ? ${name});
|
|
||||||
vlans = concatStringsSep "," (map toString (sort linkConfig.vlans));
|
vlans = concatStringsSep "," (map toString (sort linkConfig.vlans));
|
||||||
ports = concatStringsSep "," linkConfig.ports;
|
ports = concatStringsSep "," linkConfig.ports;
|
||||||
in
|
in
|
||||||
|
@ -109,31 +94,6 @@ with lib;
|
||||||
send "exit\r"
|
send "exit\r"
|
||||||
expect "(config)#"
|
expect "(config)#"
|
||||||
'') linkConfig.ports
|
'') 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: ''
|
else concatMapStrings (port: ''
|
||||||
send "interface ethernet ${port}\r"
|
send "interface ethernet ${port}\r"
|
||||||
expect "(config-if)#"
|
expect "(config-if)#"
|
||||||
|
|
|
@ -17,13 +17,6 @@ rec {
|
||||||
else ra < rb
|
else ra < rb
|
||||||
);
|
);
|
||||||
sortNetsByVlan = builtins.sort (net1: net2:
|
sortNetsByVlan = builtins.sort (net1: net2:
|
||||||
let
|
config.site.net.${net1}.vlan < config.site.net.${net2}.vlan
|
||||||
vlan1 = config.site.net.${net1}.vlan;
|
|
||||||
vlan2 = config.site.net.${net2}.vlan;
|
|
||||||
in if vlan1 == null
|
|
||||||
then true
|
|
||||||
else if vlan2 == null
|
|
||||||
then false
|
|
||||||
else vlan1 < vlan2
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,24 +0,0 @@
|
||||||
{ self, nixpkgs, system }:
|
|
||||||
with nixpkgs.legacyPackages.${system};
|
|
||||||
let
|
|
||||||
config = self.lib.config;
|
|
||||||
in
|
|
||||||
writeText "vlan-report.md" ''
|
|
||||||
# VLAN Report
|
|
||||||
|
|
||||||
${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:
|
|
||||||
map (target: "- ${host} -> ${target}") (
|
|
||||||
builtins.attrNames (
|
|
||||||
lib.filterAttrs (_: { nets, ... }:
|
|
||||||
lib.elem net nets
|
|
||||||
) config.site.hosts.${host}.links
|
|
||||||
)
|
|
||||||
)
|
|
||||||
) (lib.attrNames config.site.hosts)
|
|
||||||
)}
|
|
||||||
|
|
||||||
'') (lib.attrNames config.site.net)}
|
|
||||||
''
|
|
5985
openwrt/tl-wr841-v10.config
Normal file
5985
openwrt/tl-wr841-v10.config
Normal file
File diff suppressed because it is too large
Load Diff
5849
openwrt/tl-wr841-v11.config
Normal file
5849
openwrt/tl-wr841-v11.config
Normal file
File diff suppressed because it is too large
Load Diff
6002
openwrt/tl-wr841-v8.config
Normal file
6002
openwrt/tl-wr841-v8.config
Normal file
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user