Installation
One-line install (Linux & macOS)
The quickest way to install: a single curl | bash that detects your OS and CPU, downloads the matching binary from the latest release, installs it to /usr/local/bin, and drops an example config at /etc/shadowvpn/ (the client also gets the bundled gfwlist.txt for policy routing):
curl -fsSL https://raw.githubusercontent.com/madeye/shadowvpn/main/scripts/install.sh | sudo bash -s -- servercurl -fsSL https://raw.githubusercontent.com/madeye/shadowvpn/main/scripts/install.sh | sudo bash -s -- clientServer: one-line full setup
On a Linux server, add --setup to go from zero to a running service in one command. Beyond installing the binary, it:
- writes
/etc/shadowvpn/server.jsonwith a random password and"nat": true(an existing config is never overwritten), - installs the systemd unit with the detected WAN interface and tunnel subnet, then enables + starts it,
- opens the UDP port in ufw/firewalld (if active),
- prints the matching client config, ready to paste on your devices.
curl -fsSL https://raw.githubusercontent.com/madeye/shadowvpn/main/scripts/install.sh | sudo bash -s -- server --setupPick a port or an obfuscation mode (both ends must match; the printed client config includes them):
curl -fsSL https://raw.githubusercontent.com/madeye/shadowvpn/main/scripts/install.sh | sudo bash -s -- server --setup --port 443 --obfs quicCloud firewalls
--setup opens the host firewall only. On DigitalOcean/AWS/GCP etc., also allow the UDP port in the cloud firewall / security group — a blocked port looks exactly like a wrong password from the client side.
Uninstall
Uninstall the same way (configs are kept unless you add --purge):
curl -fsSL https://raw.githubusercontent.com/madeye/shadowvpn/main/scripts/install.sh | sudo bash -s -- uninstall servercurl -fsSL https://raw.githubusercontent.com/madeye/shadowvpn/main/scripts/install.sh | sudo bash -s -- uninstall clientOptions and overrides:
--service(after the role) also installs the systemd unit / launchd plist from the release package — installed but not enabled; see Running as a service.server --setup(Linux) does the whole server setup in one shot — see above;--port Nand--obfs none|quic|base64tune the generated config.uninstall allremoves both binaries;--purgealso removes/etc/shadowvpnconfigs.SHADOWVPN_VERSION=v0.4.0pins a release tag (default: latest);PREFIX=~/.localinstalls to a user-writable prefix without sudo (configs/services are then skipped).
Prefer to read before you pipe?
The script is scripts/install.sh — short, commented, and reviewable.
Windows has no curl | bash flow — use the self-contained release .zip (client + wintun.dll + policy data), described below.
Release packages
Tagged releases on the GitHub releases page ship prebuilt packages per target:
| Target | Package | Contents |
|---|---|---|
x86_64-unknown-linux-gnu | .tar.gz | server + client binaries, bundled gfwlist.txt |
aarch64-unknown-linux-gnu | .tar.gz | server + client binaries, bundled gfwlist.txt |
x86_64-apple-darwin | .tar.gz | server + client binaries, bundled gfwlist.txt |
aarch64-apple-darwin | .tar.gz | server + client binaries, bundled gfwlist.txt |
x86_64-pc-windows-msvc | .zip | client + matching-arch wintun.dll + policy data (self-contained) |
aarch64-pc-windows-msvc | .zip | client + matching-arch wintun.dll + policy data (self-contained) |
The release also builds installable desktop app packages — a .dmg on macOS (arm64 + x86_64), .deb/.AppImage on Linux (x86_64), and an NSIS -setup.exe on Windows (x64 + ARM64) — see the desktop app guide.
Bundled policy data
The Unix tarballs and the Windows zip bundle gfwlist.txt next to the client (the Windows zip also downloads a GeoLite2-Country.mmdb at package time), so policy routing modes work out of the box — no separate downloads.
Building from source
Requires a recent stable Rust toolchain (edition 2021):
cargo build --releaseThis produces two binaries:
target/release/shadowvpn-servertarget/release/shadowvpn-client
Run the test suite (crypto + config unit tests):
cargo test --libThe shadowvpn-uri helper (optional)
Config export/import as shadowvpn:// URIs and QR codes lives in a separate binary behind the uri feature (off by default) so the server/client builds stay lean:
cargo build --release --features uri --bin shadowvpn-uriWindows
ShadowVPN builds on Windows (x86_64-pc-windows-msvc / aarch64-pc-windows-msvc) with the MSVC toolchain; CI builds and tests the Windows target on every push.
The client's TUN layer uses Wintun, whose wintun.dll is loaded at runtime and must sit next to shadowvpn-client.exe — download the build matching the CPU architecture and drop it alongside the binary (the release zip already includes the right one).
A recommended folder layout, with the self-elevating launcher from scripts/:
shadowvpn\
shadowvpn-client.exe
wintun.dll <- required, matching CPU arch
client.json <- your config
shadowvpn-client.ps1 <- self-elevating launcher
shadowvpn-client.cmd <- wrapper that bypasses the execution policyARM64 needs the ARM64 DLL
An x86_64 wintun.dll next to an ARM64 shadowvpn-client.exe (or vice versa) fails to load — typically Windows error 193 (%1 is not a valid Win32 application). Match the DLL to the binary's architecture, not the OS marketing name.
Cipher performance on ARM
chacha20-poly1305 (the default) uses runtime SIMD feature detection and is fast out of the box on every target. AES-GCM uses AES-NI automatically on x86-64, but on aarch64 (Raspberry Pi, Apple Silicon, Windows-on-ARM) the ARMv8 AES backend is gated behind compile-time target features — a plain cargo build for ARM runs AES-GCM in slow constant-time software.
On ARM hardware that lacks (or isn't built for) AES acceleration, prefer
chacha20-poly1305— it is both faster and simpler there.To use AES-GCM at full speed on ARM, build with the crypto features enabled:
shRUSTFLAGS="-C target-feature=+aes,+neon" cargo build --release # or, when building on the target device itself: RUSTFLAGS="-C target-cpu=native" cargo build --release
See the ciphers reference for details.
Next steps
- Quick start — bring the tunnel up.
- Configuration — JSON config and CLI flags.
- Running as a service — systemd / launchd units.