VPNSmith
self-host-vpnINFO

VPN autogestito su Contabo: guida completa a WireGuard 2026

Configurazione passo-passo di WireGuard su un VPS Contabo (€4,99/mese). Script di bootstrap, UFW, fail2ban, client macOS/iOS/Linux/Windows. Limiti onesti rispetto ai VPN commerciali.

Di Eric Gerard · Fondateur · VPNSmith — Spécialiste self-host VPN & VPS GDPR15 min letturaPhoto: Taylor Vick — Unsplash

Stanco di pagare €12,99/mese a NordVPN dopo l'anno promozionale. Vuoi un tunnel criptato condiviso con nessuno, ospitato in una giurisdizione GDPR, la cui configurazione controlli riga per riga. Buone notizie: si configura in 20 minuti su un VPS Contabo a €4,99/mese, e questa guida ti fornisce ogni comando. Niente marketing, niente astrazioni — solo lo script esatto di livello produttivo.

Come autogestire un VPN con WireGuard su un VPS?

Autogestire un VPN WireGuard richiede circa 20 minuti: procurati un VPS Contabo S (€4,99/mese, Ubuntu 24.04), esegui apt install wireguard, genera le chiavi del server, scrivi un wg0.conf di 10 righe con subnet 10.66.66.0/24 sulla porta 51820, abilita l'inoltro IP e aggiungi NAT tramite iptables. Costo: meno di €60/anno contro ~€540 per NordVPN in 5 anni.

Perché autogestire invece di un servizio commerciale

Un VPN commerciale ti vende una promessa: nessun log, IP condiviso tra migliaia di utenti, giurisdizione "amica dei no-log" (Panama, BVI, Svizzera). Sulla carta è solido. In pratica:

  • IP condiviso = reputazione condivisa. Quando 4.000 utenti NordVPN escono attraverso lo stesso IP, erediti le loro blacklist. Stripe chiederà un 3DS extra. Cloudflare ti servirà sfide infinite. Ospiti il tuo VPN = il tuo IP pulito.
  • No-log non verificabile in tempo reale. Un audit PwC convalida una politica in un momento. Tra gli audit, ordini giudiziari (subpoena USA, ordini UE) possono forzare la registrazione temporanea. Sul tuo VPS, decidi tu. Puoi cancellare quando vuoi.
  • Prezzi che raddoppiano al rinnovo. NordVPN 2 anni: €71,76. Rinnovo annuale: €156/anno. In 5 anni: ~€600. Un VPS Contabo S in 5 anni: ~€300. E puoi ospitare altri servizi su di esso.

Il compromesso onesto: non sbloccherai Netflix US con un VPS dedicato (Netflix banna gli ASN dei datacenter). Per lo streaming, documentiamo una soluzione ibrida nella guida al bypass DPI.

Scegliere il giusto VPS Contabo

Contabo offre tre gamme rilevanti per un VPN personale:

PianoPrezzo/mesevCPURAMBandaIdeale per
VPS S (legacy)€4,9948 GB200 MbpsVPN solo 1-3 dispositivi
VPS S Cloud€6,994 vCPU NVMe8 GB600 MbpsVPN familiare 5-10 dispositivi
Cloud VPS 10€9,996 vCPU16 GB1 GbpsMulti-tunnel + servizi extra

La nostra scelta predefinita: VPS S a €4,99/mese. Per il 90% degli usi individuali, più che sufficiente. Banda garantita di 200 Mbps (testata con iperf3, sostenuta a 195 Mbps).

Datacenter consigliato: Norimberga (DE) per latenza <30 ms dall'Europa continentale. Se sei in Canada/USA, scegli US Central (St. Louis).

Configurazione passo-passo

Passo 1 — Procurarsi il VPS

Su contabo.com, scegli VPS S, Ubuntu 24.04 LTS, password root (creeremo un utente normale più tardi), datacenter di Norimberga. Paga con carta o PayPal. Attivazione: email entro ~5 minuti con l'IP pubblico e la password root.

Passo 2 — Mettere in sicurezza il server

