From 75466ae4e895de6c55664e2c76ef8ae81d33bb28 Mon Sep 17 00:00:00 2001 From: Johnathan Corgan Date: Thu, 26 Mar 2026 16:31:05 +0000 Subject: [PATCH] Add ip6 routing policy rule to protect fd00::/8 from interception Tailscale (and potentially other routing software) installs a default IPv6 route in an auxiliary routing table with a policy rule that runs before the main table. This silently diverts fd00::/8 FIPS traffic away from the fips0 TUN device. Add an ip6 rule (priority 5265) during TUN setup that directs fd00::/8 to the main routing table, ensuring the fips0 route is always used. --- src/upper/tun.rs | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/upper/tun.rs b/src/upper/tun.rs index 34128db..8e2e55c 100644 --- a/src/upper/tun.rs +++ b/src/upper/tun.rs @@ -467,6 +467,15 @@ async fn configure_interface(name: &str, addr: Ipv6Addr, mtu: u16) -> Result<(), .await .map_err(|e| TunError::Configure(format!("failed to add fd00::/8 route: {}", e)))?; + // Add ip6 rule to ensure fd00::/8 uses the main table, preventing other + // routing software (e.g. Tailscale) from intercepting FIPS traffic via + // catch-all rules in auxiliary routing tables. + let mut rule_req = handle.rule().add().v6().destination_prefix(fd_prefix, 8).table_id(254).priority(5265); + rule_req.message_mut().header.action = 1.into(); // FR_ACT_TO_TBL + if let Err(e) = rule_req.execute().await { + debug!("ip6 rule for fd00::/8 not added (may already exist): {e}"); + } + Ok(()) }