From 8c8900be57b76e40bedcb4c6c56d4a57d2afd9bf Mon Sep 17 00:00:00 2001 From: Viktor Liu <17948409+lixmal@users.noreply.github.com> Date: Wed, 16 Oct 2024 17:35:59 +0200 Subject: [PATCH] [client] Exclude loopback from NAT (#2747) --- client/firewall/iptables/router_linux.go | 4 +++- client/firewall/nftables/router_linux.go | 15 +++++++++++++++ client/firewall/nftables/router_linux_test.go | 12 ++++++++++++ 3 files changed, 30 insertions(+), 1 deletion(-) diff --git a/client/firewall/iptables/router_linux.go b/client/firewall/iptables/router_linux.go index e60c352d5..129323928 100644 --- a/client/firewall/iptables/router_linux.go +++ b/client/firewall/iptables/router_linux.go @@ -433,10 +433,12 @@ func (r *router) removeNatRule(pair firewall.RouterPair) error { func genRuleSpec(jump string, source, destination netip.Prefix, intf string, inverse bool) []string { intdir := "-i" + lointdir := "-o" if inverse { intdir = "-o" + lointdir = "-i" } - return []string{intdir, intf, "-s", source.String(), "-d", destination.String(), "-j", jump} + return []string{intdir, intf, "!", lointdir, "lo", "-s", source.String(), "-d", destination.String(), "-j", jump} } func genRouteFilteringRuleSpec(params routeFilteringRuleParams) []string { diff --git a/client/firewall/nftables/router_linux.go b/client/firewall/nftables/router_linux.go index 404ba6957..03526fee7 100644 --- a/client/firewall/nftables/router_linux.go +++ b/client/firewall/nftables/router_linux.go @@ -425,11 +425,15 @@ func (r *router) addNatRule(pair firewall.RouterPair) error { destExp := generateCIDRMatcherExpressions(false, pair.Destination) dir := expr.MetaKeyIIFNAME + notDir := expr.MetaKeyOIFNAME if pair.Inverse { dir = expr.MetaKeyOIFNAME + notDir = expr.MetaKeyIIFNAME } + lo := ifname("lo") intf := ifname(r.wgIface.Name()) + exprs := []expr.Any{ &expr.Meta{ Key: dir, @@ -440,6 +444,17 @@ func (r *router) addNatRule(pair firewall.RouterPair) error { Register: 1, Data: intf, }, + + // We need to exclude the loopback interface as this changes the ebpf proxy port + &expr.Meta{ + Key: notDir, + Register: 1, + }, + &expr.Cmp{ + Op: expr.CmpOpNeq, + Register: 1, + Data: lo, + }, } exprs = append(exprs, sourceExp...) diff --git a/client/firewall/nftables/router_linux_test.go b/client/firewall/nftables/router_linux_test.go index 25b7587ac..c07111b4e 100644 --- a/client/firewall/nftables/router_linux_test.go +++ b/client/firewall/nftables/router_linux_test.go @@ -69,6 +69,12 @@ func TestNftablesManager_AddNatRule(t *testing.T) { Register: 1, Data: ifname(ifaceMock.Name()), }, + &expr.Meta{Key: expr.MetaKeyOIFNAME, Register: 1}, + &expr.Cmp{ + Op: expr.CmpOpNeq, + Register: 1, + Data: ifname("lo"), + }, ) natRuleKey := firewall.GenKey(firewall.NatFormat, testCase.InputPair) @@ -97,6 +103,12 @@ func TestNftablesManager_AddNatRule(t *testing.T) { Register: 1, Data: ifname(ifaceMock.Name()), }, + &expr.Meta{Key: expr.MetaKeyIIFNAME, Register: 1}, + &expr.Cmp{ + Op: expr.CmpOpNeq, + Register: 1, + Data: ifname("lo"), + }, ) inNatRuleKey := firewall.GenKey(firewall.NatFormat, firewall.GetInversePair(testCase.InputPair))