kerrigan: replace swann for now

This commit is contained in:
Luke Granger-Brown 2025-02-13 17:07:52 +00:00
parent 7e95da407b
commit 79184b4846
6 changed files with 1125 additions and 60 deletions

View file

@ -5,14 +5,6 @@
{ depot, lib, pkgs, config, modulesPath, ... }:
let
nmFiles = builtins.attrNames (lib.filterAttrs (n: v: v == "regular" && lib.hasSuffix ".nmconnection" n) (builtins.readDir ./networkmanager));
nmBits = lib.mkMerge (map (filename: {
"NetworkManager/system-connections/${filename}" = {
source = ./networkmanager + "/${filename}";
mode = "0600";
};
}) nmFiles);
uboot-envtools = pkgs.ubootTools.override {
extraMakeFlags = [ "HOST_TOOLS_ALL=y" "CROSS_BUILD_TOOLS=1" "NO_SDL=1" "envtools" ];
@ -28,6 +20,14 @@ let
};
in
{
imports = [
./network-basics.nix
./network-bgp.nix
./network-dhcp.nix
./network-dns.nix
./network-firewall.nix
];
fileSystems = {
"/" = { device = "/dev/disk/by-label/NIXOS"; fsType = "ext4"; };
"/boot" = { device = "/dev/disk/by-label/ESP"; fsType = "vfat"; };
@ -56,71 +56,20 @@ in
"8.8.8.8"
"8.8.4.4"
];
interfaces.eth2.useDHCP = true;
interfaces.enu1u4i10.useDHCP = true;
firewall.interfaces.br0.allowedTCPPorts = [ 80 ];
nat = {
enable = true;
enableIPv6 = true;
internalInterfaces = [ "br0" ];
externalInterface = "enu1u4i10";
dmzHost = "10.42.0.2";
};
};
users.users.lukegb.extraGroups = lib.mkAfter [ "networkmanager" ];
my.systemType = "aarch64-linux";
my.ip.tailscale = "100.110.212.70";
my.ip.tailscale6 = "fd7a:115c:a1e0:ab12:4843:cd96:626e:d446";
systemd.network.netdevs.br0 = {
netdevConfig = {
Name = "br0";
Kind = "bridge";
};
};
systemd.network.networks.br0 = {
matchConfig.Name = "br0";
networkConfig = {
Address = [ "10.42.0.1/24" "2a09:a443:ee::1/64" ];
DHCPServer = true;
IPv6SendRA = true;
};
ipv6Prefixes = [{
Prefix = "2a09:a443:ee::/64";
}];
ipv6RoutePrefixes = [{
Route = "::/0";
}];
dhcpServerConfig = {
PoolOffset = 100;
PoolSize = 100;
};
};
systemd.network.networks.links-to-bridge = {
matchConfig.Name = "lan*";
networkConfig.Bridge = "br0";
};
environment.systemPackages = with pkgs; [
libqmi screen minicom conntrack-tools modemmanager android-tools
uboot-envtools
uboot-envtools ethtool
];
services.udev.packages = with pkgs; [
modemmanager
];
services.caddy = {
enable = true;
extraConfig = ''
10.42.0.1:80 {
reverse_proxy /mbbstatus http://add-on.ee.co.uk {
header_up Host add-on.ee.co.uk
}
}
'';
};
boot.loader.efi.canTouchEfiVariables = false;
boot.loader.systemd-boot.enable = true;

View file

