Fast Site-to-Site Connectivity Without Complex VPNs
Need to connect a server in a datacenter to an office server for database synchronization or internal file transfers? Instead of installing heavy systems like OpenVPN, GRE (Generic Routing Encapsulation) and IPIP (IP-over-IP) are much more “lightweight” alternatives.
Both protocols operate directly at the Linux kernel level. This ensures high packet processing speeds and low CPU overhead. I often describe them as private data pipes running through the public Internet.
Setting Up a GRE Tunnel in 5 Minutes
Let’s start with a practical example. Suppose you have two nodes that need to communicate:
- Server A (Hanoi): Public IP
1.1.1.1, Tunnel IP will be10.0.0.1 - Server B (Saigon): Public IP
2.2.2.2, Tunnel IP will be10.0.0.2
Configuration on Server A:
# Create a tunnel interface named gre0
sudo ip tunnel add gre0 mode gre remote 2.2.2.2 local 1.1.1.1 ttl 255
# Assign internal IP
sudo ip addr add 10.0.0.1/30 dev gre0
# Enable the interface
sudo ip link set gre0 up
Configuration on Server B:
sudo ip tunnel add gre0 mode gre remote 1.1.1.1 local 2.2.2.2 ttl 255
sudo ip addr add 10.0.0.2/30 dev gre0
sudo ip link set gre0 up
Once finished, try to ping 10.0.0.2 from Server A. If the latency is stable and there is no packet loss, your pipe is ready. This is a key part of diagnosing and troubleshooting network connectivity issues.
GRE vs. IPIP: Which Is the Optimal Choice?
The difference between these two protocols lies in their encapsulation capabilities and performance:
- GRE: Much more flexible. It can encapsulate almost any Layer 3 protocol, including IPv6 and Multicast. If you plan to run OSPF to automatically update routes between the two endpoints, GRE is a must.
- IPIP: Simple and lightweight. It only wraps IPv4 inside IPv4. The biggest advantage is lower overhead. IPIP uses only 20 bytes for the header, while GRE uses 24 bytes. For pure IPv4 connections where you need to squeeze out every bit of bandwidth, IPIP is slightly better.
To switch to IPIP, simply change mode gre to mode ipip in the commands above.
Routing to Connect Two LAN Segments
The ultimate goal is for workstations in LAN A (192.168.1.0/24) to reach workstations in LAN B (192.168.2.0/24).
On Server A: sudo ip route add 192.168.2.0/24 dev gre0
On Server B: sudo ip route add 192.168.1.0/24 dev gre0
Crucially, you must enable IP Forwarding, a core component of a basic Linux router setup. Otherwise, the server will receive packets but won’t forward them anywhere:
sudo sysctl -w net.ipv4.ip_forward=1
Real-world Experience: The MTU Headache
I once set up a tunnel where ping worked perfectly and SSH commands were fine. However, whenever I tried to download a large file or open a web management page, the connection would hang.
After checking with tcpdump, I discovered that packets were being dropped because they exceeded the size limit. A standard packet is 1500 bytes. Adding the 24-byte GRE header makes it 1524 bytes, which is rejected by intermediate routers on the Internet.
The permanent fix: Lower the MTU to 1400 and use MSS Clamping.
# Lower MTU to leave room for the header
sudo ip link set dev gre0 mtu 1400
# Force TCP connections to auto-adjust size (MSS Clamping)
sudo iptables -A FORWARD -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu
The TCPMSS command above is extremely important. It helps avoid packet fragmentation, which is the main cause of lag and reduced transfer speeds.
Persistent Configuration with Netplan
The ip tunnel commands will disappear upon reboot. On Ubuntu/Debian, declare them in your /etc/netplan/01-netcfg.yaml file so the system applies them at startup:
tunnels:
gre0:
mode: gre
local: 1.1.1.1
remote: 2.2.2.2
addresses:
- 10.0.0.1/30
routes:
- to: 192.168.2.0/24
via: 10.0.0.2
Security Considerations
GRE and IPIP are unencrypted by default. Your data travels across the Internet in plain text. If you are transmitting sensitive information, you should wrap this tunnel inside IPsec or consider configuring VPN clients.
At the very least, use iptables to block unknown IPs trying to connect to your GRE port:
sudo iptables -A INPUT -p gre -s 2.2.2.2 -j ACCEPT
sudo iptables -A INPUT -p gre -j DROP
Quick Summary
- Use GRE for networks with dynamic routing; use IPIP to save bandwidth.
- Always set MTU 1400 to ensure packets aren’t dropped along the way.
- TCP MSS Clamping is a lifesaver for Web/Database applications running over the tunnel.
- Remember to limit Firewall access to prevent external attacks.
Setting up a tunnel takes only a few minutes, but optimizing it for stability under high load is the real challenge. I hope these insights help you avoid the “silly” MTU errors I once encountered.

