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 192.168.168.1/30 dev gre1
ip link set gre1 up
iptables -t nat -A POSTROUTING -s 192.168.168.0/30 -j SNAT --to-source 222.x.x.x
iptables -t nat -A PREROUTING -d 222.x.x.x -j DNAT --to-destination 192.168.168.2
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 192.168.168.2/30 dev gre1
ip link set gre1 up
echo '100 tunnel' >> /etc/iproute2/rt_tables
ip rule add from 192.168.168.0/30 table tunnel
ip route add default via 192.168.168.1 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 192.168.168.2. 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?