@ -0,0 +1,445 @@
# SPDX-FileCopyrightText: 2020 Luke Granger-Brown <depot@lukegb.com>
#
# SPDX-License-Identifier: Apache-2.0
{ depot, lib, pkgs, config, ... }:
let
inherit (depot.ops) secrets;
inherit (lib) mkMerge mkForce;
in {
config = {
# Networking!
networking = {
# Routing tables:
# bgp (150) -- contains default routes over WG tunnels
# ee (201) -- table contains a default route via EE
# vm (202) -- table contains a default route via VM
# gnet (203) -- table contains a default route via gnetwork
# main (254) -- basically empty
interfaces = {
lo = {
ipv4.addresses = [
{ address = "127.0.0.1"; prefixLength = 8; }
{ address = "92.118.30.254"; prefixLength = 32; }
{ address = "92.118.30.253"; prefixLength = 32; }
];
};
lan-gnet = {
useDHCP = true;
ipv4.addresses = [
{ address = "192.168.201.2"; prefixLength = 24; }
];
# Additional options configured in networkd.
};
lan-ee = {
useDHCP = true;
ipv4.addresses = [
{ address = "192.168.2.2"; prefixLength = 24; }
];
# Additional options configured in networkd.
};
br-internal = {
ipv4.addresses = [
{ address = "192.168.1.1"; prefixLength = 23; }
{ address = "92.118.30.17"; prefixLength = 28; }
];
ipv6.addresses = [
{ address = "2a09:a443::1"; prefixLength = 64; }
{ address = "2a09:a443:1::1"; prefixLength = 48; }
];
};
vl-eduroam = {
ipv4.addresses = [
{ address = "192.168.10.1"; prefixLength = 24; }
];
ipv6.addresses = [
{ address = "2a09:a443:2::1"; prefixLength = 64; }
{ address = "2a09:a443:3::1"; prefixLength = 48; }
];
};
};
};
systemd.network = let
hexToInt = h: (builtins.fromTOML "h = ${h}").h;
physicalNetwork = rtID: wireguardFwmark: extraRules: {
dhcpV4Config.RouteTable = rtID;
ipv6AcceptRAConfig.RouteTable = rtID;
routingPolicyRules = [{
Family = "both";
FirewallMark = hexToInt wireguardFwmark;
Priority = 10000;
Table = rtID;
}] ++ extraRules;
};
wireguardNetwork = { linkName, relativePriority, rtID, v4Linknet, v6Linknet }: {
matchConfig.Name = linkName;
routes = let
replaceV4Octet = v4: fn: let
pieces = builtins.match ''(([0-9]+\.){3})([0-9]+)'' v4;
in
"${builtins.elemAt pieces 0}${toString (fn (lib.toInt (builtins.elemAt pieces 2)))}";
replaceV6Octet = v6: fn: let
pieces = builtins.match ''^(([0-9a-f]+:+)+)([0-9a-f]*)$'' v6;
in
"${builtins.elemAt pieces 0}${lib.toHexString (fn (hexToInt "0x${builtins.elemAt pieces 2}"))}";
in [
{
Destination = "${v4Linknet}/31";
Table = rtID;
}
{
Gateway = replaceV4Octet v4Linknet (n: n + 1);
Table = rtID;
}
{
Destination = "${replaceV6Octet v6Linknet (n: 0)}/112";
Table = rtID;
}
{
Gateway = replaceV6Octet v6Linknet (n: n + 1);
Table = rtID;
}
];
networkConfig = {
Address = [
"${v4Linknet}/31"
"${v6Linknet}/112"
];
};
routingPolicyRules = [
(tailscaleRule (relativePriority + 5000) rtID)
# Allow picking destination by source IP.
{
Family = "ipv4";
From = v4Linknet;
Priority = 10010;
Table = rtID;
}
{
Family = "ipv6";
From = v6Linknet;
Priority = 10010;
Table = rtID;
}
];
};
tailscaleRule = priority: table: {
# Route Tailscale (fwmark 0x80000) via Wireguard first.
Family = "both";
FirewallMark = hexToInt "0x80000"; # Should be "0x80000/0xff0000"
Priority = priority;
Table = table;
};
in let
routeTables = {
bgp = 150;
wg-ee = 152;
wg-gnet = 153;
wg-cf-ee = 154;
wg-cf-gnet = 155;
wg-eta = 160;
ee = 201;
gnet = 203;
};
in {
enable = true;
config.routeTables = routeTables;
networks."50-wg-rexxar-ee" = wireguardNetwork {
linkName = "wg-rexxar-ee";
relativePriority = 3;
rtID = routeTables.wg-ee;
v4Linknet = "92.118.30.2";
v6Linknet = "2a09:a442::2:1";
};
networks."50-wg-rexxar-gnet" = wireguardNetwork {
linkName = "wg-rexxar-gnet";
relativePriority = 1;
rtID = routeTables.wg-gnet;
v4Linknet = "92.118.30.4";
v6Linknet = "2a09:a442::3:1";
};
networks."50-wg-cofractal-ee" = wireguardNetwork {
linkName = "wg-cofractal-ee";
relativePriority = 4;
rtID = routeTables.wg-cf-ee;
v4Linknet = "92.118.30.0";
v6Linknet = "2a09:a442::1:1";
};
networks."50-wg-cofractal-gn" = wireguardNetwork {
linkName = "wg-cofractal-gn";
relativePriority = 2;
rtID = routeTables.wg-cf-gnet;
v4Linknet = "92.118.30.6";
v6Linknet = "2a09:a442::4:1";
};
networks."50-wg-eta" = wireguardNetwork {
linkName = "wg-eta";
relativePriority = 10;
rtID = routeTables.wg-eta;
v4Linknet = "169.254.2.1";
v6Linknet = "fe80:1234::b";
};
networks."40-lo" = {
routingPolicyRules = let
viaMain = priority: to: {
To = to;
Table = "main";
Priority = priority;
};
blackhole = fwmark: {
Family = "both";
FirewallMark = hexToInt fwmark;
Priority = 10001;
Type = "unreachable";
};
in [
(tailscaleRule 5000 150)
# Blackhole connections that should be routed over individual interfaces.
(blackhole "0xdead")
(blackhole "0xbeef")
(blackhole "0xcafe")
# RFC 1918 via main table.
(viaMain 10020 "192.168.0.0/16")
(viaMain 10021 "10.0.0.0/8")
(viaMain 10022 "172.16.0.0/12")
# and the linknets.
(viaMain 10023 "92.118.30.0/24")
(viaMain 10024 "2a09:a442::1:0/112")
(viaMain 10025 "2a09:a442::2:0/112")
(viaMain 10026 "2a09:a442::3:0/112")
{
# Catch-all "go via WG"
Family = "both";
Priority = 10080;
Table = routeTables.bgp;
}
];
};
networks."40-lan-ee" = (physicalNetwork routeTables.ee "0xdead" [{
# add-on.ee.co.uk goes via EE.
To = "82.192.97.153/32";
Table = routeTables.ee;
Priority = 10031;
} {
# as does anything from 192.168.2.0/24.
From = "192.168.2.0/24";
Table = routeTables.ee;
Priority = 10031;
}]) // {
linkConfig.RequiredForOnline = "no";
routes = [{
Gateway = "192.168.2.1";
Destination = "0.0.0.0/0";
Table = routeTables.ee;
} {
Destination = "192.168.2.0/24";
Table = routeTables.ee;
}];
};
networks."40-lan-gnet" = (physicalNetwork routeTables.gnet "0xcafe" [{
# Catch-all mop-up rule at the end.
Family = "both";
Priority = 32768;
Table = routeTables.gnet;
}]);
networks."40-br-internal" = {
networkConfig.VLAN = [ "vl-eduroam" ];
};
networks."40-lan-int-to-bridge" = {
matchConfig.Name = "lan-int*";
networkConfig.Bridge = "br-internal";
};
networks."40-en-int-sfp" = {
matchConfig.Name = "en-int-sfp";
networkConfig.Bridge = "br-internal";
};
links."40-en-int-sfp" = {
# named "eth0" on startup
matchConfig.MACAddress = "f0:ad:4e:28:9d:8d";
linkConfig.Name = "en-int-sfp";
};
links."40-lan0" = {
matchConfig.OriginalName = "lan0";
linkConfig.Name = "lan-int";
};
links."40-lan1" = {
matchConfig.OriginalName = "lan1";
linkConfig.Name = "lan-int2";
};
links."40-lan2" = {
matchConfig.OriginalName = "lan2";
linkConfig.Name = "lan-gnet";
};
links."40-lan3" = {
matchConfig.OriginalName = "lan3";
linkConfig.Name = "lan-ee";
};
netdevs = let
wireguard = { name, listenPort, privateKey, endpoint, publicKey, fwmark }: {
netdevConfig = {
Name = name;
Kind = "wireguard";
Description = "WireGuard tunnel ${name}";
};
wireguardConfig = {
ListenPort = listenPort;
PrivateKeyFile = privateKey;
FirewallMark = hexToInt fwmark;
RouteTable = "off";
};
wireguardPeers = [{
Endpoint = endpoint;
PublicKey = publicKey;
AllowedIPs = [
"0.0.0.0/0"
"::/0"
];
}];
};
rexxarWireguard = args: wireguard (args // {
privateKey = config.my.vault.secrets.wg-rexxar-private.path;
publicKey = "UnmWp6OI283EJfJ9PabZePq/IDsfk1ku/vilRy9TIg0=";
});
cofractalams01Wireguard = args: wireguard (args // {
privateKey = config.my.vault.secrets.wg-cofractal-ams01-private.path;
publicKey = "go9lHRpTrtPx8oGzsCs3bG1Z9bQBYsCk7l3T+1KBi1Y=";
});
in {
"40-wg-rexxar-ee" = rexxarWireguard {
name = "wg-rexxar-ee";
listenPort = 51821;
#endpoint = "92.118.28.252:51821";
endpoint = "[2a09:a442:1000::]:51821";
fwmark = "0xdead";
};
"40-wg-rexxar-gnet" = rexxarWireguard {
name = "wg-rexxar-gnet";
listenPort = 51822;
endpoint = "92.118.30.251:51822";
fwmark = "0xcafe";
};
"40-wg-cofractal-ee" = cofractalams01Wireguard {
name = "wg-cofractal-ee";
listenPort = 51823;
#endpoint = "92.118.28.252:51821";
endpoint = "[2a09:a446:1337:ffff::10]:51821";
fwmark = "0xdead";
};
"40-wg-cofractal-gn" = cofractalams01Wireguard {
name = "wg-cofractal-gn";
listenPort = 51824;
endpoint = "199.19.152.160:51822";
fwmark = "0xcafe";
};
"50-wg-eta" = {
netdevConfig = {
Name = "wg-eta";
Kind = "wireguard";
Description = "WireGuard tunnel wg-eta";
};
wireguardConfig = {
ListenPort = 51830;
PrivateKeyFile = config.my.vault.secrets.wg-eta-private.path;
RouteTable = "off";
FirewallMark = hexToInt "0xcafe"; # over gnet
};
wireguardPeers = [{
Endpoint = "shenfield-mythic.i.eta.st:51825";
#PublicKey = config.my.vault.secrets.wg-eta-public.path;
PublicKey = "JDelaz8FQBtJBRVd9CMYikO/25gKipYgfyXtjL6jgS8=";
AllowedIPs = [
"0.0.0.0/0"
"::/0"
];
}];
};
"20-br-internal" = {
netdevConfig = {
Name = "br-internal";
Kind = "bridge";
Description = "Bridge br-internal";
};
extraConfig = ''
[Bridge]
VLANFiltering=false
MulticastQuerier=true
MulticastSnooping=false
STP=true
VLANProtocol=802.1q
MulticastIGMPVersion=3
'';
};
"25-vl-eduroam" = {
netdevConfig = {
Name = "vl-eduroam";
Kind = "vlan";
Description = "Eduroam VLAN on br-internal";
};
vlanConfig = {
Id = 100;
};
};
};
};
my.vault.secrets = let
wireguardSecret = key: {
group = "systemd-network";
template = ''
{{- with secret "kv/apps/wireguard/kerrigan" -}}
{{- .Data.data.${key} -}}
{{- end -}}
'';
};
in {
wg-eta-private = wireguardSecret "privateKeyToEta";
wg-rexxar-private = wireguardSecret "privateKeyToRexxar";
wg-cofractal-ams01-private = wireguardSecret "privateKeyToCofractalAms01";
};
services.mstpd.enable = true;
networking.nat = {
enable = true;
internalInterfaces = ["br-internal"];
externalInterface = "lan-gnet";
extraCommands = ''
# Send PS5 RTMP to totoro instead.
# See DHCP static lease.
iptables -w -t nat -A nixos-nat-pre --src 92.118.30.18 -p tcp --dport 1935 -j DNAT --to-destination 192.168.1.40
# NAT packets going over EE plain.
iptables -w -t nat -A nixos-nat-post -m mark --mark 1 -o lan-ee -j MASQUERADE
# NAT packets going over GNetwork plain.
iptables -w -t nat -A nixos-nat-post -m mark --mark 1 -o lan-gnet -j MASQUERADE
# SNAT packets we're sending over tunnels.
iptables -w -t nat -A nixos-nat-post -m mark --mark 1 -o wg-rexxar-ee -j SNAT --to-source 92.118.30.254
iptables -w -t nat -A nixos-nat-post -m mark --mark 1 -o wg-rexxar-gnet -j SNAT --to-source 92.118.30.254
iptables -w -t nat -A nixos-nat-post -m mark --mark 1 -o wg-cofractal-ee -j SNAT --to-source 92.118.30.254
iptables -w -t nat -A nixos-nat-post -m mark --mark 1 -o wg-cofractal-gn -j SNAT --to-source 92.118.30.254
# eduroam
# > mark incoming eduroam packets
iptables -w -t nat -A nixos-nat-pre -i vl-eduroam -j MARK --set-mark 2
# > NAT packets going out directly.
iptables -w -t nat -A nixos-nat-post -m mark --mark 2 -o lan-ee -j MASQUERADE
iptables -w -t nat -A nixos-nat-post -m mark --mark 2 -o lan-gnet -j MASQUERADE
# > NAT packets going over tunnels.
iptables -w -t nat -A nixos-nat-post -m mark --mark 2 -o wg-rexxar-ee -j SNAT --to-source 92.118.30.253
iptables -w -t nat -A nixos-nat-post -m mark --mark 2 -o wg-rexxar-gnet -j SNAT --to-source 92.118.30.253
iptables -w -t nat -A nixos-nat-post -m mark --mark 2 -o wg-cofractal-ee -j SNAT --to-source 92.118.30.253
iptables -w -t nat -A nixos-nat-post -m mark --mark 2 -o wg-cofractal-gn -j SNAT --to-source 92.118.30.253
'';
};
};
}

