freifunk: format
This commit is contained in:
parent
6b84687f04
commit
29a78eae42
|
@ -50,7 +50,8 @@ let
|
||||||
esac
|
esac
|
||||||
'';
|
'';
|
||||||
|
|
||||||
in {
|
in
|
||||||
|
{
|
||||||
imports = [
|
imports = [
|
||||||
"${modulesPath}/profiles/minimal.nix"
|
"${modulesPath}/profiles/minimal.nix"
|
||||||
];
|
];
|
||||||
|
@ -71,47 +72,49 @@ in {
|
||||||
autoNetSetup = false;
|
autoNetSetup = false;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
services.collectd.plugins.protocols = "";
|
|
||||||
|
|
||||||
microvm.interfaces = [ {
|
microvm.interfaces = [{
|
||||||
type = "tap";
|
type = "tap";
|
||||||
id = "core-freifunk";
|
id = "core-freifunk";
|
||||||
mac = mac.core;
|
mac = mac.core;
|
||||||
} {
|
}
|
||||||
type = "tap";
|
{
|
||||||
id = "bmx-freifunk";
|
type = "tap";
|
||||||
mac = mac.bmx;
|
id = "bmx-freifunk";
|
||||||
} ];
|
mac = mac.bmx;
|
||||||
|
}];
|
||||||
|
|
||||||
networking.hostName = "freifunk";
|
networking = {
|
||||||
networking.useNetworkd = true;
|
firewall.enable = false;
|
||||||
networking.nameservers = [ "172.20.73.8" "9.9.9.9" ];
|
hostName = "freifunk";
|
||||||
networking.firewall.enable = false;
|
# Configure rt_table name
|
||||||
networking.nat = {
|
iproute2 = {
|
||||||
enable = true;
|
enable = true;
|
||||||
# This doesn't really work, hence the `extraCommands`
|
rttablesExtraConfig = ''
|
||||||
externalInterface = meshInterface;
|
${toString rt_table_upstream} upstream
|
||||||
#internalInterfaces = [ "core" ];
|
${toString rt_table_hosts} bmx_hosts
|
||||||
|
${toString rt_table_nets} bmx_nets
|
||||||
|
${toString rt_table_tuns} bmx_tuns
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
nameservers = [ "172.20.73.8" "9.9.9.9" ];
|
||||||
|
nat = {
|
||||||
|
enable = true;
|
||||||
|
# This doesn't really work, hence the `extraCommands`
|
||||||
|
externalInterface = meshInterface;
|
||||||
|
#internalInterfaces = [ "core" ];
|
||||||
|
|
||||||
# Setup routing into Freifunk,
|
# Setup routing into Freifunk,
|
||||||
# masquerading anything that isn't already their IP range
|
# masquerading anything that isn't already their IP range
|
||||||
extraCommands = ''
|
extraCommands = ''
|
||||||
${pkgs.iptables}/bin/iptables -t nat -F POSTROUTING
|
${pkgs.iptables}/bin/iptables -t nat -F POSTROUTING
|
||||||
${pkgs.iptables}/bin/iptables -t nat -A POSTROUTING \
|
${pkgs.iptables}/bin/iptables -t nat -A POSTROUTING \
|
||||||
\! --source 10.200.0.0/15 -o ipip-node51001 -j SNAT --to 10.200.${ddmeshAddrPart}
|
\! --source 10.200.0.0/15 -o ipip-node51001 -j SNAT --to 10.200.${ddmeshAddrPart}
|
||||||
${pkgs.iptables}/bin/iptables -t nat -o bat0 -A POSTROUTING -j MASQUERADE
|
${pkgs.iptables}/bin/iptables -t nat -o bat0 -A POSTROUTING -j MASQUERADE
|
||||||
set -e
|
set -e
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
# Configure rt_table name
|
useNetworkd = true;
|
||||||
networking.iproute2 = {
|
|
||||||
enable = true;
|
|
||||||
rttablesExtraConfig = ''
|
|
||||||
${toString rt_table_upstream} upstream
|
|
||||||
${toString rt_table_hosts} bmx_hosts
|
|
||||||
${toString rt_table_nets} bmx_nets
|
|
||||||
${toString rt_table_tuns} bmx_tuns
|
|
||||||
'';
|
|
||||||
};
|
};
|
||||||
|
|
||||||
environment.systemPackages = with pkgs; [ tcpdump bmon wireguard-tools iperf bmxd ];
|
environment.systemPackages = with pkgs; [ tcpdump bmon wireguard-tools iperf bmxd ];
|
||||||
|
@ -131,379 +134,356 @@ in {
|
||||||
# unbreak wg-vpn6 ingress path
|
# unbreak wg-vpn6 ingress path
|
||||||
boot.kernel.sysctl."net.ipv4.conf.core.rp_filter" = 0;
|
boot.kernel.sysctl."net.ipv4.conf.core.rp_filter" = 0;
|
||||||
|
|
||||||
systemd.network = {
|
services = {
|
||||||
netdevs = {
|
# Advertise Freifunk routes to ZW core
|
||||||
# Dummy interface for primary (10.200) address
|
bird2 = {
|
||||||
"10-bmx-prime" = {
|
enable = true;
|
||||||
enable = true;
|
# nix-build cannot access /run/secrets/
|
||||||
netdevConfig = {
|
checkConfig = false;
|
||||||
Kind = "dummy";
|
config = ''
|
||||||
Name = meshLoopback;
|
protocol kernel K4 {
|
||||||
};
|
|
||||||
};
|
|
||||||
# Freifunk Dresden Backbone
|
|
||||||
"31-wg-vpn6" = {
|
|
||||||
enable = true;
|
|
||||||
netdevConfig = {
|
|
||||||
Name = "wg-vpn6";
|
|
||||||
Kind = "wireguard";
|
|
||||||
MTUBytes = "1320";
|
|
||||||
};
|
|
||||||
wireguardConfig = {
|
|
||||||
PrivateKeyFile = config.sops.secrets."wireguard/vpn6/privateKey".path;
|
|
||||||
ListenPort = 5006;
|
|
||||||
# Mark for routing with the upstream routing table
|
|
||||||
FirewallMark = upstreamMark;
|
|
||||||
};
|
|
||||||
wireguardPeers = [ {
|
|
||||||
wireguardPeerConfig = {
|
|
||||||
Endpoint = "vpn-it4r.freifunk-dresden.de:5006";
|
|
||||||
PublicKey = "CIJa7xiRRIrLtEB7uyzwoyaQcpe0b8F2d16+3hk8KjU=";
|
|
||||||
AllowedIPs = "10.203.0.0/16";
|
|
||||||
};
|
|
||||||
} ];
|
|
||||||
};
|
|
||||||
"32-ipip-node51001" = {
|
|
||||||
enable = true;
|
|
||||||
netdevConfig = {
|
|
||||||
Name = "ipip-node51001";
|
|
||||||
Kind = "ipip";
|
|
||||||
};
|
|
||||||
tunnelConfig = {
|
|
||||||
Local = "10.203.${ddmeshAddrPart}";
|
|
||||||
Remote = "10.203.${node51001AddrPart}";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
links = {
|
|
||||||
# Wired mesh interface
|
|
||||||
"10-bmx" = {
|
|
||||||
enable = true;
|
|
||||||
matchConfig = { MACAddress = mac.bmx; };
|
|
||||||
linkConfig.Name = meshInterface;
|
|
||||||
};
|
|
||||||
# Wired core interface
|
|
||||||
"10-core" = {
|
|
||||||
enable = true;
|
|
||||||
matchConfig = { MACAddress = mac.core; };
|
|
||||||
linkConfig.Name = "core";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
networks = {
|
|
||||||
# Wired mesh interface
|
|
||||||
"10-bmx" = {
|
|
||||||
enable = true;
|
|
||||||
matchConfig = { MACAddress = mac.bmx; };
|
|
||||||
addresses = [{
|
|
||||||
addressConfig = {
|
|
||||||
Address = "10.201.${ddmeshAddrPart}/16";
|
|
||||||
Broadcast = ddmeshBroadcast;
|
|
||||||
};
|
|
||||||
}];
|
|
||||||
routingPolicyRules = [ {
|
|
||||||
routingPolicyRuleConfig = {
|
|
||||||
Priority = 300;
|
|
||||||
To = "10.200.0.0/16";
|
|
||||||
Table = rt_table_hosts;
|
|
||||||
};
|
|
||||||
} ];
|
|
||||||
};
|
|
||||||
# Dummy interface for primary (10.200) address
|
|
||||||
"11-bmx-prime" = {
|
|
||||||
enable = true;
|
|
||||||
matchConfig = { Name = meshLoopback; };
|
|
||||||
addresses = [{
|
|
||||||
addressConfig.Address = "10.200.${ddmeshAddrPart}/32";
|
|
||||||
}];
|
|
||||||
routingPolicyRules = [ {
|
|
||||||
routingPolicyRuleConfig = {
|
|
||||||
Priority = 33000;
|
|
||||||
Table = rt_table_tuns;
|
|
||||||
};
|
|
||||||
} ];
|
|
||||||
};
|
|
||||||
"31-wg-vpn6" = {
|
|
||||||
enable = true;
|
|
||||||
matchConfig.Name = "wg-vpn6";
|
|
||||||
addresses = [{
|
|
||||||
addressConfig.Address = "10.203.${ddmeshAddrPart}/16";
|
|
||||||
}];
|
|
||||||
# reverse dependency
|
|
||||||
networkConfig.Tunnel = [ "ipip-node51001" ];
|
|
||||||
};
|
|
||||||
"32-ipip-node51001" = {
|
|
||||||
enable = true;
|
|
||||||
matchConfig.Name = "ipip-node51001";
|
|
||||||
addresses = [{
|
|
||||||
addressConfig = {
|
|
||||||
Address = "10.201.${ddmeshAddrPart}/16";
|
|
||||||
Broadcast = ddmeshBroadcast;
|
|
||||||
};
|
|
||||||
}];
|
|
||||||
};
|
|
||||||
# ZW
|
|
||||||
"20-core" = {
|
|
||||||
enable = true;
|
|
||||||
matchConfig = { MACAddress = mac.core; };
|
|
||||||
addresses = map (Address: { addressConfig = { inherit Address; }; }) (
|
|
||||||
[
|
|
||||||
"${coreAddress}/${toString core.subnet4Len}"
|
|
||||||
] ++
|
|
||||||
map (hosts6: "${hosts6.${hostName}}/64") (
|
|
||||||
builtins.attrValues core.hosts6
|
|
||||||
)
|
|
||||||
);
|
|
||||||
routingPolicyRules = [ {
|
|
||||||
# Marked wireguard packets take the upstream routing table
|
|
||||||
routingPolicyRuleConfig = {
|
|
||||||
Table = rt_table_upstream;
|
|
||||||
FirewallMark = upstreamMark;
|
|
||||||
};
|
|
||||||
} ];
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
# Freifunk Dresden routing daemon
|
|
||||||
systemd.services.bmxd = {
|
|
||||||
after = [ "systemd-networkd.service" ];
|
|
||||||
wantedBy = [ "network.target" ];
|
|
||||||
serviceConfig = {
|
|
||||||
ExecStart = ''
|
|
||||||
${pkgs.bmxd}/sbin/bmxd \
|
|
||||||
--rt_table_offset=${toString rt_table_hosts} \
|
|
||||||
--no_fork 1 \
|
|
||||||
--throw-rules 0 \
|
|
||||||
--prio-rules 0 \
|
|
||||||
--network 10.200.0.0/16 \
|
|
||||||
--netid 0 \
|
|
||||||
--only_community_gw 1 \
|
|
||||||
--script ${bmxdGatewayScript} \
|
|
||||||
--hop_penalty 1 \
|
|
||||||
--lateness_penalty 10 \
|
|
||||||
--ogm_broadcasts 100 \
|
|
||||||
--udp_data_size 512 \
|
|
||||||
--ogm_interval 5000 \
|
|
||||||
--purge_timeout 35 \
|
|
||||||
-r 3 --gateway_hysteresis 20 \
|
|
||||||
--dev ${meshLoopback} /linklayer 0 \
|
|
||||||
--dev ${meshInterface} /linklayer 1 \
|
|
||||||
--dev ipip-node51001 /linklayer 1
|
|
||||||
'';
|
|
||||||
Restart = "always";
|
|
||||||
RestartSec = "60";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
# Re-register periodically
|
|
||||||
systemd.services.ddmesh-register-node = {
|
|
||||||
script = ''
|
|
||||||
${pkgs.curl}/bin/curl -k \
|
|
||||||
-o /tmp/ddmesh-registration.json \
|
|
||||||
'${ddmeshRegisterUrl}?registerkey=${ddmeshRegisterKey}&node=${
|
|
||||||
toString ddmeshNode
|
|
||||||
}'
|
|
||||||
'';
|
|
||||||
serviceConfig = {
|
|
||||||
User = "nobody";
|
|
||||||
Group = "nogroup";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
systemd.timers.ddmesh-register-node = {
|
|
||||||
partOf = [ "ddmesh-register-node.service" ];
|
|
||||||
wantedBy = [ "timers.target" ];
|
|
||||||
timerConfig.OnCalendar = "daily";
|
|
||||||
};
|
|
||||||
|
|
||||||
# Refresh sysinfo.json
|
|
||||||
systemd.services.sysinfo-json = {
|
|
||||||
script = ''
|
|
||||||
${sysinfo-json}/bin/bmxddump.sh
|
|
||||||
mkdir -p /run/nginx
|
|
||||||
${sysinfo-json}/bin/sysinfo-json.cgi > /run/nginx/sysinfo.json
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
systemd.timers.sysinfo-json = {
|
|
||||||
partOf = [ "sysinfo-json.service" ];
|
|
||||||
wantedBy = [ "timers.target" ];
|
|
||||||
timerConfig.OnCalendar = "minutely";
|
|
||||||
};
|
|
||||||
|
|
||||||
# Advertise Freifunk routes to ZW core
|
|
||||||
services.bird2 = {
|
|
||||||
enable = true;
|
|
||||||
# nix-build cannot access /run/secrets/
|
|
||||||
checkConfig = false;
|
|
||||||
config = ''
|
|
||||||
protocol kernel K4 {
|
|
||||||
ipv4 {
|
|
||||||
export all;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
# BIRD routing table for Wireguard transport
|
|
||||||
ipv4 table upstream4_table;
|
|
||||||
|
|
||||||
# Kernel routing table for Wireguard transport
|
|
||||||
protocol kernel upstream4 {
|
|
||||||
kernel table ${toString rt_table_upstream};
|
|
||||||
ipv4 {
|
|
||||||
export all;
|
|
||||||
table upstream4_table;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
protocol kernel K6 {
|
|
||||||
ipv6 {
|
|
||||||
export all;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
protocol device {
|
|
||||||
scan time 10;
|
|
||||||
}
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
protocol ospf v2 ZW4 {
|
|
||||||
ipv4 {
|
|
||||||
export where net != 0.0.0.0/0;
|
|
||||||
import where net != 0.0.0.0/0;
|
|
||||||
};
|
|
||||||
area 0 {
|
|
||||||
stubnet 10.200.0.0/15;
|
|
||||||
interface "core" {
|
|
||||||
hello 10;
|
|
||||||
wait 20;
|
|
||||||
include "${config.sops.secrets."bird/ospf/auth".path}";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
protocol ospf v2 ZW4_freifunk {
|
|
||||||
ipv4 {
|
|
||||||
export where net = 0.0.0.0/0;
|
|
||||||
};
|
|
||||||
area 0 {
|
|
||||||
interface "core" instance ${toString zentralwerk.lib.config.site.hosts.freifunk.ospf.upstreamInstance} {
|
|
||||||
hello 10;
|
|
||||||
wait 20;
|
|
||||||
include "${config.sops.secrets."bird/ospf/auth".path}";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
protocol ospf v3 ZW6 {
|
|
||||||
ipv6 {
|
|
||||||
import all;
|
|
||||||
};
|
|
||||||
area 0 {
|
|
||||||
interface "core" {
|
|
||||||
hello 10;
|
|
||||||
wait 20;
|
|
||||||
include "${config.sops.secrets."bird/ospf/auth".path}";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
${lib.concatStrings (lib.imap0 (i: upstream: ''
|
|
||||||
# OSPFv2 to receive a default route from ${upstream}
|
|
||||||
protocol ospf v2 ZW4_${upstream} {
|
|
||||||
ipv4 {
|
ipv4 {
|
||||||
import filter {
|
export all;
|
||||||
preference = preference + ${toString (200 - i)};
|
};
|
||||||
accept;
|
}
|
||||||
};
|
# BIRD routing table for Wireguard transport
|
||||||
|
ipv4 table upstream4_table;
|
||||||
|
|
||||||
|
# Kernel routing table for Wireguard transport
|
||||||
|
protocol kernel upstream4 {
|
||||||
|
kernel table ${toString rt_table_upstream};
|
||||||
|
ipv4 {
|
||||||
|
export all;
|
||||||
table upstream4_table;
|
table upstream4_table;
|
||||||
};
|
};
|
||||||
area 0 {
|
}
|
||||||
interface "core" instance ${toString zentralwerk.lib.config.site.hosts.${upstream}.ospf.upstreamInstance} {
|
protocol kernel K6 {
|
||||||
hello 10;
|
|
||||||
wait 20;
|
|
||||||
include "${config.sops.secrets."bird/ospf/auth".path}";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
'') upstreams)}
|
|
||||||
|
|
||||||
${lib.concatStrings (lib.imap0 (i: upstream: ''
|
|
||||||
# OSPFv3 to receive a default route from ${upstream}
|
|
||||||
protocol ospf v3 ZW6_${upstream} {
|
|
||||||
ipv6 {
|
ipv6 {
|
||||||
|
export all;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
protocol device {
|
||||||
|
scan time 10;
|
||||||
|
}
|
||||||
|
|
||||||
|
ipv4 table bmx_gw;
|
||||||
|
protocol kernel BMX_GW {
|
||||||
|
learn;
|
||||||
|
kernel table ${toString rt_table_tuns};
|
||||||
|
ipv4 {
|
||||||
|
table bmx_gw;
|
||||||
import filter {
|
import filter {
|
||||||
preference = preference + ${toString (200 - i)};
|
if net ~ [ 0.0.0.0/0 ] then {
|
||||||
accept;
|
# Learn Freifunk default route
|
||||||
|
accept;
|
||||||
|
}
|
||||||
|
reject;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
}
|
||||||
|
protocol pipe import_bmx_gw {
|
||||||
|
table master4;
|
||||||
|
peer table bmx_gw;
|
||||||
|
import all;
|
||||||
|
}
|
||||||
|
|
||||||
|
protocol ospf v2 ZW4 {
|
||||||
|
ipv4 {
|
||||||
|
export where net != 0.0.0.0/0;
|
||||||
|
import where net != 0.0.0.0/0;
|
||||||
|
};
|
||||||
area 0 {
|
area 0 {
|
||||||
interface "core" instance ${toString zentralwerk.lib.config.site.hosts.${upstream}.ospf.upstreamInstance} {
|
stubnet 10.200.0.0/15;
|
||||||
|
interface "core" {
|
||||||
hello 10;
|
hello 10;
|
||||||
wait 20;
|
wait 20;
|
||||||
include "${config.sops.secrets."bird/ospf/auth".path}";
|
include "${config.sops.secrets."bird/ospf/auth".path}";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
}
|
||||||
'') upstreams)}
|
|
||||||
|
|
||||||
router id ${coreAddress};
|
protocol ospf v2 ZW4_freifunk {
|
||||||
'';
|
ipv4 {
|
||||||
|
export where net = 0.0.0.0/0;
|
||||||
|
};
|
||||||
|
area 0 {
|
||||||
|
interface "core" instance ${toString zentralwerk.lib.config.site.hosts.freifunk.ospf.upstreamInstance} {
|
||||||
|
hello 10;
|
||||||
|
wait 20;
|
||||||
|
include "${config.sops.secrets."bird/ospf/auth".path}";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
protocol ospf v3 ZW6 {
|
||||||
|
ipv6 {
|
||||||
|
import all;
|
||||||
|
};
|
||||||
|
area 0 {
|
||||||
|
interface "core" {
|
||||||
|
hello 10;
|
||||||
|
wait 20;
|
||||||
|
include "${config.sops.secrets."bird/ospf/auth".path}";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
${lib.concatStrings (lib.imap0 (i: upstream: ''
|
||||||
|
# OSPFv2 to receive a default route from ${upstream}
|
||||||
|
protocol ospf v2 ZW4_${upstream} {
|
||||||
|
ipv4 {
|
||||||
|
import filter {
|
||||||
|
preference = preference + ${toString (200 - i)};
|
||||||
|
accept;
|
||||||
|
};
|
||||||
|
table upstream4_table;
|
||||||
|
};
|
||||||
|
area 0 {
|
||||||
|
interface "core" instance ${toString zentralwerk.lib.config.site.hosts.${upstream}.ospf.upstreamInstance} {
|
||||||
|
hello 10;
|
||||||
|
wait 20;
|
||||||
|
include "${config.sops.secrets."bird/ospf/auth".path}";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
'') upstreams)}
|
||||||
|
|
||||||
|
${lib.concatStrings (lib.imap0 (i: upstream: ''
|
||||||
|
# OSPFv3 to receive a default route from ${upstream}
|
||||||
|
protocol ospf v3 ZW6_${upstream} {
|
||||||
|
ipv6 {
|
||||||
|
import filter {
|
||||||
|
preference = preference + ${toString (200 - i)};
|
||||||
|
accept;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
area 0 {
|
||||||
|
interface "core" instance ${toString zentralwerk.lib.config.site.hosts.${upstream}.ospf.upstreamInstance} {
|
||||||
|
hello 10;
|
||||||
|
wait 20;
|
||||||
|
include "${config.sops.secrets."bird/ospf/auth".path}";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
'') upstreams)}
|
||||||
|
|
||||||
|
router id ${coreAddress};
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
collectd.plugins.protocols = "";
|
||||||
|
|
||||||
|
# HTTP Reverse Proxy to provide services into Freifunk
|
||||||
|
nginx = {
|
||||||
|
enable = true;
|
||||||
|
appendHttpConfig = ''
|
||||||
|
proxy_buffering off;
|
||||||
|
'';
|
||||||
|
|
||||||
|
virtualHosts = {
|
||||||
|
"c3d2.ffdd" = {
|
||||||
|
default = true;
|
||||||
|
root = ./assets;
|
||||||
|
locations =
|
||||||
|
let
|
||||||
|
sysinfo-json = {
|
||||||
|
alias = "/run/nginx/sysinfo.json";
|
||||||
|
extraConfig = ''
|
||||||
|
default_type "application/json;charset=UTF-8";
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
in
|
||||||
|
{
|
||||||
|
"/" = {
|
||||||
|
index = "index.html";
|
||||||
|
extraConfig = ''
|
||||||
|
etag off;
|
||||||
|
add_header etag "\"${builtins.substring 11 32 (./assets)}\"";
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
"=/sysinfo-json.cgi" = sysinfo-json;
|
||||||
|
"=/sysinfo.json" = sysinfo-json;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
"storage.hq.c3d2.ffdd".locations."/".proxyPass =
|
||||||
|
"http://storage.hq.c3d2.de/";
|
||||||
|
"grafana.hq.c3d2.ffdd".locations."/" = {
|
||||||
|
proxyPass = "https://grafana.hq.c3d2.de/";
|
||||||
|
extraConfig = ''
|
||||||
|
proxy_ssl_server_name on;
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
"influxdb.hq.c3d2.ffdd".locations."/".proxyPass =
|
||||||
|
"http://grafana.hq.c3d2.de:8086/";
|
||||||
|
};
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
# HTTP Reverse Proxy to provide services into Freifunk
|
systemd = {
|
||||||
services.nginx = {
|
network = {
|
||||||
enable = true;
|
netdevs = {
|
||||||
appendHttpConfig = ''
|
# Dummy interface for primary (10.200) address
|
||||||
proxy_buffering off;
|
"10-bmx-prime" = {
|
||||||
'';
|
enable = true;
|
||||||
|
netdevConfig = {
|
||||||
virtualHosts = {
|
Kind = "dummy";
|
||||||
"c3d2.ffdd" = {
|
Name = meshLoopback;
|
||||||
default = true;
|
|
||||||
root = ./assets;
|
|
||||||
locations = let
|
|
||||||
sysinfo-json = {
|
|
||||||
alias = "/run/nginx/sysinfo.json";
|
|
||||||
extraConfig = ''
|
|
||||||
default_type "application/json;charset=UTF-8";
|
|
||||||
'';
|
|
||||||
};
|
};
|
||||||
in {
|
};
|
||||||
"/" = {
|
# Freifunk Dresden Backbone
|
||||||
index = "index.html";
|
"31-wg-vpn6" = {
|
||||||
extraConfig = ''
|
enable = true;
|
||||||
etag off;
|
netdevConfig = {
|
||||||
add_header etag "\"${builtins.substring 11 32 (./assets)}\"";
|
Name = "wg-vpn6";
|
||||||
'';
|
Kind = "wireguard";
|
||||||
|
MTUBytes = "1320";
|
||||||
|
};
|
||||||
|
wireguardConfig = {
|
||||||
|
PrivateKeyFile = config.sops.secrets."wireguard/vpn6/privateKey".path;
|
||||||
|
ListenPort = 5006;
|
||||||
|
# Mark for routing with the upstream routing table
|
||||||
|
FirewallMark = upstreamMark;
|
||||||
|
};
|
||||||
|
wireguardPeers = [{
|
||||||
|
wireguardPeerConfig = {
|
||||||
|
Endpoint = "vpn-it4r.freifunk-dresden.de:5006";
|
||||||
|
PublicKey = "CIJa7xiRRIrLtEB7uyzwoyaQcpe0b8F2d16+3hk8KjU=";
|
||||||
|
AllowedIPs = "10.203.0.0/16";
|
||||||
|
};
|
||||||
|
}];
|
||||||
|
};
|
||||||
|
"32-ipip-node51001" = {
|
||||||
|
enable = true;
|
||||||
|
netdevConfig = {
|
||||||
|
Name = "ipip-node51001";
|
||||||
|
Kind = "ipip";
|
||||||
|
};
|
||||||
|
tunnelConfig = {
|
||||||
|
Local = "10.203.${ddmeshAddrPart}";
|
||||||
|
Remote = "10.203.${node51001AddrPart}";
|
||||||
};
|
};
|
||||||
"=/sysinfo-json.cgi" = sysinfo-json;
|
|
||||||
"=/sysinfo.json" = sysinfo-json;
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
"storage.hq.c3d2.ffdd".locations."/".proxyPass =
|
links = {
|
||||||
"http://storage.hq.c3d2.de/";
|
# Wired mesh interface
|
||||||
"grafana.hq.c3d2.ffdd".locations."/" = {
|
"10-bmx" = {
|
||||||
proxyPass = "https://grafana.hq.c3d2.de/";
|
enable = true;
|
||||||
extraConfig = ''
|
matchConfig = { MACAddress = mac.bmx; };
|
||||||
proxy_ssl_server_name on;
|
linkConfig.Name = meshInterface;
|
||||||
'';
|
};
|
||||||
|
# Wired core interface
|
||||||
|
"10-core" = {
|
||||||
|
enable = true;
|
||||||
|
matchConfig = { MACAddress = mac.core; };
|
||||||
|
linkConfig.Name = "core";
|
||||||
|
};
|
||||||
};
|
};
|
||||||
"influxdb.hq.c3d2.ffdd".locations."/".proxyPass =
|
networks = {
|
||||||
"http://grafana.hq.c3d2.de:8086/";
|
# Wired mesh interface
|
||||||
|
"10-bmx" = {
|
||||||
|
enable = true;
|
||||||
|
matchConfig = { MACAddress = mac.bmx; };
|
||||||
|
addresses = [{
|
||||||
|
addressConfig = {
|
||||||
|
Address = "10.201.${ddmeshAddrPart}/16";
|
||||||
|
Broadcast = ddmeshBroadcast;
|
||||||
|
};
|
||||||
|
}];
|
||||||
|
routingPolicyRules = [{
|
||||||
|
routingPolicyRuleConfig = {
|
||||||
|
Priority = 300;
|
||||||
|
To = "10.200.0.0/16";
|
||||||
|
Table = rt_table_hosts;
|
||||||
|
};
|
||||||
|
}];
|
||||||
|
};
|
||||||
|
# Dummy interface for primary (10.200) address
|
||||||
|
"11-bmx-prime" = {
|
||||||
|
enable = true;
|
||||||
|
matchConfig = { Name = meshLoopback; };
|
||||||
|
addresses = [{
|
||||||
|
addressConfig.Address = "10.200.${ddmeshAddrPart}/32";
|
||||||
|
}];
|
||||||
|
routingPolicyRules = [{
|
||||||
|
routingPolicyRuleConfig = {
|
||||||
|
Priority = 33000;
|
||||||
|
Table = rt_table_tuns;
|
||||||
|
};
|
||||||
|
}];
|
||||||
|
};
|
||||||
|
"31-wg-vpn6" = {
|
||||||
|
enable = true;
|
||||||
|
matchConfig.Name = "wg-vpn6";
|
||||||
|
addresses = [{
|
||||||
|
addressConfig.Address = "10.203.${ddmeshAddrPart}/16";
|
||||||
|
}];
|
||||||
|
# reverse dependency
|
||||||
|
networkConfig.Tunnel = [ "ipip-node51001" ];
|
||||||
|
};
|
||||||
|
"32-ipip-node51001" = {
|
||||||
|
enable = true;
|
||||||
|
matchConfig.Name = "ipip-node51001";
|
||||||
|
addresses = [{
|
||||||
|
addressConfig = {
|
||||||
|
Address = "10.201.${ddmeshAddrPart}/16";
|
||||||
|
Broadcast = ddmeshBroadcast;
|
||||||
|
};
|
||||||
|
}];
|
||||||
|
};
|
||||||
|
# ZW
|
||||||
|
"20-core" = {
|
||||||
|
enable = true;
|
||||||
|
matchConfig = { MACAddress = mac.core; };
|
||||||
|
addresses = map (Address: { addressConfig = { inherit Address; }; }) (
|
||||||
|
[
|
||||||
|
"${coreAddress}/${toString core.subnet4Len}"
|
||||||
|
] ++
|
||||||
|
map (hosts6: "${hosts6.${hostName}}/64") (
|
||||||
|
builtins.attrValues core.hosts6
|
||||||
|
)
|
||||||
|
);
|
||||||
|
routingPolicyRules = [{
|
||||||
|
# Marked wireguard packets take the upstream routing table
|
||||||
|
routingPolicyRuleConfig = {
|
||||||
|
Table = rt_table_upstream;
|
||||||
|
FirewallMark = upstreamMark;
|
||||||
|
};
|
||||||
|
}];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
# Re-register periodically
|
||||||
|
services.ddmesh-register-node = {
|
||||||
|
script = ''
|
||||||
|
${pkgs.curl}/bin/curl -k \
|
||||||
|
-o /tmp/ddmesh-registration.json \
|
||||||
|
'${ddmeshRegisterUrl}?registerkey=${ddmeshRegisterKey}&node=${
|
||||||
|
toString ddmeshNode
|
||||||
|
}'
|
||||||
|
'';
|
||||||
|
serviceConfig = {
|
||||||
|
User = "nobody";
|
||||||
|
Group = "nogroup";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
timers.ddmesh-register-node = {
|
||||||
|
partOf = [ "ddmesh-register-node.service" ];
|
||||||
|
wantedBy = [ "timers.target" ];
|
||||||
|
timerConfig.OnCalendar = "daily";
|
||||||
|
};
|
||||||
|
|
||||||
|
# Refresh sysinfo.json
|
||||||
|
services.sysinfo-json = {
|
||||||
|
script = ''
|
||||||
|
${sysinfo-json}/bin/bmxddump.sh
|
||||||
|
mkdir -p /run/nginx
|
||||||
|
${sysinfo-json}/bin/sysinfo-json.cgi > /run/nginx/sysinfo.json
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
timers.sysinfo-json = {
|
||||||
|
partOf = [ "sysinfo-json.service" ];
|
||||||
|
wantedBy = [ "timers.target" ];
|
||||||
|
timerConfig.OnCalendar = "minutely";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue