How To Install WireGuard on Fedora 44

Install WireGuard on Fedora 44

Most sysadmins who run a Linux server eventually hit the same wall: they need a fast, private tunnel between machines, and every solution they find is either too complex to configure or too slow to be practical. WireGuard solves that. It lives in the Linux kernel, needs almost no configuration to get working, and performs faster than OpenVPN by a wide margin.

This guide shows you exactly how to install WireGuard on Fedora 44, from the first package install all the way to a running, persistent VPN tunnel. Every command comes with a clear explanation of what it does and why you need it. No hand-waving, no skipping steps.

Fedora 44 ships with Linux kernel 6.19, which includes the WireGuard module natively. That is important: you do not need any external COPR repository or DKMS driver. The kernel already has everything built in.

What Is WireGuard and Why It Fits Fedora 44

Before running any commands, it is worth understanding what you are installing and why it is the right tool for the job.

WireGuard is a VPN protocol implemented directly inside the Linux kernel. It has been part of the mainline kernel since version 5.6, which means it is not a third-party add-on. It is a first-class citizen of the Linux networking stack.

The design philosophy is minimalism. WireGuard’s full codebase sits at roughly 4,000 lines. OpenVPN’s is closer to 400,000. A smaller codebase means fewer places for bugs to hide and a dramatically smaller attack surface.

WireGuard vs. OpenVPN vs. IPsec

Feature WireGuard OpenVPN IPsec
Kernel integration Yes (native) No (userspace) Partial
Config complexity Low Medium High
Codebase size ~4,000 lines ~400,000 lines Very large
Cryptography Modern (Curve25519, ChaCha20) Configurable (can be weak) Configurable
Setup time Minutes 30-60 minutes Hours

Why Fedora 44 Makes This Even Easier

Fedora 44 runs kernel 6.19 with WireGuard compiled in by default. It also ships DNF5 as the default package manager, which resolves dependencies faster than its predecessor. You only need to install the userspace tools, which is a single command.

NetworkManager on Fedora 44 also supports WireGuard natively, which gives you both command-line and GUI options for managing your tunnel. You get flexibility depending on whether you are running a headless server or a desktop workstation.

Prerequisites

Before you start, confirm your environment matches these requirements:

  • Fedora 44 installed (Workstation, Server, or Minimal edition)
  • A user account with sudo privileges
  • An active internet connection for package download
  • Basic terminal comfort: you will use nano or vim to edit one config file
  • A second device to test the tunnel (another server, a VM, or a phone)
  • UDP port 51820 reachable from the internet (or a custom port if you prefer)
  • Kernel 6.19 or newer confirmed:
uname -r

Expected output: something like 6.19.x-200.fc44.x86_64

If you see anything below 6.19, update your system first (Step 1 covers this).

Step 1: Update Your Fedora 44 System

Always update before installing anything. This step ensures your kernel, glibc, and networking libraries are at their latest state.

sudo dnf update -y

Why this matters: A stale kernel can cause a version mismatch. If dnf installs a newer kernel image during the update, your running kernel and that image will differ. After the update, check whether a new kernel was installed and reboot if so.

rpm -q kernel | sort

If you see a new version listed, reboot:

sudo reboot

After rebooting, confirm you are now running the updated kernel:

uname -r

DNF5, which is the default on Fedora 44, runs noticeably faster than older DNF versions. The dnf update -y command here resolves all dependencies in one pass and applies updates without prompting.

Step 2: Install WireGuard on Fedora 44

This is the only package you need. The kernel module is already built in.

sudo dnf install wireguard-tools -y

Why only wireguard-tools? On Fedora 31 and newer, the WireGuard kernel module ships inside the mainline Linux kernel. The old method of installing wireguard-dkms and enabling a COPR repository is outdated and no longer needed on Fedora 44. Do not install wireguard-dkms. It will create unnecessary conflicts.

The wireguard-tools package gives you three binaries you will use throughout this guide:

  • wg: The main configuration and status tool
  • wg-quick: A helper script that brings interfaces up and down using a config file
  • wg showconf: Reads the current live interface state and outputs it in config format

Verify the installation:

wg --version

Expected output:

wireguard-tools v1.0.20210914 - https://git.zx2c4.com/wireguard-tools/

The exact version number may differ, but you should see that output without any errors.

Confirm the Kernel Module Loads

Even though the module is built in, load it explicitly and confirm:

sudo modprobe wireguard
lsmod | grep wireguard

Expected output from lsmod:

wireguard             102400  0

Why this step? Loading the module manually before creating any interfaces catches potential issues early. If modprobe wireguard returns an error here, you need to investigate kernel compatibility before continuing. An empty result from lsmod means the module is not active, and wg-quick up will fail silently later.

