1. Overview
The WireguardBackend.cpp file is a WireGuard backend implementation in BastionGuard.
Parses WireGuard configuration, executes ip and wg directly without wg-quick, configures routes and DNS, restores system state on disconnect, checks public IP, and manages an nftables kill-switch.
The documentation below is generated from the supplied source and covers its API surface, runtime responsibilities, data flow, filesystem or command interactions, concurrency model, and security considerations.
2. Source Inventory
- Original path:
vpn/WireguardBackend.cpp - Language: C++
- Source type:
.cpp - Line count: 489
- SHA-256:
77c18406802c74f87960791f764e4ec5fe514c64978690cf46eaf4bb45db46ec
3. Dependencies
The file declares the following compile-time dependencies:
Project
WireguardBackend.hppunistd.hsys/wait.h
GTK/GLib
glibmm/spawn.hglibmm/shell.h
C/C++ Runtime
cstdlibcstringfstreamsstreamfilesystem
4. Types and Public Contract
The file declares or implements the following principal types:
- Class:
Section - Enum:
Section
5. API and Method Inventory
The following functions or methods are implemented in this file:
WireguardBackend::WireguardBackend(std::string iface)– Implements the operation represented by this API.WireguardBackend::run(const std::vector<std::string>& argv, bool privileged)– Executes an argument vector and captures process output.WireguardBackend::run_with_stdin(const std::vector<std::string>& argv, const std::string& stdin_data, bool privileged)– Executes a process while supplying generated data on standard input.WireguardBackend::tooling_available(std::string* missing)– Checks that the required WireGuard command-line tools are present.WireguardBackend::load_from_conf(const std::string& conf_path, std::string* err)– Parses a standard WireGuard configuration file into memory.WireguardBackend::load_from_params(const WgConfigParams& p, std::string* err)– Builds an in-memory tunnel specification from UI fields.WireguardBackend::generate_keys()– Generates a WireGuard private/public key pair.WireguardBackend::build_wg_setconf_text()– Constructs the corresponding GTK interface section.WireguardBackend::connect()– Creates and configures the WireGuard interface, routes, and DNS.WireguardBackend::disconnect()– Restores DNS and removes tunnel routes and interface state.WireguardBackend::status()– Returns a synthesized tunnel status.WireguardBackend::public_ip()– Queries external services for the current public IPv4 address.WireguardBackend::killswitch_enable()– Installs the BastionGuard nftables kill-switch table.WireguardBackend::killswitch_disable()– Deletes the BastionGuard kill-switch table.iface_(std::move(iface))– Implements the operation represented by this API.in_path_(const char* bin)– Implements the operation represented by this API.strip_(std::string s)– Implements the operation represented by this API.split_csv_(const std::string& s)– Implements the operation represented by this API.needs_default_route_(const WgTunnelSpec& sp)– Implements the operation represented by this API.
6. Functional Architecture
Direct WireGuard Operation
- Does not use
wg-quick; it builds the tunnel withip,wg, and an in-memory shell script. - Validates required tools and loads either a standard WireGuard
.confor UI-supplied parameters. - Generates client keys with
wg genkeyandwg pubkey.
Routing and DNS
- Creates the selected WireGuard interface, assigns IPv4/IPv6 addresses, and raises the link.
- Uses routing table
51820and policy rules for full-tunnel AllowedIPs. - Adds direct routes for non-default AllowedIPs.
- Backs up
/etc/resolv.confas/etc/resolv.conf.bastionguard.bak, writes tunnel DNS atomically, and restores the backup on disconnect.
Status and Public-IP Verification
- Determines interface presence through unprivileged
ip link show. - Parses endpoint and latest handshake from
wg showwhen available. - Queries multiple HTTPS public-IP services through
curlwith a 10-second limit.
Kill-Switch
- Creates an nftables table named
bastionguard_ks. - Installs an output chain with a drop policy, permitting loopback, the WireGuard interface, the configured endpoint, and UDP.
- Removes the entire nftables table when disabled.
7. Operational Flow
- Load or build an in-memory WireGuard tunnel specification.
- Validate required tools and configuration fields.
- Generate keys or create the interface and apply peers through
wg setconf. - Assign addresses, configure routes, and update DNS.
- Expose status and public-IP verification to the UI.
- Restore DNS and route state during disconnect; manage nftables kill-switch state independently.
8. Filesystem and External Command Surface
Referenced Absolute Paths
/usr/sbin:/usr/bin:/sbin:/bin
Commands or Security Primitives Referenced
curlipnftpkexecshwg
9. Concurrency and Lifecycle
The file contains no explicit worker-thread or callback-lifetime mechanism.
10. Security Considerations
- Tunnel creation, route changes, DNS replacement, and nftables updates require elevated privileges.
- Private keys are held in memory and may be displayed in the configuration form.
- Imported WireGuard configuration must be treated as sensitive input.
- Failure paths must restore DNS, routes, and kill-switch state to avoid connectivity loss.
- The backend constructs privileged shell scripts from validated configuration values; strict validation is required to prevent shell metacharacters from crossing the privilege boundary.
- The kill-switch permits all UDP traffic in addition to loopback, the tunnel interface, and the endpoint.
11. Implementation Considerations
- The implementation should remain synchronized with the matching header declarations.
- Authorization cancellation and missing Polkit support must be surfaced as normal operation failures.
12. Licensing and Branding
The source is distributed under the GNU General Public License version 3.
The source header identifies BastionGuard™ as a trademark and states that the name and branding are not licensed under the GPL.
The software is provided without warranty, including implied warranties of merchantability or fitness for a particular purpose.
