LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Linux - Networking (https://www.linuxquestions.org/questions/linux-networking-3/)
-   -   Need help implementing Port Address Translation with iptables (https://www.linuxquestions.org/questions/linux-networking-3/need-help-implementing-port-address-translation-with-iptables-786738/)

Ashmatash 02-03-2010 12:55 PM

Need help implementing Port Address Translation with iptables
 
My previous routing experience has been mostly with Cisco routers. Cisco's NAT overloading translates both sides of the connection with a single command.
If you specify that the incoming connection be translated to a different port, IOS automatically translates both sides of the connection. Sure, there are some firewall adjustments too, but as far as the NAT goes, that's all that was needed.

My current reality:

I have a client running multiple Windows machines behind a Linux router. We would like to be able to connect to RDP (port 3389) from the internet, but though a different incoming port, say, 10110.

These are the commands I'm was trying to use in my firewall.user script:
#
#
iptables --table nat --append prerouting_wan --protocol TCP --in-interface $WAN --dport 44344 --jump DNAT --to-destination [MyPrivateIP]:3389
#
iptables --append forwarding_wan --protocol TCP --destination [MyPrivateIP] --dport 3389 --jump ACCEPT
#
#

Not surprisingly, these aren't doing the job.

The problem seems to be a matter of connection tracking.

I need to figure out how to implement a one-to-one port mapping for both incoming and outgoing traffic, but to have the port re-mapping take effect only when a matching inbound connection originates on the WAN interface.

Implementing two rules, one changing the inbound traffic and one for outbound might work, but that method would be static and too restrictive. After all, the internal hosts may need to communicate on that port without the modifications to the destination port.


Please advise :)

win32sux 02-03-2010 08:52 PM

If I'm underatanding your requirements correctly, this could be done like (example):
Code:

iptables -t nat -A PREROUTING -p TCP -i $WAN_IFACE --dport 10110 -j DNAT \
--to-destination 192.168.1.101:3389
iptables -P FORWARD DROP
iptables -A FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT
iptables -A FORWARD -p TCP -i $WAN_IFACE -o $LAN_IFACE -d 192.168.1.101 --dport 3389 \
--m state --state NEW -j ACCEPT

Here, the packet arrives on the WAN interface with the primary address as destination IP and 10110 as the destination port. Linux then changes the destination address on the packet to 192.168.1.101 and the destination port to 3389. The packet then traverses the FORWARD chain and is sent to ACCEPT (so that it may be placed on the wire connected to $LAN_IFACE) if it matches the relevant rule (otherwise it'll be sent to DROP in my example).

As for the returning (source port 3389) and forthcoming packets, they will get picked up by the connection tracking mechanism, and the first rule's ESTABLISHED state should match them just fine. Notice that the only rule which affects outbound traffic is the one for packets in states RELATED and ESTABLISHED.

Ashmatash 02-04-2010 12:39 AM

Wow, thanks! That sounds like a winner.
I'll try it out and see how it goes.
I really appreciate help.

Ashmatash 02-04-2010 06:15 PM

win32sux, you the man!
You solution worked almost right out of the box.

I had to tweak it a little for OpenWRT, but is was so spot on that it worked despite myself. I'm still not completely sure about what's happening, but I think I'm getting there.
After trying to get help with this on the OpenWRT forums all week without a single response,I REALLY appreciate the quick reply, not to mention the excellent solution.

Here's the whole thing for posterity's sake, and any other newbies like myself running OpenWRT specifically.

# Some global firewall settings...
iptables -P FORWARD DROP
iptables -A FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT

# Some fiddling with the destination port...
iptables -t nat -A prerouting_wan -p TCP -i eth0.1 -dport 10110 -j DNAT --to-destination 192.168.0.101:3389

# A little forwarding rule for the connection...
iptables -A forwarding_wan -p TCP -i eth0.1 -o br-lan -d 192.168.0.101 --dport 3389 -m state --state NEW -j ACCEPT


Cheers.

win32sux 02-04-2010 10:11 PM

Quote:

Originally Posted by Ashmatash (Post 3853177)
win32sux, you the man!
You solution worked almost right out of the box.

I had to tweak it a little for OpenWRT, but is was so spot on that it worked despite myself. I'm still not completely sure about what's happening, but I think I'm getting there.
After trying to get help with this on the OpenWRT forums all week without a single response,I REALLY appreciate the quick reply, not to mention the excellent solution.

Here's the whole thing for posterity's sake, and any other newbies like myself running OpenWRT specifically.

# Some global firewall settings...
iptables -P FORWARD DROP
iptables -A FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT

# Some fiddling with the destination port...
iptables -t nat -A prerouting_wan -p TCP -i eth0.1 -dport 10110 -j DNAT --to-destination 192.168.0.101:3389

# A little forwarding rule for the connection...
iptables -A forwarding_wan -p TCP -i eth0.1 -o br-lan -d 192.168.0.101 --dport 3389 -m state --state NEW -j ACCEPT


Cheers.

I'm glad it worked out well for you. :)

BTW, many thanks for taking the time to post the final product here.


All times are GMT -5. The time now is 11:08 AM.