View file

@ -0,0 +1,370 @@
# SPDX-FileCopyrightText: 2020 Luke Granger-Brown <depot@lukegb.com>
#
# SPDX-License-Identifier: Apache-2.0
{ depot, lib, pkgs, config, ... }:
let
inherit (depot.ops) secrets;
inherit (lib) mkMerge mkForce;
in {
config = {
services.bird2 = {
enable = true;
config = ''
router id 92.118.30.254;
protocol kernel {
kernel table 150;
metric 0;
ipv4 {
import none;
export all;
};
};
protocol kernel {
kernel table 150;
metric 0;
ipv6 {
import none;
export all;
};
};
protocol device {};
protocol static export4 {
ipv4 {
import filter {
if (ro, 205479, 1000) ~ bgp_ext_community then {
bgp_ext_community.add((ro, 205479, 2000)); #
bgp_ext_community.add((ro, 205479, 2001)); #
bgp_ext_community.add((ro, 205479, 2002)); #
bgp_ext_community.add((ro, 205479, 2003)); #
bgp_ext_community.add((ro, 205479, 3000)); # clouvider from clouvider-lon01
bgp_ext_community.add((ro, 205479, 4000)); # frantech from frantech-nyc01/veloxserv from etheroute-lon01
bgp_ext_community.add((ro, 205479, 4001)); # veloxserv from rexxar
bgp_ext_community.add((ro, 205479, 4002)); # mercury from etheroute-lon01
bgp_ext_community.add((ro, 205479, 5000)); # linx route collector from rexxar
bgp_ext_community.add((ro, 205479, 5001)); # linx route server from rexxar
bgp_ext_community.add((ro, 205479, 5002)); # facebook from rexxar
bgp_ext_community.add((ro, 205479, 5003)); # openpeering from rexxar
bgp_ext_community.add((ro, 205479, 5004)); # freetransitnet from rexxar
bgp_ext_community.add((ro, 205479, 5005)); # he from rexxar
bgp_ext_community.add((ro, 205479, 5006)); # clouvider from rexxar
bgp_ext_community.add((ro, 205479, 5007)); # google from rexxar
bgp_ext_community.add((ro, 205479, 5008)); # cloudflare from rexxar
bgp_ext_community.add((ro, 205479, 5009)); # fastly from rexxar
bgp_ext_community.add((ro, 205479, 5010)); # ovh from rexxar
bgp_ext_community.add((ro, 205479, 6000)); # EMF: EMF-IX Route Server
bgp_ext_community.add((ro, 205479, 7000)); # 1299 from rexxar
}
accept;
};
};
route 0.0.0.0/0 via 92.118.30.3 bfd {
# EE, rexxar
preference = 10;
};
route 0.0.0.0/0 via 92.118.30.5 bfd {
# GNetwork, rexxar
preference = 200;
};
route 0.0.0.0/0 via 92.118.30.1 bfd {
# EE, cofractal-ams01
preference = 10;
};
route 0.0.0.0/0 via 92.118.30.7 bfd {
# GNetwork, cofractal-ams01
preference = 200;
};
route 92.118.30.0/24 unreachable {
bgp_ext_community.add((ro, 205479, 10)); # export this - internal
bgp_ext_community.add((ro, 205479, 1000)); # export this
};
route 92.118.30.16/28 via "br-internal";
route 92.118.30.254/32 via "lo";
route 92.118.30.253/32 via "lo";
route 92.118.30.0/31 via "wg-cofractal-ee";
route 92.118.30.2/31 via "wg-rexxar-ee";
route 92.118.30.4/31 via "wg-rexxar-gnet";
route 92.118.30.6/31 via "wg-cofractal-gn";
};
protocol static export6 {
ipv6 {
import filter {
if ((ro, 205479, 1000) ~ bgp_ext_community) then {
bgp_ext_community.add((ro, 205479, 2000)); #
bgp_ext_community.add((ro, 205479, 2001)); #
bgp_ext_community.add((ro, 205479, 2002)); #
bgp_ext_community.add((ro, 205479, 2003)); #
bgp_ext_community.add((ro, 205479, 3000)); # clouvider from clouvider-lon01
bgp_ext_community.add((ro, 205479, 4000)); # frantech from frantech-nyc01/veloxserv from etheroute-lon01
bgp_ext_community.add((ro, 205479, 4001)); # veloxserv from rexxar
bgp_ext_community.add((ro, 205479, 4002)); # mercury from etheroute-lon01
bgp_ext_community.add((ro, 205479, 5000)); # linx route collector from rexxar
bgp_ext_community.add((ro, 205479, 5001)); # linx route server from rexxar
bgp_ext_community.add((ro, 205479, 5002)); # facebook from rexxar
bgp_ext_community.add((ro, 205479, 5003)); # openpeering from rexxar
bgp_ext_community.add((ro, 205479, 5004)); # freetransitnet from rexxar
bgp_ext_community.add((ro, 205479, 5005)); # he from rexxar
bgp_ext_community.add((ro, 205479, 5006)); # clouvider from rexxar
bgp_ext_community.add((ro, 205479, 5007)); # google from rexxar
bgp_ext_community.add((ro, 205479, 5008)); # cloudflare from rexxar
bgp_ext_community.add((ro, 205479, 5009)); # fastly from rexxar
bgp_ext_community.add((ro, 205479, 5010)); # ovh from rexxar
bgp_ext_community.add((ro, 205479, 6000)); # EMF: EMF-IX Route Server
bgp_ext_community.add((ro, 205479, 7000)); # 1299 from rexxar
}
accept;
};
};
route ::/0 via 2a09:a442::1:2 bfd {
# EE, cofractal-ams01
preference = 10;
krt_prefsrc = 2a09:a443::1;
};
route ::/0 via 2a09:a442::2:2 bfd {
# EE, rexxar
preference = 10;
krt_prefsrc = 2a09:a443::1;
};
route ::/0 via 2a09:a442::3:2 bfd {
# GNetwork, rexxar
preference = 200;
krt_prefsrc = 2a09:a443::1;
};
route ::/0 via 2a09:a442::4:2 bfd {
# GNetwork, cofractal-ams01
preference = 200;
krt_prefsrc = 2a09:a443::1;
};
# Covering route...
route 2a09:a443::/64 via "br-internal";
route 2a09:a443:1::/48 via "br-internal";
route 2a09:a443:2::/64 via "vl-eduroam";
route 2a09:a443:3::/48 via "vl-eduroam";
route 2a09:a443::/32 unreachable {
bgp_ext_community.add((ro, 205479, 10)); # export this - internal
bgp_ext_community.add((ro, 205479, 1000)); # export this
};
};
protocol bfd {
interface "*" {
min rx interval 10ms;
min tx interval 50ms;
idle tx interval 1s;
multiplier 20;
};
neighbor 92.118.30.1;
neighbor 2a09:a442::1:2;
neighbor 92.118.30.3;
neighbor 2a09:a442::2:2;
neighbor 92.118.30.5;
neighbor 2a09:a442::3:2;
neighbor 92.118.30.7;
neighbor 2a09:a442::4:2;
};
protocol bgp rexxar_ee4 {
local 92.118.30.2 as 205479;
neighbor 92.118.30.3 as 205479;
interface "wg-rexxar-ee";
direct;
bfd on;
ipv4 {
export filter {
if source != RTS_STATIC then reject;
if ! ((ro, 205479, 10) ~ bgp_ext_community) then reject;
accept;
};
import filter {
accept;
};
next hop self;
};
};
protocol bgp rexxar_ee6 {
local 2a09:a442::2:1 as 205479;
neighbor 2a09:a442::2:2 as 205479;
interface "wg-rexxar-ee";
direct;
bfd on;
ipv6 {
export filter {
if source != RTS_STATIC then reject;
if ! ((ro, 205479, 10) ~ bgp_ext_community) then reject;
accept;
};
import filter {
accept;
};
next hop self;
};
};
protocol bgp rexxar_gnet4 {
local 92.118.30.4 as 205479;
neighbor 92.118.30.5 as 205479;
interface "wg-rexxar-gnet";
direct;
bfd on;
ipv4 {
export filter {
if source != RTS_STATIC then reject;
if ! ((ro, 205479, 10) ~ bgp_ext_community) then reject;
accept;
};
import filter {
accept;
};
next hop self;
};
};
protocol bgp rexxar_gnet6 {
local 2a09:a442::3:1 as 205479;
neighbor 2a09:a442::3:2 as 205479;
interface "wg-rexxar-gnet";
direct;
bfd on;
ipv6 {
export filter {
if source != RTS_STATIC then reject;
if ! ((ro, 205479, 10) ~ bgp_ext_community) then reject;
accept;
};
import filter {
accept;
};
next hop self;
};
};
protocol bgp cofractal_ee4 {
local 92.118.30.0 as 205479;
neighbor 92.118.30.1 as 205479;
interface "wg-cofractal-ee";
direct;
bfd on;
ipv4 {
export filter {
if source != RTS_STATIC then reject;
if ! ((ro, 205479, 10) ~ bgp_ext_community) then reject;
accept;
};
import filter {
accept;
};
next hop self;
};
};
protocol bgp cofractal_ee6 {
local 2a09:a442::1:1 as 205479;
neighbor 2a09:a442::1:2 as 205479;
interface "wg-cofractal-ee";
direct;
bfd on;
ipv6 {
export filter {
if source != RTS_STATIC then reject;
if ! ((ro, 205479, 10) ~ bgp_ext_community) then reject;
accept;
};
import filter {
accept;
};
next hop self;
};
};
protocol bgp cofractal_gnet4 {
local 92.118.30.6 as 205479;
neighbor 92.118.30.7 as 205479;
interface "wg-cofractal-gn";
direct;
bfd on;
ipv4 {
export filter {
if source != RTS_STATIC then reject;
if ! ((ro, 205479, 10) ~ bgp_ext_community) then reject;
accept;
};
import filter {
accept;
};
next hop self;
};
};
protocol bgp cofractal_gnet6 {
local 2a09:a442::4:1 as 205479;
neighbor 2a09:a442::4:2 as 205479;
interface "wg-cofractal-gn";
direct;
bfd on;
ipv6 {
export filter {
if source != RTS_STATIC then reject;
if ! ((ro, 205479, 10) ~ bgp_ext_community) then reject;
accept;
};
import filter {
accept;
};
next hop self;
};
};
protocol bgp eta4 {
local 169.254.2.1 as 205479;
neighbor 169.254.2.0 as 213185;
interface "wg-eta";
ipv4 {
export filter {
if source != RTS_STATIC then reject;
if ! ((ro, 205479, 1000) ~ bgp_ext_community) then reject;
bgp_ext_community.delete([(ro, 205479, *)]);
accept;
};
import filter {
if ! (net ~ [
44.31.189.0/24
]) then reject;
accept;
};
next hop self;
};
};
protocol bgp eta6 {
local fe80:1234::b as 205479;
neighbor fe80:1234::a as 213185;
interface "wg-eta";
ipv6 {
export filter {
if source != RTS_STATIC then reject;
if ! ((ro, 205479, 1000) ~ bgp_ext_community) then reject;
bgp_ext_community.delete([(ro, 205479, *)]);
accept;
};
import filter {
if ! (net ~ [
2a0d:1a40:7553::/48{48,64}
]) then reject;
accept;
};
next hop self;
};
};
'';
};
};
}

