Get Rewarded! We will reward you with up to €50 credit on your account for every tutorial that you write and we publish!

Creazione di un tunnel GRE su Linux

profile picture
Author
Fabrizio La Rosa
Published
2019-08-20
Time to read
6 minutes reading time

Introduzione

Il Generic Routing Encapsulation (GRE) è un protocollo di rete progettato da Cisco Systems che permette di incapsulare una grande varietà di protocolli di terzo livello all'interno di un collegamento virtuale punto-a-punto.

Un tunnel GRE è utile in determinate situazioni, come proteggere un server senza una protezione DDoS utilizzandone un altro che invece la possiede o per permettere ad un'applicazione che utilizza solo IPv4 di accettare anche IPv6.

Prerequisiti

Prima di tutto, dovremo avere due server con accesso amministrativo. I due server che andremo ad utilizare verranno chiamati Server A e Server B e avranno le seguenti caratteristiche:

  • Server A - Il server alla quale i client si connetteranno
    • IP: 198.51.100.1
    • IP interno del tunnel GRE: 10.0.0.1
  • Server B - Il server sulla quale verranno eseguite le applicazioni
    • IP: 203.0.113.1
    • IP interno del tunnel GRE: 10.0.0.2

1 - Caricamento del modulo

Per creare un tunnel GRE su Linux dovremo avere il modulo ip_gre caricato nel kernel. Per essere sicuri che sia caricato utilizziamo:

sudo modprobe ip_gre
lsmod | grep gre

E dovremmo vedere:

ip_gre                 #####  0
gre                    #####  1 ip_gre

Se ci sarà scritto qualcos'altro è possibile che il kernel non supporti il tunnelling GRE.

Per far passare il traffico all'interno del tunnel GRE utilizzeremo iptables e iproute2 che dovrebbero essere già presenti nella maggior parte delle distribuzioni Linux. Nel caso non fossero installate possiamo utilizzare il seguente comando

per le distribuzioni derivate da Debian:

sudo apt install iptables iproute2

per le distribuzioni derivate da Red Hat:

sudo yum install iptables iproute2

2 - Creazione del tunnel

Per prima cosa dobbiamo creare il nostro tunnel.

Sul Server A eseguiamo questi comandi per abilitare l'ip forwarding:

sudo echo 'net.ipv4.ip_forward=1' >> /etc/sysctl.conf
sudo sysctl -p

Ora creiamo una nuova interfaccia di rete che verrà utilizzata per il tunnel GRE:

sudo ip tunnel add gre1 mode gre local 198.51.100.1 remote 203.0.113.1 ttl 255
sudo ip addr add 10.0.0.1/30 dev gre1
sudo ip link set gre1 up

Successivamente facciamo la stessa cosa sul Server B cambiando gli IP:

sudo ip tunnel add gre1 mode gre local 203.0.113.1 remote 198.51.100.1 ttl 255
sudo ip addr add 10.0.0.2/30 dev gre1
sudo ip link set gre1 up

2.1 - Ping Test

Sul Server A utilizziamo:

ping 10.0.0.2

E sul Server B utilizziamo:

ping 10.0.0.1

Se il ping funziona allora abbiamo creato correttamente il tunnel GRE.

3 - Aggiunta nuove Route

Le route sono necessarie per fare in modo che tutti i dati che passano dal tunnel GRE vengano gestiti correttamente.

Sul Server B eseguiamo:

sudo echo '100 GRE' >> /etc/iproute2/rt_tables
sudo ip rule add from 10.0.0.0/30 table GRE
sudo ip route add default via 10.0.0.1 table GRE

4 - Configurazione NAT

Il NAT è utilizzato per passare i dati da un capo all'altro del tunnel GRE.

Sul Server A eseguiamo:

iptables -t nat -A POSTROUTING -s 10.0.0.0/30 ! -o gre+ -j SNAT --to-source 198.51.100.1

Per provare la connessione in uscita eseguiamo sul Server B questi comandi:

per le distribuzioni derivate da Debian:

sudo apt install curl

per le distribuzioni derivate da Red Hat:

sudo yum install curl

e successivamente:

curl http://www.cpanel.net/showip.cgi --interface 10.0.0.2

A questo punto dovremmo leggere l'IP del Server A.

5 - Inoltro delle porte

Sul Server A eseguiamo questi comandi per consentire a tutti i dati provenienti e indirizzati al Server B di passare:

sudo iptables -A FORWARD -d 10.0.0.2 -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT
sudo iptables -A FORWARD -s 10.0.0.2 -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT

Successivamente, vogliamo inoltrare tutti i dati in transito su determinate porte dal Server A al Server B.

Eseguiamo sul Server A:

sudo iptables -t nat -A PREROUTING -d 198.51.100.1 -p PROTO -m PROTO --dport PORT -j DNAT --to-destination 10.0.0.2

rimpiazzando PORT e PROTO con la porta e il protocollo (TCP o UDP) che ci interessa.

Per esembio, per inoltrare tutti i dati relativi ad un Webserver (Porta TCP 80) utilizzeremo:

sudo iptables -t nat -A PREROUTING -d 198.51.100.1 -p TCP -m TCP --dport 80 -j DNAT --to-destination 10.0.0.2

Dobbiamo farlo per tutte le porte che vorremo utilizzare.

6 - Rendere il tunnel persistente

Al riavvio del server la maggior parte delle cose che abbiamo fatto verrà cancellata. Per assicurarsi che il tunnel GRE continui a funzionare anche dopo un riavvio dovremo modificare il file /etc/rc.local aggiungendo tutti i comandi che abbiamo fatto (ad eccezione del comando "echo"!) prima del exit 0.

Conclusione

Ora, se ci connettiamo al Server A utilizzando le porte che abbiamo configurato (ad esempio la porta TCP 80) andremo in realtà a connetterci al Server B senza rendercene conto.

Nota: se utilizzi CSF per gestire iptables potrebbe essere necessario inserire tutti i comandi realtivi a iptables che abbiamo fatto nel file /etc/csf/csfpost.sh e inserire entrambi gli IP dei server (sia quello pubblico che quello interno del tunnel) nel file /etc/csf/csf.allow.

License: MIT
Want to contribute?

Get Rewarded: Get up to €50 in credit! Be a part of the community and contribute. Do it for the money. Do it for the bragging rights. And do it to teach others!

Report Issue
Try Hetzner Cloud

Get 20€ free credit!

Valid until: 31 December 2024 Valid for: 3 months and only for new customers
Get started
Want to contribute?

Get Rewarded: Get up to €50 credit on your account for every tutorial you write and we publish!

Find out more