netfilter.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* Using NAT engine information to apply fwmark to packet
@ 2024-05-28  9:41 Tobias Jakobi (Compleo)
  0 siblings, 0 replies; only message in thread
From: Tobias Jakobi (Compleo) @ 2024-05-28  9:41 UTC (permalink / raw)
  To: netfilter

Hello everyone,

looking for some pointers concerning this problem. So what I'm trying to 
achieve is to base the routing decision of a packet on the question "Was 
this packet handled by the NAT engine?".

I'm using systemd-networkd to setup NAT / masquerading on the system, 
which basically means that networkd enables forwarding for the correct 
interfaces and adds a nftables table.

Which looks like this:
table ip io.systemd.nat {
     set masq_saddr {
         type ipv4_addr
         flags interval
         elements = { 192.168.15.0/24 }
     }

     map map_port_ipport {
         type inet_proto . inet_service : ipv4_addr . inet_service
     }

     chain prerouting {
         type nat hook prerouting priority dstnat + 1; policy accept;
         fib daddr type local dnat ip to meta l4proto . th dport map 
@map_port_ipport
     }

     chain output {
         type nat hook output priority -99; policy accept;
         ip daddr != 127.0.0.0/8 oif "lo" dnat ip to meta l4proto . th 
dport map @map_port_ipport
     }

     chain postrouting {
         type nat hook postrouting priority srcnat + 1; policy accept;
         ip saddr @masq_saddr masquerade
     }
}

My naive approach was to add another table, which looks like this:
table ip nat.test {
     chain prerouting {
         type nat hook prerouting priority dstnat + 2; policy accept;
         meta mark set 0x00000007
     }
}

I can then use the fwmark 0x7 in my routing policy rule to select an 
appropriate routing table.

However this does not work properly.

When I issue a simple ping to 8.8.8.8 from my NAT client (which has the 
192.168.15.2), then I see that the ICMP packet pops up on the gateway 
(the 192.168.15.1), is then masqueraded and tagged with the fwmark, 
before eventually being send to the Google DNS, where it is answered.

So this direction "NAT client -> outside world" seems to be working. 
What is not working is the when the Google DNS replies and then whole 
masquerading stuff is done in reverse. In this case I don't see any 
fwmark being added, and hence the routing policy rule does not apply.

Looking at the netfilter flowchart 
(https://wiki.nftables.org/wiki-nftables/index.php/Netfilter_hooks) I 
get the impression that applying rules with priority dstnat + 2 is 
probably too late when the NAT engine detects that a packet belongs to a 
connection that it is tracking.

So I guess my question is: I this whole thing even possible, and if yes, 
how do I extract the required information from the NAT engine?

I'm currently looking into netfilter's connmark functionality, as the 
NAT engine is basically conntrack?! (is it really?) And it seems to 
allow to transfer connection marks with packet marks, which I probably 
need here.

Thanks in advance!

With best wishes,
Tobias


^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2024-05-28  9:41 UTC | newest]

Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-05-28  9:41 Using NAT engine information to apply fwmark to packet Tobias Jakobi (Compleo)

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).