iptables does not block forwarding to another IP of the host itself

iptables does not block forwarding to another IP of the host itself

I have host used as gateway with

net.ipv4.conf.all.rp_filter=0

and iptables rpfilter that is used instead

iptables -t raw -A PREROUTING -m rpfilter --invert -j LOG-DROP-RP

My host have 2 interfaces eth1 with IP 10.0.0.1/8 and eth2 with IP 192.168.0.1/16. If some host with IP 192.168.0.2 on eth1 send packet it's dropped and logged. Forwarding table also block forwarding between eth1 and eth2. Packet from 10.0.0.2 on eth1 to 192.168.0.2 on eth2 blocked and logged by forwarding rules.

But if host with IP 10.0.0.2 on eth1 send packet to 192.168.0.1 it will pass. rpfilter just ignores it. Forwarding table seems to be ignored as well.

How do I prevent it? Because there may be some private interface eth3 on this host with private service listening on it and it can be accessed from anywhere which is unwanted.

答案1

Linux uses the weak host model: any IP address assigned to any interface belongs to the host as a whole. When you reach from 10.0.0.2 to 192.168.0.1 there's no forwarding involved because the destination address belongs to the host: the packet gets handled by filter/INPUT, not by filter/FORWARD (which thus won't be evaluated for this packet). A detailed schematic of the packet's trip can be found there.

This is not a routing anomaly, so this won't trigger Strict Reverse Path Forwarding, be it set in the routing stack or in iptables's rpfilter module.

So you have to also add explicit rules for this with IP addresses. If still wishing to put this in the raw table, the addrtype match works even there to figure out if the destination is local (or also broadcast). You can add after the SRPF test these rules (which would work if multiple IP addresses were assigned to the host rather than just the .1 ones):

iptables -t raw -A PREROUTING -s 10.0.0.0/8 ! -d 10.0.0.0/8 -m addrtype --dst-type LOCAL,BROADCAST -j DROP
iptables -t raw -A PREROUTING -s 192.168.0.0/16 ! -d 192.168.0.0/16 -m addrtype --dst-type LOCAL,BROADCAST -j DROP

I wouldn't know with iptables how to add generic rules that will not include details related to the specific addresses in use. It's possible with nftables:

# drop packets to address not configured on incoming interface
filter prerouting fib daddr . iif type != { local, broadcast, multicast } drop

相关内容