From 56bae7e5ef01e8dc2b65e7f687843e58e473a206 Mon Sep 17 00:00:00 2001 From: Luke Granger-Brown Date: Fri, 28 Jun 2024 08:21:05 +0100 Subject: [PATCH] cofractal-ams01: bring up quadv on ams --- ops/nixos/cofractal-ams01/default.nix | 75 ++++++++++++++++++++++++++- ops/nixos/lib/bgp.nix | 12 +++++ 2 files changed, 86 insertions(+), 1 deletion(-) diff --git a/ops/nixos/cofractal-ams01/default.nix b/ops/nixos/cofractal-ams01/default.nix index 7c4c31b63a..bd4e33a390 100644 --- a/ops/nixos/cofractal-ams01/default.nix +++ b/ops/nixos/cofractal-ams01/default.nix @@ -178,6 +178,36 @@ in 443 # HTTP/3 51821 51822 51823 # wireguard ]; + firewall.extraCommands = '' + # Flush old rules. + ip46tables -D FORWARD -j lukegb-forward 2>/dev/null || true + for chain in lukegb-forward lukegb-fwd-accept lukegb-fwd-reject; do + ip46tables -F "$chain" 2>/dev/null || true + ip46tables -X "$chain" 2>/dev/null || true + done + + ip46tables -N lukegb-fwd-accept + ip46tables -A lukegb-fwd-accept -j ACCEPT + + ip46tables -N lukegb-fwd-reject + ip46tables -A lukegb-fwd-reject -p tcp ! --syn -j REJECT --reject-with tcp-reset + ip46tables -A lukegb-fwd-reject -j REJECT + + ip46tables -N lukegb-forward + + # Accept from "trusted" quadv2 interface + ip46tables -A lukegb-forward -i quadv2 -j lukegb-fwd-accept + + # Accept to quadv2 interface if we're multipathing. + ip46tables -A lukegb-forward -o quadv2 -j lukegb-fwd-accept + + # Accept from established/related connections. + ip46tables -A lukegb-forward -m conntrack --ctstate ESTABLISHED,RELATED -j lukegb-fwd-accept + + # Set up the firewall. + ip46tables -A lukegb-forward -j lukegb-fwd-reject + ip46tables -A FORWARD -j lukegb-forward + ''; }; systemd.network = let wireguard = { name, listenPort, privateKey, publicKey, endpoint ? null }: { @@ -260,6 +290,33 @@ in Address = "2a09:a442:2000::/128"; }]; }; + + netdevs.quadv2 = { + netdevConfig = { + Name = "quadv2"; + Kind = "wireguard"; + }; + + wireguardConfig = { + PrivateKeyFile = pkgs.writeText "cofractal-ams01-quadv" depot.ops.secrets.wireguard.quadv2.lukegb.privateKey; + ListenPort = 51820; + RouteTable = "off"; + }; + + wireguardPeers = [{ + PublicKey = depot.ops.secrets.wireguard.quadv2.quadv.publicKey; + AllowedIPs = "0.0.0.0/0,::/0"; + }]; + }; + networks.quadv2 = { + matchConfig.Name = "quadv2"; + networkConfig.Address = "169.254.112.0/31"; + + routes = [{ + Gateway = "169.254.112.1"; + Destination = "92.118.31.0/24"; + }]; + }; }; my.ip.tailscale = "100.83.36.130"; my.ip.tailscale6 = "fd7a:115c:a1e0:ab12:4843:cd96:6253:2482"; @@ -332,6 +389,22 @@ in }]; }; }; + + peering.quadv = { + local = local // { + v4 = "169.254.112.0"; + }; + remote = { + asn = 197753; + export_community = 4099; + routers = [{ + v4 = "169.254.112.1"; + }]; + prefix_limit.v4 = 10; + prefix_limit.v6 = 10; + set_imported_next_hop_to = "2a09:a446:1337:ffff::10"; + }; + }; }; }; @@ -378,7 +451,7 @@ in security.polkit.enable = true; users.users.lukegb.extraGroups = lib.mkAfter [ "libvirtd" ]; - my.vault.secrets = let + my.vault.secrets = let wireguardSecret = key: { group = "systemd-network"; template = '' diff --git a/ops/nixos/lib/bgp.nix b/ops/nixos/lib/bgp.nix index 123fb55f60..89d7328680 100644 --- a/ops/nixos/lib/bgp.nix +++ b/ops/nixos/lib/bgp.nix @@ -14,10 +14,12 @@ let { if ! (avoid_martians4()) then reject; ${if ix.remote.must_be_next_hop then "if (bgp_path.first != ${toString ix.remote.asn}) then reject;" else "# no next-hop requirement"} + ${if ix.remote.set_imported_next_hop_to != null then "bgp_next_hop = ${ix.remote.set_imported_next_hop_to};" else "# no imported bgp_next_hop override"} ${lib.concatMapStringsSep "\n" (asn: "if (bgp_path ~ [= * ${toString asn} * =]) then reject;") ix.remote.drop_asns} ${lib.optionalString (ixName == "quadv") '' bgp_ext_community.add((ro, 205479, 1000)); bgp_ext_community.add((ro, 205479, 4000)); # etheroute + bgp_ext_community.add((ro, 205479, 6000)); # cofractal-ams01 #bgp_ext_community.add((ro, 205479, 4002)); # gsl # Etheroute communities @@ -75,6 +77,7 @@ let enabledSnippet = { enabled ? true, ... }: "disabled ${if enabled then "off" else "on"};"; passwordSnippet = { password ? null, ... }: if password == null then "# no password" else "password \"${password}\";"; multihopSnippet = { multihop ? null, ... }: if multihop == null then "# not multihop" else "multihop ${toString multihop};"; + nexthopSnippet = { next_hop ? null, ... }: if next_hop == null then "# no next hop override" else "next hop ${toString next_hop};"; passiveSnippet = { passive, ... }: "passive ${if passive then "on" else "off"};"; prefixLimitSnippet = limit: if limit == null then "# no import limit" else "import limit ${toString limit} action restart;"; generateSnippetForRouter = { ixName, ix, routerNum, router, ... }: '' @@ -83,6 +86,7 @@ let ${enabledSnippet router} ${passwordSnippet router} ${multihopSnippet router} + ${nexthopSnippet router} ${passiveSnippet ix.remote} local ${ix.local.v4} as ${toString ix.local.asn}; neighbor ${router.v4} as ${toString ix.remote.asn}; @@ -201,6 +205,10 @@ in { type = bool; default = true; }; + set_imported_next_hop_to = mkOption { # lukegbgp.config.peering..remote.set_imported_next_hop_to + type = nullOr str; + default = null; + }; drop_asns = mkOption { # lukegbgp.config.peering..remote.drop_asns type = listOf int; default = []; @@ -234,6 +242,10 @@ in { type = nullOr str; default = null; }; + next_hop = mkOption { # lukegbgp.config.peering..remote.routers..next_hop + type = nullOr str; + default = null; + }; }; }); };