View file

@ -0,0 +1,164 @@
# SPDX-FileCopyrightText: 2020 Luke Granger-Brown <depot@lukegb.com>
#
# SPDX-License-Identifier: Apache-2.0
{ depot, lib, pkgs, config, ... }:
let
inherit (depot.ops) secrets;
inherit (lib) mkMerge mkForce;
in {
config = {
systemd.services.kea-dhcp4-server.serviceConfig = {
Restart = "always";
RestartSec = "100ms";
RestartSteps = 10;
RestartMaxDelaySec = "1min";
};
services.kea = {
dhcp4.enable = true;
dhcp4.settings = {
interfaces-config = {
interfaces = ["br-internal" "vl-eduroam"];
service-sockets-require-all = true;
service-sockets-max-retries = 20; # retry up to 20 times
service-sockets-retry-wait-time = 5000; # 5 seconds
};
lease-database = {
type = "memfile";
persist = true;
name = "/var/lib/kea/dhcp4.leases";
};
reservations-global = true;
reservations = [{
hw-address = "40:8d:5c:1f:e8:68";
ip-address = "192.168.1.40";
hostname = "totoro";
} {
hw-address = "52:54:00:cf:cd:94";
ip-address = "192.168.1.41";
hostname = "totoro-pfsense";
} {
hw-address = "00:0d:5d:1b:14:ba";
ip-address = "192.168.1.50";
hostname = "kvm";
} {
hw-address = "9c:93:4e:ad:1f:7b";
ip-address = "192.168.1.51";
hostname = "printer-xerox";
} {
hw-address = "e8:ed:f3:6a:b9:24";
ip-address = "192.168.1.52";
hostname = "phone-lukegb-desk";
option-data = [{
name = "tftp-server-name";
data = "192.168.1.1";
}];
} {
hw-address = "bc:33:29:26:01:5c";
ip-address = "92.118.30.18";
hostname = "ps5";
} {
hw-address = "84:39:be:77:65:52";
ip-address = "192.168.1.60";
hostname = "qvmpc6552";
}];
subnet4 = [{
id = 1;
subnet = "192.168.1.0/24";
pools = [{
pool = "192.168.1.100 - 192.168.1.200";
}];
option-data = [{
name = "routers";
data = "192.168.1.1";
} {
name = "domain-name-servers";
data = "192.168.1.1";
} {
name = "domain-name";
data = "house.as205479.net";
} {
name = "interface-mtu";
data = "1420";
}];
} {
id = 2;
subnet = "92.118.30.16/28";
option-data = [{
name = "routers";
data = "92.118.30.17";
} {
name = "domain-name-servers";
data = "92.118.30.17";
} {
name = "domain-name";
data = "house-ext.as205479.net";
} {
name = "interface-mtu";
data = "1420";
}];
} {
id = 10;
subnet = "192.168.10.0/24";
pools = [{
pool = "192.168.10.100 - 192.168.10.200";
}];
option-data = [{
name = "routers";
data = "192.168.10.1";
} {
name = "domain-name-servers";
data = "192.168.10.1";
} {
name = "domain-name";
data = "eduroam.as205479.net";
} {
name = "interface-mtu";
data = "1420";
}];
}];
};
dhcp6.enable = true;
dhcp6.settings = {
interfaces-config.interfaces = ["br-internal" "vl-eduroam"];
lease-database = {
type = "memfile";
persist = true;
name = "/var/lib/kea/dhcp6.leases";
};
subnet6 = [{
id = 1;
subnet = "2a09:a443:1::/48";
pd-pools = [{
prefix = "2a09:a443:1:8000::";
prefix-len = 49;
delegated-len = 64;
}];
option-data = [{
name = "dns-servers";
data = "2a09:a443:1::1";
} {
name = "domain-search";
data = "house.as205479.net";
}];
} {
id = 3;
subnet = "2a09:a443:3::/48";
pd-pools = [{
prefix = "2a09:a443:3:8000::";
prefix-len = 49;
delegated-len = 64;
}];
option-data = [{
name = "dns-servers";
data = "2a09:a443:3::1";
} {
name = "domain-search";
data = "eduroam.as205479.net";
}];
}];
};
};
};
}

