2021-03-05 00:43:49 +01:00
|
|
|
{ config, pkgs, lib, modulesPath, hostRegistry, ... }:
|
2021-01-06 18:17:57 +01:00
|
|
|
|
|
|
|
let
|
2021-03-05 01:16:16 +01:00
|
|
|
coreAddress = hostRegistry.hosts.freifunk.ip4;
|
2021-05-27 01:35:38 +02:00
|
|
|
corePrefixlen = 25;
|
2021-01-06 18:17:57 +01:00
|
|
|
meshInterface = "bmx";
|
|
|
|
meshLoopback = "bmx_prime";
|
|
|
|
ddmeshRegisterUrl = "https://register.freifunk-dresden.de/bot.php";
|
2021-10-31 19:00:03 +01:00
|
|
|
inherit (pkgs.c3d2-freifunk) ddmeshRegisterKey;
|
2021-01-06 18:17:57 +01:00
|
|
|
ddmeshNode = 51073;
|
|
|
|
ddmeshAddrPart = "200.74";
|
2021-04-29 22:55:31 +02:00
|
|
|
rt_table_hosts = 7;
|
|
|
|
rt_table_nets = rt_table_hosts + 1;
|
|
|
|
rt_table_tuns = rt_table_hosts + 2;
|
2021-02-26 20:22:15 +01:00
|
|
|
sysinfo-json = import ./sysinfo-json.nix { inherit pkgs ddmeshNode; };
|
2021-01-06 18:17:57 +01:00
|
|
|
in {
|
|
|
|
imports = [
|
2021-02-26 20:22:15 +01:00
|
|
|
"${modulesPath}/profiles/minimal.nix"
|
|
|
|
../../../lib/lxc-container.nix
|
|
|
|
../../../lib/shared.nix
|
2021-01-06 18:17:57 +01:00
|
|
|
];
|
|
|
|
|
|
|
|
boot.tmpOnTmpfs = true;
|
2021-04-29 21:56:37 +02:00
|
|
|
boot.postBootCommands = ''
|
|
|
|
if [ ! -c /dev/net/tun ]; then
|
|
|
|
mkdir -p /dev/net
|
|
|
|
mknod -m 666 /dev/net/tun c 10 200
|
|
|
|
fi
|
|
|
|
'';
|
2021-01-06 18:17:57 +01:00
|
|
|
c3d2 = {
|
|
|
|
isInHq = false;
|
|
|
|
hq.statistics.enable = true;
|
|
|
|
};
|
|
|
|
services.collectd.plugins.protocols = "";
|
|
|
|
|
|
|
|
networking.hostName = "freifunk";
|
|
|
|
networking.useNetworkd = true;
|
|
|
|
networking.nameservers = [ "172.20.73.8" "9.9.9.9" ];
|
|
|
|
networking.firewall.enable = false;
|
|
|
|
networking.nat = {
|
|
|
|
enable = true;
|
|
|
|
# This doesn't really work, hence the `extraCommands`
|
|
|
|
externalInterface = meshInterface;
|
|
|
|
#internalInterfaces = [ "core" ];
|
|
|
|
|
|
|
|
# Setup routing into Freifunk,
|
|
|
|
# masquerading anything that isn't already their IP range
|
|
|
|
extraCommands = ''
|
|
|
|
${pkgs.iproute}/bin/ip rule del priority 300 || true
|
2021-04-30 00:08:49 +02:00
|
|
|
${pkgs.iproute}/bin/ip rule add to 10.200.0.0/16 table bmx_hosts priority 300
|
|
|
|
${pkgs.iproute}/bin/ip rule del priority 33000 || true
|
|
|
|
${pkgs.iproute}/bin/ip rule add table bmx_tuns priority 33000
|
2021-01-06 18:17:57 +01:00
|
|
|
${pkgs.iptables}/bin/iptables -t nat -F POSTROUTING
|
|
|
|
${pkgs.iptables}/bin/iptables -t nat -A POSTROUTING \
|
|
|
|
\! --source 10.200.0.0/15 -o ${meshInterface} -j SNAT --to 10.200.${ddmeshAddrPart}
|
2021-04-29 23:08:28 +02:00
|
|
|
${pkgs.iptables}/bin/iptables -t nat -o bat0 -A POSTROUTING -j MASQUERADE
|
2021-01-06 18:17:57 +01:00
|
|
|
set -e
|
|
|
|
'';
|
2021-03-05 00:43:49 +01:00
|
|
|
|
|
|
|
forwardPorts = [ {
|
|
|
|
# Yggdrasil
|
|
|
|
destination = "${hostRegistry.hosts.yggdrasil.ip4}:46823";
|
|
|
|
proto = "tcp";
|
|
|
|
sourcePort = 46823;
|
|
|
|
} ];
|
2021-01-06 18:17:57 +01:00
|
|
|
};
|
|
|
|
# Configure rt_table name
|
|
|
|
networking.iproute2 = {
|
|
|
|
enable = true;
|
2021-04-29 22:55:31 +02:00
|
|
|
rttablesExtraConfig = ''
|
|
|
|
${toString rt_table_hosts} bmx_hosts
|
|
|
|
${toString rt_table_nets} bmx_nets
|
|
|
|
${toString rt_table_tuns} bmx_tuns
|
|
|
|
'';
|
2021-01-06 18:17:57 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
# Required for krops: ssh git
|
|
|
|
services.openssh.enable = true;
|
2021-10-02 19:31:56 +02:00
|
|
|
environment.systemPackages = with pkgs; [ tcpdump ];
|
2021-01-06 18:17:57 +01:00
|
|
|
|
|
|
|
systemd.network = {
|
|
|
|
netdevs = {
|
|
|
|
# Dummy interface for primary (10.200) address
|
|
|
|
bmx_prime = {
|
|
|
|
enable = true;
|
|
|
|
netdevConfig = {
|
|
|
|
Kind = "bridge";
|
|
|
|
Name = meshLoopback;
|
|
|
|
};
|
|
|
|
};
|
|
|
|
};
|
|
|
|
networks = {
|
|
|
|
# Wired mesh interface
|
|
|
|
"10-bmx" = {
|
|
|
|
enable = true;
|
|
|
|
matchConfig = { Name = meshInterface; };
|
2021-02-22 11:45:12 +01:00
|
|
|
addresses = [{
|
2021-01-06 18:17:57 +01:00
|
|
|
addressConfig = {
|
|
|
|
Address = "10.201.${ddmeshAddrPart}/16";
|
|
|
|
Broadcast = "10.255.255.255";
|
|
|
|
};
|
2021-02-22 11:45:12 +01:00
|
|
|
}];
|
2021-01-06 18:17:57 +01:00
|
|
|
};
|
|
|
|
# Dummy interface for primary (10.200) address
|
|
|
|
"11-bmx-loopback" = {
|
|
|
|
enable = true;
|
|
|
|
matchConfig = { Name = meshLoopback; };
|
2021-02-22 11:45:12 +01:00
|
|
|
addresses = [{
|
2021-01-06 18:17:57 +01:00
|
|
|
addressConfig = {
|
|
|
|
Address = "10.200.${ddmeshAddrPart}/32";
|
|
|
|
Broadcast = "10.255.255.255";
|
|
|
|
};
|
2021-02-22 11:45:12 +01:00
|
|
|
}];
|
2021-01-06 18:17:57 +01:00
|
|
|
};
|
|
|
|
# ZW
|
|
|
|
"20-core" = {
|
|
|
|
enable = true;
|
|
|
|
matchConfig = { Name = "core"; };
|
|
|
|
addresses = map (Address: { addressConfig = { inherit Address; }; }) [
|
|
|
|
"${coreAddress}/${toString corePrefixlen}"
|
2021-06-02 21:37:18 +02:00
|
|
|
"2a00:8180:2c00:281:8000::1/64"
|
2021-01-06 18:17:57 +01:00
|
|
|
"fd23:42:c3d2:581:8000::1/64"
|
|
|
|
];
|
2021-04-29 22:55:50 +02:00
|
|
|
# routes = map (Gateway: { routeConfig = { inherit Gateway; }; }) [
|
|
|
|
# # upstream1
|
2021-06-02 21:37:18 +02:00
|
|
|
# "2a00:8180:2c00:281::b:0"
|
2021-04-29 22:55:50 +02:00
|
|
|
# # anon1
|
|
|
|
# "172.20.72.7"
|
|
|
|
# ];
|
2021-01-06 18:17:57 +01:00
|
|
|
};
|
|
|
|
};
|
|
|
|
};
|
|
|
|
# Freifunk Dresden routing daemon
|
|
|
|
systemd.services.bmxd = {
|
|
|
|
after = [ "systemd-networkd.service" ];
|
|
|
|
wantedBy = [ "network.target" ];
|
|
|
|
serviceConfig = {
|
|
|
|
ExecStart = ''
|
2021-02-26 20:22:15 +01:00
|
|
|
${pkgs.bmxd}/sbin/bmxd \
|
2021-04-29 22:55:31 +02:00
|
|
|
--rt_table_offset=${toString rt_table_hosts} \
|
2021-01-06 18:17:57 +01:00
|
|
|
--no_fork 1 \
|
|
|
|
--throw-rules 0 \
|
|
|
|
--prio-rules 0 \
|
|
|
|
--gateway_tunnel_network 10.200.0.0/16 \
|
|
|
|
--purge_timeout 20 \
|
|
|
|
--one_way_tunnel 1 \
|
2021-04-29 21:53:23 +02:00
|
|
|
-r 3 --gateway_hysteresis 20 \
|
2021-01-06 18:17:57 +01:00
|
|
|
dev=bmx_prime /linklayer 0 \
|
|
|
|
dev=${meshInterface} /linklayer 1
|
2021-02-22 11:45:12 +01:00
|
|
|
'';
|
2021-01-06 18:17:57 +01:00
|
|
|
Restart = "always";
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
# Re-register periodically
|
|
|
|
systemd.services.ddmesh-register-node = {
|
|
|
|
script = ''
|
2021-09-22 00:01:41 +02:00
|
|
|
${pkgs.curl}/bin/curl -k \
|
2021-01-06 18:17:57 +01:00
|
|
|
-o /tmp/ddmesh-registration.json \
|
2021-02-22 11:45:12 +01:00
|
|
|
'${ddmeshRegisterUrl}?registerkey=${ddmeshRegisterKey}&node=${
|
|
|
|
toString ddmeshNode
|
|
|
|
}'
|
2021-01-06 18:17:57 +01:00
|
|
|
'';
|
|
|
|
serviceConfig = {
|
|
|
|
User = "nobody";
|
|
|
|
Group = "nogroup";
|
|
|
|
};
|
|
|
|
};
|
|
|
|
systemd.timers.ddmesh-register-node = {
|
2021-02-22 11:45:12 +01:00
|
|
|
partOf = [ "ddmesh-register-node.service" ];
|
|
|
|
wantedBy = [ "timers.target" ];
|
2021-01-06 18:17:57 +01:00
|
|
|
timerConfig.OnCalendar = "daily";
|
|
|
|
};
|
|
|
|
|
|
|
|
# Refresh sysinfo.json
|
|
|
|
systemd.services.sysinfo-json = {
|
|
|
|
script = ''
|
|
|
|
${sysinfo-json}/bin/bmxddump.sh
|
2021-01-06 18:42:01 +01:00
|
|
|
${sysinfo-json}/bin/sysinfo-json.cgi > /run/nginx/sysinfo.json
|
2021-01-06 18:17:57 +01:00
|
|
|
'';
|
|
|
|
};
|
|
|
|
systemd.timers.sysinfo-json = {
|
2021-02-22 11:45:12 +01:00
|
|
|
partOf = [ "sysinfo-json.service" ];
|
|
|
|
wantedBy = [ "timers.target" ];
|
2021-01-06 18:17:57 +01:00
|
|
|
timerConfig.OnCalendar = "minutely";
|
|
|
|
};
|
|
|
|
|
|
|
|
# Advertise Freifunk routes to ZW core
|
|
|
|
services.bird2 = {
|
|
|
|
enable = true;
|
|
|
|
config = ''
|
2021-02-22 11:45:12 +01:00
|
|
|
protocol kernel K4 {
|
|
|
|
ipv4 {
|
|
|
|
export all;
|
|
|
|
};
|
|
|
|
}
|
|
|
|
protocol kernel K6 {
|
|
|
|
ipv6 {
|
|
|
|
export all;
|
|
|
|
};
|
|
|
|
}
|
|
|
|
protocol device {
|
|
|
|
scan time 10;
|
|
|
|
}
|
|
|
|
|
2021-04-29 22:55:50 +02:00
|
|
|
ipv4 table bmx_gw;
|
|
|
|
protocol kernel BMX_GW {
|
|
|
|
learn;
|
|
|
|
kernel table ${toString rt_table_tuns};
|
|
|
|
ipv4 {
|
|
|
|
table bmx_gw;
|
|
|
|
import filter {
|
|
|
|
if net ~ [ 0.0.0.0/0 ] then {
|
|
|
|
# Learn Freifunk default route
|
|
|
|
accept;
|
|
|
|
}
|
|
|
|
reject;
|
|
|
|
};
|
|
|
|
};
|
|
|
|
}
|
|
|
|
protocol pipe import_bmx_gw {
|
|
|
|
table master4;
|
|
|
|
peer table bmx_gw;
|
|
|
|
import all;
|
|
|
|
}
|
|
|
|
|
2021-02-22 11:45:12 +01:00
|
|
|
protocol ospf v2 ZW4 {
|
2021-04-29 22:55:50 +02:00
|
|
|
ipv4 {
|
2021-05-01 01:41:26 +02:00
|
|
|
export where net != 0.0.0.0/0;
|
|
|
|
import where net != 0.0.0.0/0;
|
2021-04-29 22:55:50 +02:00
|
|
|
};
|
2021-02-22 11:45:12 +01:00
|
|
|
area 0 {
|
|
|
|
stubnet 10.200.0.0/15;
|
|
|
|
interface "core" {
|
|
|
|
authentication cryptographic;
|
2021-03-05 01:16:57 +01:00
|
|
|
password "${pkgs.zentralwerk-ospf-message-digest-key}";
|
2021-01-06 18:17:57 +01:00
|
|
|
};
|
2021-02-22 11:45:12 +01:00
|
|
|
};
|
|
|
|
}
|
2021-01-06 18:17:57 +01:00
|
|
|
|
2021-05-01 01:41:26 +02:00
|
|
|
protocol ospf v2 ZW4_freifunk {
|
|
|
|
ipv4 {
|
|
|
|
export where net = 0.0.0.0/0;
|
|
|
|
};
|
2021-02-22 11:45:12 +01:00
|
|
|
area 0 {
|
2021-05-01 01:41:26 +02:00
|
|
|
interface "core" instance 6 {
|
|
|
|
authentication cryptographic;
|
|
|
|
password "${pkgs.zentralwerk-ospf-message-digest-key}";
|
2021-01-06 18:17:57 +01:00
|
|
|
};
|
2021-05-01 01:41:26 +02:00
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
protocol ospf v3 ZW6 {
|
|
|
|
ipv6 {
|
|
|
|
import all;
|
|
|
|
};
|
|
|
|
area 0 {
|
2021-06-16 20:02:11 +02:00
|
|
|
interface "core" {
|
|
|
|
authentication cryptographic;
|
|
|
|
password "${pkgs.zentralwerk-ospf-message-digest-key}";
|
|
|
|
};
|
2021-02-22 11:45:12 +01:00
|
|
|
};
|
|
|
|
}
|
2021-01-06 18:17:57 +01:00
|
|
|
|
2021-02-22 11:45:12 +01:00
|
|
|
router id ${coreAddress};
|
|
|
|
'';
|
2021-01-06 18:17:57 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
# HTTP Reverse Proxy to provide services into Freifunk
|
|
|
|
services.nginx = {
|
|
|
|
enable = true;
|
|
|
|
recommendedOptimisation = true;
|
|
|
|
recommendedGzipSettings = true;
|
|
|
|
appendHttpConfig = ''
|
|
|
|
proxy_buffering off;
|
|
|
|
'';
|
|
|
|
|
|
|
|
virtualHosts = {
|
|
|
|
"c3d2.ffdd" = {
|
|
|
|
default = true;
|
2021-02-26 20:22:15 +01:00
|
|
|
root = ./assets;
|
2021-02-22 11:45:12 +01:00
|
|
|
locations = let
|
|
|
|
sysinfo-json = {
|
|
|
|
alias = "/run/nginx/sysinfo.json";
|
|
|
|
extraConfig = ''
|
|
|
|
add_header Content-Type "application/json;charset=UTF-8";
|
|
|
|
'';
|
|
|
|
};
|
|
|
|
in {
|
|
|
|
"/" = {
|
|
|
|
index = "index.html";
|
|
|
|
extraConfig = ''
|
|
|
|
etag off;
|
2021-02-26 20:22:15 +01:00
|
|
|
add_header etag "\"${builtins.substring 11 32 (./assets)}\"";
|
2021-02-22 11:45:12 +01:00
|
|
|
'';
|
2021-01-06 18:17:57 +01:00
|
|
|
};
|
2021-02-22 11:45:12 +01:00
|
|
|
"=/sysinfo-json.cgi" = sysinfo-json;
|
|
|
|
"=/sysinfo.json" = sysinfo-json;
|
|
|
|
};
|
2021-01-06 18:17:57 +01:00
|
|
|
};
|
2021-02-22 11:45:12 +01:00
|
|
|
"storage.hq.c3d2.ffdd".locations."/".proxyPass =
|
|
|
|
"http://storage.hq.c3d2.de/";
|
2021-01-06 18:17:57 +01:00
|
|
|
"grafana.hq.c3d2.ffdd".locations."/" = {
|
|
|
|
proxyPass = "https://grafana.hq.c3d2.de/";
|
|
|
|
extraConfig = ''
|
|
|
|
proxy_ssl_server_name on;
|
|
|
|
'';
|
|
|
|
};
|
2021-02-22 11:45:12 +01:00
|
|
|
"influxdb.hq.c3d2.ffdd".locations."/".proxyPass =
|
|
|
|
"http://grafana.hq.c3d2.de:8086/";
|
2021-01-06 18:17:57 +01:00
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
# This value determines the NixOS release with which your system is to be
|
|
|
|
# compatible, in order to avoid breaking some software such as database
|
|
|
|
# servers. You should change this only after NixOS release notes say you
|
|
|
|
# should.
|
|
|
|
system.stateVersion = "20.03"; # Did you read the comment?
|
|
|
|
}
|