Contenuti




Implementare una VPN WireGuard

Server su OCI e client Linux con configurazione completa


Implementare una VPN WireGuard

Guida pratica per collegare un server OCI a un client Linux con WireGuard, usando UFW per il routing e il NAT.

In questo articolo
  • Requisiti server e client
  • Generazione chiavi e scambio
  • Configurazione di server e client
  • Firewall UFW con NAT e routing
  • Test e troubleshooting

Cos’è WireGuard e perché usarlo

WireGuard è un protocollo e tool VPN di nuova generazione, open source, progettato per essere estremamente semplice, veloce e sicuro. A differenza di VPN più datate come OpenVPN o IPSec, WireGuard punta su:

  • Criptografia moderna: utilizza algoritmi all’avanguardia (come ChaCha20 per la cifratura) garantendo un alto livello di sicurezza.
  • Prestazioni elevate: grazie a un codice snello (solo poche migliaia di linee) è molto efficiente; ciò si traduce in throughput elevato e bassa latenza anche su hardware modesto.
  • Facilità d’uso: la configurazione di WireGuard richiede pochi passaggi e file di configurazione semplici. Questo ne facilita l’implementazione e la manutenzione rispetto a soluzioni più complesse.
  • Multi-piattaforma: è disponibile su Linux (dove è integrato nel kernel dalle versioni recenti), ma anche su Windows, macOS, Android, iOS, etc. Ciò significa che il client Zorin OS di esempio (o qualsiasi altra distro Linux) e il server Linux in cloud possono comunicare senza problemi di compatibilità.

In sintesi, WireGuard offre una VPN veloce, semplice e sicura, ideale per collegare in modo protetto un server cloud (come un’istanza OCI) con client remoti. Proprio per queste caratteristiche è un candidato perfetto a rimpiazzare soluzioni storiche come IPSec e OpenVPN in molti scenari.

Requisiti lato server e client

Lato Server (OCI): Avremo bisogno di un’istanza cloud (ad esempio la Always Free di Oracle Cloud) con un sistema operativo Linux aggiornato. Vanno bene distribuzioni come Oracle Linux, Ubuntu o Debian – in questo articolo presupponiamo di usare una distribuzione tipo Ubuntu 20.04/22.04 LTS per semplicità. I requisiti fondamentali sono:

  • Accesso root o sudo: bisogna poter installare pacchetti e modificare configurazioni di sistema sul server.
  • Kernel compatibile: le moderne versioni di Linux includono WireGuard nel kernel (dalla versione 5.6 in poi). Su Ubuntu e derivate, se il kernel è più vecchio, il pacchetto wireguard-dkms provvederà a installare il modulo. In genere sulle immagini OCI aggiornate non ci sono problemi di compatibilità.
  • Connessione di rete e IP pubblico: il server deve avere un IP pubblico (o un modo per essere raggiungibile da Internet) per consentire al client di connettersi. Su OCI, l’istanza può avere un IP pubblico assegnato o si può usare l’IP pubblico del load balancer/VPN endpoint. Inoltre, bisogna assicurarsi che il traffico UDP sulla porta WireGuard (default 51820/udp) sia permesso a livello di cloud (VCN) – approfondiremo le regole firewall più avanti.
  • Pacchetti software: installare WireGuard sul server. Sulle distribuzioni Debian/Ubuntu si può installare il metapacchetto wireguard (che include strumenti e modulo) oppure wireguard-tools. Su Oracle Linux si utilizzerà dnf install -y wireguard-tools (docs.oracle.com)

Lato Client (Zorin OS): Zorin OS è basato su Ubuntu, quindi i requisiti sono simili. La guida vale anche per qualsiasi distro basata su Ubuntu (es. Linux Mint, Pop!_OS, Elementary).

  • Zorin OS aggiornato: assicurarsi di avere aggiornato il sistema. Zorin OS 16 (basato su Ubuntu 20.04) o versioni successive funzionano bene. Anche qui è necessario accesso amministrativo (sudo) per installare pacchetti.
  • WireGuard tools sul client: installare il client WireGuard. Su Zorin (Ubuntu) si può usare sudo apt install wireguard wireguard-tools. In alternativa, il client ufficiale WireGuard (con interfaccia grafica) esiste per Windows/macOS/mobile, ma su Linux di solito si usa direttamente l’integrazione nel sistema operativo.
  • Connettività Internet: il client deve poter raggiungere l’IP pubblico del server OCI. Se il client è dietro NAT (ad esempio connesso via router casalingo), non è un problema: WireGuard funzionerà comunque (eventualmente useremo una keepalive per mantenere aperta la comunicazione NAT).

