How to Set Up GRE Tunnels Between Servers
GRE (Generic Routing Encapsulation) tunnels create point-to-point virtual links between two Breeze instances over the public internet. They allow you to route private traffic between servers, connect isolated networks, and encapsulate various protocols inside IP packets.
How GRE Works
GRE wraps packets in an additional IP header with protocol number 47. This adds 24 bytes of overhead (20-byte IP header + 4-byte GRE header), reducing the effective MTU to 1476 bytes when the underlying link uses 1500. GRE tunnels do not provide encryption — for secure communication, combine GRE with IPsec or use it within a trusted network.
Prerequisites
- Two Breeze instances with public IP addresses
- GRE protocol (IP protocol 47) allowed by firewalls
- The
iputility from theiproute2package
Creating the GRE Tunnel
On Breeze Server A (public IP: 203.0.113.1):
sudo ip tunnel add gre1 mode gre \
remote 198.51.100.1 \
local 203.0.113.1 \
ttl 255
sudo ip addr add 10.10.10.1/30 dev gre1
sudo ip link set gre1 up
sudo ip link set gre1 mtu 1476
On Breeze Server B (public IP: 198.51.100.1):
sudo ip tunnel add gre1 mode gre \
remote 203.0.113.1 \
local 198.51.100.1 \
ttl 255
sudo ip addr add 10.10.10.2/30 dev gre1
sudo ip link set gre1 up
sudo ip link set gre1 mtu 1476
Testing the Tunnel
From Server A, ping Server B through the tunnel:
ping -c 4 10.10.10.2
Check the tunnel interface status:
ip tunnel show
ip addr show gre1
ip route show dev gre1
Routing Traffic Through the Tunnel
To route a remote subnet through the GRE tunnel, add a static route. For example, if Server B has a private network 172.16.0.0/24 behind it:
# On Server A
sudo ip route add 172.16.0.0/24 via 10.10.10.2 dev gre1
# On Server B (if Server A has 172.17.0.0/24)
sudo ip route add 172.17.0.0/24 via 10.10.10.1 dev gre1
Enable IP forwarding on both hosts:
sudo sysctl -w net.ipv4.ip_forward=1
echo "net.ipv4.ip_forward = 1" | sudo tee -a /etc/sysctl.conf
Making the Tunnel Persistent
On Ubuntu/Debian, create a Netplan config or a systemd-networkd configuration. For systemd-networkd, create two files:
# /etc/systemd/network/25-gre1.netdev
[NetDev]
Name=gre1
Kind=gre
[Tunnel]
Remote=198.51.100.1
Local=203.0.113.1
TTL=255
# /etc/systemd/network/25-gre1.network
[Match]
Name=gre1
[Network]
Address=10.10.10.1/30
[Route]
Destination=172.16.0.0/24
Gateway=10.10.10.2
Restart networking:
sudo systemctl restart systemd-networkd
GRE Over IPsec
For encrypted GRE tunnels, configure IPsec transport mode between the two Breeze instances using strongSwan or libreswan. IPsec encrypts the GRE-encapsulated packets, adding security without changing the tunnel configuration. This adds additional overhead, so set the GRE interface MTU to approximately 1400 to account for IPsec headers.
Troubleshooting
If the tunnel does not pass traffic, verify that protocol 47 is allowed through all firewalls, the remote and local IPs are correct on both sides, and IP forwarding is enabled. Use tcpdump -i eth0 proto gre to confirm GRE packets are being sent and received.