GRE connects two devices with a tunnel over IPv4. For example, you can use it to route a private network between two VPSes on the trusted vpsFree internal network. The example below creates a simple tunnel between these addresses:
| VPS A | VPS B | |
|---|---|---|
| outer VPS address | 185.8.164.10/32 | 185.8.164.20/32 |
| address inside the tunnel | 10.0.0.1 | 10.0.0.2 |
The outer addresses are examples from the vpsFree playground range. Replace
them with /32 addresses actually assigned to your VPSes. You can keep the
private tunnel addresses if they do not overlap another network you use.
GRE uses IP protocol 47, not TCP or UDP port 47. If traffic is filtered on either VPS, allow protocol 47 from the other endpoint's outer address.
Use this setup only over the trusted vpsFree internal network, where source-address ownership is enforced. GRE itself does not encrypt traffic or authenticate the peer, so do not carry it over the public Internet. Use WireGuard for public-Internet connections.
Run this on VPS A:
#!/usr/bin/env bash set -eu ip tunnel add gre1 mode gre \ local 185.8.164.10 remote 185.8.164.20 ttl 255 ip address add 10.0.0.1/30 dev gre1 ip link set dev gre1 mtu 1476 up
Run this on VPS B:
#!/usr/bin/env bash set -eu ip tunnel add gre1 mode gre \ local 185.8.164.20 remote 185.8.164.10 ttl 255 ip address add 10.0.0.2/30 dev gre1 ip link set dev gre1 mtu 1476 up
Test the connection in both directions:
#!/usr/bin/env bash # On VPS A ping -c 3 10.0.0.2
#!/usr/bin/env bash # On VPS B ping -c 3 10.0.0.1
These commands last only until the next restart. You can remove the interface
with ip tunnel del gre1. See the
ip-tunnel(8) manual
for additional options.
The default Debian template uses ifupdown. On VPS A, save the following as
/etc/network/interfaces.d/gre1:
auto gre1 iface gre1 inet tunnel mode gre address 10.0.0.1 netmask 255.255.255.252 dstaddr 10.0.0.2 local 185.8.164.10 endpoint 185.8.164.20 ttl 255 mtu 1476
Use this on VPS B:
auto gre1 iface gre1 inet tunnel mode gre address 10.0.0.2 netmask 255.255.255.252 dstaddr 10.0.0.1 local 185.8.164.20 endpoint 185.8.164.10 ttl 255 mtu 1476
address and dstaddr are the addresses inside the tunnel. In
contrast, local and endpoint are its outer endpoints. Bring the
interface up on both VPSes:
ifup gre1
See the interfaces(5) manual for all supported options.
If your distribution does not use ifupdown, create the same GRE tunnel with its network manager. See the current documentation for NetworkManager and systemd-networkd.
Basic GRE over IPv4 adds overhead, so the example uses an MTU of 1476 instead of the usual 1500 bytes. If the outer path has a lower MTU or larger transfers stall, reduce the MTU further at both ends.
If the tunnel does not work, verify the outer addresses with ip address, IP
protocol 47 in your firewall, and the tunnel state with
ip -details tunnel show gre1. Then check that local on each side is its
outer address and remote or endpoint is the peer's outer address.