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

I have a VPN tunnel established between 2 servers: VPS-A and VPS-B having the (fictional) public IP addresses: 66.55.44.33 and 77.88.55.66, and VPN endpoints 10.0.1.1 and 10.0.2.1 respectively.

There is a web server running on VPS-A. I can without a problem SSH to VPS-B and receive a response when issuing an HTTP request to 10.0.1.1 via curl for example:

curl http://10.0.1.1/

I can also open up a browser on any given computer connected to the Internet and successfully open

http://66.55.44.33/

...but I want to also be able to reach the web server at VPS-A by sending a request to VPS-B i.e.

http://77.88.55.66/

Now, I've added the following rule on VPS-B (edited to show the correct rule)

iptables -t nat -A PREROUTING -p tcp --dport 80 -j DNAT --to-destination 10.0.1.1:80

...and when I'm doing a tcpdump on port 80, I can clearly see how requests to http://77.88.55.66/ are being properly forwarded to http://10.0.1.1. However, the web server at VPS-A doesn't seem to acknowledge the TCP request. Here's what tcpdump shows exactly:

2013-04-27 03:45:15.001564 IP 45.248.82.171.51377 > 10.0.1.1.80: S 791893048:791
2013-04-27 03:45:15.252571 IP 45.248.82.171.51378 > 10.0.1.1.80: S 670490211:670
2013-04-27 03:45:18.001526 IP 45.248.82.171.51377 > 10.0.1.1.80: S 791893048:791
2013-04-27 03:45:18.258666 IP 45.248.82.171.51378 > 10.0.1.1.80: S 670490211:670

..while for a request coming through the VPN:

2013-04-27 04:26:57.464859 IP 10.0.2.1.33258 > 10.0.1.1.80: S 2369100373:2369100373(0) win 5744 <mss 1436,sackOK,timestamp 121795122 0,nop,wscale 7>
2013-04-27 04:26:57.464913 IP 10.0.1.1.80 > 10.0.2.1.33258: S 3524730589:3524730589(0) ack 2369100374 win 5744 <mss 1436,nop,nop,sackOK,nop,wscale 7>
2013-04-27 04:26:57.532428 IP 10.0.2.1.33258 > 10.0.1.1.80: . ack 1 win 45

I'm very new to Linux, so I'm sure I'm not doing something right, but I don't know what exactly. I tried searching for similar questions, but I didn't find anything. If someone can point me to a useful resource or give me a practical example - that would be great.

Thanks for your time reading my post!

share|improve this question

1 Answer 1

up vote 0 down vote accepted

Your description must be incomplete. Rules in INPUT and FORWARD will not make packets for 77.88.55.66 go to 10.0.1.1 instead. That is possible with the DNAT target in the PREROUTING chain of the nat table only. Obviously there is such a rule.

For successful redirection you don't need rules in INPUT anyway as those packets are not to be received by the redirecting system.

The problem with DNAT without SNAT (like in your case) is that a system usually does not care about it over which interface it has been reached when routing the answer. Your VPS-A sees a connection opening from 45.248.82.171 and if it is willing to communicate with that client then it sends a response to – yes, 45.248.82.171. The client has sent a SYN packet to 77.88.55.66 and receives a SYN ACK from 66.55.44.33 and obviously just thinks WTF? Why from 66.55.44.33? Because the reply is not sent over the tunnel because the routing configuration of VPS-A tells it not to send packets to this destination over the tunnel. If they went back through the tunnel then VPS-B would rewrite the source address to its own and everything would be alright.

So you either have to use iptables to mark the connections which come over the tunnel (why over the tunnel anyway?), rewrite the connection mark to a packet mark and use advanced routing with this packet mark for having those packets sent over the tunnel. Or you do both sides of NAT, make SNAT before sending them from VPS-B through the tunnel and get them back from VPS-A the easy way. Disadvantage: The webserver logs show the "wrong" IP address (always 10.0.2.1).

BTW: 10.0.2.1 and 10.0.1.1 are strange end point addresses of the same VPN, aren't they?

share|improve this answer
    
You are right, there was an additional rule in the PREROUTING chain that I overlooked iptables -t nat -A PREROUTING -p tcp --dport 80 -j DNAT --to-destination 10.0.1.1:80 Your response has really been useful, however I can't figure out how the exact SNAT rule should look like. Can you please give me an example? –  maringtr Apr 27 '13 at 12:33
    
@maringtr There is not just one rule that will lead to success, many variants will do. The only "risk" is to do SNAT for more packets than necessary which will hardly result in problems, though. iptables -t nat -A POSTROUTING -o $tun_dev \! -s 10.0.2.1 -j SNAT --to-source 10.0.2.1 should do. To be more precise and catch only the connections in question you may add -d 10.0.1.1, -p tcp --dport 80, --ctstate DNAT, --ctorigdst 77.88.55.66, and / or --ctorigdstport 80. –  Hauke Laging Apr 27 '13 at 12:52
    
thanks a million, this has really been helpful! –  maringtr Apr 27 '13 at 14:18

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.