Cos’è una VPN?
Una VPN (Virtual Private Network) è una protocollo che permette di creare una rete virtuale, simulando una connessione diretta tra due o più dispositivi. Le VPN sono anche utilizzate per garantire la sicurezza e la privacy delle comunicazioni su Internet, crittografando i dati e nascondendo l’indirizzo IP dell’utente, facendolo apparire come se fosse connesso a un altro luogo.
Loading diagram...
WireGuard
WireGuard è un software open-source per la creazione di VPN ad alte prestazioni. È progettato per essere semplice, veloce e sicuro, utilizzando algoritmi crittografici moderni. WireGuard è disponibile su diverse piattaforme, tra cui Linux, Windows, macOS, iOS e Android, progettato per essere facile da configurare e utilizzare. WireGuard è stato integrato nel kernel Linux a partire dalla versione 5.6, il che significa che può essere utilizzato direttamente come modulo del kernel, migliorando le prestazioni e la sicurezza.
IAC-VPN
Sebbene installare e configurare una VPN non sia una operazione troppo complessa, ripeterla più volte o eseguirla al volo nel momento di bisogno sarebbe fastidioso e propenso a errori. Per evitare questo, ho preparato una serie di script di orchestrazione che vanno ad utilizzare Terraform e Ansible per automatizzare l’intero processo. La repository contenente tutto il necessario è disponibile su GitHub,
Provisioning
Per mettere su la nostra topologia, ci serve un server VPS. Il modo più comodo per crearlo ed assicurarsi che sia sempre raggiungibile da qualsiasi sorgente è utilizzare un provider di cloud computing, sebbene nulla vieti di utilizzare un server fisico o una macchina virtuale in locale.
Per poter supportare quante più configurazioni possibili utilizziamo una serie di configurazioni Terraform che includono Google Cloud, Oracle Cloud e OpenStack.
Nulla vieta di utilizzare un provider diverso, ma dovrete modificare i file di configurazione per adattarli al vostro provider, o addirittura creare tutte le risorse necessarie con l’interfaccia grafica messa a disposizione dal provider.
Per utilizzare Terraform, bisogna installarlo e configurare le credenziali per il provider scelto. La procedura è diversa per ogni provider, quindi va consultata la documentazione ufficiale. Dopo aver compiuto la scelta, e dopo aver installato Terraform, dovrete:
- Installare le dipendenze necessarie con
terraform init
- Creare un file
terraform.tfvars
con le variabili necessarie per il provider scelto - Eseguire
terraform plan
per vedere quali risorse verranno create - Eseguire
terraform apply
per creare le risorse - Eseguire
terraform destroy
per distruggere le risorse create - Eseguire
terraform output
per vedere le informazioni sulle risorse create
Script di provisioning
Se state utilizzando bash, potete utilizzare lo script di provisioning che trovate nella repository con
./run.sh <provider>
Provisioning manuale
In generale dovrete:
- Creare una VPS con il provider scelto
- Assicurarsi che le regole di sicurezza permettano il traffico in entrata e in uscita almeno sulle porte TCP 22 (SSH), 80 (HTTP) e UDP 51820 (WireGuard)
- Creare una macchina virtuale con Linux (preferibilmente Debian based)
- Creare una chiave SSH per accedere al server
Configurare WireGuard
A questo punto possiamo procedere con la configurazione di WireGuard. Per farlo utilizziamo Ansible, che ci permette di definire una serie di task da eseguire in sequenza in maniera automatica ed idempotente.
Per utilizzare Ansible, dovrete installarlo e configurare le credenziali per il server scelto.
C’è poi da configurare il file inventory
con le informazioni sul server, come l’indirizzo IP e la chiave SSH.
Fra le variabili che bisogna necessariamente definire ci sono:
all:
hosts:
vpn_server:
ansible_host: server_ip # ip pubblico del server
ansible_user: ubuntu # username del server
vpn_client:
ansible_host: localhost # ip del client
ansible_connection: local # se il client è in locale
vars:
wireguard:
internet: true # se true, la vpn verrà usata per connettersi a internet
net: 10.0.0.0/24 # rete della vpn
server:
sk: key! | # chiave privata del server
pk: pkey! | # chiave pubblica del server
port: 51820 # porta del server
vpn_addr: "10.0.0.1" # indirizzo che il server utilizza all'interno della vpn
out_interface: ens3 # interfaccia di rete del server per connettersi a internet
clients:
- sk: key! | # chiave privata del client
- pk: pkey! | # chiave pubblica del client
vpn_addr: "10.0.0.2" # indirizzo che il client utilizza all'interno della vpn
Generare le chiavi
Per generare le chiavi, potete utilizzare il comando
wg genkey | tee privatekey | wg pubkey > publickey
I file privatekey
e publickey
conterranno rispettivamente la chiave privata e la chiave pubblica.
Potete quindi copiare il contenuto di questi nei campi sk
e pk
del file inventory
.
Ripetere l’operazione per il server e per ogni client che volete aggiungere alla VPN.
Lanciare Ansible
Per lanciare Ansible, dovrete eseguire il comando
ansible-playbook -i inventory playbook.yml
o, più semplicemente, eseguire lo script
./run.sh wireguard
Configurare il client
Configurare il client è piuttosto semplice.
Potete lasciare che Ansible si occupi di tutto, oppure potete farlo manualmente.
Nel primo caso, dovrete assicurarvi che l’ip del client sia localhost
e che abbiate aggiunto la flag --ask-become-pass
per permettere ad Ansible di eseguire i comandi con i privilegi di root.
Se invece avete deciso di farlo manualmente, dovrete installare WireGuard e configurarlo.
Nella pratica, basta aggiungere il file di configurazione che Ansible ha creato per voi, che si trova in /etc/wireguard/wg0.conf
.
Questo conterrà qualcosa di simile a questo:
# /etc/wireguard/wg0.conf
[Interface]
Address = 10.0.0.2/24
PrivateKey = <chiave privata del client>
MTU = 1420
PostUp = ping -c1 10.0.0.1
[Peer]
PublicKey = <chiave pubblica del server>
Endpoint = <ip del server>:51820
AllowedIPs = 10.0.0.0/24
PersistentKeepalive = 25
Infine, per avviare la VPN, dovrete eseguire il comando
sudo wg-quick up wg0
Utilizzare TCP
Loading diagram...
Wireguard supporta unicamente il protocollo di trasporto UDP, più veloce e leggero rispetto a TCP.
Tuttavia certe configurazioni di rete potrebbero bloccare il traffico UDP, rendendo impossibile l’utilizzo di Wireguard.
Per aggirare il problema, possiamo utilizzare un tunnel TCP, che incapsula il traffico UDP in pacchetti TCP.
La mia scelta è ricaduta su wstunnel, un piccolo strumento open-source che utilizza WebSocket proprio per questo scopo.
La repository mette disposizione i binari precompilati, ma nulla vi vieta di produrre l’eseguibile a partire dal codice sorgente, soprattutto nel caso l’antivirus del vostro sistema operativo non gradisca i file.
Dovo esservi assicurati che sia eseguibile ed averlo messo in una cartella presente nel PATH, potete procedere lanciando prima il server
wstunnel server --restrict-to localhost:51820 wss://0.0.0.0:80
e poi il client
wstunnel client -L 'udp://51820:localhost:51820?timeout_sec=0' wss://<server_ip>:80