Tired of paying €12.99/month to NordVPN after the promo year. You want an encrypted tunnel shared with no one, hosted in a GDPR jurisdiction, whose configuration you control line by line. Good news: it stands up in 20 minutes on a Contabo VPS at €4.99/month, and this guide gives you every command. No marketing, no abstraction — just the script we run in production for 14 months.
Why self-host rather than a commercial service
A commercial VPN sells you a promise: no logs, shared IP across thousands of users, "no-logs friendly" jurisdiction (Panama, BVI, Switzerland). On paper it's solid. In practice:
- Shared IP = shared reputation. When 4,000 NordVPN users exit through the same IP, you inherit their blacklists. Stripe will ask for an extra 3DS. Cloudflare will serve you endless challenges. You host your own VPN = your own clean IP.
- No-logs unverifiable in real time. A PwC audit validates a policy at one moment. Between audits, court orders (US subpoenas, EU orders) can force temporary logging. On your VPS, you decide. You purge whenever you want.
- Prices that double on renewal. NordVPN 2yr: €71.76. Yearly renewal: €156/yr. Over 5 years: ~€600. A Contabo VPS S over 5 years: ~€300. And you can host other services on it.
The honest tradeoff: you won't unblock Netflix US with a dedicated VPS (Netflix bans datacenter ASNs). For streaming, we document a hybrid solution in the DPI bypass guide.
Picking the right Contabo VPS
Contabo offers three relevant ranges for a personal VPN:
| Plan | Price/mo | vCPU | RAM | Bandwidth | Best for |
|---|---|---|---|---|---|
| VPS S (legacy) | €4.99 | 4 | 8 GB | 200 Mbps | Solo VPN 1-3 devices |
| VPS S Cloud | €6.99 | 4 vCPU NVMe | 8 GB | 600 Mbps | Family VPN 5-10 devices |
| Cloud VPS 10 | €9.99 | 6 vCPU | 16 GB | 1 Gbps | Multi-tunnel + extra services |
Our default pick: VPS S at €4.99/mo. For 90% of individual uses, more than enough. 200 Mbps bandwidth is guaranteed (iperf3-tested, sustained 195 Mbps).
Recommended datacenter: Nuremberg (DE) for <30 ms latency from continental Europe. If you're in Canada/US, pick US Central (St. Louis).
Step-by-step setup
Step 1 — Provision the VPS
On contabo.com, pick VPS S, Ubuntu 24.04 LTS, root password (we'll create a normal user later), Nuremberg datacenter. Pay via card or PayPal. Activation: email within ~5 minutes with the public IP and root password.
Step 2 — Harden the server
First SSH connection:
ssh root@YOUR_PUBLIC_IP
# Password is in the Contabo email
Create a non-root user, add your SSH key, disable root login:
adduser ericg
usermod -aG sudo ericg
mkdir -p /home/ericg/.ssh
# Paste your public key (~/.ssh/id_ed25519.pub locally)
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
# Disable root + password login
sed -i 's/^PermitRootLogin .*/PermitRootLogin no/' /etc/ssh/sshd_config
sed -i 's/^#PasswordAuthentication.*/PasswordAuthentication no/' /etc/ssh/sshd_config
systemctl restart ssh
Exit the root shell, reconnect via ssh ericg@YOUR_IP. If it works, continue.
Install firewall and 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
Step 3 — Install and configure WireGuard
sudo apt install -y wireguard qrencode
# Server key generation
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)
Identify your public interface (often ens3 or eth0):
ip route | grep default
# default via X.X.X.X dev ens3 ...
Create /etc/wireguard/wg0.conf:
sudo nano /etc/wireguard/wg0.conf
Content (replace ens3 with your interface if different):
[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
Enable IP forwarding:
echo "net.ipv4.ip_forward=1" | sudo tee -a /etc/sysctl.conf
sudo sysctl -p
Start WireGuard:
sudo systemctl enable --now wg-quick@wg0
sudo wg show
# You should see "interface: wg0" and "listening port: 51820"
Step 4 — Generate a client
For each device:
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)
Create /tmp/macbook.conf (on the server, to generate the QR — then delete):
[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
Add this peer to the server:
sudo wg set wg0 peer PASTE_CLIENT_PUB allowed-ips 10.66.66.2/32
# And persist:
sudo nano /etc/wireguard/wg0.conf
# Append at the bottom:
# [Peer]
# PublicKey = PASTE_CLIENT_PUB
# AllowedIPs = 10.66.66.2/32
For iOS/Android: generate the QR code
qrencode -t ansiutf8 < /tmp/macbook.conf
Scan with the official WireGuard app. Toggle on. You're done.
Step 5 — Verify no leaks
On your client connected to the tunnel:
- Go to ipleak.net — IP must be the Contabo VPS, not yours.
- Go to browserleaks.com/webrtc — no local IP exposed.
- Go to dnsleaktest.com — DNS resolved via 1.1.1.1 (Cloudflare).
If a WebRTC leak shows: enable kill switch in WireGuard mobile ("On-Demand"), or block WebRTC in Firefox (about:config → media.peerconnection.enabled → false).
Additional hardening
Recommended production hardenings:
- Lynis audit:
sudo apt install lynis && sudo lynis audit system. Target score: 80+/100. - SSH on custom port: change
/etc/ssh/sshd_configport 2222, update UFW. - Disable IPv6 if unused:
sudo sysctl -w net.ipv6.conf.all.disable_ipv6=1(persist in sysctl.conf). - Minimum logs: by default, journald retains 4 weeks. Reduce to 7 days via
/etc/systemd/journald.confif threat model is strict. - Contabo backups: enable automatic snapshots in the Contabo panel (€1/mo, not for logs but for quick recovery after a mishap).
Monthly cost: Contabo VPS S vs NordVPN yearly
Honest 5-year calculation:
| Solution | Yr 1 | Yr 2 | Yr 3 | Yr 4 | Yr 5 | Total |
|---|---|---|---|---|---|---|
| NordVPN 2yr + renewals | €71.76 | €0 | €156 | €156 | €156 | €539.76 |
| Contabo VPS S Cloud 24 mo × 2 | €59.76 | €59.76 | €59.76 | €59.76 | €59.76 | €298.80 |
Savings: €241 over 5 years (45%). Bonus: you can host your Bitwarden, Nextcloud, Umami, whatever you want.
Honest self-host limitations
For completeness:
- Netflix US streaming, BBC iPlayer, etc.: almost never works. Netflix detects datacenter ASNs (Contabo ASN 51167) and serves you the local catalog. For streaming, keep a NordVPN 1yr as a complement.
- DPI bypass Iran/China: WireGuard on port 51820/udp in plaintext is detected by sophisticated DPI. For these cases, add V2Ray or Cloak as obfuscation (see the dedicated guide).
- No chat support: Contabo replies via email within 24-48h. If you want live chat, check Hetzner Cloud (~2× the price, FR/DE/EN chat support).
- You're the admin: if the VPS crashes, you debug. Opposite of a managed service.
Read next
- Contabo vs Hetzner vs OVH: Europe VPS for self-host VPN 2026
- WireGuard vs OpenVPN on VPS: real-world benchmarks 2026
- Custom VPN routing on Contabo: DPI bypass Iran/China 2026
- Official sources: WireGuard whitepaper, Contabo VPS docs, Ubuntu 24.04 hardening guide
Article published 2026-06-02. Bootstrap script last verified on Ubuntu 24.04 LTS on 2026-06-02. If the procedure breaks for you, open an issue on our GitHub or email contact@vpnsmith.com.
★ Datacenter Nuremberg GDPR · ✓ IPv4 dédiée incluse · 200+ Mbps garantis
Get Contabo30 jours satisfait ou remboursé→