How to create GRE tunnel

GRE stands for Generic Routing Encapsulation and is mainly used to connect several hosts via virtual network interfaces created in those hosts. In simple terms, by using GRE tunnel we can send traffic from one server to another that is located in totally separate data centers or networks.

GRE tunnel scheme

In this article, we will show how to create a GRE tunnel between 2 servers that are located in 2 separate data centers. Also, we will show how additional IP addresses that are routed to the local server can be used in a remote server.

  • Check if ip_gre module is loaded in the kernel.
[root@server-a ~]# lsmod | grep ip_gre
ip_gre                 22749  0
ip_tunnel              25163  1 ip_gre
gre                    13144  1 ip_gre
  • If the above command not showing ip_gre module in the output then enable it with command below.
[root@server-a ~]# modprobe ip_gre
  • Repeat the same commands in the server-b.
[root@server-b ~]# modprobe ip_gre
[root@server-b ~]# lsmod | grep gre
ip_gre                 22749  0
ip_tunnel              25163  1 ip_gre
gre                    13144  1 ip_gre
  • Enable IPv4 forward in the server-a.
[root@server-a ~]# echo 'net.ipv4.ip_forward=1' >> /etc/sysctl.conf
[root@server-a ~]# sysctl -p
net.ipv4.ip_forward = 1
  • Create GRE tunnel in the server-a and check if it was created.
[root@server-a ~]# ip tunnel add GREAB mode gre local 2.58.28.45 remote 181.215.247.22 ttl 255
[root@server-a ~]# ip addr add 192.168.0.1/30 dev GREAB
[root@server-a ~]# ip link set GREAB up
[root@server-a ~]# ip tunnel show
gre0: gre/ip remote any local any ttl inherit nopmtudisc
GREAB: gre/ip remote 181.215.247.22 local 2.58.28.45 ttl 255
  • Create GRE tunnel in the server-b and check if it was created too.
[root@server-b ~]# ip tunnel add GREAB mode gre local 181.215.247.22 remote 2.58.28.45 ttl 255
[root@server-b ~]# ip addr add 192.168.0.2/30 dev GREAB
[root@server-b ~]# ip link set GREAB up
[root@server-b ~]# ip tunnel show
gre0: gre/ip remote any local any ttl inherit nopmtudisc
GREAB: gre/ip remote 2.58.28.45 local 181.215.247.22 ttl 255
  • Check if server-b is reachable from server-a.
[root@server-a ~]# ping 192.168.0.2
PING 192.168.0.2 (192.168.0.2) 56(84) bytes of data.
64 bytes from 192.168.0.2: icmp_seq=1 ttl=64 time=129 ms
64 bytes from 192.168.0.2: icmp_seq=2 ttl=64 time=129 ms
64 bytes from 192.168.0.2: icmp_seq=3 ttl=64 time=129 ms
64 bytes from 192.168.0.2: icmp_seq=4 ttl=64 time=129 ms
64 bytes from 192.168.0.2: icmp_seq=5 ttl=64 time=129 ms
^C
--- 192.168.0.2 ping statistics ---
5 packets transmitted, 5 received, 0% packet loss, time 4006ms
rtt min/avg/max/mdev = 129.412/129.505/129.607/0.328 ms
  • Do the same check from server-b.
[root@server-b ~]# ping 192.168.0.1
PING 192.168.0.1 (192.168.0.1) 56(84) bytes of data.
64 bytes from 192.168.0.1: icmp_seq=1 ttl=64 time=129 ms
64 bytes from 192.168.0.1: icmp_seq=2 ttl=64 time=129 ms
64 bytes from 192.168.0.1: icmp_seq=3 ttl=64 time=129 ms
64 bytes from 192.168.0.1: icmp_seq=4 ttl=64 time=129 ms
64 bytes from 192.168.0.1: icmp_seq=5 ttl=64 time=129 ms
^C
--- 192.168.0.1 ping statistics ---
5 packets transmitted, 5 received, 0% packet loss, time 4006ms
rtt min/avg/max/mdev = 129.402/129.451/129.482/0.229 ms

That’s it, the GRE tunnel has been established between 2 servers. However, let’s say we want to use additional IP addresses in the server-b which are statically routed to the server-a. This can be accomplished in the following steps.

In this case, we will use IP range 2.57.20.220/30 which is already statically routed to the server-a primary IP address 2.58.28.45.

  • Route IP range via GRE tunnel in the server-a.
[root@server-a ~]# ip route add 2.57.20.220/30 dev GREAB
[root@server-a ~]# ip route ls
default via 2.58.28.1 dev eth0
2.57.20.220/30 dev GREAB scope link
2.58.28.0/24 dev eth0 proto kernel scope link src 2.58.28.45
  • Create new route table in the server-b.
[root@server-b ~]# echo '100 GRE' >> /etc/iproute2/rt_tables
[root@server-b ~]# ip rule add from 2.57.20.220/30 table GRE
[root@server-b ~]# ip route add default via 192.168.0.1 table GRE
  • Add IP address 2.57.20.220 in the server-b.
[root@server-b ~]# ip addr add 2.57.20.220/32 dev eth0
  • Test if the added IP address is reachable.
PING 2.57.20.220 (2.57.20.220) 56(84) bytes of data.
64 bytes from 2.57.20.220: icmp_seq=1 ttl=52 time=171 ms
64 bytes from 2.57.20.220: icmp_seq=2 ttl=52 time=171 ms
64 bytes from 2.57.20.220: icmp_seq=3 ttl=52 time=170 ms
64 bytes from 2.57.20.220: icmp_seq=4 ttl=52 time=171 ms
64 bytes from 2.57.20.220: icmp_seq=5 ttl=52 time=170 ms
^C
--- 2.57.20.220 ping statistics ---
5 packets transmitted, 5 received, 0% packet loss, time 4004ms
rtt min/avg/max/mdev = 170.327/170.823/171.110/0.413 ms

To use other IP addresses simply add them to the server-b network interface.

Related articles:

Was this article helpful?

Still need help?

Heficed Slack Community

Get involved in Heficed Slack community. Get updates, ask questions, connect with peers.

Heficed Slack

Need support?

If you need any further help, don't hesitate to send a support request to our support team.