Managed web hosting services, VPS and dedicated servers offered since 2007. WordPress Hosting plans with Daily Backups and e-Mail Accounts. Live ChatSupport Center Customer Login

How To Setup GRE Tunnel On Linux Servers


Generic Routing Encapsulation (GRE) is a tunneling protocol developed by Cisco Systems which can encapsulate a wide variety of network layer protocols inside virtual point-to-point links or point-to-multipoint links over an Internet Protocol network.

A GRE tunnel is useful in certain situations, like protecting a server without DDoS protection using another one with the protection, or to enable applications that only allow IPv4 to also accept IPv6.

It is relatively easy to set up and secure GRE tunnel ("pipe") between server A and server B, which will allow packets to be forwarded with minimal resource usage.


How does GRE tunnel work?

When you create a GRE tunnel on the server, your server will act as a virtual router. Keep in mind that both ends will need a public IP address as packets are sent over multiple networks.


GRE tunnel setup prerequisites

First of all, you must have two servers with root access. If you don't have yet, you can obtain and use either Virtual Private Server (VPS) or a Dedicated Server to create GRE Tunnel. In this tutorial they will be called Server A and Server B, and will have the following characteristics:

  • Server A - the server that all the clients will connect to

    • IP:
    • GRE tunnel internal IP:
  • Server B - the server which is actually running all the applications

    • IP:
    • GRE tunnel internal IP:

Step 1 - Module loading

For setting up a GRE tunnel on Linux you must have ip_gre module loaded in your kernel. To make sure it's loaded just run the following SSH commands:


sudo modprobe ip_gre  
lsmod | grep gre

And you should see:


ip_gre                 #####  0  
gre                    #####  1 ip_gre

If you see something else it's possible that your kernel does not support GRE.

To forward all the traffic in and out of the GRE tunnel we're going to use iptables and iproute2 that should be already installed in all the major linux distributions. In case they're not installed use the following command

for Debian based distros:


sudo apt install iptables iproute2

for Red Hat based distros:


sudo yum install iptables iproute2


Step 2 - GRE Tunnel setup

First we have to set up our tunnel.

On Server A execute this code to enable ip forwarding:


sudo echo 'net.ipv4.ip_forward=1' >> /etc/sysctl.conf  
sudo sysctl -p


Now create a new networking interface which will be the one using the GRE tunnel:


sudo ip tunnel add gre1 mode gre local remote ttl 255  
sudo ip addr add dev gre1  
sudo ip link set gre1 up


Then, do the same on Server B changing the IPs:


sudo ip tunnel add gre1 mode gre local remote ttl 255  
sudo ip addr add dev gre1  
sudo ip link set gre1 up


Step 2.1 - Ping test


On Server A run this SSH command:



And on Server B run this command:



If the ping works then the GRE tunnel is correctly set up.


Step 3 - Implementing the new routes

A route is required to make sure data that comes in via the GRE tunnel is handled correctly.

On Server B execute:


sudo echo '100 GRE' >> /etc/iproute2/rt_tables  
sudo ip rule add from table GRE  
sudo ip route add default via table GRE


Step 4 - NAT configuration

NAT is used to pass data over our GRE and out the other end.

On Server A run:


iptables -t nat -A POSTROUTING -s ! -o gre+ -j SNAT --to-source

To test the outbound connection execute on Server B this commands:

for Debian based distros:


sudo apt install curl

for Red Hat based distros:


sudo yum install curl

And then run the following command:



At the end you should see Server A's IP address.


Step 5 - Port forwarding

On Server A run this commands to allow all the data going to and coming from Server B:


sudo iptables -A FORWARD -d -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT  
sudo iptables -A FORWARD -s -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT

Then, we want to forward all our data from Server A to Server B.

Execute this on Server A:


sudo iptables -t nat -A PREROUTING -d -p PROTO -m PROTO --dport PORT -j DNAT --to-destination

replacing PROTO and PORT with your actual ones.

For example, to forward all the data to a Webserver (Port TCP 80) we have to run:


sudo iptables -t nat -A PREROUTING -d -p TCP -m TCP --dport 80 -j DNAT --to-destination

We must do it for each port we are using.


Step 6 - Persistence

On a server restart all the things we did will be wiped out. To make sure the GRE tunnel and everything else is going to work after a restart we have to edit the file /etc/rc.local and add all the commands we did (except for the echo ones!) before the exit 0.



Now, if we connect to Server A using the ports we configured (Port TCP 80 for example) we're going instead to connect to Server B without knowing it.

Note: if you use CSF to manage iptables you may have to put all the iptables commands in your /etc/csf/ and insert both servers' IP (also the GRE one) in your /etc/csf/csf.allow.



Back To Blog Posts


Published on: 03-10-2020

EURO-SPACE on Facebook Share Your Hosting Experience With EURO-SPACE on Twitter Share Your Hosting Experience With EURO-SPACE on LinkedIn