Commercial VPN clients

Chapter 7 — Commercial VPN Clients on Linux

The previous four chapters covered self-hosted VPNs — you own the server, you control the traffic, and your public IP is your own server's IP. Commercial VPN services flip that model: a company runs thousands of servers worldwide, and you connect to whichever country you need. Your traffic exits from a shared IP pool, making individual attribution harder.

This chapter covers installing and using two of the most privacy-focused commercial providers — ProtonVPN and Mullvad — from the Linux command line, and how to verify that neither is leaking your real DNS queries or IP address.

ProtonVPN vs Mullvad — Key Differences

ProtonVPN
Swiss jurisdiction · open-source · free tier available
Built by the team behind ProtonMail. Strong transparency record — published independent audits and open-sourced all clients. The free tier is genuinely usable (no data cap, 3 countries) making it the best free option in the market. Paid plans add Secure Core (routing through privacy-friendly countries before exiting), NetShield (DNS-based ad/malware blocking), and P2P servers.
  • Jurisdiction: Switzerland (not EU/US)
  • Logging: No-logs, independently audited
  • Protocols: WireGuard, OpenVPN, Stealth (obfuscated)
  • Free tier: Yes — 3 countries, unlimited data
  • Linux CLI: Official proton-vpn-gtk-app + headless mode
  • Accepts: Cash, crypto, cards
Mullvad
Swedish jurisdiction · account-number only · flat €5/month
Mullvad takes anonymity further than almost any other provider: accounts are random numbers with no email required, you can pay in cash by post, and they have resisted and publicised law enforcement attempts to hand over user data. The flat €5/month pricing (no annual discounts, no tiers) keeps things simple. The Linux app is a first-class CLI tool, not an afterthought.
  • Jurisdiction: Sweden
  • Logging: No-logs, independently audited
  • Protocols: WireGuard, OpenVPN
  • Free tier: No — €5/month flat
  • Linux CLI: Official mullvad CLI — excellent
  • Accepts: Cash, Monero, Bitcoin, cards
The trust question doesn't go away. A commercial VPN moves trust from your ISP to the VPN provider. "No-logs" claims can only be partially verified through audits — you are ultimately trusting the provider's honesty and jurisdiction. If true anonymity is the goal, a VPN alone is not sufficient regardless of provider.

ProtonVPN on Linux

Install

debian/ubuntu — install ProtonVPN
# install dependencies philip@laptop:~$ sudo apt install -y wget gnupg # add ProtonVPN repository philip@laptop:~$ wget -q -O- https://repo.protonvpn.com/debian/public_key.asc | \ sudo gpg --dearmor -o /usr/share/keyrings/protonvpn.gpg philip@laptop:~$ echo "deb [signed-by=/usr/share/keyrings/protonvpn.gpg] \ https://repo.protonvpn.com/debian stable main" | \ sudo tee /etc/apt/sources.list.d/protonvpn.list philip@laptop:~$ sudo apt update && sudo apt install -y proton-vpn-gtk-app

CLI usage (non-interactive / headless)

protonvpn — CLI commands
# login (stores credentials locally) philip@laptop:~$ protonvpn-cli login your@email.com # connect to the fastest available server philip@laptop:~$ protonvpn-cli connect --fastest Connecting to NL#47 via WireGuard... Connected! # connect to a specific country philip@laptop:~$ protonvpn-cli connect --cc CH # Switzerland philip@laptop:~$ protonvpn-cli connect --cc DE # Germany philip@laptop:~$ protonvpn-cli connect --cc US # United States # connect using a specific protocol philip@laptop:~$ protonvpn-cli connect --fastest --protocol wireguard philip@laptop:~$ protonvpn-cli connect --fastest --protocol openvpn-tcp # show connection status philip@laptop:~$ protonvpn-cli status Connected to NL#47 Protocol: WireGuard Time: 00:04:31 IP: 185.159.157.47 Country: Netherlands Server load: 34% # disconnect philip@laptop:~$ protonvpn-cli disconnect # enable kill switch (blocks internet if VPN drops) philip@laptop:~$ protonvpn-cli killswitch --on philip@laptop:~$ protonvpn-cli killswitch --off

Mullvad on Linux

Install

debian/ubuntu — install Mullvad
# add Mullvad repository philip@laptop:~$ curl -fsSL https://repository.mullvad.net/deb/mullvad-keyring.asc | \ sudo gpg --dearmor -o /usr/share/keyrings/mullvad-keyring.gpg philip@laptop:~$ echo "deb [signed-by=/usr/share/keyrings/mullvad-keyring.gpg arch=$( dpkg --print-architecture )] \ https://repository.mullvad.net/deb/stable $(lsb_release -cs) main" | \ sudo tee /etc/apt/sources.list.d/mullvad.list philip@laptop:~$ sudo apt update && sudo apt install -y mullvad-vpn

CLI usage

