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
- IP:
- Server B - Il server sulla quale verranno eseguite le applicazioni
- IP:
203.0.113.1
- IP interno del tunnel GRE:
10.0.0.2
- IP:
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:
1
2
sudo modprobe ip_gre
lsmod | grep gre
E dovremmo vedere:
1
2
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:
1
sudo apt install iptables iproute2
per le distribuzioni derivate da Red Hat:
1
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:
1
2
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:
1
2
3
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:
1
2
3
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:
1
ping 10.0.0.2
E sul Server B utilizziamo:
1
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:
1
2
3
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:
1
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:
1
sudo apt install curl
per le distribuzioni derivate da Red Hat:
1
sudo yum install curl
e successivamente:
1
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:
1
2
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:
1
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:
1
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 relativi 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
.