Riepilogo requisiti: In breve, serve una macchina Linux su OCI con WireGuard installato e un PC Zorin OS con WireGuard installato. Entrambi avranno bisogno di scambiare chiavi pubbliche e comunicare tramite la porta UDP configurata. Nel prossimo step genereremo le chiavi crittografiche necessarie.

Generazione delle chiavi

La generazione delle chiavi avviene tramite gli strumenti di WireGuard (una volta installati). I comandi vanno eseguiti separatamente su server e client per ottenere due coppie distinte:

1) Generare chiavi sul server: Accedere al server via SSH. Si consiglia di creare una directory sicura per le chiavi e limitare i permessi:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
# Creare directory per le configurazioni WireGuard
sudo mkdir -p /etc/wireguard
cd /etc/wireguard

# Generare la chiave privata del server
wg genkey | sudo tee server_private_key

# Generare la chiave pubblica del server dalla privata
sudo cat server_private_key | wg pubkey | sudo tee server_public_key

# Impostare permessi sicuri
sudo chmod 600 server_private_key
sudo chmod 644 server_public_key

2) Generare chiavi sul client: Sul computer Zorin OS eseguire comandi simili:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
# Creare directory per le configurazioni WireGuard
sudo mkdir -p /etc/wireguard
cd /etc/wireguard

# Generare la chiave privata del client
wg genkey | sudo tee client_private_key

# Generare la chiave pubblica del client
sudo cat client_private_key | wg pubkey | sudo tee client_public_key

# Impostare permessi sicuri
sudo chmod 600 client_private_key
sudo chmod 644 client_public_key

3) Scambiare le chiavi pubbliche: Annotare le chiavi pubbliche di server e client. Queste dovranno essere inserite nelle rispettive configurazioni:

1
2
3
4
5
# Sul server - visualizzare la chiave pubblica del server
sudo cat /etc/wireguard/server_public_key

# Sul client - visualizzare la chiave pubblica del client
sudo cat /etc/wireguard/client_public_key

Configurazione del server WireGuard

1) Creare il file di configurazione del server:

1
sudo nano /etc/wireguard/wg0.conf

Inserire la seguente configurazione, sostituendo i valori con le proprie chiavi e indirizzi IP:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
[Interface]
# Chiave privata del server
PrivateKey = <SERVER_PRIVATE_KEY>

# Indirizzo IP interno del server nella VPN
Address = 10.0.0.1/24

# Porta su cui il server ascolta (default 51820)
ListenPort = 51820

# Configurazione client
[Peer]
# Chiave pubblica del client
PublicKey = <CLIENT_PUBLIC_KEY>

# Range di IP che il client può usare nella VPN
AllowedIPs = 10.0.0.2/32

Sostituisci <PUBLIC_IF> con l’interfaccia di rete pubblica del server (es. eth0, ens3) quando configuri UFW. Puoi individuarla con:

1
ip route get 1.1.1.1 | awk '{print $5; exit}'

2) Abilitare l’IP forwarding sul server:

1
2
3
4
5
6
# Abilitare subito
sudo sysctl -w net.ipv4.ip_forward=1

# Rendere persistente
echo 'net.ipv4.ip_forward = 1' | sudo tee /etc/sysctl.d/99-wireguard.conf
sudo sysctl --system

3) Configurare il firewall del sistema (UFW su Ubuntu/Debian/derivate):

1
2
3
4
5
6
7
8
9
# Consenti WireGuard e SSH
sudo ufw allow 51820/udp
sudo ufw allow ssh

# Consenti traffico instradato dalla VPN verso Internet
sudo ufw route allow in on wg0 out on <PUBLIC_IF>

# Abilita UFW
sudo ufw --force enable

Accesso ai servizi interni via VPN (opzionale):

