Here's what I do.

Server (public internet is 222.x.x.x):

echo 'net.ipv4.ip_forward=1' >> /etc/sysctl.conf  
sysctl -p  
iptunnel add gre1 mode gre local 222.x.x.x remote 115.x.x.x ttl 255  
ip add add dev gre1  
ip link set gre1 up  
iptables -t nat -A POSTROUTING -s -j SNAT --to-source 222.x.x.x  
iptables -t nat -A PREROUTING -d 222.x.x.x -j DNAT --to-destination  

Client (public internet is 115.x.x.x):

iptunnel add gre1 mode gre local 115.x.x.x remote 222.x.x.x ttl 255  
ip add add dev gre1  
ip link set gre1 up  
echo '100 tunnel' >> /etc/iproute2/rt_tables  
ip rule add from table tunnel  
ip route add default via table tunnel  

Until here, all seems going right. But then 1st question, how to use GRE tunnel as a default route? Client computer is still using 115.x.x.x interface as default.

2nd question, how to force only ICMP traffic to go through tunnel, and everything else go default interface? I try doing this in client computer:

ip rule add fwmark 200 table tunnel  
iptables -t mangle -A OUTPUT -p udp -j MARK --set-mark 200  

But after doing this, my ping program will timeout (if I not doing 2 command above, and using ping -I gre1 ip instead, it will works). Later I want to do something else also, like only UDP port 53 through tunnel, etc.

3rd question, in client computer, I force one mysql program to listen on gre1 interface In client computer, there's also one more public interface (IP 114.x.x.x)... How to forward traffic properly using iptables and route so mysql also respond a request coming from this 114.x.x.x public interface?


Question 1

Check out using a gre tunnel as default route.

Question 2 all icmp through tunnel

iptables -t nat -A POSTROUTING -o gre1 -p icmp -j SNAT --to-source

Question 3

On client machine, use DNAT to do port forwarding from external port to server port.

Method 2 - port reflection/port mirroring

iptables -t nat -A PREROUTING -p tcp -m tcp -m multiport -d 114.x.x.x --dports 3306 -j DNAT --to-destination
iptables -t nat -A POSTROUTING -o gre1 -p tcp -m tcp -m multiport -d --dports 3306 -j SNAT --to-source
| improve this answer | |
  • my main problem in here is how to set up a routing and forwarding properly. In the link that you give, I see the tunneling command is the same. The only difference is the routing command. But I'm not sure how to translate it properly to my network, since their case have some IP range to routes, while I only have 1 interface each, directly connected to public internet. I'm sorry, but the 2nd syntax that you give me doesn't work. It still use 115.x.x.x as default routing. I presume its because -o gre1 only catch if its using gre1 interface? But it's still using venet0 as default. – wew Dec 14 '12 at 5:39
  • About the 3rd answer, it seems its not as simple as that. I have tried executing this: iptables -t nat -A PREROUTING -d 114.x.x.x -j DNAT --to-destination But due to routing syntax I give above, if mysql client made a request to 114.x.x.x, it will passed to, processed by mysqld, then mysqld reply it to, then goes to 222.x.x.x. Since it doesn't reply via 114.x.x.x, the packet is invalid. How to properly set up so it will reply back via 114.x.x.x? – wew Dec 14 '12 at 5:40
  • I updated Question 2 answer already, it was a mistake before. – John Siu Dec 14 '12 at 5:48
  • Q3, add port reflection. – John Siu Dec 14 '12 at 6:02
  • I finally do the 1st question by using | ip route del default | | ip route add default via dev gre1 | | ip route add 222.x.x.x via 115.x.x.x dev venet0 | | ip route flush cache | But seems the dns is not working – wew Dec 14 '12 at 6:26

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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