View file

@ -0,0 +1,52 @@
# SPDX-FileCopyrightText: 2020 Luke Granger-Brown <depot@lukegb.com>
#
# SPDX-License-Identifier: Apache-2.0
{ depot, lib, pkgs, config, ... }:
let
inherit (depot.ops) secrets;
inherit (lib) mkMerge mkForce;
in {
config = {
services.coredns = {
enable = true;
config = ''
.:53 {
bind 192.168.1.1 92.118.30.17 192.168.10.1 127.0.0.253 2a09:a443::1 2a09:a443:1::1 2a09:a443:2::1 2a09:a443:3::1
acl {
allow net 192.168.0.0/16 172.16.0.0/12 10.0.0.0/8 127.0.0.0/8 100.64.0.0/10 2a09:a443::/32 92.118.30.0/24
block
}
hosts /dev/null {
#216.239.38.120 stadia.google.com stadia.com
fallthrough
}
loadbalance
forward . tls://8.8.8.8 tls://8.8.4.4 {
tls_servername dns.google
}
cache {
success 4096
denial 1024
prefetch 512
}
prometheus :9153
errors
log
}
'';
};
systemd.services.coredns = {
serviceConfig = {
Restart = mkForce "always";
RestartSec = "100ms";
RestartSteps = 10;
RestartMaxDelaySec = "1min";
};
};
my.prometheus.additionalExporterPorts.coredns = 9153;
networking.resolvconf.extraConfig = ''
name_servers='127.0.0.253'
'';
};
}