Step 3: Generate WireGuard Cryptographic Keys

WireGuard uses a public/private key pair for authentication. Every machine in your VPN (server and each client) needs its own pair. Generate the server’s pair now.

First, set strict permissions and navigate to the config directory:

sudo mkdir -p /etc/wireguard
sudo chmod 700 /etc/wireguard
cd /etc/wireguard

Why chmod 700? This restricts access to /etc/wireguard so only root can read or write files inside it. Private keys stored here must never be world-readable.

Now generate both keys in one command:

wg genkey | sudo tee /etc/wireguard/privatekey | wg pubkey | sudo tee /etc/wireguard/publickey

Breaking down this command:

  • wg genkey: Generates a random 256-bit Curve25519 private key
  • tee /etc/wireguard/privatekey: Writes the private key to a file AND passes it through the pipe
  • wg pubkey: Reads the private key from stdin and computes the matching public key
  • tee /etc/wireguard/publickey: Writes the public key to its own file

Lock down the private key file immediately:

sudo chmod 600 /etc/wireguard/privatekey

Why chmod 600? If wg-quick detects that your private key file is readable by anyone other than root, it prints a security warning and may refuse to start. Fixing permissions after the fact is possible, but setting them correctly now is cleaner.

Verify both files exist with the right permissions:

sudo ls -la /etc/wireguard/

Expected output:

-rw------- 1 root root  45 Jun 16 18:00 privatekey
-rw-r--r-- 1 root root  45 Jun 16 18:00 publickey

You need the private key content in the next step. Read it with:

sudo cat /etc/wireguard/privatekey

Copy that output. You will paste it into the config file.

Step 4: Create the WireGuard Interface Configuration File

The wg0.conf file is the heart of your WireGuard setup. It defines the interface, the cryptographic identity of the server, and every peer that is allowed to connect.

Open a new file:

sudo nano /etc/wireguard/wg0.conf

Paste this configuration, replacing the placeholder values:

[Interface]
Address = 10.0.0.1/24
ListenPort = 51820
PrivateKey = PASTE_YOUR_PRIVATE_KEY_HERE
SaveConfig = false
PostUp = firewall-cmd --permanent --zone=public --add-port=51820/udp; firewall-cmd --permanent --zone=public --add-masquerade; firewall-cmd --reload
PostDown = firewall-cmd --permanent --zone=public --remove-port=51820/udp; firewall-cmd --permanent --zone=public --remove-masquerade; firewall-cmd --reload

[Peer]
PublicKey = PASTE_CLIENT_PUBLIC_KEY_HERE
AllowedIPs = 10.0.0.2/32

Why each directive exists:

  • Address = 10.0.0.1/24: Assigns a private IP to the wg0 interface. The /24 subnet supports up to 254 peers on the 10.0.0.x range. This is internal VPN addressing, completely separate from your server’s public IP.
  • ListenPort = 51820: The UDP port WireGuard listens on. WireGuard uses UDP specifically because it handles its own packet ordering and retransmission. Using TCP would create a “TCP-over-TCP” tunneling problem that destroys performance under packet loss.
  • PrivateKey: The server’s private key. This is what cryptographically signs outgoing handshakes. Never share this value or commit it to any version control system.
  • SaveConfig = false: Prevents wg-quick from overwriting your config file with runtime state when the interface shuts down. Keeping this as false means your file on disk always reflects your intended configuration, not a snapshot of current connections.
  • PostUp / PostDown: Shell commands that run automatically when the interface starts or stops. Tying the firewall rules to the interface lifecycle ensures they stay in sync. If WireGuard is down, the firewall port closes too.
  • AllowedIPs = 10.0.0.2/32: This serves a dual purpose. It tells WireGuard to route packets destined for 10.0.0.2 through this peer, and it also acts as an access control rule. Only traffic from 10.0.0.2 is accepted from this peer.

Set strict permissions on the config file:

sudo chmod 600 /etc/wireguard/wg0.conf

Step 5: Enable IPv4 Forwarding for Packet Routing

By default, the Linux kernel drops any packet that is not addressed directly to the host. That is the right behavior for a regular workstation, but a VPN server needs to forward packets between its WireGuard interface and its outbound network interface. You need to enable IP forwarding.

echo "net.ipv4.ip_forward = 1" | sudo tee /etc/sysctl.d/99-wireguard-forward.conf
sudo sysctl -p /etc/sysctl.d/99-wireguard-forward.conf

Why write to /etc/sysctl.d/ instead of /etc/sysctl.conf?

Drop-in files under /etc/sysctl.d/ persist across reboots and survive system upgrades without being overwritten. The main /etc/sysctl.conf file can be modified or replaced by package updates. Using a dedicated drop-in file is the correct Fedora practice.

