diff --git a/machines/shinobu/services/router/default.nix b/machines/shinobu/services/router/default.nix index 8710a6a..aa44a79 100644 --- a/machines/shinobu/services/router/default.nix +++ b/machines/shinobu/services/router/default.nix @@ -110,6 +110,19 @@ in UseDNS = "no"; UseGateway = false; # should not be used by default for routing (wg-he takes precendence) }; + routingPolicyRules = lib.singleton { + routingPolicyRuleConfig = { + Family = "ipv6"; + FirewallMark = 31092; # 0x7974 + Table = 31092; # 0x7974 + }; + }; + routes = lib.singleton { + routeConfig = { + Gateway = "_ipv6ra"; + Table = 31092; # 0x7974 + }; + }; }; physical-lan = { name = "enp2s0"; diff --git a/machines/shinobu/services/router/dnsmasq.nix b/machines/shinobu/services/router/dnsmasq.nix index 7b3e432..a447154 100644 --- a/machines/shinobu/services/router/dnsmasq.nix +++ b/machines/shinobu/services/router/dnsmasq.nix @@ -5,6 +5,11 @@ { config, lib, pkgs, ... }: let cfg = pkgs.callPackage ./common.nix { }; + + bypassHe = [ + "googlevideo.com" + "youtube.com" + ]; in { services.dnsmasq = { @@ -51,6 +56,10 @@ in ]) cfg.vlan); + nftset = [ + "/${lib.concatStringsSep "/" bypassHe}/6#ip6#he-bypass#addresses" + ]; + server = [ "127.0.0.1#5053" ]; diff --git a/machines/shinobu/services/router/rules.nft b/machines/shinobu/services/router/rules.nft index 05cdaed..9acc1b3 100644 --- a/machines/shinobu/services/router/rules.nft +++ b/machines/shinobu/services/router/rules.nft @@ -41,6 +41,42 @@ table ip nat { } } +# Bypass HE tunnel by setting a firewall mark. +# This acts in two places that are handled separatly by nftables: +# Packets from the local host (output hook) and forwared packets (prerouting hook). +# To simplify the handling, +# there is a single chain that handles both, +# which is jumped to from the specific chains. +# Additionally, masquerading is allowed for all packages with a destination of the dynamic set. +table ip6 he-bypass { + # Dynamically managed by dnsmasq (based on resolved addresses). + set addresses { + type ipv6_addr + comment "IPv6 addresses for which the HE tunnel should be bypassed by using NAT on wan instead" + } + + # This must be of type route, otherwise no route lookup will be performed + chain output { + type route hook output priority mangle + jump common + } + + # This does not need to be of type route + chain prerouting { + type filter hook prerouting priority mangle + jump common + } + + chain common { + ip6 daddr @addresses mark set 0x7974 counter + } + + chain postrouting { + type nat hook postrouting priority filter; policy accept + oifname $NAT_WAN_IFACES ip6 daddr @addresses masquerade + } +} + table ip6 public-access { chain input { type filter hook input priority filter; policy accept