You are on untrusted WiFi and need a secure tunnel
You are sitting in a crowded airport terminal. The free WiFi works, but your browser warns that the connection is not private. You need to tunnel your traffic through a trusted server before opening your email or banking app. You have the configuration files from your provider, but you are not sure whether to drag them into a settings window or type commands in a terminal. Fedora handles this through NetworkManager, which unifies the GUI and the command line. You can set up OpenVPN, WireGuard, or IPsec without leaving the tools you already use.
How NetworkManager manages VPN tunnels
NetworkManager treats a VPN as a first-class network connection. When you activate a VPN, NetworkManager does not just run a daemon in the background. It creates a virtual network interface, negotiates the encryption keys, and modifies your routing table so traffic flows through the tunnel. The encryption happens in the kernel for WireGuard and in user-space daemons for OpenVPN and StrongSwan. NetworkManager coordinates the key exchange, interface creation, and DNS updates so your applications do not need to change.
Think of it like adding a secure pipe to your plumbing. Water flows through the pipe instead of the main line, and the pipe is shielded so no one can see what is inside. NetworkManager also manages DNS. If the VPN config specifies a DNS server, NetworkManager updates the system resolver so your queries go through the tunnel. This prevents DNS leaks where your ISP sees your domain lookups even though your data is encrypted.
Run nmcli connection show --active to see all active connections. The VPN will appear as a separate connection with its own device name. If the VPN is active, the routing table will show a default route or specific routes pointing to the tunnel interface.
WireGuard: The modern standard
WireGuard is built into the Linux kernel since version 5.6. Fedora ships the user-space tools and the NetworkManager plugin. WireGuard is faster and simpler than OpenVPN because the protocol is minimal and runs in the kernel. It uses UDP by default and supports split tunneling natively through the AllowedIPs directive.
Install the required packages. The wireguard-tools package provides the wg and wg-quick commands, while the NetworkManager plugin integrates the tunnel into the system network manager.
sudo dnf install wireguard-tools NetworkManager-wireguard
# wireguard-tools provides the wg and wg-quick commands for manual control and debugging.
# NetworkManager-wireguard integrates the tunnel into nmcli and the desktop GUI.
# Both packages are needed for full functionality.
Create a configuration file in /etc/wireguard/. This file defines your private key, IP address, and the server peer. NetworkManager reads this file to create the connection profile.
[Interface]
PrivateKey = <your-private-key>
# This key authenticates your machine to the server. Keep it secret and never share it.
Address = 10.0.0.2/24
# Assigns an IP address inside the tunnel network. Must match the server's assignment.
DNS = 1.1.1.1
# Forces DNS queries through the tunnel to prevent leaks. Omit this for split tunneling.
[Peer]
PublicKey = <server-public-key>
# The server's public key. Used to encrypt traffic destined for the server.
AllowedIPs = 0.0.0.0/0
# Routes all traffic through this peer. Use specific subnets for split tunneling.
Endpoint = vpn.example.com:51820
# The server address and port. WireGuard uses UDP by default.
PersistentKeepalive = 25
# Sends a keepalive packet every 25 seconds to maintain NAT mappings.
Import the configuration into NetworkManager. This step creates a persistent connection profile that survives reboots and appears in the desktop network menu.
sudo nmcli connection import type wireguard file /etc/wireguard/wg0.conf
# Imports the config into NetworkManager so it persists across reboots.
# The connection name defaults to the filename without extension.
nmcli connection up wg0
# Activates the tunnel via NetworkManager.
# NetworkManager handles the interface creation and routing automatically.
If you need to test the config quickly without importing it, you can use wg-quick. This bypasses NetworkManager and is useful for debugging.
sudo wg-quick up wg0
# Brings up the tunnel using wg-quick directly.
# This does not integrate with NetworkManager or the desktop GUI.
sudo wg-quick down wg0
# Tears down the tunnel.
Check the handshake status to ensure the tunnel is alive. A stale handshake means the tunnel is dead and traffic is not flowing.
sudo wg
# Displays the current state of WireGuard interfaces and peers.
# Check the "latest handshake" time. It should update every few seconds.
# If the handshake is old, check your firewall and endpoint connectivity.
Check the handshake timestamp. A stale handshake means the tunnel is dead.
OpenVPN: The legacy workhorse
OpenVPN is the most widely supported VPN protocol. It runs in user-space and supports both TCP and UDP. Many providers still use OpenVPN because it works through restrictive firewalls and supports legacy certificate authentication. The configuration is more complex than WireGuard, but NetworkManager handles the details once you import the file.
Install the NetworkManager OpenVPN plugin. The gnome package adds the import dialog to the desktop settings, while the base package provides the backend for nmcli.
sudo dnf install NetworkManager-openvpn NetworkManager-openvpn-gnome
# NetworkManager-openvpn provides the backend plugin for nmcli and the GUI.
# NetworkManager-openvpn-gnome adds the import dialog to GNOME Settings.
# Install both for the best experience on a desktop system.
Import your .ovpn configuration file. NetworkManager parses the file and creates a connection profile. If the file requires credentials, NetworkManager will prompt you when you activate the connection.
sudo nmcli connection import type openvpn file ~/Downloads/client.ovpn
# Parses the .ovpn file and creates a NetworkManager connection profile.
# Credentials are often stored in a separate file or prompted at activation.
nmcli connection up client
# Starts the OpenVPN daemon and routes traffic through the tunnel.
# If the connection name differs, use the name shown by nmcli connection show.
OpenVPN can fail if the provider blocks UDP ports. Switch to TCP if UDP fails. Some providers offer both UDP and TCP configs. Use the TCP config if you are behind a firewall that drops UDP packets.
Import the file once. NetworkManager remembers the profile forever.
IPsec with StrongSwan: Enterprise connectivity
IPsec is the standard for enterprise VPNs. Fedora uses StrongSwan as the IPsec implementation. StrongSwan supports IKEv2, which is faster and more secure than IKEv1. NetworkManager has a plugin for StrongSwan, but you can also manage connections directly with swanctl.
Install StrongSwan and the NetworkManager plugin. The strongswan package provides the daemon and tools, while the plugin allows managing connections via nmcli.
sudo dnf install strongswan NetworkManager-strongswan
# strongswan provides the IKEv2 daemon and swanctl tool.
# NetworkManager-strongswan allows managing connections via nmcli.
# Fedora defaults to the swanctl configuration style in /etc/swanctl/.
For manual control, use swanctl. This tool manages the IKEv2 connections directly. It is useful for debugging and for scripts that do not use NetworkManager.
sudo swanctl --initiate --child my-vpn
# Manually initiates the IKEv2 connection using the swanctl control interface.
# This bypasses NetworkManager and is useful for debugging.
sudo swanctl --list-sas
# Lists the active security associations.
# Verify that the child SA is established and has the correct traffic selectors.
If you use the legacy ipsec.conf format, note that Fedora is moving toward swanctl configuration in /etc/swanctl/. The ipsec.conf file is still supported but may be deprecated in future releases. Use swanctl for new configurations.
Trust the daemon logs. swanctl --list-sas shows the active security associations.
Verify the tunnel is routing traffic
After activating the VPN, verify that traffic is flowing through the tunnel. Check your public IP address and inspect the routing table.
curl -s ifconfig.me
# Fetches the public IP address visible to the internet.
# Compare this output with your local IP to confirm the tunnel is routing traffic.
ip route get 8.8.8.8
# Shows the routing path for a specific destination.
# Look for the tunnel interface name in the output.
If curl returns your home IP, the tunnel is not routing. Check the AllowedIPs in WireGuard or the routing directives in OpenVPN. Ensure the VPN config sets a default route or includes the destination subnets.
Run journalctl -xeu NetworkManager if the connection fails. The logs explain why the activation was rejected. Look for errors related to missing plugins, invalid configs, or authentication failures.
If curl returns your home IP, the tunnel is not routing. Check AllowedIPs.
Common pitfalls and error patterns
DNS leaks happen when the VPN config does not specify a DNS server. Your system falls back to the local router, and your ISP sees your queries. Always set DNS in the WireGuard interface or dhcp-options in OpenVPN. NetworkManager will update the resolver only if the VPN provides DNS servers.
SELinux denials can block VPN configs if you copy files manually. If you place a config file in /etc/wireguard/ or /etc/strongswan/, run sudo restorecon -v /path/to/config. SELinux requires the correct context for NetworkManager to read the file. A missing context results in a silent failure where the connection refuses to start.
Routing conflicts occur when multiple VPNs are active or when the VPN routes overlap with your local network. NetworkManager handles metrics automatically, but manual configs can cause loops. Use ip route to inspect the routing table. If you see duplicate default routes, check the metrics. The route with the lower metric takes precedence.
The nmcli connection up command may return Error: Connection activation failed: No suitable device found. This usually means the plugin is missing or the interface type is wrong. Verify that you installed the correct NetworkManager plugin for your protocol.
Run journalctl -xeu NetworkManager first. Read the actual error before guessing.
Choose the right tool for your connection
Use WireGuard when you want low latency, simple configuration, and kernel-level performance.
Use OpenVPN when your provider only supports TCP or requires legacy certificate authentication.
Use IPsec with StrongSwan when you are connecting to a corporate network that mandates IKEv2.
Use NetworkManager integration when you need the VPN to appear in the desktop menu and persist across reboots.
Use wg-quick or swanctl directly when you are debugging a connection and need to bypass NetworkManager overhead.