Guida Creazione di un tunnel GRE su Linux

Fabrimat

Utente Silver
10 Aprile 2013
18
7
7
54
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.

Per cosa può essere utilizzato?
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.

Per creare un tunnel GRE su Linux dovremo avere il modulo ip_gre caricato nel kernel. Per essere sicuri che sia caricato utilizziamo:
Bash:
sudo modprobe ip_gre
lsmod | grep gre
E dovremmo vedere:
Codice:
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:
Bash:
sudo apt install iptables iproute2
per le distribuzioni derivate da Red Hat:
Bash:
sudo yum install iptables iproute2

Terminologia
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 - Creazione del tunnel
Per prima cosa dobbiamo creare il nostro tunnel.

Sul Server A eseguiamo questi comandi per abilitare l'ip forwarding:
Bash:
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:
Bash:
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:
Bash:
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 - Proviamo il tunnel GRE con il Ping
Sul Server A utilizziamo:
Bash:
ping 10.0.0.2
E sul Server B utilizziamo:
Bash:
ping 10.0.0.1
Se il ping funziona allora abbiamo creato correttamente il tunnel GRE.

3 - Aggiunta delle nuove route nella route table
Le route sono necessarie per fare in modo che tutti i dati che passano dal tunnel GRE vengano gestiti correttamente.

Sul Server B eseguiamo:
Bash:
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 - NAT per le connessioni in uscita
Il NAT è utilizzato per passare i dati da un capo all'altro del tunnel GRE.

Sul Server A eseguiamo:
Bash:
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:
Bash:
sudo apt install curl
per le distribuzioni derivate da Red Hat:
Bash:
sudo yum install curl
e successivamente:
Bash:
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:
Bash:
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:
Bash:
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:
Bash:
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 GRE 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