1
2
3
4
5
6
# SSH verso il server dall'interno della VPN
sudo ufw allow in on wg0 to any port 22

# HTTP/HTTPS verso servizi interni
sudo ufw allow in on wg0 to any port 80
sudo ufw allow in on wg0 to any port 443

Abilitare NAT con UFW:

1
sudo nano /etc/ufw/before.rules

Aggiungi queste righe prima della sezione *filter:

1
2
3
4
*nat
:POSTROUTING ACCEPT [0:0]
-A POSTROUTING -s 10.0.0.0/24 -o <PUBLIC_IF> -j MASQUERADE
COMMIT

Poi ricarica UFW:

1
sudo ufw reload

Se usi firewalld (Oracle Linux/CentOS/RHEL):

1
2
3
sudo firewall-cmd --permanent --add-port=51820/udp
sudo firewall-cmd --permanent --add-masquerade
sudo firewall-cmd --reload

Configurazione del client WireGuard

1) Creare il file di configurazione del client:

1
sudo nano /etc/wireguard/wg0.conf

Inserire la configurazione client:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
[Interface]
# Chiave privata del client
PrivateKey = <CLIENT_PRIVATE_KEY>

# Indirizzo IP interno del client nella VPN
Address = 10.0.0.2/24

# DNS da usare (opzionale)
DNS = 8.8.8.8, 1.1.1.1

[Peer]
# Chiave pubblica del server
PublicKey = <SERVER_PUBLIC_KEY>

# IP pubblico e porta del server OCI
Endpoint = <SERVER_PUBLIC_IP>:51820

# Traffico da instradare attraverso la VPN
# 0.0.0.0/0 = tutto il traffico (full tunnel)
# 10.0.0.0/24 = solo traffico VPN interno (split tunnel)
AllowedIPs = 0.0.0.0/0

# Keepalive per mantenere la connessione attraverso NAT
PersistentKeepalive = 25

Configurazione del firewall OCI

1) Accedere alla console OCI:

  • Navigare su “Networking” → “Virtual Cloud Networks”
  • Selezionare la VCN dell’istanza
  • Andare su “Security Lists”

2) Aggiungere regola ingresso:

  • Source Type: CIDR
  • Source CIDR: 0.0.0.0/0
  • IP Protocol: UDP
  • Destination Port Range: 51820
  • Description: WireGuard VPN

3) Configurazioni aggiuntive (opzionali): Se si vuole permettere l’accesso a servizi interni attraverso la VPN:

  • Aggiungere regole per le porte necessarie (es. SSH 22, HTTP 80, HTTPS 443)
  • Source CIDR: 10.0.0.0/24 (range VPN interno)

Avvio e test della connessione

1) Avviare WireGuard sul server:

1
2
3
4
5
6
7
8
# Avviare l'interfaccia wg0
sudo wg-quick up wg0

# Verificare lo stato
sudo wg show

# Abilitare avvio automatico
sudo systemctl enable wg-quick@wg0

2) Avviare WireGuard sul client:

1
2
3
4
5
# Avviare l'interfaccia
sudo wg-quick up wg0

# Verificare lo stato
sudo wg show

3) Test di connettività:

1
2
3
4
5
6
7
8
# Dal client, pingare l'IP interno del server
ping 10.0.0.1

# Verificare l'IP pubblico (dovrebbe essere quello del server OCI)
curl ifconfig.me

# Test DNS
nslookup google.com

4) Verificare i log:

1
2
3
4
5
# Sul server - controllare i log
sudo journalctl -u wg-quick@wg0 -f

# Monitorare il traffico WireGuard
sudo wg show wg0 transfer

Troubleshooting comuni

Problema: Connessione non si stabilisce

  • Verificare che la porta 51820/udp sia aperta nei firewall
  • Controllare che l’IP pubblico del server sia corretto
  • Verificare che le chiavi pubbliche siano corrette nei file di configurazione

Problema: Connessione si stabilisce ma nessun traffico

  • Verificare l’IP forwarding: cat /proc/sys/net/ipv4/ip_forward (deve essere 1)
  • Verificare UFW: sudo ufw status e la regola di NAT in /etc/ufw/before.rules
  • Verificare che AllowedIPs sia configurato correttamente