View file

@ -0,0 +1,85 @@
# SPDX-FileCopyrightText: 2020 Luke Granger-Brown <depot@lukegb.com>
#
# SPDX-License-Identifier: Apache-2.0
{ depot, lib, pkgs, config, ... }:
let
inherit (depot.ops) secrets;
inherit (lib) mkMerge mkForce;
in {
config = {
networking.firewall = {
interfaces.br-internal = {
allowedTCPPorts = [
8080 6789 # Unifi
53 # DNS
];
allowedUDPPorts = [
3478 10001 # Unifi
53 # DNS
69 # TFTP
80 # HTTP
];
};
interfaces.vl-eduroam = {
allowedTCPPorts = [
53 # DNS
];
allowedUDPPorts = [
53 # DNS
];
};
interfaces.en-ee = {
allowedUDPPorts = [
51821
];
};
interfaces.en-gnet = {
allowedUDPPorts = [
51822
];
};
interfaces.wg-rexxar-ee = {
allowedUDPPorts = [
3784 # BFD
];
};
interfaces.wg-rexxar-gnet = {
allowedUDPPorts = [
3784 # BFD
];
};
interfaces.wg-cofractal-ee = {
allowedUDPPorts = [
3784 # BFD
];
};
interfaces.wg-cofractal-gn = {
allowedUDPPorts = [
3784 # BFD
];
};
interfaces.wg-eta = {
allowedTCPPorts = [
179 # BGP
];
};
extraCommands = ''
ip46tables -F FORWARD
ip46tables -N ts-forward || true
ip46tables -A FORWARD -j ts-forward
iptables -A FORWARD -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --set-mss 1360
ip6tables -A FORWARD -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --set-mss 1360
ip46tables -A FORWARD -i vl-eduroam -o wg-rexxar-ee -j ACCEPT
ip46tables -A FORWARD -i vl-eduroam -o wg-rexxar-gnet -j ACCEPT
ip46tables -A FORWARD -i vl-eduroam -o wg-cofractal-ee -j ACCEPT
ip46tables -A FORWARD -i vl-eduroam -o wg-cofractal-gn -j ACCEPT
ip46tables -A FORWARD -i vl-eduroam -o wg-eta -j ACCEPT
ip46tables -A FORWARD -i vl-eduroam -m state --state NEW,RELATED -j REJECT
'';
};
};
}