Take the 2-minute tour ×
Server Fault is a question and answer site for system and network administrators. It's 100% free, no registration required.

I have a setup where I have a CentOS server that is acting as an internet gateway. This machine performs the NAT between our main switch and our internet connection. I'm also hosting a virtual machine on this server which can be accessed using remote desktop on port 3389.

What I want to do is set up iptables so that port 10101 is forwarded from the wan side to 3389 on the lan side. I want people on the outside to ONLY be able to see port 10101 and have that redirected to port 3389 on the pc's local IP address.

In my setup I have a local adapter called lan0 (192.168.1.15) and another adapter called wan0 which gets our public IP address assigned to it. So I want it to look like this:

wan0 xxx.xxx.xxx.xxx:10101 -> lan0 192.168.1.15:3389

I've tried several things and I just can't seem to get it right. It seems like the difference between what I'm doing and most of the examples online is that most of the examples involve a gateway which forwards the traffic to a different pc whereas mine is still on the same system.

Update:

To make things clearer, here is my entire iptables config file including cjc's suggestion. I have included comments about the lines according to my understanding. I understand VERY little about iptables so please correct me if I'm wrong about ANYTHING.

# Generated by iptables-save v1.3.5 on Fri Jul  8 12:41:58 2011
*nat
:PREROUTING ACCEPT [0:0]
:POSTROUTING ACCEPT [0:0]
:OUTPUT ACCEPT [5:316]
# route all requests for web traffic through squid on port 3128
-A PREROUTING -i lan0 -p tcp -m tcp --dport 80 -j DNAT --to-destination 192.168.1.15:3128

# forward outside requests from 10101 to 3389 per cjc
-A PREROUTING -i wan0 -p tcp --dport 10101 -j DNAT --to 192.168.1.15:3389

# needed for transparent squid proxy
-A POSTROUTING -j MASQUERADE

COMMIT
# Completed on Fri Jul  8 12:41:58 2011
# Generated by iptables-save v1.3.5 on Fri Jul  8 12:41:58 2011
*filter
:INPUT ACCEPT [89:5788]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [1046:126223]
:RH-Firewall-1-INPUT - [0:0]
# accept all traffic from loopback
-A INPUT -i lo -j ACCEPT

# accept traffic destined to this machine regarding as part of existing connections
-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT

# accept traffic destined to this machine from our local network
-A INPUT -s 192.168.1.0/24 -j ACCEPT

# accept traffic destined to this machine from the wan on port 10101 per cjc
-A INPUT -i wan0 -p tcp --dport 10101 -j ACCEPT

# reject all other wan traffic
-A INPUT -i wan0 -j REJECT --reject-with icmp-port-unreachable

# drop ping requests from the outside (is this needed and in the right order?)
-A INPUT -i wan0 -p icmp -m icmp --icmp-type 8 -j DROP

# allow forwarding of packets from the lan to the wan for squid proxying
-A FORWARD -s 192.168.1.0/24 -i lan0 -o wan0 -m state --state NEW -j ACCEPT

# allow forwarding of any packets pertaining to an existing connection
-A FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT
COMMIT
# Completed on Fri Jul  8 12:41:58 2011
share|improve this question

3 Answers 3

Something like this doesn't work?

iptables -A INPUT -i wan0 -p tcp --dport 10101 -j ACCEPT
iptables -t nat -A PREROUTING -i wan0 -p tcp --dport 10101 -j DNAT --to 192.168.1.15:3389

If the VM is on a different network from your other boxes, you may also need a forward directive like (assuming it isn't already allowed by your other rules):

iptables -A FORWARD -i wan0 -d 192.168.1.15 -j ACCEPT
share|improve this answer
1  
I would use -I instead of -A in a working iptables configuration as -A will likely put the new rule after the blanket DROP statement for the chain and therefore be ignored. –  Iain Nov 3 '11 at 19:47
    
This didn't seem to work for me either. I went back and put my whole iptables config file in the question along with your suggestions just in case one of my other configuration statements is messing me up. The VM is on the 192.168.1.15 machine but I tried adding the forward line anyway...it didn't help. –  Matthew Nov 3 '11 at 20:23
    
Silly questions: is "cat /proc/sys/net/ipv4/ip_forward" returning "1"? Does the Windows box route to the outside world (i.e., on the Windows box, ping 8.8.8.8)? –  cjc Nov 3 '11 at 20:38
    
cat /proc/sys/net/ipv4/ip_forward does return one (and my squid transparent proxy is forwarding nicely). The "windows box" is inside a VirtualBox headless VM. The RDP connection is handled directly by virtualbox and not the guest OS. I can access it fine from within my local network by connecting to 192.168.1.15:3389 –  Matthew Nov 3 '11 at 20:58
    
Apparently adding a line like "-A INPUT -i wan0 -p tcp --dport 3389 -j ACCEPT" just after the 10101 accept-line allows me to connect on port 10101 (but unfortunately 3389 as well). I suspect it's because the DNAT'ed packet shows as coming from wan0 to 3389? Is there any way to mangle the packet in the prerouting line so that it looks like it came in on lan0? –  Matthew Nov 3 '11 at 21:06

You state the problem clearly in this comment of the script:

"# accept traffic destined to **this machine** from the wan on port 10101"

No, you aren't accepting traffic destined to this machine, you are accepting traffic destined to some other machine. If you want to FORWARD traffic to 192.168.1.15, then open the filter at the FORWARD chain, not INPUT.

iptables -A FORWARD -i wan0 -p tcp --dport 10101 -j ACCEPT

The DNAT at PREROUTING is right.

The "generic" RELATED, ESTABLISHED rules at the filter chains are cool too, but you might want to put them at the start of the chain. You'll save cpu if the rules that match more frequently (like the bulk of packets that belong to already allowed connections) get out of the tables as fast as possible.

share|improve this answer
    
192.168.1.15 is this machine. This pc has two network interfaces, a wan0 and a lan0. I may have misunderstood...does the INPUT chain not deal with all traffic destined to the current host regardless of which interface it's heading to? –  Matthew Nov 3 '11 at 21:15
    
Well, maybe I misunderstood. I though you had a VM whose tcp/3389 you are trying to reach. –  ata Nov 3 '11 at 21:22
    
Yes, that VM is installed in the gateway machine and is attached to it's local-side interface. VirtualBox provides an RDP connection not to the guest OS but to the VirtualMachine display itself, allowing one to reboot the machine and see it "post" for instance. That way it isn't going to the network interface on the virtual machine at all, eliminating the forward that would otherwise be involved. –  Matthew Nov 3 '11 at 21:42
    
In that case this post is null (except for the last paragraph). You should indeed work with INPUT. –  ata Nov 3 '11 at 22:40
up vote 0 down vote accepted

This will not work using only iptables. Because the request is destined for my gateway server and it isn't simply acting as a proxy in this case, I cannot use SNAT to change the source address of the packets. If I block requests to port 3389 from wan0, even packets being DNAT'ed from port 10101 to 3389 will get blocked because wan0 is still their source.

cjc points out that other software could be combined with iptables to accomplish this but that level of sophistication is not required for my problem.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.