From: "Tobias Jakobi (Compleo)" <tobias.jakobi.compleo@gmail.com>
To: netfilter@vger.kernel.org
Subject: Using NAT engine information to apply fwmark to packet
Date: Tue, 28 May 2024 11:41:15 +0200 [thread overview]
Message-ID: <f0c38ac0-5445-491b-9706-c1a129d77acd@gmail.com> (raw)
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
reply other threads:[~2024-05-28 9:41 UTC|newest]
Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=f0c38ac0-5445-491b-9706-c1a129d77acd@gmail.com \
--to=tobias.jakobi.compleo@gmail.com \
--cc=netfilter@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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).