WireGuard Remote Access: Fedora ↔︎ Windows
A concise guide for setting up WireGuard VPN to remotely access a Fedora machine from Windows, with SSH locked to the tunnel for security.
Overview
- Fedora: WireGuard server, listens on UDP 51820
- Windows: WireGuard client, connects from anywhere with internet
- Tunnel subnet:
10.10.10.0/24(server =.1, client =.2) - Security posture: SSH only reachable via tunnel, not LAN or internet
Part 1: Fedora Server Setup
1.1 Install WireGuard
sudo dnf install wireguard-tools -yThe kernel module is built into modern Fedora — no extra packages needed.
1.2 Generate server keys
cd /etc/wireguard
sudo sh -c 'umask 077; wg genkey | tee server_private.key | wg pubkey > server_public.key'View them:
sudo cat /etc/wireguard/server_private.key
sudo cat /etc/wireguard/server_public.key1.3 Create server config
Create /etc/wireguard/wg0.conf:
[Interface]
Address = 10.10.10.1/24
ListenPort = 51820
PrivateKey = <paste server_private.key contents>
[Peer]
PublicKey = <Windows client public key — fill in after Part 2>
AllowedIPs = 10.10.10.2/32Set permissions:
sudo chmod 600 /etc/wireguard/wg0.conf1.4 Configure firewall
Find your active zone first:
sudo firewall-cmd --get-active-zonesTypical active zone is FedoraWorkstation (desktop) or FedoraServer. Add WireGuard port to that zone and bind wg0 to the trusted zone:
# Replace <active-zone> with whatever --get-active-zones returns
sudo firewall-cmd --permanent --zone=<active-zone> --add-port=51820/udp
sudo firewall-cmd --permanent --zone=trusted --add-interface=wg0
sudo firewall-cmd --reload1.5 Start and enable the tunnel
sudo systemctl enable --now wg-quick@wg01.6 Router port forward
On your home router, forward UDP 51820 to the Fedora box's LAN IP.
Find the Fedora LAN IP:
ip -4 addr show | grep inetFind your public IP (what to put in Windows Endpoint):
curl -4 ifconfig.me⚠️ CGNAT check: if curl -4 ifconfig.me doesn't match your router's WAN IP, you're behind CGNAT and port forwarding won't work. Use Tailscale instead.
Part 2: Windows Client Setup
2.1 Install WireGuard
Download from wireguard.com/install and install.
2.2 Create empty tunnel
Open WireGuard → Add Tunnel → Add empty tunnel...
A keypair is auto-generated. Copy the public key shown at the top — you'll paste it into the Fedora config.
2.3 Fill in the config
Replace the dialog contents with:
[Interface]
PrivateKey = <leave the auto-generated one>
Address = 10.10.10.2/32
DNS = 1.1.1.1
[Peer]
PublicKey = <Fedora server's public key>
Endpoint = <your-public-ip-or-ddns>:51820
AllowedIPs = 10.10.10.0/24
PersistentKeepalive = 25Name the tunnel (e.g. fedora-home) and save.
2.4 Paste Windows public key into Fedora config
Back on Fedora:
sudo nano /etc/wireguard/wg0.confReplace the <Windows client public key> placeholder with the actual key from Windows, then restart:
sudo systemctl restart wg-quick@wg02.5 Activate on Windows
In the WireGuard GUI, click Activate. Status should flip to "Active" within seconds.
Part 3: Verification & Sanity Checks
3.1 Check WireGuard is running (Fedora)
sudo systemctl status wg-quick@wg0
sudo wg show
ip -brief addr | grep wg0Expected: service active, wg0 interface with 10.10.10.1/24, listening port 51820.
3.2 Verify keys match on both sides
Server public key (Fedora):
sudo wg show wg0 public-keyThis must equal the [Peer] PublicKey in your Windows config.
Check peer public key Fedora expects:
sudo wg show wg0 | grep peerThis must equal the Public key shown in the Windows WireGuard GUI.
Validate key lengths (should all be 44 chars ending in =):
sudo grep -E "PrivateKey|PublicKey" /etc/wireguard/wg0.conf | awk '{print $3, "length:", length($3)}'3.3 Sanity-check config file
sudo cat /etc/wireguard/wg0.conf
sudo ls -la /etc/wireguard/Config should have both [Interface] and [Peer] blocks with no placeholder text. Permissions should be -rw------- (600), owned by root.
Validate config parses correctly:
sudo wg-quick strip wg0Prints clean config if valid, errors if not.
3.4 Verify firewall state
sudo firewall-cmd --get-active-zones
sudo firewall-cmd --zone=<active-zone> --list-all
sudo firewall-cmd --zone=trusted --list-allActive zone should have 51820/udp in ports. Trusted zone should have wg0 in interfaces with target: ACCEPT.
3.5 Confirm port is listening
sudo ss -ulnp | grep 51820Should show something bound to *:51820.
3.6 Test handshake live
On Fedora, run tcpdump to watch packets. First identify your WAN-facing interface:
ip route | grep defaultNote the dev <name> — that's your WAN interface. Then:
sudo tcpdump -i any -n udp port 51820(-i any captures on all interfaces, easiest for troubleshooting.)
Then click Activate on Windows (from outside your LAN — use phone hotspot). You should see both incoming and outgoing packets within a second.
Interpreting tcpdump output:
- In + Out packets → handshake working
- Only In, no Out → Fedora receives but doesn't respond (firewall or config issue)
- No packets → traffic not reaching Fedora (router forward or CGNAT)
3.7 Confirm handshake completed
After activating Windows tunnel:
sudo wg showLook for:
latest handshake: X seconds agotransfer: X received, Y sentwith non-zero values
3.8 Test connectivity
From Windows PowerShell with tunnel active:
ping 10.10.10.1
ssh <user>@10.10.10.1Part 4: Lock SSH to the Tunnel (Recommended)
Once SSH works through the tunnel, remove it from public exposure.
4.1 Remove SSH from active zone
sudo firewall-cmd --permanent --zone=<active-zone> --remove-service=ssh
sudo firewall-cmd --reload4.2 Verify SSH still works via tunnel
From Windows (tunnel active):
ssh <user>@10.10.10.1Should still work — wg0 is in the trusted zone which allows all traffic.
4.3 Verify SSH blocked from LAN
From any other LAN device:
ssh <user>@<fedora-lan-ip>
Should time out or be refused.
4.4 Optional: Key-only SSH auth
Generate an Ed25519 key on Windows:
ssh-keygen -t ed25519
ssh-copy-id <user>@10.10.10.1Then disable password auth on Fedora — edit /etc/ssh/sshd_config:
PasswordAuthentication no
PermitRootLogin no
Reload:
sudo systemctl reload sshdPart 5: Troubleshooting Quick Reference
No handshake (bytes sent but not received)
- Check tcpdump on Fedora — are packets arriving?
- If no: router port forward, stale endpoint IP, or CGNAT
- If yes but no response: firewall or key mismatch
Endpoint IP changed (dynamic home IP)
curl -4 ifconfig.meUpdate the Windows config's Endpoint = line with the new value.
Tunnel shows active but ping fails
Check wg0 is in trusted zone:
sudo firewall-cmd --zone=trusted --list-interfacesIf missing:
sudo firewall-cmd --permanent --zone=trusted --add-interface=wg0
sudo firewall-cmd --reloadService fails to start
sudo journalctl -u wg-quick@wg0 -n 50 --no-pagerCommon causes:
- Key length not 44 chars → regenerate or re-paste
- Port 51820 already in use →
sudo ss -ulnp | grep 51820 - Placeholder text left in config → re-check
wg0.conf
Verify after reboot
sudo systemctl is-enabled wg-quick@wg0 # should say: enabled
sudo wg show
ip -brief addr | grep wg0Final Expected State
Fedora firewall
<active-zone> (default, active)
interfaces: <your-wan-interface>
services: dhcpv6-client
ports: 51820/udp
masquerade: no
trusted (active)
interfaces: wg0
target: ACCEPT
What you can do now
- Activate Windows WireGuard tunnel from any internet connection
ssh user@10.10.10.1into Fedora- SSH is invisible to the internet and LAN
- Port 51820/udp is the only thing exposed externally
Data Usage Reference (over tunnel)
| Activity | Data/hour |
|---|---|
| SSH (terminal) | 1-10 MB |
| X11 forwarding (single GUI app) | 20-100 MB |
| RDP, tuned for low bandwidth | 100-200 MB |
| RDP, defaults | 200-500 MB |
| RDP with video | 1-5 GB (avoid) |
Use SSH for most things, RDP only when GUI is necessary.