nix-config/hosts/containers/freifunk/configuration.nix

278 rivejä
7.7 KiB
Nix

{ config, pkgs, lib, modulesPath, ... }:
let
coreAddress = "172.20.72.40";
corePrefixlen = 26;
meshInterface = "bmx";
meshLoopback = "bmx_prime";
ddmeshRegisterUrl = "https://register.freifunk-dresden.de/bot.php";
secrets = import <secrets/hosts/freifunk>;
ddmeshRegisterKey = secrets.ddmeshRegisterKey;
ddmeshNode = 51073;
ddmeshAddrPart = "200.74";
rt_table = 7;
bmxd = import ../../../lib/pkgs/bmxd.nix { inherit pkgs; };
sysinfo-json =
import ./sysinfo-json.nix { inherit pkgs bmxd ddmeshNode; };
in {
imports = [
(modulesPath + "/profiles/minimal.nix")
../../../lib
../../../lib/lxc-container.nix
../../../lib/shared.nix
];
boot.tmpOnTmpfs = true;
c3d2 = {
isInHq = false;
enableHail = 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
${pkgs.iproute}/bin/ip rule add to 10.200.0.0/16 table bmx priority 300
${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}
set -e
'';
forwardPorts = [ {
destination = "172.20.73.8";
proto = "udp";
sourcePort = 53;
} {
destination = "172.20.73.8";
proto = "tcp";
sourcePort = 53;
} ];
};
# Configure rt_table name
networking.iproute2 = {
enable = true;
rttablesExtraConfig = "${toString rt_table} bmx";
};
# Required for krops: ssh git
services.openssh.enable = true;
environment.systemPackages = with pkgs; [ git tcpdump ];
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; };
addresses = [ {
addressConfig = {
Address = "10.201.${ddmeshAddrPart}/16";
Broadcast = "10.255.255.255";
};
} ];
};
# Dummy interface for primary (10.200) address
"11-bmx-loopback" = {
enable = true;
matchConfig = { Name = meshLoopback; };
addresses = [ {
addressConfig = {
Address = "10.200.${ddmeshAddrPart}/32";
Broadcast = "10.255.255.255";
};
} ];
};
# ZW
"20-core" = {
enable = true;
matchConfig = { Name = "core"; };
addresses = map (Address: { addressConfig = { inherit Address; }; }) [
"${coreAddress}/${toString corePrefixlen}"
"2a02:8106:208:5281:8000::1/64"
"fd23:42:c3d2:581:8000::1/64"
];
routes = map (Gateway: { routeConfig = { inherit Gateway; }; }) [
# upstream1
"2a02:8106:208:5281::b:0"
# anon1
"172.20.72.7"
];
};
};
};
# Freifunk Dresden routing daemon
systemd.services.bmxd = {
after = [ "systemd-networkd.service" ];
wantedBy = [ "network.target" ];
serviceConfig = {
ExecStart = ''
${bmxd}/sbin/bmxd \
--rt_table_offset=${toString rt_table} \
--no_fork 1 \
--throw-rules 0 \
--prio-rules 0 \
--gateway_tunnel_network 10.200.0.0/16 \
--purge_timeout 20 \
--one_way_tunnel 1 \
-g 500000/50000 \
dev=bmx_prime /linklayer 0 \
dev=${meshInterface} /linklayer 1
'';
Restart = "always";
};
};
# Re-register periodically
systemd.services.ddmesh-register-node = {
script = ''
${pkgs.curl}/bin/curl \
-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";
};
environment.etc."freifunk-server-version".text = "Custom NixOS configuration: 0.0.0";
# Refresh sysinfo.json
systemd.services.sysinfo-json = {
script = ''
${sysinfo-json}/bin/bmxddump.sh
${sysinfo-json}/bin/sysinfo-json.cgi > /tmp/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;
config = ''
protocol kernel K4 {
ipv4 {
export all;
};
}
protocol kernel K6 {
ipv6 {
export all;
};
}
protocol device {
scan time 10;
}
protocol ospf v2 ZW4 {
area 0 {
networks {
172.20.72.0/21;
};
stubnet 10.200.0.0/15;
interface "core" {
authentication cryptographic;
password "${import <secrets/shared/ospf/message-digest-key.nix>}";
};
};
}
protocol ospf v3 ZW6 {
area 0 {
networks {
fd23:42:c3d2:500::/56;
2a02:8106:208:5200::/56;
2a02:8106:211:e900::/56;
};
interface "core" {
#authentication cryptographic;
#password "${import <secrets/shared/ospf/message-digest-key.nix>}";
};
};
}
router id ${coreAddress};
'';
};
# 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;
root = <this-host/assets>;
locations =
let
sysinfo-json = {
alias = "/tmp/sysinfo.json";
extraConfig = ''
add_header Content-Type "application/json;charset=UTF-8";
'';
};
in {
"/" = {
index = "index.html";
extraConfig = ''
etag off;
add_header etag "\"${builtins.substring 11 32 (<this-host> + "/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/";
};
};
# 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?
}