WireguardBackend

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.hpp
  • unistd.h
  • sys/wait.h

GTK/GLib

  • glibmm/spawn.h
  • glibmm/shell.h

C/C++ Runtime

  • cstdlib
  • cstring
  • fstream
  • sstream
  • filesystem

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 with ip, wg, and an in-memory shell script.
  • Validates required tools and loads either a standard WireGuard .conf or UI-supplied parameters.
  • Generates client keys with wg genkey and wg pubkey.

Routing and DNS

  • Creates the selected WireGuard interface, assigns IPv4/IPv6 addresses, and raises the link.
  • Uses routing table 51820 and policy rules for full-tunnel AllowedIPs.
  • Adds direct routes for non-default AllowedIPs.
  • Backs up /etc/resolv.conf as /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 show when available.
  • Queries multiple HTTPS public-IP services through curl with 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

  1. Load or build an in-memory WireGuard tunnel specification.
  2. Validate required tools and configuration fields.
  3. Generate keys or create the interface and apply peers through wg setconf.
  4. Assign addresses, configure routes, and update DNS.
  5. Expose status and public-IP verification to the UI.
  6. 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

  • curl
  • ip
  • nft
  • pkexec
  • sh
  • wg

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.