mullvad — CLI commands
# login with your account number (no email required) philip@laptop:~$ mullvad account login 1234567890123456 Logged in to account 1234567890123456 # check account status and expiry philip@laptop:~$ mullvad account get Account: 1234567890123456 Expires: 2026-12-18 00:00:00 UTC # connect (auto-selects fastest server) philip@laptop:~$ mullvad connect Connecting... # show current status philip@laptop:~$ mullvad status Connected to Amsterdam, Netherlands (nl-ams-wg-201) via WireGuard # set preferred country / city philip@laptop:~$ mullvad relay set location ch # Switzerland philip@laptop:~$ mullvad relay set location se got # Sweden, Gothenburg philip@laptop:~$ mullvad relay set location us dal # US, Dallas # list available countries philip@laptop:~$ mullvad relay list | grep -E "^\w" | head -20 # set protocol philip@laptop:~$ mullvad relay set tunnel-protocol wireguard philip@laptop:~$ mullvad relay set tunnel-protocol openvpn # kill switch — always on by default in Mullvad philip@laptop:~$ mullvad lockdown-mode set on # block all traffic when disconnected philip@laptop:~$ mullvad lockdown-mode set off # disconnect philip@laptop:~$ mullvad disconnect
Mullvad's lockdown mode is stricter than a standard kill switch — it blocks all internet traffic whenever the VPN is not connected, not just when the tunnel drops unexpectedly. This means even if you manually disconnect, nothing gets through until you reconnect. Enable it if you want a guarantee that unencrypted traffic is impossible on this machine.

DNS Leak Testing — Why It Matters

A DNS leak occurs when your device sends DNS queries outside the VPN tunnel — to your ISP's resolver or your router — despite being connected to a VPN. This reveals your browsing activity to your ISP even while the VPN is active, defeating the purpose of using one.

DNS leaks happen because:

  • The OS prefers the system DNS resolver over the VPN-pushed one
  • Some browsers use their own DNS-over-HTTPS resolver (bypassing the OS)
  • Split-tunnel mode may not route DNS queries through the tunnel
  • IPv6 DNS resolvers leak when the VPN only tunnels IPv4

What a clean result looks like

dnsleaktest.com — Extended Test results ✓ No leak detected
DNS Server IP
ISP / Owner
Country
185.159.157.1
Mullvad
Netherlands
185.159.157.2
Mullvad
Netherlands

What a leaking result looks like

dnsleaktest.com — Extended Test results ✗ Leak detected — your ISP can see your queries
DNS Server IP
ISP / Owner
Country
185.159.157.1
Mullvad
Netherlands
82.132.240.1
BT (your ISP)
United Kingdom ← LEAK

DNS leak test from the terminal

linux — check DNS resolution path
# see which DNS server is currently being used philip@laptop:~$ resolvectl status | grep "Current DNS" Current DNS Server: 185.159.157.1 ← should be VPN provider's DNS # quick check — query a hostname and see which server answered philip@laptop:~$ dig +short TXT whoami.ds.akahelp.net "ns" "185.159.157.1" ← the resolver that answered # check for IPv6 DNS leak (if IPv6 is active) philip@laptop:~$ dig -6 +short myip.opendns.com @2606:4700:4700::1111 # confirm no ISP DNS servers in resolv.conf philip@laptop:~$ cat /etc/resolv.conf nameserver 185.159.157.1 ← VPN DNS only — no leak nameserver 185.159.157.2

Full Verification Checklist

  • 🌐
    Public IP check
    Confirm your IP shows as the VPN server's IP, not your real IP
    ipinfo.io · ifconfig.me · ipify.org
  • 🔍
    DNS leak test — standard
    Run the standard test: all DNS servers shown should belong to the VPN provider
    dnsleaktest.com → Standard Test
  • 🔬
    DNS leak test — extended
    Runs more queries to catch intermittent leaks. Run this if the standard test passes but you're still suspicious
    dnsleaktest.com → Extended Test
  • 📡
    WebRTC leak test
    Browsers can expose your real local IP via WebRTC even through a VPN. Check that no local IPs are revealed
    browserleaks.com/webrtc · ipleak.net
  • 6️⃣
    IPv6 leak test
    If your VPN only tunnels IPv4, IPv6 traffic goes unencrypted. Mullvad and ProtonVPN block IPv6 by default when connected
    ipleak.net · ipv6leak.com
  • 🛡
    Kill switch test
    Enable kill switch, connect to VPN, then manually disconnect. Attempt to load a webpage — it should fail if the kill switch is working
    curl ifconfig.me (should time out or be refused)
Browser DNS-over-HTTPS can bypass VPN DNS. Chrome and Firefox have built-in DoH resolvers that bypass the OS DNS settings entirely. If your VPN reports no DNS leak but the browser behaves differently, check: Chrome → Settings → Privacy and security → Security → Use secure DNS — disable or point it at your VPN provider's DoH endpoint. Firefox: about:preferences#privacy → DNS over HTTPS.
Next — Chapter 8: Troubleshooting and Security Hardening. The final chapter covers DNS leaks in depth, kill switch implementation, MTU issues (the silent performance killer), logging and audit, and a practical checklist for verifying that your VPN setup — self-hosted or commercial — is actually doing what you think it is.