NetworkManager integration for a FortiGate IKEv2/EAP+2FA VPN client on Linux (strongSwan). Provides a NetworkManager VPN plugin (D-Bus service + editor), a standalone connection-management GUI, and a 2FA (email OTP) prompt agent that runs in the user's graphical session.
English/Polish: this package's installer and GUI support both languages
(--lang pl|en / FORTIVPN_LANG=pl|en, auto-detected from system locale
otherwise).
fortivpn-config — the standalone connection editor (Connection field
shows placeholder/example values, not a real gateway):
The 2FA prompt shown by fortivpn-otp-agent when the gateway requests an
EAP-GTC token:
This repo is the NetworkManager integration layer — it is not
strongSwan itself. It talks to a locally installed, patched strongSwan
(swanctl/vici) to do the actual IKEv2/EAP negotiation with a FortiGate
gateway; the strongSwan-side patches (EAP-GTC token handling, FortiGate
auth quirks) live in a separate repository/fork of strongSwan.
Components:
nm/nm-fortivpn-service.py— the NetworkManager VPN plugin's D-Bus service (root). Rendersswanctl.conffrom a template, drivesswanctl --initiate/--terminate, reports state back to NetworkManager.nm/nm-fortivpn-editor.c— the libnm VPN editor plugin (GTK3). Known limitation:gnome-control-centeris a GTK4 process, and mixing a GTK3 plugin into it deadlocks (a GNOME-side issue, not fixable from here) — usefortivpn-configinstead of the GNOME Settings VPN editor.sbin/fortivpn-config-gui.py— standalone GTK3 connection editor (own process, so no GTK3/GTK4 conflict). Handles multiple independent FortiVPN tunnels, IKE/ESP algorithm proposals, DH groups. Installed asfortivpn-config.sbin/fortivpn-otp-agent.py— runs in the user's session (systemd --user), shows azenityprompt for the 2FA code on request.sbin/fortigate-otp-helper.sh— theotp_helperinvoked by the patchedeap-gtcstrongSwan plugin; requests a code from the agent above via a FIFO rendezvous (root/fortivpngroup only reads the code, never bridges into the user's session).sbin/fortivpn-up.sh/fortivpn-down.sh— directswanctlCLI wrapper, an alternative to the NetworkManager path (useful for scripting or debugging without NM).etc/—swanctl.conftemplate and strongSwan config drop-ins (fortigate.conffor the FortiClient-compatibility knobs,fct_data.txtidentity data sent to the gateway,eap-gtc-otp.conf, logging).
Requires gcc, libnm/gtk+-3.0/gmodule-2.0 dev headers, and a locally
installed strongSwan (for header/plugin compatibility — install the base
strongswan-swanctl charon-systemd libcharon-extra-plugins packages first).
sudo install/build-deb.shProduces dist/fortivpn-nm_1.0_<arch>.deb. This package alone is not
sufficient — the gateway requires the patched strongSwan libcharon (see the
companion strongSwan patches repo) installed and held (apt-mark hold)
first.
sudo install/install-client.sh --gateway vpn.example.com --user youruserSee INSTALL.md (Polish) / INSTALL.en.md (English) for the full manual
step-by-step and troubleshooting.
- Ubuntu 26.04 LTS "Resolute Raccoon" (
VERSION_ID=26.04, codenameresolute) - Kernel
7.0.0-14-generic - strongSwan packages
6.0.4-1ubuntu3.1
- Secrets (VPN password, gateway PSK) are entered via hidden prompts only — never passed as CLI arguments or left in shell history.
- The OTP agent runs as an unprivileged user; the root-side helper only ever reads a code back over a FIFO, it never runs anything in the user's session.
etc/fct_data.txtships with placeholder identity values (IP=192.0.2.1, a zeroed MAC) — adjust only if your environment actually needs FortiClient-identity spoofing to match a specific gateway policy.

