heather: fix BGP default precedence, YC fallback and WAN BGP exposure

This commit is contained in:
heather 2026-09-27 00:09:28 +00:00
commit 8223868774

View file

@ -55,6 +55,11 @@ let
}];
};
in {
# DHCP keeps the WAN address/DNS but not a competing kernel default route.
# FRR otherwise prefers the existing kernel route over the BGP default;
# WAN failback is provided by policy table 100 below.
networking.dhcpcd.extraConfig = "nogateway";
networking.wireguard.interfaces = {
# The fe80:: link-locals are required: without one FRR's IPv6 BGP
# next-hop selection fails and the v6 session never leaves Connect.
@ -92,6 +97,8 @@ in {
type filter hook input priority -150; policy accept;
# Full inbound access from AstrNet to Heather, IPv4 and IPv6.
iifname { "wg-mic-der", "wg-mic-bd8" } accept
# bgpd listens on 0.0.0.0 and ::; never expose BGP on public WAN.
iifname "enp7s0" tcp dport 179 drop
}
chain forward {
type filter hook forward priority -150; policy accept;
@ -131,6 +138,7 @@ in {
requiredBy = [ "frr.service" ];
path = [ pkgs.iproute2 ];
serviceConfig = { Type = "oneshot"; RemainAfterExit = true; };
unitConfig.OnFailure = "astrnet-wan-recovery.service";
script = ''
ip route replace default via ${wanGw4} dev ${wanIf} table ${wanTable}
'' + lib.optionalString (wanGw6 != "") ''
@ -149,8 +157,21 @@ in {
'' + lib.concatMapStrings (r: ''
ip ${r.fam} rule del ${r.sel} lookup ${wanTable} priority 1000 2>/dev/null || true
ip ${r.fam} rule add ${r.sel} lookup ${wanTable} priority 1000
'') wanRules;
'') wanRules + ''
# Main BGP default wins; WAN table 100 is used if BGP withdraws it.
ip -4 rule del lookup main priority 2000 2>/dev/null || true
ip -4 rule add lookup main priority 2000
ip -4 rule del lookup ${wanTable} priority 2001 2>/dev/null || true
ip -4 rule add lookup ${wanTable} priority 2001
# A kernel default in main outranks BGP in FRR itself, regardless of
# Linux route metric. Remove it only AFTER the fallback rule is live.
ip -4 route del default via ${wanGw4} dev ${wanIf} 2>/dev/null || true
'';
preStop = ''
# On rollback restore the plain WAN path first.
ip -4 route replace default via ${wanGw4} dev ${wanIf} metric 1002 || true
ip -4 rule del lookup main priority 2000 || true
ip -4 rule del lookup ${wanTable} priority 2001 || true
ip -4 rule del to 169.254.169.254 lookup ${wanTable} priority 998 || true
ip -4 rule del lookup main suppress_prefixlength 0 priority 999 || true
ip -6 rule del lookup main suppress_prefixlength 0 priority 999 || true
@ -159,6 +180,14 @@ in {
'') wanRules;
};
# If policy setup fails, leave a normal WAN default rather than a stranded host.
systemd.services.astrnet-wan-recovery = {
description = "Restore YC WAN route if AstrNet policy fails";
path = [ pkgs.iproute2 ];
serviceConfig.Type = "oneshot";
script = "ip -4 route replace default via ${wanGw4} dev ${wanIf} metric 1002";
};
# BGP only inside the tunnels, never on the public interface.
networking.firewall.interfaces."wg-mic-bd8".allowedTCPPorts = [ 179 ];
networking.firewall.interfaces."wg-mic-der".allowedTCPPorts = [ 179 ];