A fast, lightweight Proton VPN client for Linux with a terminal UI. Written in Go.
Daemon-based architecture — the VPN stays connected when you close the TUI. Works with NetworkManager, systemd-networkd + iwd, or bare setups — auto-detects your network stack.
Unlike the official Proton VPN Linux app, pVPN:
- Doesn't require NetworkManager — works on any network setup
- Supports Stealth protocol (WireGuard-over-TLS) — bypasses DPI and firewalls
- Runs as a lightweight daemon — no Electron, no Python, just Go binaries
Everything the TUI does is also scriptable via pvpnctl — useful for
waybar, tmux status bars, cron jobs, or just CI smoke tests:
$ pvpnctl status
Status: Connected
Server: DE#905
Country: DE
IP: 194.126.177.218
Protocol: stealth
Duration: 1h 23m 4s
Upload: 128.4 MB
Download: 2.1 GB
$ pvpnctl servers DE | head -5
NAME CC LOAD FEATURES
--------------------------------------------------
DE#1 DE 22% P2P,Stream
DE#2 DE 31% P2P
DE#905 DE 47% P2P,Stream- Daemon + client architecture (VPN persists when TUI closes)
- Stealth protocol (WireGuard-over-TLS, bypasses DPI/firewalls)
- Smart protocol selection (auto-detect best protocol/port)
- Secure Core multi-hop (route through CH/IS/SE before exit)
- Server filters (Tor, Streaming, P2P, Secure Core toggles)
- Port forwarding with automatic renewal (NAT-PMP)
- Custom DNS (override Proton DNS via config)
- SRP authentication with 2FA
- Session persists across restarts (no re-login)
- Kill switch (nftables)
- NetShield (ad/tracker/malware blocking)
- VPN Accelerator, Moderate NAT
- IPv6 leak prevention
Required:
- Linux kernel 5.6+ (WireGuard is built-in; older kernels need the
wireguardmodule loaded — pVPN talks to it via netlink/wgctrl, nowg-quickbinary needed) systemd(for the bundled daemon unit)x86_64oraarch64(prebuilt binaries; other architectures can build from source)- A Proton VPN account (Plus or higher unlocks the full server list)
Required only for specific features:
nftables(nftbinary) — only if the kill switch is enabled- A paid Proton plan with NAT-PMP — only for port forwarding
DNS backend — any ONE of these is auto-detected at runtime:
- NetworkManager (if running)
systemd-resolved(if running)- Direct
/etc/resolv.confmanagement (fallback)
NOT required (unlike Proton's official Linux client):
- NetworkManager — pVPN works on NM-free setups:
systemd-networkd,netctl,dhcpcd-only,iwd-only, bare-metal servers, LXC containers, etc. The official Proton app hard-requires NetworkManager; pVPN auto-detects whichever stack is present and picks the right backend. - Python, Electron, or any GUI stack — pure Go binaries, ~15 MB total
wg-quick/wireguard-toolsuserspace — the kernel interface is managed via netlink directly
The daemon runs as root with CAP_NET_ADMIN to create the WireGuard
interface, set routes, and manage nftables rules. The TUI and CLI run
as your user and talk to the daemon over a Unix socket guarded by the
pvpn group.
curl -fsSL https://raw.githubusercontent.com/YourDoritos/pVPN/main/install.sh | sudo bashThis fetches the latest prebuilt binaries from the GitHub release, verifies
checksums, installs the systemd unit, and creates a pvpn group so you can
talk to the daemon without sudo. Your user is added to the group
automatically — open a new shell (or run newgrp pvpn) to pick it up.
Pin a specific version:
PVPN_VERSION=v0.2.0 curl -fsSL https://raw.githubusercontent.com/YourDoritos/pVPN/main/install.sh | sudo -E bashyay -S pvpn-goThe daemon is enabled automatically and the pvpn group is created.
Add yourself to the group with sudo usermod -aG pvpn $USER, then run pvpn.
Requires Go 1.26+ (see go.mod).
git clone https://github.com/YourDoritos/pVPN.git
cd pVPN
sudo make install
sudo groupadd -r pvpn # unprivileged IPC access
sudo usermod -aG pvpn $USER
sudo systemctl daemon-reload
sudo systemctl enable --now pvpnd
# open a new shell (or: newgrp pvpn)
pvpn# One-liner (preserves ~/.config/pvpn by default; add --purge to wipe it)
curl -fsSL https://raw.githubusercontent.com/YourDoritos/pVPN/main/uninstall.sh | sudo bash
# AUR
sudo pacman -Rns pvpn-go
# From source
sudo make uninstallmake buildProduces three binaries: pvpnd (daemon), pvpn (TUI), pvpnctl (CLI).
# Start daemon (if not using systemd)
sudo pvpnd
# Open TUI (no sudo needed)
pvpn
# CLI usage
pvpnctl connect fastest
pvpnctl status
pvpnctl disconnectOn first launch the TUI shows a login screen. After login, your session is saved and you go straight to the server list.
| Key | Action |
|---|---|
1 |
Status tab |
2 |
Servers tab |
3 |
Settings tab |
Enter |
Select server / connect |
d |
Disconnect |
/ |
Search servers |
t |
Toggle Tor filter |
s |
Toggle Streaming filter |
p |
Toggle P2P filter |
c |
Toggle Secure Core filter |
Esc |
Back |
Ctrl+C |
Quit |
Toggle features from the settings tab -- changes apply on next connection:
- Kill Switch -- block all traffic if VPN drops
- VPN Accelerator -- split TCP for faster throughput
- Moderate NAT -- deterministic NAT (useful for gaming/P2P)
- Port Forwarding -- get an inbound port (displayed in status tab)
- NetShield -- block malware, ads, and trackers at DNS level
Custom DNS can be set from the Settings tab in the TUI (select the DNS row, press Enter, type your servers), or edited directly in ~/.config/pvpn/config.toml:
[dns]
custom_dns = ["1.1.1.1", "8.8.8.8"]Note: Custom DNS bypasses NetShield ad/tracker blocking.
pvpnd runs as a systemd service and owns the VPN connection (WireGuard interface, routes, DNS, kill switch, certificate rotation, reconnection). pvpn (TUI) and pvpnctl (CLI) are unprivileged clients that communicate with the daemon via Unix socket IPC at /run/pvpn/pvpn.sock.
- Authenticates via Proton's SRP protocol
- Fetches server list and certificates
- Creates a WireGuard interface (
pvpn0) via netlink - Sets up fwmark-based policy routing (all traffic through tunnel)
- Connects Local Agent via mTLS to negotiate features
- Switches DNS to Proton's resolver (or custom DNS if configured)
- On disconnect: tears everything down in reverse order
Stored in ~/.config/pvpn/config.toml (respects SUDO_USER for the real home directory).
Session data in ~/.local/share/pvpn/session.enc (encrypted with machine-id derived key).
GPL-3.0 -- required by ProtonVPN/go-vpn-lib dependency.
