I'm trying to redirect all traffic arriving on the firewall on ports 80 and 443 to

I gather from this that NATting in an input chain should be possible. But it seems that dnat is not. What kind of NATting is possible?

The reason I am trying to do this using the input chain is because, if I put it in the prerouting chain, all traffic is dnatted, not only traffic destined for the firewall.

This is my attempt so far:

table inet nat already exists.

# nft 'add chain inet nat input { type nat hook input priority -100; }'

# nft 'add rule inet nat input tcp dport { 80, 443 } dnat ip to'
Error: Could not process rule: Operation not supported
add rule inet nat input tcp dport { 80, 443 } dnat ip to

  • Can you add a description of the topology of the network? You say that you can't use PREROUTING is because "all traffic is dnatted, not just traffic destined for the firewall". Does this mean that your "firewall" is acting as a router for most traffic, and you just want to intercept traffic to the "outside" address of the firewall on ports 80 and 443? Would a simple program like 'netcat' set up to listen on port 80 and connecting to port 80 and a second one on port 443 work? It is obviously less efficient that routing, but I am trying to understand the use case.
    – icarus
    Jan 9 at 21:16

1 Answer 1


You are trying to redirect packets arriving to a local port to a non-local destination. To succeed, that redirection would need to be done before a routing decision is made, i.e. in a PREROUTING chain.

The packets in the INPUT chain are already on the way to be delivered to some local process, so while changing the port number should be unrestricted, changing the destination IP address might be impossible or restricted to only addresses that are in use on the local host.

You could do something like

nft 'add chain inet nat prerouting { type nat hook prerouting priority -100; };'
nft 'add rule inet nat prerouting ip daddr <firewall's own IP here> tcp dport { 80, 443 } dnat ip to'

Because your DNAT affects the routing decision (to local vs. non-local), it must be done in the prerouting hook.

Yes, you can match on the original destination address before you change it in your prerouting chain. Further chains will then see the packet with the changed destination IP address, so you must take care that e.g. your forward rules will allow it.

And yes, you can require the packet to match to more than one thing (e.g. destination address and destination port) in the same rule.

  • I added some more information as to why I can't use prerouting.
    – Philippe
    Jan 9 at 17:46
  • Is there a way to do this if the IP of the firewall is dynamic?
    – Philippe
    Sep 30 at 15:42
  • Use connection tracking, and think carefully about rule ordering: first make a rule in the prerouting hook that will accept any pre-existing traffic without NATting them. If the connection tracking rule does not match to a packet incoming to port 80 or 443, it must be a new incoming connection to the firewall, which should be DNATted. Remember that the rule processing for a packet on each table ends on the first matching rule with a terminal statement, like accept, drop or dnat.
    – telcoM
    Sep 30 at 21:38

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .