iptables: Internal port forwarding with fwmark and routing tables

8,222

Solution 1

I solve this issue with CONNMARK in the B server.

With the use of masquerade it works quickly, but because is a web server, I need the original IP addres and masquerade changes the source IP to the $intif_ip of my A server, so I cannot use masquerade.

Because i am not firewalling with iptables, I discard the FOWRARD chain rule, so I only have the DNAT and SNAT rules in the A server.

iptables -A PREROUTING -t nat -i $extif -p tcp --dport $extif_port -d $extif_ip -j DNAT --to-destination $dst_ip:$dst_port"
iptables -A POSTROUTING -t nat -s $dst_ip -p tcp --sport $dst_port -j SNAT --to-source $extif_ip:$extif_port"

Then in the B server I got the problen because it does not route the packet, I try 1001 ways to force the use of the $intif_ip of server A as gateway, but finnaly I found it!.

The theory is apply a MARK to the packet and his stream goes in the ip of the gateway ruled for a fwmark, but the mar it looses in the routing decission, so I start to use CONNMARK to save this fwmark.

When use CONNMARK it does not work anyway, until y log all chains. Since I read about CONNMARK the examples restores the rules in mangle's POSTROUTING chain, but the first chain that traverse is the mangle's OUTPUT. So, I change CONNMARK to mangle's OUTPUT chain, and works like a charm.

This is the ruleset for server B.

iptables -A PREROUTING -t mangle ! -s $int_net -p tcp -i $int_if --dport $int_port -j MARK --set-mark 1
iptables -A PREROUTING -t mangle -m mark --mark 0x1 -j CONNMARK --save-mark
iptables -A OUTPUT -t mangle -j CONNMARK --restore-mark

And the iproute2 commands (server B)

ip route flush table 1
ip rule add fwmark 1 lookup 1
ip route add default via $intif_ip_serverA table 1
ip route flush cache

hope this helps your tormented minds with this weird issue. have a nice day.

Solution 2

I have seen a few answers with incorrect use of the CONNMARK target. Use the MARK target in the mangle chain and it should work.

Share:
8,222

Related videos on Youtube

Felipe Alcacibar
Author by

Felipe Alcacibar

Updated on September 18, 2022

Comments

  • Felipe Alcacibar
    Felipe Alcacibar almost 2 years

    I have 2 servers and I need to forwart to internal port.

    To explain I use the server with 2 interfaces (internal/external) as server A and the internal server as server B.

    In server A i use

    iptables -A PREROUTING -t nat -i $extif -p tcp --dport $extif_port -j DNAT --to-destination $dst_ip:$dst_port"
    iptables -A FORWARD -t filter -d $dst_ip -j ACCEPT"
    iptables -A POSTROUTING -t nat -p tcp -s $dst_ip --sport $dst_port -j SNAT --to-source $extif_ip"
    

    And in the server B I use a fwmark and routing to the server A using fwmark and iproute2:

    ip rule  $command  fwmark 1 lookup 1
    ip route $command  default via $rt_ip table 1
    

    --

    iptables -A PREROUTING -t mangle -p tcp -i $intif ! -s $intif_net --dport $port -j MARK --set-mark 1
    iptables -A PREROUTING -t mangle -p tcp -i $intif -s $intif_ip --sport $port -j MARK --set-mark 1
    iptables -A POSTROUTING -t mangle -p tcp -o $intif -s $intif_ip --sport $port -j MARK --set-mark 1
    

    Playing with the three rules above in the server B the connections only stuck with SYN_RECV state, and in the log does not sent the ACK in the connection, in some part the packet is loss internally, but i don't know why.

    Any help is welcome, have a nice day.

  • Felipe Alcacibar
    Felipe Alcacibar over 5 years
    yep, in my auto-answer I wrote it