Another Qt OpenVPN Management UI
  • Python 98.5%
  • Shell 1.5%
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
mysticalsoap 4afaa4ce76
All checks were successful
ci / test (pull_request) Successful in 27s
ci / test (push) Successful in 1m16s
fix: stop logging expected startup states as errors and warnings
Three normal conditions made every start read like a failure:

- A caller whose bus connection died before its polkit check -- a stale
  gui call racing a service restart -- was logged as 'polkit
  unavailable' at error. NameHasNoOwner names the subject, not polkit;
  it now logs at info as a vanished caller, and only other DBus
  failures keep the error.
- QtWebEngine's absence was an 'Import Error' at error level, though
  it is deliberately optional and only the location map degrades.
- A json file not written yet (profile.json on first run,
  last_server.json before any connection) warned with a raw errno.
  Absent files log debug and return defaults; a file that exists but
  does not parse still warns.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-24 19:55:51 -04:00
.forgejo/workflows fix: clear pacman's download sandboxes from the CI cache 2026-08-21 11:52:58 -04:00
aqomui fix: stop logging expected startup states as errors and warnings 2026-08-24 19:55:51 -04:00
packaging/arch fix: authenticate the ProtonVPN import over SRP 2026-08-24 15:23:21 -04:00
resources fix: authenticate the ProtonVPN import over SRP 2026-08-24 15:23:21 -04:00
screenshots rename: qomui -> aqomui, bump to 0.9.0 (#1) 2026-08-16 18:47:25 -04:00
scripts fix: make bypass over a VPN server work again 2026-08-19 22:22:21 -04:00
systemd fix: authorize service calls through polkit 2026-08-18 20:50:51 -04:00
tests fix: stop logging expected startup states as errors and warnings 2026-08-24 19:55:51 -04:00
.gitignore add: Arch packaging 2026-08-17 12:50:48 -04:00
CHANGELOG.md add: the 0.9.1 changelog entry, bump to 0.9.1 2026-08-23 02:27:11 -04:00
CONTRIBUTING.md rename: build-branch.sh to build-branch-and-install.sh 2026-08-19 15:07:19 -04:00
LICENSE Update LICENSE 2018-04-12 07:03:43 +00:00
README.md add: auto-open Proton's verification page in the gui's browser 2026-08-24 16:20:39 -04:00
setup.py change: split the providers into their own package 2026-08-24 12:19:59 -04:00
VERSION add: the 0.9.1 changelog entry, bump to 0.9.1 2026-08-23 02:27:11 -04:00

aqomui

Description

aqomui (Another Qt OpenVPN Management UI) is an easy-to-use OpenVPN/WireGuard gui for GNU/Linux with some unique features such as provider-independent support for double-hop connections. aqomui supports multiple providers with added convenience when using AirVPN, ProtonVPN, Windscribe or Mullvad.

"a" for "another": aqomui is a hard fork of corrad1nho/qomui (dormant since 2019) via samicrusader/qomui (dormant since 2023). The app bypass/split-tunneling feature relied on the cgroup v1 net_cls controller, which cgroup v2 removed outright — not a compatibility flag to flip, so this fork rewrites that mechanism for v2 rather than patching it. Everything else in this README describes inherited behavior from upstream qomui unless noted otherwise.

Features

  • works with all VPN providers that offer OpenVPN/WireGuard config files
  • easy-to-use gui written in PyQt5
  • automatic download function for Mullvad, Windscribe, ProtonVPN and AirVPN including support for OpenVPN over SSL and SSH for AirVPN and OpenVPN over SSL for Windscribe (Stealth Mode)
  • allows double-hop VPN connections (VPN chains) between different providers
  • killswitch & leak protection via an iptables-based, configurable firewall that blocks all outgoing network traffic in case the VPN connection breaks down
  • provides the possibility to allow applications to bypass the VPN tunnel, open a second VPN tunnel or use the VPN only for specific applications
  • supports WireGuard
  • command-line interface
  • security-conscious separation of the gui and a D-Bus service that handles commands that require root privileges

Screenshots

Screenshots were taken on Arch Linux/Plasma Arc Dark Theme - aqomui will adapt to your theme.

Dependencies/Requirements

  • aqomui should work on any GNU/Linux distribution
  • python 3 (developed and CI-tested against current releases)
  • python-pyqt5, python-dbus, and python-dbus.mainloop.pyqt5
  • Additional python packages: psutil, requests, beautifulsoup4, lxml, pexpect, netifaces, cryptography
  • openvpn, dnsutils and stunnel
  • geoip and geoip-database (optional: to identify server locations)
  • dnsmasq, iptables >= 1.6 (optional: required for bypassing OpenVPN)
  • wireguard-tools, openresolv (optional: wireguard)

Installation

  • Arch Linux: build and install from the PKGBUILD in packaging/arch/ with makepkg -si.
  • Other distributions: install the dependencies above, then run sudo python3 setup.py install from a checkout.

Calls to aqomui-service are authorized through polkit: by default the user at an active local session may control it and everyone else is refused. For headless or SSH use, grant the org.aqomui.service.manage action to your user with a polkit rule. A source install needs the action file copied into place:

sudo cp systemd/org.aqomui.service.policy /usr/share/polkit-1/actions/

General usage

aqomui contains two components: aqomui-gui and aqomui-service (and aqomui-cli: see below). The latter exposes methods via D-Bus and can be controlled via systemd (alternatively you can start it with "sudo aqomui-service" - this is not recommended).

Current configurations for AirVPN, Mullvad, ProtonVPN and Windscribe can be automatically downloaded via the provider tab. aqomui will update these every five days if you choose to enable the respective setting in the options tab. For all other providers you can conveniently add a config file folder. aqomui will automatically resolve host names, determine the location of servers (using geoip-database) and save your username and password (in a file readable only by root).

ProtonVPN sign-in takes your Proton account credentials, not the OpenVPN pair (that one is fetched and stored for you), plus a third field for the current 2FA code if your account uses one. It needs python-proton-core installed. Proton gates logins from apps it does not recognize behind a CAPTCHA: on the first attempt aqomui opens the verification page in your browser — solve it, then hit Continue on the dialog within half an hour and the sign-in finishes with the credentials you already typed (2FA accounts are asked for a fresh code).

Once you added server configurations, you can browse and filter them in the server tab. Furthermore, you can mark servers as favourites and connect to one of them randomly. To see a list of all favourited servers click on the star in the upper right. There is also an option to create connection profiles in the respective tab. Profiles will select a server automatically based on the criteria you set. Criteria include protocol (OpenVPN or WireGuard), countries, providers and one of the following selection modes:

  • Random: Chooses a random server among all servers matching the profile
  • Fastest: Chooses the fastest server matching the profile based on latency. For this option to work properly the "Perform latency checks" option needs to be ticked.
  • Fast/Random: Chooses a random server among the fastest twenty percent. If your profile includes more than one country, the algorithm also increases the chance to select a server from a different country next.

Credential handling

What happens to credentials typed into the provider tab:

  • They end up in a root-readable-only auth file, for OpenVPN's own use.
  • ProtonVPN is the exception: the account password is used once, in memory, for the API sign-in — sent nowhere (SRP proves it without transmitting it, so not even Proton's server sees it) and written nowhere. What lands on disk is the fetched OpenVPN pair, which can connect to the VPN but cannot sign in to your account. The API session is logged out as soon as the import finishes.
  • If your Proton account guards more than VPN (Mail, Pass, Drive), you can keep its credentials out of aqomui entirely: download OpenVPN config files and your OpenVPN credential pair from the Proton dashboard and import them as a custom provider. That costs the automatic server list and updates; nothing account-scoped ever touches the app.

Options

  • Autoconnect/reconnect: Automatically connect to the last server/last profile once a new internet connection has been detected or after the OpenVPN process has died unexpectedly.
  • Start minimized: Hides the application window on startup. This only works if your desktop environment supports tray icons.
  • Auto-update: Updates server configurations for supported providers automatically every five days.
  • Perform latency check: Checks server latency and sorts servers accordingly.
  • Disable IPv6: Completely disables the IPv6 stack systemwide. This is not recommended unless you know what you are doing.
  • Allow OpenVPN bypass: See bypass section below.
  • Activate Firewall: See firewall section below.
  • Always use alternative DNS servers: Your own resolvers answer tunneled DNS instead of the provider's (the default) — for when you run an ad-blocker, use a split-horizon LAN resolver, or prefer a specific public one. The first server is the primary; the second answers only while the primary is down, and selection returns to the primary automatically once it recovers. On a split-horizon network, set the local resolver first and a public one second so internal names keep their internal answers; the local resolver must be reachable outside the tunnel (routing handles that by itself; with the firewall active, LAN traffic is allowed unless "Block LAN" is set).
  • Never change DNS servers: aqomui leaves DNS entirely alone. Warning: tunneled lookups then keep going wherever the system already sends them — on most setups that is a DNS leak.
  • Use same DNS servers for bypass: Skips the bypass resolver (dnsmasq): bypassed applications use the same DNS servers as everything else. Be aware that servers set via the tunnel might not be reachable outside it, which can leave bypassed applications without working DNS.

Firewall (Killswitch)

It is highly recommended to activate the firewall to prevent against ipv6 and DNS leaks. By default, once aqomui-service has been started, all internet connectivity outside the VPN tunnel will be blocked whether or not the gui is running. Hence, your system will be always protected if you enable aqomui-service via systemd. Depending on your distribution, it might be necessary to disable preinstalled firewall services such as ufw or firewalld to avoid conflicts. Alternatively, the "Edit firewall" dialog in the options tab offers a setting to enable/disable the firewall only if you start/quit the gui. You can also add custom iptables rules there.

Double-Hop

To create a "double-hop" simply choose a first server via the "hop"-button before connecting to the second one. You can mix connections to different providers. However, the double-hop feature does not support OpenVPN over SSL/SSH and WireGuard. Also be aware that depending on your choice of servers this feature may drastically reduce the speed of your internet connection and increase your ping. In any case, you will likely trade some bandwidth for the added privacy of separate entry and exit providers. Background on the routing technique: this discussion on the OpenVPN forum and this github repository.

Bypass

Bypass is opt-in split tunneling: mark the applications that should not use the VPN — a browser for sites that block VPN exits, say — and everything else stays tunneled. It works alongside aqomui's firewall and double-hop connections.

Add an application in the bypass tab and every future launch of it — desktop menu, taskbar, krunner — runs outside the tunnel automatically. Adding or removing an app takes effect from its next start, so restart it if it is already running; reconnecting or switching VPN servers needs no restarts, because bypass membership survives reconnects. For terminal commands, prefix them with aqomui-bypass:

aqomui-bypass curl https://icanhazip.com

Everything a bypassed application starts inherits the bypass, so list the entry point of the process tree you want outside the tunnel: listing Steam bypasses every game it launches. To bypass a single game without bypassing Steam, set the game's Launch Options to aqomui-bypass %command% instead.

Applications set to start on login are covered too: their autostart entries get the same wrapper, which briefly waits at login for bypass to come up (when enabled) before starting the app.

A listed application that was already running when bypass came up — restored by session restore, or started before aqomui at login — is moved into the bypass when it activates. Connections it had already opened stay on the tunnel for their lifetime, so restart such an application if it matters that all of its traffic bypasses.

Known gaps: an application started by an unlisted process exec'ing its binary directly passes through no launcher and no unit of its own — list the parent instead. KDE resolves global-shortcut launches (Ctrl+Alt+T and friends) once per session, so list changes reach those only at the next login, though the launch itself is caught once bypass activates.

Bypassing forwarded traffic

The application list only reaches traffic that originates on this machine — packets it merely forwards (containers, VMs, other LAN clients using it as a gateway) have no local process to mark, so they ride the tunnel with no opt-out. Notably, a container running its own VPN gets silently double-tunnelled: its already-encrypted traffic is encrypted again, throughput drops, and its connection state becomes coupled to the host VPN's.

Network entries in the bypass tab cover this: traffic from a listed source network routes past the tunnel while bypass is active. An optional protocol and destination port keep the entry narrow — to exempt only a container VPN's own transport, list the container subnet with the VPN's port (e.g. udp 51820 for WireGuard), and everything else from that subnet stays tunneled. Changes apply immediately, including to established flows.

The bypass feature also allows you to open a second OpenVPN tunnel (this does currently not work with WireGuard). You can choose any starred servers from a drop-down menu in the bypass tab. Furthermore, it is possible to connect to a server only via bypass, thereby allowing you to use your VPN only for selected applications. OpenVPN in bypass mode is currently limited to ipv4 to prevent leaks.

Bypassed applications resolve through the network's own DNS servers, as if the VPN were off, falling back to the alternative DNS servers when none are discoverable. A second bypass VPN tunnel uses the alternative servers instead, since its traffic exits through that tunnel.

Limitation: Opening two OpenVPN tunnels using servers from the same provider only works if your provider supports two concurrent connections on different subnets. Airvpn and Windscribe allow that, Mullvad and ProtonVPN don't. There is no known way to force this from the client apart from using a different port or protocol on the second connection.

WireGuard

You can add WireGuard config files from any provider as easily as OpenVPN files. WireGuard configs for Mullvad are now downloaded automatically alongside their OpenVPN configs as long as WireGuard is installed. If you choose to manually import WireGuard config files, aqomui will automatically recognize the type of file. As of now, WireGuard will not be installed automatically with DEB and RPM packages. You can find the official installation guidelines for different distributions here.

Cli

The cli interface is still experimental and missing some features, e.g. automatic reconnects. Avoid using the cli and the gui concurrently.

Example usage

Add config files:

aqomui-cli -a $provider

Connect to a server:

aqomui-cli -c $server

Activate options (e.g. firewall):

aqomui-cli -e firewall

List and filter available servers:

aqomui-cli -l Airvpn "United States"

To see all other available options:

aqomui-cli --help