nix-config/hosts/dn42/default.nix
2024-09-25 23:56:00 +02:00

258 lines
6.8 KiB
Nix

{ config, pkgs, lib, ... }:
let
address4 = "172.22.99.253";
address6 = "fe80::deca:fbad";
neighbors = import ./neighbors.nix;
in
{
networking = {
domain = "hq.c3d2.de";
hostName = "dn42";
useNetworkd = true;
# No Firewalling!
firewall.enable = false;
};
c3d2 = {
deployment.server = "server10";
interface = "c3d2";
statistics.enable = true;
};
services = {
collectd.plugins.exec =
let
routecount = pkgs.writeShellScript "run-routecount" ''
export PATH=${lib.makeBinPath (with pkgs; [ ruby iproute2 ] )}
ruby ${./routecount.rb}
'';
in
''
Exec "collectd" "${routecount}"
'';
resolved.enable = false;
};
sops = {
age.sshKeyPaths = [ "/etc/ssh/ssh_host_ed25519_key" ];
defaultSopsFile = ./secrets.yaml;
secrets = lib.foldl'
(result: name:
let
conf = neighbors.${name};
in
result // (
if conf ? openvpn
then { "neighbors/${name}/openvpn/key" = { }; }
else if conf ? wireguard
then { "neighbors/${name}/wireguard/privateKey" = { }; }
else { }
)
)
{ }
(lib.attrNames neighbors);
};
boot.kernel.sysctl = {
"net.ipv4.conf.all.forwarding" = true;
"net.ipv4.conf.default.forwarding" = true;
"net.ipv6.conf.all.forwarding" = true;
"net.ipv6.conf.default.forwarding" = true;
};
boot.postBootCommands = /* bash */''
if [ ! -c /dev/net/tun ]; then
mkdir -p /dev/net
mknod -m 666 /dev/net/tun c 10 200
fi
'';
services.openvpn =
let
openvpnNeighbors = lib.filterAttrs (_: conf: conf ? openvpn) neighbors;
mkServer = name: conf: {
config = ''
dev ${name}
dev-type tun
ifconfig ${address4} ${conf.address4}
user nobody
group nogroup
persist-tun
persist-key
ping 30
ping-restart 45
verb 1
${conf.openvpn}
secret ${config.sops.secrets."neighbors/${name}/openvpn/key".path}
'';
up = ''
${pkgs.iproute2}/bin/ip addr flush dev $1
${lib.optionalString (conf ? address4) ''
${pkgs.iproute2}/bin/ip addr add ${address4} dev ${name} peer ${conf.address4}/32
''}
${pkgs.iproute2}/bin/ip addr add ${address6}/64 dev $1
'';
};
in
{
servers = builtins.mapAttrs mkServer openvpnNeighbors;
};
networking.wireguard = {
enable = true;
interfaces =
let
wireguardNeighbors = lib.filterAttrs (_: conf: conf ? wireguard) neighbors;
in
builtins.mapAttrs (name: conf: {
inherit (conf.wireguard) listenPort;
privateKeyFile = config.sops.secrets."neighbors/${name}/wireguard/privateKey".path;
ips = [ "${address4}/32" "${address6}/64" ];
allowedIPsAsRoutes = false;
postSetup = ''
${pkgs.iproute2}/bin/ip addr del ${address4}/32 dev ${name}
${pkgs.iproute2}/bin/ip addr add ${address4} dev ${name}${lib.optionalString (conf ? address4) " peer ${conf.address4}/32"}
'';
peers = [
({
inherit (conf.wireguard) publicKey;
allowedIPs = [ "0.0.0.0/0" "::0/0" ];
persistentKeepalive = 30;
} // (lib.optionalAttrs (conf.wireguard ? endpoint) {
inherit (conf.wireguard) endpoint;
}))
];
}) wireguardNeighbors;
};
services.bird2 = {
enable = true;
config =
let
bgpNeighbors = builtins.concatStringsSep "\n" (builtins.attrValues
(builtins.mapAttrs
(name: conf@{ multiprotocol ? false, ... }:
let
neighbor4 =
lib.optionalString (conf ? address4 && multiprotocol != "ipv6") ''
protocol bgp ${name}_4 from ${if multiprotocol == "ipv4" then "dnpeers" else "dnpeers4"} {
neighbor ${conf.address4} as ${builtins.toString conf.asn};
}
'';
neighbor6 =
lib.optionalString (conf ? address6 && multiprotocol != "ipv4") ''
protocol bgp ${name}_6 from ${if multiprotocol == "ipv6" then "dnpeers" else "dnpeers6"} {
neighbor ${conf.address6}%${interface} as ${
builtins.toString conf.asn
};
}
'';
interface = conf.interface or name;
in
"${neighbor4}${neighbor6}") neighbors));
in
''
protocol kernel {
ipv4 {
export all;
};
}
protocol kernel {
ipv6 {
export all;
};
}
protocol device {
scan time 10;
}
protocol static {
ipv4;
route 10.0.0.0/8 unreachable;
route 172.16.0.0/12 unreachable;
route 192.168.0.0/16 unreachable;
}
protocol static {
ipv6;
route 2000::/3 via 2a00:8180:2c00:281::c3d2:3;
route fd00::/8 unreachable;
}
protocol static hq4 {
ipv4;
route 172.22.99.0/24 via "c3d2";
}
protocol static hq6 {
ipv6;
route fd23:42:c3d2:500::/56 unreachable;
}
template bgp dnpeers {
local as 64699;
ipv4 {
import filter {
if proto = "hq4" then reject;
accept;
};
export filter {
if source = RTS_BGP then accept;
if proto = "hq4" then accept;
reject;
};
};
ipv6 {
import filter {
if proto = "hq6" then reject;
accept;
};
export filter {
if source = RTS_BGP then accept;
if proto = "hq6" then accept;
reject;
};
};
}
template bgp dnpeers4 {
local as 64699;
ipv4 {
import filter {
if proto = "hq4" then reject;
accept;
};
export filter {
if source = RTS_BGP then accept;
if proto = "hq4" then accept;
reject;
};
};
}
template bgp dnpeers6 {
local as 64699;
ipv6 {
import filter {
if proto = "hq6" then reject;
accept;
};
export filter {
if source = RTS_BGP then accept;
if proto = "hq6" then accept;
reject;
};
};
}
${bgpNeighbors}
router id ${address4};
'';
};
system.stateVersion = "19.09";
}