nftables DNAT routes to wrong iface
Marc SCHAEFER <[email protected]>
| Newsgroups | gmane.comp.security.firewalls.netfilter.general |
|---|---|
| Message-ID | <[email protected]> |
Hello,
I am trying to do this:
Both local IP addresses, when access from outside:
enp2s0.310: 193.72.186.130:8080
br0: 46.140.72.218:8080
are DNATed to
enp2s0.202: 192.168.202.10:80 (a remote machine)
I know there are two steps:
- the incoming DNAT in prerouting (and the forward accept)
-> this part I am stuck, see below
- then when the reply comes back, route to the proper interface where
it came from (using conntrack + marks + specific routing tables)
-> this part I have not done yet -- it would be required for
193.72.186.130:8080 obviously because the default route
does not go there.
What I observe:
telnet 46.140.72.218 8080 from outside works (*), it connects to 192.168.202.10:80
and there is nothing bizarre in tcpdump either on br0 nor on
enp2s0.202 (no delays, lost packets, e.g.) (**)
telnet 193.72.186.130 8080 gives this on enp2s0.300
IP 193.72.186.190.52636 > 193.72.186.130.8080 (normal)
IP 193.72.186.190.52636 > 192.168.202.10.80 (good, it was DNATted, BUT should be on enp2s0.202!)
aka the DNAT is executed, but then 192.168.202.10 is not routed
correctly. From the diagram https://wiki.nftables.org/wiki-nftables/index.php/Netfilter_hooks
I thought that routing would be done AFTER prerouting/DNAT.
The routing table has:
default via 46.140.72.217 dev br0 onlink
46.140.72.216/29 dev br0 proto kernel scope link src 46.140.72.218
192.168.202.0/24 dev enp2s0.202 proto kernel scope link src 192.168.202.2
193.72.186.128/26 dev enp2s0.300 proto kernel scope link src 193.72.186.130
(*) not from 193.72.186.0/24, however, gets the same bug.
The nftables config:
table ip filter {
# obviously a later goal is also to encode the L4 protocol here
# and not hardcode it in the prerouting
map multihoming_ext {
type ipv4_addr . inet_service : ipv4_addr . inet_service
elements = { 193.72.186.130 . 8080 : 192.168.202.10 . 80,
46.140.72.218 . 8080 : 192.168.202.10 . 80 }
}
set w_all {
type ipv4_addr
flags interval
elements = { 46.140.72.216/29,
192.168.202.1, 193.72.186.0/24
}
}
chain input {
type filter hook input priority filter; policy drop;
ct state invalid counter packets 3 bytes 120 drop
ct state { established, related } counter packets 1092 bytes 76846 accept
iif "lo" counter packets 0 bytes 0 accept
counter packets 324 bytes 13539 jump whitelist
counter packets 323 bytes 13455 jump blacknets
counter packets 323 bytes 13455 jump blacklist
counter packets 323 bytes 13455 jump incoming
}
chain forward {
type filter hook forward priority filter; policy drop;
ct state invalid counter packets 0 bytes 0 drop
ct state { established, related } counter packets 12 bytes 548 accept
# already after DNAT, obviously
iifname "br0" ip daddr 192.168.202.10 tcp dport 80 accept
iifname "enp2s0.300" ip daddr 192.168.202.10 tcp dport 80 accept
}
chain output {
type filter hook output priority filter; policy accept;
ct state invalid counter packets 0 bytes 0 drop
ct state { established, related } counter packets 890 bytes 182096 accept
oif "lo" counter packets 0 bytes 0 accept
counter packets 1 bytes 76 jump outgoing
}
chain rejectcounter {
meta l4proto tcp counter packets 0 bytes 0 reject with tcp reset
meta l4proto udp counter packets 0 bytes 0 reject
counter packets 0 bytes 0 drop
}
chain dropcounter {
counter packets 320 bytes 13349 drop
}
chain whitelist {
ip saddr @w_all counter packets 1 bytes 84 accept
}
chain blacknets {
}
chain blacklist {
}
chain incoming {
icmp type echo-request counter packets 3 bytes 106 accept
icmp type echo-reply counter packets 0 bytes 0 accept
tcp dport 22 ip saddr { 46.140.72.216/29, 192.168.202.1, 193.72.186.0/24 } counter packets 0 bytes 0 jump dropcounter
udp dport 22 ip saddr { 46.140.72.216/29, 192.168.202.1, 193.72.186.0/24 } counter packets 0 bytes 0 jump dropcounter
counter packets 320 bytes 13349 jump dropcounter
}
chain outgoing {
}
chain multihoming_prerouting {
type nat hook prerouting priority dstnat; policy accept;
# this is the DNAT
dnat ip to ip daddr . tcp dport map @multihoming_ext
}
}
table ip myhelpers {
chain prerouting {
type filter hook prerouting priority filter; policy accept;
}
}
[ I removed ip6 entries ]
Any idea what could be wrong?
Thank you.
(**) very nice:
br0:
IP 46.140.72.222.60394 > 46.140.72.218.8080
IP 46.140.72.218.8080 > 46.140.72.222.60394
IP 46.140.72.222.60394 > 46.140.72.218.8080
enp2s0.202 (another connection):
IP 46.140.72.222.57790 > 192.168.202.10.80
IP 192.168.202.10.80 > 46.140.72.222.57790
IP 46.140.72.222.57790 > 192.168.202.10.80