Confirm the setting is active right now:

sysctl net.ipv4.ip_forward

Expected output:

net.ipv4.ip_forward = 1

If this returns 0, the sysctl change did not apply. Run sudo sysctl --system to reload all sysctl configs from disk.

What happens if you skip this step? Clients will connect to the WireGuard tunnel successfully, but they will get no internet access through it. The server will accept their packets and then throw them away because forwarding is disabled. This is one of the most common mistakes in WireGuard setups.

Step 6: Configure firewalld on Fedora 44 for WireGuard

Fedora 44 uses firewalld as its default firewall manager. You must open UDP port 51820 and enable masquerading (NAT) so that VPN clients can access the internet through the server.

Do not edit raw iptables rules directly on a Fedora system running firewalld. Direct iptables edits conflict with firewalld’s zone management and vanish on the next firewalld reload.

Run these commands:

# Open the WireGuard UDP port permanently
sudo firewall-cmd --permanent --zone=public --add-port=51820/udp

# Enable NAT masquerading so VPN clients can reach the internet
sudo firewall-cmd --permanent --zone=public --add-masquerade

# Apply all permanent rules to the running configuration
sudo firewall-cmd --reload

# Confirm everything is in place
sudo firewall-cmd --list-all

Why each flag matters:

  • --permanent: Without this flag, rules only exist until the next firewall-cmd --reload or system reboot. Always use --permanent for rules you intend to keep.
  • --add-masquerade: This enables Network Address Translation on the public zone. Your VPN clients have private IP addresses (10.0.0.x). When their traffic exits the server, masquerading rewrites the source IP to the server’s public IP. Without it, responses from the internet never know where to go back.
  • --reload: Applies permanent rules to the live firewall without dropping active connections. Always run this after making permanent changes.

Verify the output of firewall-cmd --list-all:

Look for these lines in the output:

ports: 51820/udp
masquerade: yes

If either is missing, the corresponding command did not complete correctly. Re-run it and check for error messages.

Step 7: Start WireGuard and Enable It at Boot with systemd

Bring the wg0 interface up and make it start automatically on every reboot.

# Bring up the WireGuard interface immediately
sudo wg-quick up wg0

# Enable the systemd service so it starts at boot
sudo systemctl enable wg-quick@wg0

# Start the service through systemd (for consistency)
sudo systemctl start wg-quick@wg0

# Check the current service status
sudo systemctl status wg-quick@wg0

Why each command:

  • wg-quick up wg0: Reads /etc/wireguard/wg0.conf, creates the wg0 network interface in the kernel, assigns the IP address, sets up routing tables, and runs the PostUp commands. It is the fastest way to get the tunnel running.
  • systemctl enable wg-quick@wg0: Creates a systemd symlink so the service starts automatically after every reboot. Without this, you have to manually run wg-quick up wg0 every time the server restarts.
  • systemctl start wg-quick@wg0: Starts the service through systemd explicitly so that the systemd dependency tree and journal logs are properly populated from the start.

What the correct systemctl status output looks like:

wg-quick@wg0.service - WireGuard via wg-quick(8) for wg0
     Loaded: loaded (/lib/systemd/system/wg-quick@.service; enabled; vendor preset: disabled)
     Active: active (exited) since Tue 2026-06-16 18:00:00 WIB; 5s ago

The active (exited) state is correct and expected. wg-quick runs once to configure the interface and then exits cleanly. The interface stays up even after the process exits.

Step 8: Verify the WireGuard Interface Is Running

Run three checks to confirm the tunnel is fully operational.

# Show WireGuard interface status
sudo wg show

# Confirm the kernel sees the wg0 interface
ip addr show wg0

# Ping the WireGuard interface IP from the server itself
ping -c 4 10.0.0.1

What to look for in sudo wg show:

interface: wg0
  public key: <your server public key>
  private key: (hidden)
  listening port: 51820

If a peer has connected and completed a handshake, you will also see:

peer: <client public key>
  allowed ips: 10.0.0.2/32
  latest handshake: X seconds ago
  transfer: 1.23 KiB received, 4.56 KiB sent

A latest handshake timestamp that is under 3 minutes old means the peer is actively connected. No handshake listed means the client has not connected yet, which is expected until you configure a client device.

ip addr show wg0 output should show:

4: wg0: <POINTOPOINT,NOARP,UP,LOWER_UP> mtu 1420 qdisc noqueue state UNKNOWN
    inet 10.0.0.1/24 scope global wg0

The UP,LOWER_UP flags confirm the interface is active and the kernel is routing through it.

Optional: Manage WireGuard via NetworkManager (nmcli) on Fedora 44 Workstation

