Vai al contenuto
GLGiuseppe Lanza Scrivimi

Tunnel GRE tra un router Cisco e Ubuntu Linux

Collegare due sedi con un tunnel GRE tra un router Cisco IOS e un server Ubuntu: indirizzamento, configurazione di entrambi i lati, MTU, firewall, verifiche e risoluzione dei problemi.

Sistemi: Cisco IOS / IOS XE · Ubuntu 24.04 LTSLivello: IntermedioTempo: 45 minutiAggiornata: novembre 2026

Che cos’è un tunnel GRE

GRE (Generic Routing Encapsulation, RFC 2784) incapsula un pacchetto IP dentro un altro pacchetto IP. Le due sedi si vedono come se fossero collegate da un cavo punto-punto: ognuna ha un indirizzo sul tunnel e le reti locali vengono instradate attraverso di esso.

GRE è semplice, supportato da quasi tutti i router e dal kernel Linux, e trasporta anche multicast: per questo ci passano bene i protocolli di routing dinamico come OSPF. Ha però un limite importante:

GRE non cifra niente

Il traffico nel tunnel viaggia in chiaro su Internet. Per un collegamento tra sedi vero usa GRE solo dentro IPsec: lo spiego nella guida GRE su IPsec tra Cisco e Ubuntu. Questa guida serve a costruire e capire il tunnel, che poi proteggerai.

Lo scenario

Due sedi: la sede A ha un router Cisco, la sede B un server Ubuntu che fa da router per la sua LAN. Entrambi hanno un indirizzo IP pubblico statico.

LAN sede A 192.168.10.0/24 Router Cisco Gi0/0 198.51.100.1 Internet Ubuntu 24.04 ens18 203.0.113.10 LAN sede B 192.168.20.0/24 Tunnel GRE · 10.255.255.0/30 Tunnel0 .1 gre1 .2 Gi0/1 .1 (gateway) ens19 .1 (gateway)
Le LAN delle due sedi si raggiungono attraverso il tunnel GRE tra il router Cisco e il server Ubuntu.
ElementoSede A (Cisco)Sede B (Ubuntu)
IP pubblico198.51.100.1 su Gi0/0203.0.113.10 su ens18
LAN192.168.10.0/24, gateway .1 su Gi0/1192.168.20.0/24, gateway .1 su ens19
Interfaccia tunnelTunnel0 – 10.255.255.1/30gre1 – 10.255.255.2/30

Gli indirizzi pubblici usati qui sono quelli riservati alla documentazione: sostituiscili con i tuoi. Le due LAN non devono sovrapporsi.

Prima di cominciare: MTU e MSS

GRE aggiunge 24 byte a ogni pacchetto (20 di nuova intestazione IP e 4 di intestazione GRE). Se il collegamento ha MTU 1500, dentro il tunnel restano 1476 byte. Per evitare frammentazione e connessioni TCP che “si bloccano” sulle pagine grandi:

  • imposta l’MTU del tunnel a 1476 su entrambi i lati;
  • riduci l’MSS TCP a 1436 (1476 − 40 byte di intestazioni IP e TCP).

Se la connessione è PPPoE (MTU 1492) togli altri 8 byte: tunnel a 1468, MSS a 1428.

Configurazione del router Cisco

Cisco IOS – configurazione
configure terminal
!
interface Tunnel0
 description GRE verso sede B (Ubuntu)
 ip address 10.255.255.1 255.255.255.252
 ip mtu 1476
 ip tcp adjust-mss 1436
 tunnel source GigabitEthernet0/0
 tunnel destination 203.0.113.10
 tunnel mode gre ip
!
ip route 192.168.20.0 255.255.255.0 10.255.255.2
!
end
write memory

tunnel mode gre ip è il valore predefinito: lo scrivo per chiarezza. Se sull’interfaccia WAN hai una access list in ingresso, aggiungi una riga che accetti GRE (protocollo IP 47) dal server Ubuntu:

Cisco IOS – access list WAN
ip access-list extended WAN-IN
 permit gre host 203.0.113.10 host 198.51.100.1
E il NAT?

Se il router fa NAT verso Internet (ip nat inside source … overload), escludi dalla traslazione il traffico tra le due LAN. Di solito basta che la access list usata dal NAT abbia in testa una riga deny ip 192.168.10.0 0.0.0.255 192.168.20.0 0.0.0.255. In realtà, poiché quel traffico esce dall’interfaccia Tunnel0 e non da quella esterna, il NAT spesso non lo tocca comunque: controlla con show ip nat translations.

Configurazione di Ubuntu

1. Abilitare l’instradamento

Ubuntu deve inoltrare i pacchetti tra la LAN e il tunnel:

/etc/sysctl.d/99-router.conf
net.ipv4.ip_forward = 1
# filtro sul percorso inverso in modalità "loose": evita scarti
# sul traffico che entra dal tunnel
net.ipv4.conf.all.rp_filter = 2
net.ipv4.conf.default.rp_filter = 2
sudo sysctl --system

2. Creare il tunnel con Netplan

Su Ubuntu Server la rete si configura con Netplan. Crea un file dedicato al tunnel:

/etc/netplan/60-gre.yaml
network:
  version: 2
  tunnels:
    gre1:
      mode: gre
      local: 203.0.113.10
      remote: 198.51.100.1
      addresses:
        - 10.255.255.2/30
      mtu: 1476
      routes:
        - to: 192.168.10.0/24
          via: 10.255.255.1