Prima connessione SSH:

ssh root@YOUR_PUBLIC_IP
# La password è nell'email di Contabo

Crea un utente non-root, aggiungi la tua chiave SSH, disabilita il login root:

adduser ericg
usermod -aG sudo ericg
mkdir -p /home/ericg/.ssh
# Incolla la tua chiave pubblica (~/.ssh/id_ed25519.pub localmente)
nano /home/ericg/.ssh/authorized_keys
chmod 700 /home/ericg/.ssh
chmod 600 /home/ericg/.ssh/authorized_keys
chown -R ericg:ericg /home/ericg/.ssh

# Disabilita login root + password
sed -i 's/^PermitRootLogin .*/PermitRootLogin no/' /etc/ssh/sshd_config
sed -i 's/^#PasswordAuthentication.*/PasswordAuthentication no/' /etc/ssh/sshd_config
systemctl restart ssh

Esci dalla shell root, riconnettiti via ssh ericg@YOUR_IP. Se funziona, continua.

Installa firewall e fail2ban:

sudo apt update && sudo apt upgrade -y
sudo apt install -y ufw fail2ban
sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw allow 22/tcp
sudo ufw allow 51820/udp
sudo ufw --force enable
sudo systemctl enable --now fail2ban

Passo 3 — Installa e configura WireGuard

sudo apt install -y wireguard qrencode

# Generazione chiavi server
cd /etc/wireguard
sudo wg genkey | sudo tee server_private.key | sudo wg pubkey | sudo tee server_public.key
sudo chmod 600 server_private.key
SERVER_PRIV=$(sudo cat server_private.key)

Identifica la tua interfaccia pubblica (spesso ens3 o eth0):

ip route | grep default
# default via X.X.X.X dev ens3 ...

Crea /etc/wireguard/wg0.conf:

sudo nano /etc/wireguard/wg0.conf

Contenuto (sostituisci ens3 con la tua interfaccia se diversa):

[Interface]
PrivateKey = PASTE_SERVER_PRIV_HERE
Address = 10.66.66.1/24
ListenPort = 51820
PostUp = iptables -A FORWARD -i %i -j ACCEPT; iptables -A FORWARD -o %i -j ACCEPT; iptables -t nat -A POSTROUTING -o ens3 -j MASQUERADE
PostDown = iptables -D FORWARD -i %i -j ACCEPT; iptables -D FORWARD -o %i -j ACCEPT; iptables -t nat -D POSTROUTING -o ens3 -j MASQUERADE

Abilita l'inoltro IP:

echo "net.ipv4.ip_forward=1" | sudo tee -a /etc/sysctl.conf
sudo sysctl -p

Avvia WireGuard:

sudo systemctl enable --now wg-quick@wg0
sudo wg show
# Dovresti vedere "interface: wg0" e "listening port: 51820"

Passo 4 — Genera un client

Per ogni dispositivo:

cd /etc/wireguard
sudo wg genkey | sudo tee macbook_private.key | sudo wg pubkey | sudo tee macbook_public.key
CLIENT_PRIV=$(sudo cat macbook_private.key)
CLIENT_PUB=$(sudo cat macbook_public.key)
SERVER_PUB=$(sudo cat server_public.key)

Crea /tmp/macbook.conf (sul server, per generare il QR — poi elimina):

[Interface]
PrivateKey = PASTE_CLIENT_PRIV
Address = 10.66.66.2/24
DNS = 1.1.1.1, 9.9.9.9

[Peer]
PublicKey = PASTE_SERVER_PUB
Endpoint = YOUR_PUBLIC_IP:51820
AllowedIPs = 0.0.0.0/0
PersistentKeepalive = 25

Aggiungi questo peer al server:

sudo wg set wg0 peer PASTE_CLIENT_PUB allowed-ips 10.66.66.2/32
# E persisti:
sudo nano /etc/wireguard/wg0.conf
# Aggiungi in fondo:
# [Peer]
# PublicKey = PASTE_CLIENT_PUB
# AllowedIPs = 10.66.66.2/32

Per iOS/Android: genera il codice QR

