A free macOS menu-bar client for OpenVPN profiles that keeps several VPN connections up at the same time.
The office VPN, a client's VPN and your home lab — at the same time, each with its own tunnel,
routes and DNS. MugVPN sits in the menu bar; every .ovpn profile gets its own submenu, and a
Connections window creates, edits, imports and removes them. Under the hood each connection runs
its own openvpn 2.7, which runs without root: a small helper checks every profile and every route and DNS change it asks for.
Several connections at once
- Every connection has its own
utun, routes and DNS; connect, disconnect and reconnect each on its own. - Split DNS per connection: names in the domains a server pushes go to that tunnel's DNS, everything else as before — so two VPNs can each answer for their own domains. For servers that push only
dhcp-option DOMAIN, one switch makes those domains split too. A server that pushes no domains at all can still be used for the domains you list in the connection's options (the server's DNS, no addresses to type). - Your own DNS for a connection: its servers for the domains you list (or for all names), or leave the Mac's DNS alone.
- Warnings when connections collide: two that both take all traffic, overlapping routes (IPv4 and IPv6), DNS already taken.
Connections window
- Create a connection from scratch — servers, ports, protocols, CA, certificate, key,
tls-auth/tls-crypt, password sign-in — or edit any profile in a form or as text. Only the lines you change are rewritten. - Import
.ovpnfiles (with the keys they name), Tunnelblick.tblkfolders, profiles from a URL or an OpenVPN Access Server; duplicate, rename, delete. - Per connection: connect at launch, its own proxy, connect silently, what to do when the Mac sleeps.
Protection
- Kill switch (per connection, off by default): if a connection that carries all traffic drops unexpectedly, your TCP and UDP traffic outside the VPN stays blocked (PF) until you reconnect or unblock it from the menu — even across a restart of the helper. Name lookups through the Mac's resolver still go out, so the VPN can find its server again.
- Leak protection while a connection carries all traffic: no IPv6 and no DNS outside the VPN; the local network can be allowed.
- Leak check after connecting and on every network change: warns if the default route, a public network (as a rogue DHCP server would push — TunnelVision) or the DNS goes around the tunnel.
Signing in
- Username and password, private-key passwords, static and dynamic challenges (OTP), web/SSO sign-in, PKCS#12 certificates, HTTP proxies. Passwords are kept in your login Keychain, per connection.
- A warning when a connection's client certificate expires within 30 days, or has expired — before it connects.
Everyday
- Coloured live log with a light/dark switch; View Log opens the log file (in Console by default); notifications.
- Reconnects at once after sleep and on network changes (another Wi-Fi, a new router or lease); optional disconnect on sleep.
- Networks that ask for a sign-in first (hotels, airports): the menu offers it, lifting a kill switch's block for two minutes so the page can load (a persistent connection's block: administrators only).
- Opens at login if you like; Export Diagnostics… makes a zip for a bug report — versions, routes, DNS, logs, and the profiles reduced to settings known to hold no secrets (keys, passwords,
setenvvalues and the like are left out). - Persistent connections that an administrator puts in
config-autostart at boot, before anyone logs in. - Your own scripts beside a profile (
<name>_pre.sh,_up.sh,_down.sh) — run as you, never as root; variables a server pushes (echo setenv NAME value) reach them asPUSHED_NAME. - Command line:
MugVPN --command connect|disconnect|reconnect|status|listwith exit codes and JSON — for scripts. - 22 languages, VoiceOver labels, light and dark appearance, an uninstaller.
MugVPN is made for more than one VPN at a time: each connection keeps its own routes and DNS, and the kill switch, leak protection and leak check work with all of them together.
| MugVPN | Tunnelblick 9 | Viscosity 1.13 | OpenVPN Connect 3.8 | |
|---|---|---|---|---|
| Several OpenVPN connections at once | Yes | Yes ("for experts only") | Yes | No: one at a time |
| Split DNS for several VPNs at once | Yes | Not documented | Yes | One connection only |
| Kill switch with several tunnels | Yes: per connection, blocks only traffic outside the tunnels | Turns off all network services; not advised with several VPNs | No built-in | Seamless Tunnel (one connection) |
| IPv6 and DNS kept inside the VPN (firewall) | Yes (macOS packet filter) | IPv6 off | IPv6 blocked | IPv6 blocked |
| Leak check after connecting, incl. TunnelVision | Yes | Public IP check | DNS problems in the log | No |
| Warnings when connections collide | Yes: both take all traffic, overlapping routes, DNS | Generic warning | No | — |
| openvpn runs without root | Yes | No (root) | Not documented | Not documented |
| Editor for servers, certificates, keys | Yes | No (text files) | Yes | Name, server, proxy only |
| Hotel/airport Wi-Fi sign-in | Yes, even while the kill switch blocks | Not documented | Not documented | Yes |
| Command line | connect/disconnect/status/list, exit codes, JSON | AppleScript | AppleScript | No connect/disconnect on macOS |
| Connections at boot, before login | Yes | Yes | No | No (Windows only) |
| Managed settings (MDM) | Yes | Partial | Yes | Yes |
| Price, license | Free, MIT | Free, GPL v2 | US$16, proprietary | Free, proprietary |
| macOS | 13+ | 13+ | 14+ | 11+ |
As documented by each product on 2026-10-10: Tunnelblick (kill switch, background programs), Viscosity (multiple connections, leaks), OpenVPN Connect (one connection, command line). Corrections welcome in an issue.
- openvpn runs without root. Each tunnel's
openvpnruns unprivileged; a small helper does what needs root, after checking each request. - Profiles are checked before they run: options that would run programs or load code are refused, with the line that caused it.
- Passwords stay in your login Keychain, per connection.
- Built test-first, with integration tests in virtual machines against real OpenVPN servers.
Found a security problem? Please report it privately through GitHub's security advisories rather than an issue.
macOS 13 Ventura or later, Apple silicon or Intel.
brew install --cask tanderbold/tap/mugvpn
or download MugVPN-<version>.dmg from the latest release
(signed with a Developer ID and notarized by Apple; its SHA-256 is beside it), open it and drag
MugVPN to Applications, then open it from there. The first time you connect, macOS asks you to
allow MugVPN's helper in System Settings > General > Login Items; MugVPN opens that page for you.
Install it as an administrator. A newer version replaces the app in the same way (brew upgrade);
its helper is updated once no connection needs it. A helper too old to update itself is offered from
the menu (Update MugVPN's Helper…, which stops every user's MugVPN connections).
Or build it yourself (Building): copy build/MugVPN.app to /Applications. The first
build makes a code-signing certificate of your own, kept in ~/Library/Application Support/MugVPN Build;
MugVPN's helper then works only with an app signed with it, so it trusts what runs as your account
(the uninstaller leaves that folder; delete it when you no longer build MugVPN).
Macs with standard users. Routes and DNS are the whole Mac's, so by default a standard
(non-administrator) user's connections reach only private networks (10/8, 172.16/12, 192.168/16,
100.64/10, fc00::/7), carry only that user's own TCP and UDP traffic (no ping), and set no DNS
unless an administrator allows its names. The routing table is still
the Mac's: such a route can make that private network unreachable for the Mac's other users while
the connection is up. An administrator can allow more, or list the networks standard users may
reach, in /Library/Application Support/MugVPN/policy.json (owned by root):
{
"allowedNetworks": ["203.0.113.0/24", "2001:db8::/32"],
"allowedDomains": ["corp.example.com"],
"usersMayRouteAllTraffic": false,
"usersMayChangeDNS": false,
"trustedUsers": ["alice"]
}usersMayRouteAllTraffic lets standard users send all traffic through a VPN; usersMayChangeDNS
lets them set DNS for any names, all names included; trustedUsers are treated as administrators.
Managed settings. A configuration profile (MDM) for com.mugvpn.app can set and lock any of
MugVPN's settings; MugVPN then shows them as set by the administrator. Among them:
require_kill_switch, require_leak_protection (IPv6 and DNS only through the VPN),
disable_save_passwords, allow_lan_when_blocked, persistent_connections (auto, manual,
disable) and the proxy.
| Where | What |
|---|---|
~/Library/Application Support/MugVPN/config |
your profiles (Import puts them here, one folder each) |
/Library/Application Support/MugVPN/config |
profiles an administrator installs for every user |
/Library/Application Support/MugVPN/config-auto |
persistent profiles, started by the system at boot |
A persistent profile is config-auto/<name>.ovpn; it and the files it names (inside config-auto)
must be root's and readable only by root (chmod 600). Its settings go beside it, as <name>.json
(root's, not writable by group or others; without it, all of these are off); MugVPN's window shows
them but does not change them:
{ "kill_switch": true, "allow_lan": false, "block_ipv6": true, "dns_only_tunnel": true, "split_dns": false }Its kill switch blocks the whole Mac's traffic outside the tunnel until the tunnel is back; a persistent tunnel that ends unexpectedly is started again, waiting longer each time (up to 5 minutes).
Standard .ovpn profiles work as they are. For safety, no profile — not even an administrator's —
may run programs as root: up, down, plugin, script-security 2 and the like are refused, with
the line that caused it. Use the _pre/_up/_down.sh scripts instead; they run as you.
MugVPN --connect <profile>
MugVPN --command connect|disconnect|reconnect <profile> [--wait] [--timeout <seconds>]
MugVPN --command list | status [<profile>]
MugVPN --command disconnect_all | rescan | exit
MugVPN --command silent_connection 0|1
MugVPN --command import <path>
MugVPN --uninstall [--keep-profiles] [--yes]
MugVPN here is /Applications/MugVPN.app/Contents/MacOS/MugVPN. --connect starts MugVPN and
connects the profile (if MugVPN is running, it connects it there). A command returns once MugVPN has
started it; with --wait (60 s) or --timeout <seconds>, once the connection is up or down.
Exit codes: 0 done, 1 failed (an unknown profile, a connection that did not come up), 2 a usage
error, 3 MugVPN is not running or does not answer (connect and import start it; exit just
succeeds), 4 timed out. list prints every profile and status the connected ones (or the one
named), as JSON: name, path, source (user, system, persistent), status (disconnected,
connecting, waiting_for_web_auth, connected, reconnecting, disconnecting), ip, ipv6. A profile
is named as MugVPN shows it, by its file path, or by its name when only one profile has it.
Drag MugVPN to the Trash: a minute later its helper removes what MugVPN put on the Mac — the
helper itself, its files and logs, and every user's MugVPN logs and settings. Profiles stay (yours and
those administrators installed, and policy.json), for a reinstall to find. Should the Trash be emptied
and the Mac restarted within that minute, the system part goes at the next start; users' logs and
settings and the Login Items entry then stay. Anything left is named in the system log (in Console, search
for MugVPN).
About MugVPN > Uninstall MugVPN…, or MugVPN --uninstall --yes in Terminal (--uninstall alone
lists what would go), removes everything; an administrator's. It disconnects every tunnel and removes
the helper, its files and logs, the profiles administrators installed (config, config-auto) and
policy.json, your own profiles, settings and saved passwords, and moves the app to the Trash; other
users' own profiles and passwords stay. Keep my profiles (--keep-profiles) keeps every profile and
policy.json. If the helper does not answer, MugVPN asks for an administrator's password to remove
its system part itself (the command line prints the command instead).
With Homebrew: brew uninstall --cask mugvpn; --zap removes your profiles and settings too.
- MugVPN.app (your rights): the menu, the windows, your profiles and saved passwords. It talks
to each
openvpnover its management interface. - The helper (a LaunchDaemon): starts and stops
openvpnfor the app, sets up the tunnels it asks for and cleans up after a tunnel that ended. - openvpn 2.7, built from source with OpenSSL 3.5, LZ4 and LZO, inside the app.
Only the Xcode Command Line Tools are needed.
tools/build-openvpn.sh # openvpn and its libraries (build.sh also runs it when needed)
MUGVPN_ARCH=native tools/build.sh # build/MugVPN.app (omit MUGVPN_ARCH for a universal build)
Translations: tools/l10n/l10n.py build writes Resources/<language>.lproj from tools/l10n/translations.
Third-party notices: tools/notices.sh writes THIRD-PARTY-NOTICES.txt from the pinned source archives.
Three layers, written before the code they test (Tests/):
- Logic — parsers, profiles, the helper's and the app's decisions, with the system faked:
swift build --product MugVPNTests && .build/debug/MugVPNTests - Integration — real tunnels, routes, DNS and the helper as root, only inside two virtual
machines (
tools/stand/stand.sh: a macOS client and Ubuntu OpenVPN servers):.venv/bin/pytest Tests/Integration - Interface — the menu and windows, driven inside the macOS VM's login session against the
app's test mode with a fake backend:
tools/stand/stand.sh ui
Both run against a testing build (MUGVPN_TESTING=1 tools/build.sh).
Nothing in the integration or interface tests touches the Mac you run them from.
MugVPN is under the MIT License.
The app bundle also contains openvpn (GPLv2, with MugVPN's patch in tools/), OpenSSL (Apache 2.0),
LZ4 (BSD 2-Clause) and LZO (GPLv2), each under its own license, built from the official releases
listed with their full license texts in THIRD-PARTY-NOTICES.txt.
MugVPN runs openvpn as a separate program.
"OpenVPN" is a trademark of OpenVPN Inc. MugVPN is not affiliated with or endorsed by OpenVPN Inc.; the name is used only to say which profiles MugVPN works with.






