5

I'd like to do an iptables REDIRECT rule in the NAT PREROUTING chain, to redirect connections to port 80 to go to 8080. But I'd like to only do it for input packets (destined for this machine), not forwarded packets (destined for e.g. the Internet).

Is there a way, in rules in the PREROUTING chain, to distinguish packets that are destined for this machine, versus packets that are being forwarded, and handle them differently?

It would be ideal to do this in a way that doesn't require specific interfaces or IP addresses to be enumerated in the rules, because this is less flexible (e.g. if interfaces or IP addresses change, it's more complicated to then need to update iptables rules).

I would also be interested in an equivalent functionality using nftables.

Craig McQueen
  • 780
  • 7
  • 20

2 Answers2

4

I think you're doomed to having to manually list all your "local" IP addresses. Based on my reading of this netfilter packet flow diagram, there's no differentiation of input/forward packets until after all the PREROUTING chains -- which makes sense, because the chain is, after all, called PREROUTING...

womble
  • 96,255
  • 29
  • 175
  • 230
  • That makes sense, since it's `PREROUTING`. I have to use the `PREROUTING` chain since my goal is to possibly change the routing, however I want to do it in a routing-dependent way. In that case, it would be great if there was a rule that could do a kind of look-forward to the currently-expected routing destination, which would make a call to the existing kernel logic for that routing test. Manually listing local IP addresses is a pain because (1) it's a duplication of effort; and (2) IP addresses may be dynamic as network interfaces are added and removed, DHCP etc. – Craig McQueen Oct 19 '15 at 06:03
3

I just came across the addrtype module, which seems to be able to differentiate incoming packets depending on whether the destination address is a local address or not. So this can be used to distinguish between input and forward packets.

E.g. something like:

iptables -A PREROUTING -t nat -p tcp --dport 80 -m addrtype --dst-type LOCAL -j REDIRECT --to-port 8080

For nftables, the equivalent appears to be the fib module. But I haven't tested this yet.

nft add rule ip nat prerouting tcp dport 80 fib daddr . iif type local redirect to :8080
Craig McQueen
  • 780
  • 7
  • 20
  • 1
    The nftables rule sounds fine. The fib module queries the routing stack to know what should happen "in the future". This even allows to know the *output* interface of a routed/forwarded packet in advance during the prerouting phase, at the cost of one extra route lookup. – A.B Mar 14 '23 at 07:56