sudo chmod 600 /etc/netplan/60-gre.yaml
sudo netplan try      # applica e torna indietro da solo se perdi la connessione
sudo netplan apply
Per una prova veloce, senza Netplan

Gli stessi passaggi a mano (si perdono al riavvio):

sudo ip tunnel add gre1 mode gre local 203.0.113.10 remote 198.51.100.1 ttl 255
sudo ip addr add 10.255.255.2/30 dev gre1
sudo ip link set gre1 mtu 1476 up
sudo ip route add 192.168.10.0/24 via 10.255.255.1

3. Aprire il firewall a GRE e correggere l’MSS

GRE non usa porte: è il protocollo IP numero 47. Con nftables (il firewall predefinito di Ubuntu, vedi la guida Firewall completo con nftables) aggiungi queste regole alle catene esistenti:

/etc/nftables.conf – estratto
table inet filtro {
  chain input {
    # ... regole esistenti ...
    ip saddr 198.51.100.1 ip protocol gre accept
  }
  chain forward {
    # ... regole esistenti ...
    # MSS clamping: adegua l'MSS dei SYN all'MTU del percorso
    tcp flags syn tcp option maxseg size set rt mtu
    iifname "ens19" oifname "gre1" accept
    iifname "gre1" oifname "ens19" accept
  }
}

Se usi UFW invece di nftables diretto:

sudo ufw allow proto gre from 198.51.100.1
sudo ufw route allow in on ens19 out on gre1
sudo ufw route allow in on gre1 out on ens19

Ricorda che i client della LAN B devono avere il server Ubuntu (192.168.20.1) come gateway, oppure una rotta verso 192.168.10.0/24 che passi da lì.

Verifiche

Sul router Cisco

show interfaces Tunnel0          ! deve risultare "up, line protocol is up"
show ip route 192.168.20.0
ping 10.255.255.2 source Tunnel0
ping 192.168.20.1 source GigabitEthernet0/1

Su Ubuntu

ip -d link show gre1
ip route get 192.168.10.1
ping -c 3 10.255.255.1
ping -c 3 -I 192.168.20.1 192.168.10.1
# vedere i pacchetti GRE sulla WAN
sudo tcpdump -ni ens18 ip proto 47

Per controllare l’MTU senza frammentazione, da un client della LAN B:

ping -M do -s 1448 192.168.10.10   # 1448 + 28 = 1476: deve passare
ping -M do -s 1460 192.168.10.10   # deve fallire: "Frag needed and DF set (mtu = 1476)"

Il secondo comando non deve “appendersi” senza risposta: deve ricevere dal server Ubuntu il messaggio che indica l’MTU del tunnel. Se resta muto, da qualche parte un firewall sta bloccando i messaggi ICMP e la scoperta automatica dell’MTU non funziona.

Keepalive: sapere quando il tunnel è giù

Un’interfaccia GRE resta “up” anche se l’altro capo non risponde. Sul Cisco puoi attivare i keepalive GRE:

interface Tunnel0
 keepalive 10 3

Il router invia ogni 10 secondi un pacchetto che l’altro capo deve rimandare indietro; dopo 3 risposte mancate il tunnel va giù e la rotta statica sparisce, così può subentrare una rotta di riserva. Linux rimanda indietro i keepalive solo se l’instradamento è attivo e il filtro rp_filter non li scarta (per questo l’abbiamo messo a 2). Se con il keepalive attivo il tunnel continua a cadere, toglilo e controlla la raggiungibilità con un monitoraggio esterno, oppure usa un protocollo di routing come OSPF, che ha i suoi messaggi di controllo.

Problemi comuni

SintomoCausa probabileCosa fare
Tunnel0 “up/down” sul CiscoManca la rotta verso l’IP pubblico remoto, oppure keepalive senza rispostaVerifica show ip route 203.0.113.10; prova senza keepalive
Nessun pacchetto GRE con tcpdump su UbuntuGRE bloccato da un firewall o dal providerControlla l’ACL sul Cisco e il firewall di Ubuntu; alcuni modem/router del provider bloccano il protocollo 47
Ping tra i tunnel OK, tra le LAN noInstradamento disattivato o gateway sbagliato sui clientsysctl net.ipv4.ip_forward deve valere 1; controlla le rotte dei client
Ping OK, ma siti e condivisioni si bloccanoMTU/MSSVerifica ip tcp adjust-mss sul Cisco e la regola MSS su Ubuntu
Ubuntu dietro un router con NATGRE non attraversa bene il NATInoltra il protocollo 47 verso Ubuntu, oppure usa IPsec con NAT-T o WireGuard

Il passo successivo

Il tunnel funziona, ma è in chiaro. Il passo successivo è proteggerlo con IPsec: nella guida GRE su IPsec tra Cisco e Ubuntu cifriamo lo stesso tunnel senza cambiare indirizzi e rotte. Per un collegamento IPsec puro, senza GRE, vedi VPN IPsec tra Cisco e Ubuntu con strongSwan.

Prima di andare in produzione

Prova sempre la configurazione in laboratorio, salva quella attuale prima di modificarla e tieni un accesso di emergenza (console o accesso fuori banda) quando lavori su firewall e VPN da remoto.