qrencode -t ansiutf8 &lt; /tmp/macbook.conf

Scansiona con l'app ufficiale WireGuard. Attiva. Fatto.

Passo 5 — Verifica che non ci siano perdite

Sul tuo client connesso al tunnel:

  1. Vai su ipleak.net — l'IP deve essere quello del VPS Contabo, non il tuo.
  2. Vai su browserleaks.com/webrtc — nessun IP locale esposto.
  3. Vai su dnsleaktest.com — DNS risolto tramite 1.1.1.1 (Cloudflare).

Se appare una perdita WebRTC: abilita il kill switch in WireGuard mobile ("On-Demand"), o blocca WebRTC in Firefox (about:configmedia.peerconnection.enabledfalse).

Ulteriore messa in sicurezza

Indurimenti consigliati per la produzione:

  • Audit Lynis: sudo apt install lynis && sudo lynis audit system. Punteggio obiettivo: 80+/100.
  • SSH su porta personalizzata: cambia la porta in /etc/ssh/sshd_config a 2222, aggiorna UFW.
  • Disabilita IPv6 se non usato: sudo sysctl -w net.ipv6.conf.all.disable_ipv6=1 (persisti in sysctl.conf).
  • Log minimi: di default, journald conserva 4 settimane. Riduci a 7 giorni tramite /etc/systemd/journald.conf se il modello di minaccia è severo.
  • Backup Contabo: abilita snapshot automatici nel pannello Contabo (€1/mese, non per i log ma per un rapido recupero dopo un errore).

Configurazione automatizzata tramite un playbook Ansible

Server racks illuminati di blu in un data center
Server racks illuminati di blu in un data center

Se prevedi di procurarti più di un VPS — o semplicemente vuoi ricostruire il tuo tunnel in 3 minuti dopo un incidente — automatizzare tramite Ansible evita di digitare nuovamente i comandi sopra. Ecco il playbook che eseguiamo in produzione. Idempotente (sicuro da rieseguire), testato su Ubuntu 24.04 LTS Contabo Norimberga a maggio 2026.

Prerequisiti locali

# Sul tuo laptop
pip install --user ansible
mkdir -p ~/vpn-ansible && cd ~/vpn-ansible

