I have done some searching on the internet and found little about this specific topic, hence this post.
CentOS 7 will be my first choice of server operating system. I believe the steps for other OSes are very similar. I will also include some of the generic setup steps in this tutorial. I will not talk about the concept of GRE and IPSec because you’ll find a lot of other nice articles on the internet.
In IPSec concept, the source machine is called left and the destination is called right. I also will call them these names. All actions are done with root user.
Here is the information about the 2 servers:
Public IP: 22.214.171.124
GRE internal IP: 192.168.168.1
Public IP: 126.96.36.199
GRE internal IP: 192.168.168.2
Configuring GRE is very straightforward. First, we need to make sure we enabled the IP forwarding function in the kernel, by applying those parameters to
net.ipv4.conf.all.forwarding = 1 net.ipv4.conf.default.forwarding = 1 net.ipv4.ip_forward = 1
sysctl -p --system to apply those rules.
Make sure you have GRE module loaded in your kernel (and when boot up). This is a shell script.
lsmod | grep ip_gre > /dev/null if [ $? -eq 1 ]; then modprobe ip_gre echo 'ip_gre' >> /etc/modules-load.d/gre.conf # for CentOS only fi
For CentOS users, now it’s time to write some configuration files. On left:
DEVICE=gre1 BOOTPROTO=none ONBOOT=yes TYPE=GRE PEER_OUTER_IPADDR=188.8.131.52 #Right's public ip address PEER_INNER_IPADDR=192.168.168.2 #Right's internal GRE ip MY_INNER_IPADDR=192.168.168.1 #Left's internal GRE ip
For right server, use the same configuration structure but change the values to appropriate ones.
Finally, start those GRE tunnels:
For non-CentOS users, you may add your tunnel by executing those commands on each ends:
iptunnel add gre1 mode gre local 184.108.40.206 remote 220.127.116.11_IP ttl 255 ip addr add 192.168.168.1/30 dev gre1 ip link set gre1 up
Remember to change values.
Before we test it with ping, we need to add to iptables to allow NAT between the network.
iptables -t nat -A POSTROUTING -o gre1 -j ACCEPT iptables -A INPUT -p gre -j ACCEPT
Now we can ping from left to right or vice versa.
yum install libreswan -y
Initialize a new NSS databse:
Enable auto start from boot.
systemctl enable ipsec
Add ports to firewall. IKE uses UDP 500, IKE NAT-Traversal uses UDP 4500, Encapsulated Security Payload (ESP) uses protocol 50 and Authenticated Header (AH) uses protocol 51.
# IKE iptables -A INPUT -p udp -m state --state NEW -m udp --dport 500 -j ACCEPT # NAT-T iptables -A INPUT -p udp -m state --state NEW -m udp --dport 4500 -j ACCEPT # ESP iptables -A INPUT -p esp -j ACCEPT # AH iptables -A INPUT -p ah -j ACCEPT
iptables-save > /etc/sysconfig/iptables to save firewall rules.
In this section, we are going to use RSA encryption to encrypt our tunnel.
Firstly, create key pairs on both of our servers.
ipsec newhostkey --configdir /etc/ipsec.d --output /etc/ipsec.d/mytunnel.secrets
Find our left and right key on corresponding left and right server.
showhostkey --left # or right
There will be something like
right/leftrsasigkey=0sAQOw3XLeYw3q4…., copy it.
Write those keys into
/etc/ipsec/mytunnel.conf, put the file on both of the servers. The content could be the same as servers will determine itself as right or left.
conn mytunnel [email protected] left=192.168.168.1 leftrsasigkey=0sAQOrlo+hOafUZDlCQmXFrje/oZm [...] W2n417C/4urYHQkCvuIQ== [email protected] right=192.168.168.2 rightrsasigkey=0sAQO3fwC6nSSGgt64DWiYZzuHbc4 [...] D/v8t5YTQ== authby=rsasig # load and initiate automatically auto=start
systemctl start ipsec ipsec auto --add mytunnel ipsec auto --up mytunnel
You do not need to execute the last 2 lines every time you boot the system. It is all automatic.
On the right server, we start our
tcpdump -n -i gre1 esp or udp port 500 or udp port 4500
From left, ping right:
09:48:42.198023 IP 192.168.168.1 > 192.168.168.2: ESP(spi=0x52f7e0f4,seq=0x4), length 132 09:48:42.198271 IP 192.168.168.2 > 192.168.168.1: ESP(spi=0x1b637a20,seq=0x4), length 132 09:48:43.198544 IP 192.168.168.1 > 192.168.168.2: ESP(spi=0x52f7e0f4,seq=0x5), length 132 09:48:43.199250 IP 192.168.168.2 > 192.168.168.1: ESP(spi=0x1b637a20,seq=0x5), length 132 09:48:44.199709 IP 192.168.168.1 > 192.168.168.2: ESP(spi=0x52f7e0f4,seq=0x6), length 132 09:48:44.200260 IP 192.168.168.2 > 192.168.168.1: ESP(spi=0x1b637a20,seq=0x6), length 132
If we captured ESP packages, then our setup is successful.
Configure our routing policy to go through GRE tunnel rather than our default gateway. Example: route all Google DNS traffic to GRE:
ip route add 18.104.22.168/16 dev gre1
You need to add the rules to
/etc/rc.local if you want to have persistent routing when you reboot your server.