You want a VPN you own. No annual "no-logs" audit, no IP shared with 4,000 strangers, no price doubling when the promo ends. This guide gets WireGuard running on a Contabo VPS in 20 minutes, from signup to the first curl ifconfig.me returning your German VPS IP.
This is the exact config we recommend for a production self-host tunnel. Contabo advertises a 200 Mbit/s link, and Nuremberg's central-Europe location keeps latency low for FR/EU clients.
Tip: if the tunnel refuses to connect, the cause is almost always the port. See our guide to WireGuard's default port (UDP 51820) and how to open, forward or change it.
Why Contabo over Hetzner, OVH or DigitalOcean
The VPS provider choice for a self-host VPN is not trivial and conditions the price-performance-jurisdiction ratio you'll get for the next 3 to 5 years. Comparing the published specs of Contabo, Hetzner Cloud and OVH, the verdict comes down to three axes: price, performance, jurisdiction.
On price, Contabo Cloud VPS 10 at 5,50 €/mo (June 2026) for 4 vCPU / 8 GB RAM / 200 Mbps+ is unbeatable in Europe. Hetzner CX22 has an equivalent at €4.15/mo but only 2 vCPU and 4 GB RAM, half the headroom if you want to host Nextcloud, Pi-hole or Vaultwarden alongside the VPN. OVH VPS Value at €4.50/mo offers 2 vCPU / 4 GB / 1 vCPU throttled at 20% CPU steal on certain periods - the worst deal of the three in practice.
On performance, both hosts advertise ample bandwidth for a personal VPN (Contabo a 200 Mbit/s link, Hetzner a shared gigabit port). For a self-host VPN, even a 200 Mbit/s link is more than enough to saturate most home connections, so raw peak throughput rarely is the deciding factor - jurisdiction and price usually matter more. Run iperf3 yourself from your own connection if you need exact numbers.
On jurisdiction, Contabo has its main DC in Nuremberg (Germany), Hetzner in Falkenstein (Germany too), OVH in Roubaix or Strasbourg (France). Germany and France have comparable GDPR frameworks and both are outside the US CLOUD Act. Practical difference: Contabo's parent company is pure-German (GmbH Munich), Hetzner same (GmbH Gunzenhausen), OVHcloud has been listed on Paris stock exchange since 2021 which adds a shareholder pressure layer the other two don't have. For a privacy-first VPN, we slightly prefer the non-listed German GmbHs.
The final differentiator is email support. Contabo replies typically between 4 and 24h on tickets, Hetzner between 2 and 12h, OVH between 24h and 5 days. For a personal VPN where you can solve most issues yourself via SSH, support matters little - except the day your VPS doesn't reboot after a kernel update and you need rescue console access. That day, Hetzner wins easily.
Step 1 - Order the Contabo VPS
Go to contabo.com via our link /go/contabo-vps-2y and pick:
- Plan: Cloud VPS 10 (4 vCPU, 8 GB RAM, 75 GB NVMe, 200 Mbps+ guaranteed, unlimited traffic / fair-use)
- Term: 12 months (5,50 €/mo, June 2026); longer terms lower the monthly rate
- OS: Ubuntu 22.04 LTS (24.04 works too, but 22.04 stays more stable for WireGuard packages)
- Datacenter: Nuremberg (DE) - best France/Europe latency + German GDPR jurisdiction
- Root password: generate a strong one, stash temporarily in your password manager (delete after creating non-root user)
- Add-ons: untick everything (Contabo backups not needed, we back up ourselves)
Total ~66 € for a 12-month term (5,50 €/mo, June 2026). On activation you receive an email with the public IP and root password. Plan 5 minutes to 4 hours depending on time. Peak hours (6pm-10pm CET, Tuesday/Wednesday) are slowest.
Disclosure:
/go/contabo-vps-2yis a sponsored link. If you grab the VPS, we earn a commission at zero cost to you. Our pricing is unaffected. We wouldn't write this guide if we weren't using Contabo ourselves.
Step 2 - First SSH and hardening
In your local terminal:
ssh root@YOUR.PUBLIC.IP
# Accept fingerprint, paste root password
Once connected, update first:
apt update && apt upgrade -y
apt install -y curl wget unzip fail2ban
Create a non-root user (SSH root will be disabled):
adduser eric
# Follow prompts (strong password, optional full name)
usermod -aG sudo eric
Copy your SSH public key from your local MacBook (in another terminal):
ssh-copy-id eric@YOUR.PUBLIC.IP
# If ssh-copy-id is missing: cat ~/.ssh/id_ed25519.pub | ssh root@IP "mkdir -p /home/eric/.ssh && cat >> /home/eric/.ssh/authorized_keys && chown -R eric:eric /home/eric/.ssh && chmod 700 /home/eric/.ssh && chmod 600 /home/eric/.ssh/authorized_keys"
Test non-root login in a new terminal without closing the first:
ssh eric@YOUR.PUBLIC.IP
# Should login with SSH key passphrase only
If that works, disable root SSH and password auth in /etc/ssh/sshd_config (from the root shell):
sed -i 's/^#*PermitRootLogin.*/PermitRootLogin no/' /etc/ssh/sshd_config
sed -i 's/^#*PasswordAuthentication.*/PasswordAuthentication no/' /etc/ssh/sshd_config
systemctl restart sshd
Now port 22 stays open but SSH-key only and only for eric. No more root brute-force risk.
Step 3 - UFW firewall
# Still as root
apt install -y ufw
ufw default deny incoming
ufw default allow outgoing
ufw allow 22/tcp comment 'SSH'
ufw allow 51820/udp comment 'WireGuard'
ufw enable
# Answer y
ufw status verbose
UFW is now active. Log out of the root session and continue as eric with sudo.
Step 4 - Install WireGuard
# As eric with sudo
sudo apt install -y wireguard qrencode iptables-persistent
Generate server keys:
sudo bash -c 'umask 077 && wg genkey | tee /etc/wireguard/server.key | wg pubkey > /etc/wireguard/server.pub'
sudo cat /etc/wireguard/server.pub
# Note the pubkey, you'll need it for clients
Identify the public interface (could be eth0, ens3, ens18, etc.):
ip route | awk '/default/ {print $5}'
# On Contabo usually eth0 or ens18
Step 5 - Configure /etc/wireguard/wg0.conf
Edit (adjust eth0 if different above):
sudo nano /etc/wireguard/wg0.conf
Paste this (replace SERVER_PRIVATE_KEY with the contents of /etc/wireguard/server.key):
[Interface]
PrivateKey = SERVER_PRIVATE_KEY
Address = 10.66.66.1/24
ListenPort = 51820
MTU = 1420
PostUp = iptables -A FORWARD -i wg0 -j ACCEPT
PostUp = iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
PostDown = iptables -D FORWARD -i wg0 -j ACCEPT
PostDown = iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE
Enable ip_forward:
sudo bash -c 'echo "net.ipv4.ip_forward=1" >> /etc/sysctl.conf'
sudo sysctl -p
# Verify: sysctl net.ipv4.ip_forward (should say 1)
Start WireGuard:
sudo systemctl enable --now wg-quick@wg0
sudo wg show
# Should show interface wg0, public key, listening port
Step 6 - Create the first peer (client)
On the server, generate a client key:
sudo mkdir -p /etc/wireguard/clients
sudo bash -c 'umask 077 && wg genkey | tee /etc/wireguard/clients/mac.key | wg pubkey > /etc/wireguard/clients/mac.pub'
sudo cat /etc/wireguard/clients/mac.pub
# Note this pubkey
Add the peer to server wg0.conf:
sudo bash -c 'cat >> /etc/wireguard/wg0.conf <<EOF
[Peer]
# MacBook
PublicKey = CLIENT_MAC_PUBKEY
AllowedIPs = 10.66.66.2/32
EOF'
Reload config without down:
sudo wg syncconf wg0 <(wg-quick strip wg0)
Generate the client file (transfer securely to MacBook/iPhone):
sudo bash -c 'cat > /etc/wireguard/clients/mac.conf <<EOF
[Interface]
PrivateKey = $(cat /etc/wireguard/clients/mac.key)
Address = 10.66.66.2/24
DNS = 9.9.9.9, 149.112.112.112
MTU = 1420
[Peer]
PublicKey = $(cat /etc/wireguard/server.pub)
Endpoint = YOUR.PUBLIC.IP:51820
AllowedIPs = 0.0.0.0/0, ::/0
PersistentKeepalive = 25
EOF'
For iPhone / Android, encode as QR:
sudo qrencode -t ansiutf8 < /etc/wireguard/clients/mac.conf
Scan this QR from the WireGuard app (App Store, Play Store) and the tunnel is configured.
For macOS / Linux desktop, fetch the .conf locally:
# On your Mac
scp eric@YOUR.PUBLIC.IP:/etc/wireguard/clients/mac.conf ~/Downloads/
# Import from official WireGuard app
Step 7 - Leak tests
Enable the tunnel on your client, then in a browser:
- ipleak.net: your public IP must be the Contabo Nuremberg VPS. Geo = Germany. If you still see your French ISP IP → tunnel isn't routing, check client
AllowedIPs. - dnsleaktest.com → "Extended test" button: returned DNS must be Quad9 (9.9.9.9) or your VPS. If you see Orange/SFR/Free DNS → DNS leak, check
DNS = 9.9.9.9in client.conf. - browserleaks.com/webrtc: no local IP must leak via WebRTC. If leaking → disable WebRTC in the browser (uBlock Origin → "Prevent WebRTC from leaking").
curl ifconfig.mefrom client terminal: must return the VPS IP.
All green: your self-host VPN works. Welcome.
Step 8 - Backups and maintenance
The tunnel runs. Good habits:
- Backup
/etc/wireguard/weekly:rsync -avz eric@VPS:/etc/wireguard/ ~/backup-wg/$(date +%F)/ - Monthly updates:
sudo apt update && sudo apt upgrade -y && sudo reboot(~30s downtime, or useunattended-upgrades) - Monitoring: see the Prometheus + Grafana monitoring guide
- Client-side kill switch: see the Linux kill switch (iptables + systemd) guide
- Specific-case templates: see the 8 ready-to-use WireGuard templates
Total cost over 5 years
To honestly compare with a commercial VPN service:
| Option | 1-year cost | 5-year cost (extrapolated) | Bandwidth |
|---|---|---|---|
| Contabo Cloud VPS 10 (self-host) | ~66 € | ~330 € | 200 Mbps+, unlimited (fair-use) |
| NordVPN 2 yrs + yearly renewal | 36 € | ~600 € | "Unlimited" shared |
| ExpressVPN 1 yr + renewal | 100 € | ~750 € | "Unlimited" shared |
And on the Contabo VPS you can also host: a Pi-hole DNS, Nextcloud, Vaultwarden, a Discord bot, a personal Mastodon instance. The VPN itself uses ~1% of CPU and RAM in normal personal use.
Verdict
WireGuard on Contabo Cloud VPS 10 at 5,50 €/mo (June 2026) remains our #1 pick for self-host VPN. ~20-min setup, an advertised 200 Mbit/s+ link, low latency from Western Europe, German GDPR jurisdiction. The real downside: email-only support, not ideal during an urgent outage.
To get started: Contabo Cloud VPS 10 via our link /go/contabo-vps-2y. You can cancel within the first 30 days if the setup doesn't fit, per Contabo's terms.
Our full Contabo VPS review details strengths and weaknesses across 5 categories (perf, price, RAM/CPU, support, dashboard) with the score breakdown.
★ Nuremberg GDPR datacenter · ✓ Dedicated IPv4 included · 200+ Mbps guaranteed
Self-host your VPN on your own VPS → ContaboFull root access · public IPv4 · pick your region→