If you are running Fedora 44 Workstation with GNOME 50, you can import your WireGuard config directly into NetworkManager. This lets you toggle the VPN from the GNOME network settings panel.

Import the existing config:

sudo nmcli connection import type wireguard file /etc/wireguard/wg0.conf

Or create a new WireGuard connection manually:

sudo nmcli connection add type wireguard con-name "wg-vpn" ifname wg0 autoconnect no

Why autoconnect no? On a workstation, you usually want to connect the VPN on demand, not automatically on every network change. Set autoconnect yes only on headless servers where the tunnel should always be up.

This method is entirely optional for server setups. The wg-quick + systemd approach from Steps 7 covers everything a server needs.

Troubleshooting Common WireGuard Issues on Fedora 44

Interface Fails to Start

Symptom: sudo wg-quick up wg0 returns an error immediately.

Fix: Check these in order:

  1. Confirm the private key in wg0.conf has no extra whitespace or newline characters
  2. Verify file permissions: sudo ls -la /etc/wireguard/ (both privatekey and wg0.conf must be 600)
  3. Run sudo journalctl -u wg-quick@wg0 --no-pager to see the full systemd error log

Clients Connect But Have No Internet Access

Symptom: The VPN tunnel is up and the handshake completes, but the client cannot browse the web.

Fix:

# Check IP forwarding is on
sysctl net.ipv4.ip_forward

# Check masquerade is active
sudo firewall-cmd --list-all | grep masquerade

If ip_forward returns 0, re-apply Step 5. If masquerade: no, re-apply the masquerade command from Step 6.

UDP Port 51820 Not Reachable from Outside

Symptom: Clients time out during handshake and never connect.

Fix:

sudo firewall-cmd --list-ports

Confirm 51820/udp appears. If you are behind a home router or cloud firewall (security groups), also open UDP 51820 at the network level, not just on the OS firewall. WireGuard will not respond on TCP, so TCP port scanners will always show the port as “filtered.”

SELinux Blocking WireGuard Operations

Symptom: Interface starts but behaves unexpectedly, or PostUp commands fail silently.

Fix: Check SELinux audit log for WireGuard denials:

sudo ausearch -c 'wireguard' --raw | head -40

If you see AVC denial messages, generate a policy module to allow the blocked operation:

sudo ausearch -c 'wireguard' --raw | audit2allow -M wireguard-local
sudo semodule -i wireguard-local.pp

Never set SELinux to permissive mode permanently in a production environment. Investigate and write a proper policy instead.

Config File Changes Not Taking Effect

Symptom: You edited wg0.conf but the running interface does not reflect the change.

Fix: You must bring the interface down and back up to reload the config:

sudo wg-quick down wg0
sudo wg-quick up wg0

Alternatively, use wg set for live changes that do not require a full restart (for example, adding a new peer public key without disrupting existing connections).

Security Hardening After Installation

Getting WireGuard running is step one. These steps close the gaps that default configurations leave open.

Rotate keys periodically. Generate a new server key pair and update wg0.conf without downtime:

wg genkey | sudo tee /etc/wireguard/privatekey | wg pubkey | sudo tee /etc/wireguard/publickey
sudo wg set wg0 private-key /etc/wireguard/privatekey

Use a preshared key for each peer. This adds a second layer of symmetric encryption on top of the Curve25519 handshake, providing resistance against future quantum computing attacks:

wg genpsk | sudo tee /etc/wireguard/preshared.key

Add PresharedKey = <output> to the relevant [Peer] block in wg0.conf.

Audit active peers regularly:

sudo wg show

Remove any peer whose latest handshake is stale for weeks. Delete their [Peer] block from wg0.conf and restart the service. An unused peer with a valid key is an open door.

Restrict SSH access to the WireGuard subnet. If this server is VPN-only, remove SSH from the public firewalld zone and only allow it on the wg0 interface IP range. This ensures administrative access only works through the tunnel.

[su_box title=”VPS Manage Service Offer” style=”bubbles” box_color=”#000000″ radius=”10″]If you don’t have time to do all of this stuff, or if this is not your area of expertise, we offer a service to do “VPS Manage Service Offer”, starting from $10 (Paypal payment). Please contact us to get the best deal![/su_box]

r00t is a Linux Systems Administrator and open-source advocate with over ten years of hands-on experience in server infrastructure, system hardening, and performance tuning. Having worked across distributions such as Debian, Arch, RHEL, and Ubuntu, he brings real-world depth to every article published on this blog. r00t writes to bridge the gap between complex sysadmin concepts and practical, everyday application — whether you are configuring your first server or optimizing a production environment. Based in New York, US, he is a firm believer that knowledge, like open-source software, is best when shared freely.

Related Posts