Blog
GRE tunnels for IPv4: when you need one and how to set it up
A tunnel lets you use IPv4 addresses on a server that could not carry them otherwise. The block is announced by a network that can announce it, and the tunnel carries its traffic to your server and back. It is the answer when your provider does not offer bring your own IP (BYOIP), when you have no AS number, or when you need fewer than the 256 addresses the internet will route on their own.
What the tunnel actually does
Packets for your block arrive at the network that announces it. There each packet is wrapped in a new one, addressed to your server, and sent across the ordinary internet. Your server unwraps it and sees the original packet, as though the addresses were configured on a local interface.
Original packet: [IP header | data]
GRE packet: [outer IP | GRE header | IP header | data]Replies take the same path in reverse: your server wraps them, sends them to the far end of the tunnel, and that network delivers them. That return path is the step most setups get wrong, and the configuration below shows why.
When a tunnel beats BYOIP
BYOIP lets a cloud or hosting provider announce your block from its own network (which providers do). Where it is available and you have at least a /24, it is the cleaner option: no extra hop, no extra point of failure, and the provider's full bandwidth. A tunnel is the better choice in four cases.
- Your provider does not offer BYOIP. Scaleway, for one, says so plainly in its documentation, and several others take it only on request, for some of their products, such as Infomaniak, TransIP and UpCloud. Others, among them Contabo, Exoscale, Hostinger and Akamai Cloud, publish no procedure at all.
- You need fewer than 256 addresses. A /24 is the smallest block networks accept in their routing tables, and no provider's BYOIP goes below it. A tunnel can deliver a /29, or a single address.
- You have no ASN, and the provider wants one. Some providers only accept your space over a BGP session with your own AS number. A tunnel needs neither.
- You want the same addresses in several places, or freedom to move. The announcement stays where it is; the tunnel goes wherever your server goes.
The price is a detour. Traffic travels to the tunnel's far end before it reaches you, so choose an endpoint close to your server, and remember that the tunnel's capacity, not your server's port, sets the ceiling.
GRE or WireGuard
Both carry the same traffic; they differ in what the path between the two ends needs.
| GRE | WireGuard | |
|---|---|---|
| Encryption | None | Yes |
| Overhead on IPv4 | 24 bytes | 60 bytes |
| Behind NAT or CGNAT | Does not work reliably | Works |
| Support | Every router and the Linux kernel | The Linux kernel, most routers, small and auditable |
| Best when | The path is trusted and throughput matters most | Traffic crosses networks you do not control, or the endpoint has no public address |
If your endpoint sits behind NAT, the choice is made for you: WireGuard. The same goes for Azure, which blocks GRE in its virtual networks.
MTU and MSS: the classic failure
Encapsulation adds headers, so the largest packet that fits inside the tunnel is smaller than the 1,500 bytes of a plain Ethernet link: 1,476 bytes for GRE over IPv4, and WireGuard commonly runs at 1,420. Get it wrong and you see the classic symptom: small requests work, while large downloads and TLS handshakes hang, because the packets that do not fit are dropped and the messages that should report it are often filtered on the way.
Two settings prevent it. Set the tunnel interface's MTU to the right value, and clamp the TCP maximum segment size (MSS) on traffic you route through the tunnel, so that both ends agree to send packets that fit. We send both values with every tunnel, and change them on request.
A minimal Linux setup
The example below brings a block to a single Linux server over GRE. The addresses are documentation ranges: 203.0.113.1 is your server's public address, 198.51.100.1 the far end of the tunnel, and 192.0.2.0/24 the block.
# 1. The tunnel, from your server to the far end
ip tunnel add gre1 mode gre local 203.0.113.1 remote 198.51.100.1 ttl 255
ip link set gre1 mtu 1476 up
ip addr add 10.0.0.2/30 dev gre1
# 2. An address from the block on the server itself
ip addr add 192.0.2.10/32 dev lo
# 3. Replies from the block go back through the tunnel
ip rule add from 192.0.2.0/24 lookup 100
ip route add default via 10.0.0.1 dev gre1 table 100Step 3 is the one people miss. Without it, replies from 192.0.2.10 leave through your provider's own uplink, carrying a source address that provider never gave you, and its anti-spoofing filters drop them. If your distribution enables strict reverse-path filtering, set it to loose for the tunnel as well (sysctl -w net.ipv4.conf.gre1.rp_filter=2).
If the server routes the block on to virtual machines or containers, clamp the MSS on the traffic it forwards:
iptables -t mangle -A FORWARD -o gre1 -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtuBGP over the tunnel
If you have your own AS number and want to control the announcement yourself, you can run a BGP session over the tunnel instead of a static route, with BIRD, FRR or your router's own daemon. Most customers do not need this and take the static setup. If you do announce from your own ASN, the ROA has to name that ASN (RPKI and ROAs).
Where RTM Networks fits
We announce the block and deliver it to your server over GRE or WireGuard, wherever the server is. That works where BYOIP does not, including for fewer than 256 addresses and for providers that do not accept your space at all. Tell us where the server is and what it runs, and we will recommend GRE or WireGuard and send the configuration with the right MTU and MSS values (GRE and WireGuard tunnels).
Contact
Need advice on your own situation?
This article is general; your network is not. Tell us what you are working with and we will look at it properly. We usually reply in 1-3 business hours.