Crea inventory.yml (sostituisci l'IP con quello che Contabo ti ha inviato via email):

all:
  hosts:
    vpn1:
      ansible_host: YOUR_PUBLIC_IP
      ansible_user: root
      ansible_python_interpreter: /usr/bin/python3

Il playbook.yml

---
- name: Bootstrap VPNSmith WireGuard su Contabo
  hosts: vpn1
  become: yes
  vars:
    admin_user: ericg
    admin_ssh_key: "{{ lookup('file', '~/.ssh/id_ed25519.pub') }}"
    wg_subnet: "10.66.66.0/24"
    wg_port: 51820
  tasks:

    - name: Aggiorna cache apt
      apt:
        update_cache: yes
        cache_valid_time: 3600

    - name: Aggiorna tutti i pacchetti
      apt:
        upgrade: dist
        autoremove: yes

    - name: Installa pacchetti di hardening + WireGuard
      apt:
        name:
          - ufw
          - fail2ban
          - wireguard
          - qrencode
          - unattended-upgrades
        state: present

    - name: Crea utente admin
      user:
        name: "{{ admin_user }}"
        groups: sudo
        shell: /bin/bash
        password: "!"

    - name: Autorizza chiave SSH admin
      authorized_key:
        user: "{{ admin_user }}"
        key: "{{ admin_ssh_key }}"
        state: present

    - name: Disabilita login root SSH + password
      lineinfile:
        path: /etc/ssh/sshd_config
        regexp: "{{ item.regex }}"
        line: "{{ item.line }}"
      loop:
        - { regex: '^#?PermitRootLogin', line: 'PermitRootLogin no' }
        - { regex: '^#?PasswordAuthentication', line: 'PasswordAuthentication no' }
      notify: restart ssh

    - name: Configura politiche predefinite UFW
      ufw:
        direction: "{{ item.direction }}"
        policy: "{{ item.policy }}"
      loop:
        - { direction: incoming, policy: deny }
        - { direction: outgoing, policy: allow }

    - name: Consenti SSH + WireGuard tramite UFW
      ufw:
        rule: allow
        port: "{{ item.port }}"
        proto: "{{ item.proto }}"
      loop:
        - { port: 22, proto: tcp }
        - { port: "{{ wg_port }}", proto: udp }

    - name: Abilita UFW
      ufw:
        state: enabled
        policy: deny

    - name: Abilita inoltro IP
      sysctl:
        name: net.ipv4.ip_forward
        value: "1"
        state: present
        reload: yes

    - name: Rileva interfaccia pubblica
      shell: ip -o -4 route show to default | awk '{print $5}'
      register: pub_iface
      changed_when: false

    - name: Genera chiavi server WireGuard
      shell: |
        umask 077
        wg genkey | tee /etc/wireguard/server_private.key | wg pubkey > /etc/wireguard/server_public.key
      args:
        creates: /etc/wireguard/server_private.key

    - name: Leggi chiavi server
      slurp:
        src: "/etc/wireguard/{{ item }}"
      register: wg_keys
      loop:
        - server_private.key
        - server_public.key

    - name: Renderizza wg0.conf
      copy:
        dest: /etc/wireguard/wg0.conf
        mode: '0600'
        content: |
          [Interface]
          PrivateKey = {{ wg_keys.results[0].content | b64decode | trim }}
          Address = 10.66.66.1/24
          ListenPort = {{ wg_port }}
          PostUp = iptables -A FORWARD -i %i -j ACCEPT; iptables -A FORWARD -o %i -j ACCEPT; iptables -t nat -A POSTROUTING -o {{ pub_iface.stdout }} -j MASQUERADE
          PostDown = iptables -D FORWARD -i %i -j ACCEPT; iptables -D FORWARD -o %i -j ACCEPT; iptables -t nat -D POSTROUTING -o {{ pub_iface.stdout }} -j MASQUERADE

    - name: Abilita + avvia wg-quick@wg0
      systemd:
        name: wg-quick@wg0
        enabled: yes
        state: started

    - name: Abilita + avvia fail2ban
      systemd:
        name: fail2ban
        enabled: yes
        state: started

  handlers:
    - name: restart ssh
      systemd:
        name: ssh
        state: restarted

Esecuzione

ansible-playbook -i inventory.yml playbook.yml

Conta ~3 minuti la prima volta (essenzialmente apt upgrade). Il tunnel è attivo. Il tuo utente ericg può fare SSH con la chiave Ed25519. Puoi rieseguire il playbook tutte le volte che vuoi senza rompere nulla — non sovrascriverà le chiavi WireGuard (idempotenza garantita tramite il flag creates:).

Per aggiungere un client (gestito in una seconda fase del playbook, documentato nella guida ai template di configurazione WireGuard): genera chiavi client, renderizza client.conf con Jinja2, invia tramite QR encode.

Consiglio pratico: versiona il playbook in un repo Git privato (mai pubblico — le chiavi Ansible Vault non sono sicure contro GitHub pubblico se la passphrase dovesse mai trapelare). Usiamo un Gitea autogestito sullo stesso VPS per una perfetta circolarità.

Monitoraggio uptime gratuito con UptimeRobot

Se vuoi sapere quando il tuo tunnel cade senza aggiornare manualmente, UptimeRobot copre il 95% delle esigenze gratuitamente. Piano gratuito: 50 monitor, controlli ogni 5 minuti, avvisi email + Telegram + webhook Discord.

Monitoriamo 3 endpoint distinti per disambiguare il tipo di guasto:

Monitor 1 — Salute del server (ping HTTPS dell'IP)

Tipo UptimeRobot "HTTP(s)", URL https://YOUR_PUBLIC_IP/healthz. Per rispondere a questo controllo, installa un Caddy leggero sulla porta 443:

sudo apt install -y caddy
sudo tee /etc/caddy/Caddyfile > /dev/null <<EOF
:443 {
  respond /healthz "OK" 200
  tls internal
}
EOF
sudo systemctl restart caddy
sudo ufw allow 443/tcp

Se questo monitor va GIÙ → il VPS stesso è irraggiungibile (interruzione di rete Contabo, o il tuo VPS è crashato).

Monitor 2 — Salute del tunnel (da Cloudflare Workers)

Configura un Cloudflare Worker gratuito (100k req/giorno tier gratuito) che recupera https://ifconfig.me con un user-agent personalizzato. Perché il controllo sia significativo, il Worker dovrebbe attraversare il tunnel WireGuard, cosa non direttamente possibile con i Workers — soluzione alternativa con un monitor "Keyword" di UptimeRobot che colpisce un endpoint che ospiti che verifica che la risposta contenga l'IP del VPS Contabo (non uno residenziale).

URL monitorato: https://YOUR_PUBLIC_IP/whoami (Caddy fa da proxy a ifconfig.me).

Parola chiave: l'IPv4 del tuo VPS.

Se il routing si rompe (hijack DNS, NAT rotto), l'IP restituito differirebbe e il monitor avviserebbe.

Monitor 3 — Salute DNS tramite 1.1.1.1

URL: https://1.1.1.1/cdn-cgi/trace, parola chiave "warp=off". Questo controllo verifica che puoi risolvere Cloudflare dal VPS — cioè che la rotta in uscita del VPS non sia rotta.

Configurazione avvisi

In UptimeRobot, imposta:

  • Email primaria: ricevi un avviso entro 30s dalla rilevazione
  • Bot Telegram (gratuito): invia al tuo telefono anche senza email
  • Soglia: "avvisa dopo 2 controlli falliti" per evitare falsi positivi di rete

In pratica, questa configurazione avvisa principalmente su eventi reali — una finestra di manutenzione pianificata di Contabo, o un crash del servizio (ad esempio Caddy che fallisce su un rinnovo del certificato). Con la soglia "2 controlli falliti", i falsi positivi di rete rimangono rari.

Costo totale: €0. UptimeRobot gratuito + Cloudflare Workers gratuito + Caddy gratuito.

Indurimento SSH con fail2ban + autenticazione solo chiave

Il bootstrap iniziale disabilita la password SSH, ma in produzione dovresti andare oltre. Ecco l'indurimento da applicare a ogni VPS Contabo, motivato dalla costante scansione SSH automatizzata che qualsiasi host esposto a Internet riceve (bot scansionano permanentemente gli intervalli IP degli hosting, incluso quello di Contabo).

Passo 1 — Porta SSH personalizzata

Cambiare la porta SSH non è "vera" sicurezza (sicurezza tramite oscurità) ma riduce i log del 95%. I bot scansionano prima la porta 22.

sudo sed -i 's/^#Port 22/Port 2289/' /etc/ssh/sshd_config
sudo ufw delete allow 22/tcp
sudo ufw allow 2289/tcp
sudo systemctl restart ssh
# Verifica da un terminale separato PRIMA di chiudere il primo:
# ssh -p 2289 ericg@YOUR_IP

⚠ Tieni aperto il vecchio terminale finché non hai confermato che la connessione alla nuova porta funziona. Altrimenti ti blocchi fuori.

Passo 2 — Jail SSH personalizzato per fail2ban

fail2ban monitora la porta 22 di default. Regola:

sudo tee /etc/fail2ban/jail.d/sshd-custom.local > /dev/null <<EOF
[sshd]
enabled = true
port = 2289
maxretry = 3
findtime = 600
bantime = 86400
EOF
sudo systemctl restart fail2ban
sudo fail2ban-client status sshd

Politica: 3 fallimenti in 10 minuti → ban di 24h. Più severo del default (5 fallimenti / ban di 1h) perché non permettiamo password comunque — un fallimento di autenticazione = un bot.

Passo 3 — Audit quota fail2ban

La jail SSH tipica banna 30-80 IP/giorno su Contabo Norimberga. Per controllare cosa sta succedendo:

sudo fail2ban-client status sshd
# IP attualmente bannati: 47
# Lista IP bannati: 185.x.x.x 91.x.x.x ...
sudo zcat /var/log/fail2ban.log* | grep "Ban " | wc -l
# Bans totali dall'inizio

Se vedi >200 ban/giorno, puoi irrigidire bantime = 604800 (1 settimana) per limitare il carico IO sul server.

Passo 4 — Chiavi SSH Ed25519 con passphrase

Se non hai generato la tua chiave Ed25519 sul laptop, ora è il momento:

# Sul tuo laptop
ssh-keygen -t ed25519 -C "ericg@laptop-2026" -f ~/.ssh/id_ed25519_vpn
# Scegli una passphrase forte (digitata una volta al giorno tramite ssh-agent)
ssh-add -t 10800 ~/.ssh/id_ed25519_vpn  # la dimentica dopo 3h

Ed25519 > RSA 4096: firme più veloci, chiavi più corte, stato dell'arte nel 2026. Ogni VPS Ubuntu 24.04 Contabo supporta Ed25519 nativamente.

Passo 5 — Disabilita ChallengeResponseAuthentication

Assicurati che queste righe siano in /etc/ssh/sshd_config:

PubkeyAuthentication yes
PasswordAuthentication no
ChallengeResponseAuthentication no
KbdInteractiveAuthentication no
UsePAM yes
AuthenticationMethods publickey

Con AuthenticationMethods publickey, anche se un CVE 0-day consente a un attaccante di bypassare PAM, avrà comunque bisogno della chiave. Cintura e bretelle.

Dopo questi 5 passi, la maggior parte dei tentativi di forza bruta SSH automatizzati sono bloccati al firewall e il resto non può mai autenticarsi (login solo con chiave). Nessuno riesce. Puoi dormire tranquillo.

Costo mensile: Contabo VPS S vs NordVPN annuale

Calcolo onesto a 5 anni:

SoluzioneAnno 1Anno 2Anno 3Anno 4Anno 5Totale
NordVPN 2 anni + rinnovi€71,76€0€156€156€156€539,76
Contabo VPS S Cloud 24 mesi × 2€59,76€59,76€59,76€59,76€59,76€298,80

Risparmio: €241 in 5 anni (45%). Bonus: puoi ospitare il tuo Bitwarden, Nextcloud, Umami, quello che vuoi.

Limitazioni oneste dell'autogestione

Per completezza:

  • Streaming Netflix US, BBC iPlayer, ecc.: quasi mai funziona. Netflix rileva gli ASN dei datacenter (Contabo ASN 51167) e ti serve il catalogo locale. Per lo streaming, mantieni un NordVPN 1 anno come complemento.
  • Bypass DPI Iran/Cina: WireGuard sulla porta 51820/udp in chiaro è rilevato da DPI sofisticati. Per questi casi, passa a V2Ray VMess/VLESS con REALITY su questo stesso VPS Contabo — stesso hardware, stack di protocolli diverso, non rilevabile dal GFW nel 2026.
  • Nessun supporto chat: Contabo risponde via email entro 24-48h. Se vuoi chat live, controlla Hetzner Cloud (~2× il prezzo, supporto chat FR/DE/EN).
  • Sei l'amministratore: se il VPS crasha, devi fare il debug. Opposto di un servizio gestito.

Leggi successivamente

Articolo pubblicato il 2026-06-02, ultimo aggiornamento il 2026-06-03 (aggiunto: playbook Ansible idempotente, monitoraggio gratuito a 3 endpoint con UptimeRobot, indurimento SSH con fail2ban + Ed25519). Script di bootstrap verificato l'ultima volta su Ubuntu 24.04 LTS il 2026-06-03. Se la procedura non funziona per te, apri un problema sul nostro GitHub o invia un'email a contact@vpnsmith.com.

★ Datacenter GDPR di Norimberga · ✓ IPv4 dedicato incluso · 200+ Mbps garantiti

Self-host your VPN on your own VPS → ContaboFull root access · public IPv4 · pick your region