Problema: DNS non funziona

  • Aggiungere DNS nella configurazione client
  • Se usi resolvconf, verifica che sia installato: sudo apt install resolvconf

Comandi utili per il debug:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
# Visualizzare configurazione attiva
sudo wg show all

# Monitorare traffico in tempo reale
sudo wg show all transfer

# Riavviare interfaccia
sudo wg-quick down wg0 && sudo wg-quick up wg0

# Test connettività con traceroute
traceroute 8.8.8.8

Considerazioni sulla sicurezza

1) Gestione delle chiavi:

  • Mantenere le chiavi private sicure e non condividerle mai
  • Rigenerare le chiavi periodicamente (es. ogni 6 mesi)
  • Usare permessi restrittivi sui file di configurazione (600)

2) Configurazione di rete:

  • Limitare AllowedIPs ai range necessari quando possibile
  • Usare firewall aggiuntivi per limitare l’accesso ai servizi
  • Monitorare i log per attività sospette

3) Aggiornamenti:

  • Mantenere WireGuard e il sistema operativo aggiornati
  • Monitorare le security advisory per WireGuard

Configurazioni avanzate

Più client: Per aggiungere altri client, generare nuove chiavi e aggiungere sezioni [Peer] nel server:

1
2
3
4
5
6
7
8
# Nel server wg0.conf
[Peer]
PublicKey = <CLIENT2_PUBLIC_KEY>
AllowedIPs = 10.0.0.3/32

[Peer]
PublicKey = <CLIENT3_PUBLIC_KEY>
AllowedIPs = 10.0.0.4/32

Site-to-site VPN: Per connettere intere reti, usare range più ampi in AllowedIPs:

1
2
# Esempio per connettere rete 192.168.1.0/24 con 10.0.0.0/24
AllowedIPs = 192.168.1.0/24, 10.0.0.0/24

Conclusioni

WireGuard offre una soluzione VPN moderna, veloce e sicura per connettere client remoti a server cloud. La configurazione tra un’istanza OCI e un client Zorin OS è relativamente semplice una volta compresi i concetti di base.

I vantaggi principali includono:

  • Prestazioni elevate grazie all’implementazione kernel-level
  • Configurazione semplice con pochi file di testo
  • Sicurezza robusta con crittografia moderna
  • Compatibilità multi-piattaforma

Per uso in produzione, considerare l’implementazione di monitoring, backup delle configurazioni e procedure di disaster recovery.

Script utili

wireguard_check.sh

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
#!/usr/bin/env bash
# ============================================================
# wireguard_check.sh
# Controllo rapido stato WireGuard + routing
# ============================================================

WG_IF="wg0"
WG_NET="10.0.0.0/24"

echo "=== 🔐 WireGuard quick check ==="
echo

# 1. Stato servizio
if systemctl is-active --quiet "wg-quick@${WG_IF}"; then
  echo "✅ Servizio wg-quick@${WG_IF} attivo"
else
  echo "❌ Servizio wg-quick@${WG_IF} NON attivo"
fi
echo

# 2. Stato interfaccia
echo "👉 Interfaccia ${WG_IF}:"
ip addr show "$WG_IF" 2>/dev/null || echo "❌ Interfaccia ${WG_IF} non trovata"
echo

# 3. wg show
echo "👉 Peers WireGuard:"
sudo wg show "$WG_IF" 2>/dev/null || echo "❌ Nessun output da 'wg show'"
echo

# 4. Forwarding kernel
echo "👉 IP forwarding:"
sysctl net.ipv4.ip_forward
echo

# 5. UFW NAT per 10.0.0.0/24
echo "👉 Regola NAT per ${WG_NET}:"
grep -n "POSTROUTING.*${WG_NET}" /etc/ufw/before.rules || echo "⚠️ Nessuna regola NAT trovata per ${WG_NET}"
echo

# 6. Route verso rete WireGuard
echo "👉 Route attuali per ${WG_NET}:"
ip route show | grep "${WG_NET}" || echo "⚠️ Nessuna rotta trovata per ${WG_NET}"
echo

echo "✅ Check completato."
echo "Se i peer hanno 'latest handshake' recente e c'è la regola NAT, la VPN è ok."