How to set mark on packet when forwarding it in nat prerouting table?

21,884

It is not possible to get this done with only one command per DNAT – unless... see below. But it is possible to enter the data just once.

Let's define the mark range 1024–2047 for connections which get DNATted and forwarded.

One line with each DNAT match condition in mangle:

iptables -t mangle -A PREROUTING -p tcp --dport 46000 -j MARK --set-mark 0x400
iptables -t mangle -A PREROUTING -p tcp --dport 46001 -j MARK --set-mark 0x401
iptables -t mangle -A PREROUTING -p tcp --dport 46002 -j MARK --set-mark 0x402

One command for each in nat:

iptables -t nat -A PREROUTING -m mark --mark 0x400 -j DNAT \
  --to-destination 172.16.8.2:46000
iptables -t nat -A PREROUTING -m mark --mark 0x401 -j DNAT \
  --to-destination 172.16.8.2:46001
iptables -t nat -A PREROUTING -m mark --mark 0x402 -j DNAT \
  --to-destination 172.16.8.2:46002

One command for all in filter:

iptables -A FORWARD -m mark --mark 0x400/0x400 -j ACCEPT

BTW: There is no need to give the destination port for -j DNAT if it is not changed.

Edit 1:

You can do that if you do without allowing the connections explicitly, if you are fine with allowing everything that has been DNATted. In that case you would stick to your

iptables -t nat -A PREROUTING -p tcp --dport 46000 -j DNAT --to-destination 172.16.8.2:46000

but have only one FORWARD rule for all:

iptables -A FORWARD -m conntrack --ctstate DNAT -j ACCEPT
Share:
21,884
Poma
Author by

Poma

MSU student

Updated on September 18, 2022

Comments

  • Poma
    Poma over 1 year

    I have a few port forward rules like this

    iptables -t nat -A PREROUTING -p tcp --dport 46000 -j DNAT --to-destination 172.16.8.2:46000
    iptables -A FORWARD -p tcp -d 172.16.8.2 --dport 46000 -j ACCEPT
    

    I wonder if there is a way to add new forward rules in one line instead of two so I don't have to enter the same data twice. I mean rules like this:

    1. In nat PREROUTING forward packet to destination and mark it
    2. In filter FORWARD allow all packets that were marked using rule 1

    Is it possible?

  • Poma
    Poma almost 11 years
    That's still 2 commands for each port, one in mangle and one in nat
  • Hauke Laging
    Hauke Laging almost 11 years
    @Poma See the edit: There is a one command solution which is not equivalent but similar to your original rule set.
  • Poma
    Poma almost 11 years
    yes that's just what I need
  • cold_coder
    cold_coder over 7 years
    How to set mark by the hostname?
  • kato2
    kato2 almost 3 years
    Could I do the same with UDP? I'm trying a similar solution but the packets do not arrive to the nat table.
  • Hauke Laging
    Hauke Laging almost 3 years
    @kato2 UDP packets certainly go through the nat table. Maybe you used PREROUTING where you would have needed OUTPUT.
  • kato2
    kato2 almost 3 years
    @HaukeLaging you might be right, however adding this rule after the current ones, solved the issue iptables -t mangle -A PREROUTING -p udp --dport 46000 -j CONNMARK --save-mark