iptables: Internal port forwarding with fwmark and routing tables
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.
Related videos on Youtube
Felipe Alcacibar
Updated on September 18, 2022Comments
-
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 over 5 yearsyep, in my auto-answer I wrote it