macOS App
The rVPN macOS app creates a full-tunnel VPN connection using a Network Extension. All traffic is routed through an encrypted tunnel.
Requirements
Section titled “Requirements”- macOS 13.0 or later
- A deployed rVPN server
- Server address, identity key, and prekey bundle
1. Install the App
Section titled “1. Install the App”Install rVPN from the Mac App Store.
2. Add a Profile
Section titled “2. Add a Profile”Open the app from the menu bar icon. Click Settings… (or press ⌘,). The Settings window has two segmented tabs — Profiles and Settings. Stay on Profiles.
Click the + button in the bottom toolbar (or click the up-arrow-into-doc icon next to it to import a .rvpn file exported from another device). The Profile editor opens in the window.
Fill in the fields you care about; the essentials are:
- Name — anything you like (e.g. “Home HK”)
- Colour — a swatch to identify the profile in lists and the menu bar
- Default Profile — click the star row to make this the default (auto-connects on launch)
- Server Address —
wss://your-server.com/api/v1/ws/tun - Trust on First Use — leave on for standard TOFU pinning, or paste an expected Server Fingerprint below for stricter verification
- Identity Key — click Generate to create a new X3DH identity for this profile, or Import… to load an existing key file
- Prekey Bundle — click Import Prekey Bundle and select the JSON file provided by your server administrator
- DNS Servers — comma-separated resolvers used when DNS falls back locally (default
1.1.1.1, 8.8.8.8) - Bypass Networks — extra CIDR ranges to send direct
- MTU — TUN interface MTU (default
1420) - Split Tunnel — off routes everything through the VPN; on exposes the section below
- Bypass Country — pick one built-in country (CN, HK, SG, JP, KR, and others) whose CIDR ranges bypass the tunnel
- Bypass Domains — extra domains to send direct
- Tunnel Domains — domains to force through the tunnel even when Split Tunnel is on
Click Save. The Identity Key and Prekey Bundle rows show a green checkmark once they’re present.
3. Connect
Section titled “3. Connect”Click Connect in the menu bar dropdown. macOS will prompt you to allow the VPN configuration the first time. Approve it to proceed.
The app will:
- Connect to your server via TLS WebSocket
- Establish forward-secret encryption (X3DH + Double Ratchet)
- Receive a tunnel IP address from the server
- Route all traffic through the VPN
Once connected, the menu bar dropdown shows live IP, Uptime, and Sent/Recv counters — click the menu bar icon any time to check.
Split Tunnel
Section titled “Split Tunnel”Split tunnel lives in the profile editor’s Traffic section. It routes only international traffic through the VPN and lets domestic traffic (e.g. Chinese sites) go direct. See the field list above for each setting.
Ad blocking is on for every profile and cannot be turned off from the UI (this matches the mobile apps).
Multi-server routing (exit servers)
Section titled “Multi-server routing (exit servers)”(App v1.2.9 and later.)
A profile can route traffic for specific domains or IP ranges out through other rVPN servers while everything else uses the profile’s own (primary) server. Typical use case: default all traffic through Hong Kong, but send google.com through a US exit so geolocated content resolves on the US side. Every exit must be a reachable rVPN server — traffic stays end-to-end encrypted through each of them.
Add an exit server
Section titled “Add an exit server”Exit servers come from your other existing profiles — there’s no manual server entry. Open Settings › Profiles, open the profile, and in the profile sheet go to Exit Servers → Add Exit Server, then pick the profile whose server you want to use. The server address, pinned TOFU fingerprint, and prekey bundle are seeded from that profile, and the exit gets a name derived from the profile name. Each exit keeps its own server identity pin, independent of the profile’s own pin.
Set routes
Section titled “Set routes”Each exit has Route Domains and Route IPs:
- A bare domain is a suffix match:
google.comroutes google.com and every subdomain;*.google.commatches subdomains only. Two-letter TLDs and short domains work fine. - IPs accept CIDRs (e.g.
1.1.1.0/24).
When a routed domain resolves, the tunnel learns the answer’s addresses into an ip→exit map (kept for the answer’s TTL), so later connections to those IPs take the same exit. Static CIDR rules match directly. Everything else goes to the primary server.
Routed traffic never silently falls back to the primary exit: if an exit server is down, its routed traffic fails rather than leaking to another exit. Extra exits start lazily on first routed use and reconnect independently — the app’s displayed tunnel state always reflects the primary server.
Rules load when the tunnel starts — after editing exit servers or routes, disconnect and reconnect.
DNS and export/import
Section titled “DNS and export/import”Each exit resolves DNS over HTTPS through its own tunnel, so routed domains get answers local to that exit (no geo-DNS surprises). The tunnel answers DNS inside the Network Extension, which is what makes per-exit routing possible.
Profile export/import carries the whole multi-server config. Prekey bundles for exits are embedded when you export with the identity key; exports made by older app versions import cleanly with an empty exit list.
The CLI client has a separate, TOML-based multi-server pool (SOCKS5-only) since v1.3.3 — see Client Configuration Reference. It shares no configuration with this feature.
Profiles
Section titled “Profiles”The app supports up to 10 profiles. Switch between profiles from the menu bar dropdown or the Profiles settings tab.
Each profile stores its own:
- Server address
- Identity key
- Prekey bundle
- Split tunnel settings
Share a profile
Section titled “Share a profile”To hand a profile off to another device — your iPhone, another Mac, a colleague — export it as a .rvpn file and share it however you like (AirDrop, email, Files.app).
Open Settings › Profiles, swipe or right-click on the profile you want to share, and pick Export. A dialog asks whether to include the identity key:
- Export Without Identity — safer. The recipient can inspect the profile and connect using their own key material (they need a prekey bundle from the same server administrator). Use this when sharing across users or into an untrusted place.
- Include Identity — the recipient can connect as-is on another device. Only pick this if the other device is yours, or you fully trust the recipient. The exported file contains your private key.
macOS then opens a save panel for the .rvpn file — from there you can drop it into AirDrop, attach it in Mail, or drag it into Messages.
The exported file also carries the server’s pinned identity (ik:1: fingerprint) once you’ve connected at least once. That means the recipient’s client refuses to connect if the server ever presents a different key, and no separate out-of-band verification is needed — the sender has vouched for the server by handing you the file. See Server Identity Pinning for the full model.
Server identity (TOFU)
Section titled “Server identity (TOFU)”Trust on First Use (on by default per profile) accepts and pins the server’s identity on the first successful connection. Pins are written in the canonical ik:1:<base32> form and live on the profile itself.
If the server ever presents a different key, the app shows a Server identity changed alert with the pinned and received pins side-by-side and three options: Cancel, Delete Profile, or Trust New Identity. If the operator rotated the key using the signed rotation ceremony, the app updates the pin silently — no dialog.
For stricter verification, paste the pin (from the operator, in ik:1: form) into the profile’s Server Fingerprint field before the first connect.
For the full model — pin format, rotation ceremony, threat model — see Server Identity Pinning.
Troubleshooting
Section titled “Troubleshooting”App shows “Connected” but no traffic passes
Section titled “App shows “Connected” but no traffic passes”- Check that your server is running and accessible on port 443.
- Verify the server address in your profile is correct (must start with
wss://). - Check the server logs for connection errors.
”Failed to start VPN” or connection fails immediately
Section titled “”Failed to start VPN” or connection fails immediately”- Ensure both the identity key and prekey bundle are present in the profile editor (green checkmarks).
- Verify the server address does not have trailing whitespace.
- Regenerate your identity key and re-import the prekey bundle if the issue persists.
VPN stops working after an app update
Section titled “VPN stops working after an app update”macOS persists VPN profiles in System Settings independently of the app. After an update, the stored profile may reference a stale tunnel extension.
Fix:
- Open System Settings > VPN (or System Settings > General > VPN & Filter on newer macOS).
- Delete the rVPN entry.
- Re-open the rVPN app and reconnect. The app will create a fresh profile.
This is resolved in version 1.2.4 and later, which automatically detects and replaces stale profiles.
VPN profile appears in System Settings but app shows “Disconnected”
Section titled “VPN profile appears in System Settings but app shows “Disconnected””The VPN profile was likely created by a previous version or a different build. Remove it:
- Open System Settings > VPN.
- Click the info button (i) next to the rVPN entry and delete it.
- Re-open the rVPN app. It will create a new profile on the next connection attempt.
Tunnel connects but DNS does not resolve
Section titled “Tunnel connects but DNS does not resolve”The app runs a local DNS proxy for split-tunnel DNS resolution. If DNS fails:
- Check that the server address is reachable.
- Try disabling split tunnel in the profile editor to use full-tunnel mode.
- Check the server logs for DNS proxy errors.
How to collect diagnostic logs
Section titled “How to collect diagnostic logs”Rust-level logs are written to a file in the App Group container:
cat ~/Library/Group\ Containers/group.org.rvpn.client/rvpn_tunnel_rust.logFor system-level logs:
log show --predicate 'subsystem == "org.rvpn.tunnel"' --last 5m --level debugNext Steps
Section titled “Next Steps”- iOS App - Mobile VPN with the same encryption
- Server Setup - Deploy your own rVPN server
- Troubleshooting - General troubleshooting guide
- Client Configuration Reference - All configuration options