Even on a non-default port, a Remote Desktop login screen open to the whole internet still gets scanned. Putting RDP behind a WireGuard VPN means only devices holding a valid VPN key can reach it at all. This guide sets up WireGuard on the Windows server, connects one client, and then narrows the RDP firewall rule to the VPN, with a safe way back if something goes wrong.
Before you start
- A Windows VPS or Admin RDP server, with its IP address and login from your VPS provider's control panel.
- Administrator rights on the server.
- Your own Windows, Mac or Linux computer to use as the VPN client.
- The browser console in your VPS provider's control panel. Open it once now to confirm it works. It is your way back in if the firewall change locks you out.
The example values below are:
- Server public IP:
203.0.113.10 - VPN subnet:
10.8.0.0/24, server10.8.0.1, your computer10.8.0.2 - WireGuard port: UDP
51820
Install WireGuard on the server
- Connect to the server over RDP as usual at
203.0.113.10:3389. - In a browser on the server, open the official site
wireguard.com/installand download the Windows installer. - Run it. This installs the WireGuard app and the
wg.exetool inC:\Program Files\WireGuard.
Create keys
Each side needs its own key pair. On the server, in PowerShell as Administrator:
cd 'C:\Program Files\WireGuard'
$serverPriv = .\wg.exe genkey
$serverPub = $serverPriv | .\wg.exe pubkey
"Server private: $serverPriv"
"Server public: $serverPub"Do the same for the client. You can run these commands on the server and move the client's private key to your computer securely, or generate it in the client's WireGuard app with Add empty tunnel, which creates a key pair for you.
Warning: A private key is a password. Never paste it into chat, email or a ticket. Only public keys are shared between the two sides.
Write the server tunnel
Create C:\ProgramData\WireGuard\wg0.conf with Notepad running as Administrator:
[Interface]
PrivateKey = SERVER_PRIVATE_KEY
Address = 10.8.0.1/24
ListenPort = 51820
[Peer]
PublicKey = CLIENT_PUBLIC_KEY
AllowedIPs = 10.8.0.2/32Install it as a service so it starts at boot, before anyone logs in:
& 'C:\Program Files\WireGuard\wireguard.exe' /installtunnelservice 'C:\ProgramData\WireGuard\wg0.conf'Allow WireGuard's port through Windows Firewall:
New-NetFirewallRule -DisplayName "WireGuard (UDP 51820)" `
-Direction Inbound -Protocol UDP -LocalPort 51820 -Action AllowConnect a client
In the WireGuard app on your computer, create a tunnel with this content:
[Interface]
PrivateKey = CLIENT_PRIVATE_KEY
Address = 10.8.0.2/32
[Peer]
PublicKey = SERVER_PUBLIC_KEY
Endpoint = 203.0.113.10:51820
AllowedIPs = 10.8.0.1/32
PersistentKeepalive = 25AllowedIPs = 10.8.0.1/32 sends only traffic for the server's VPN address through the tunnel. Your normal browsing stays on your own internet. Activate the tunnel.
Now connect Remote Desktop through the VPN address:
10.8.0.1:3389Do not continue until this works. If it fails, read Troubleshoot WireGuard connections.
Limit the RDP rule to the VPN subnet
Warning: This step can lock you out. Stay connected over the VPN address 10.8.0.1:3389 while you make it, and keep your VPS provider's browser console open in another tab.
Find the rule that allows TCP 3389 and restrict its source addresses to the VPN:
Get-NetFirewallPortFilter -Protocol TCP |
Where-Object LocalPort -eq 3389 |
Get-NetFirewallRule |
Set-NetFirewallRule -RemoteAddress 10.8.0.0/24If you also allow UDP 3389, restrict that rule the same way with -Protocol UDP. Check the result:
Get-NetFirewallPortFilter -Protocol TCP |
Where-Object LocalPort -eq 3389 |
Get-NetFirewallRule |
Get-NetFirewallAddressFilterRemoteAddress should show 10.8.0.0/255.255.255.0. More on scoping rules is in Check the Windows Firewall rule for RDP port 3389.
Check it works
- With the VPN on, connect to
10.8.0.1:3389. It should work. - Turn the VPN off and test the public address from your computer:
Test-NetConnection 203.0.113.10 -Port 3389TcpTestSucceeded: False means RDP is now hidden from the internet.
- Restart the server from your VPS provider's control panel and confirm the tunnel comes back on its own, then connect again over the VPN.
Undo the change from the console
If you lose access, open the browser console from your VPS provider's control panel, sign in, and open PowerShell. Remove the restriction:
Get-NetFirewallPortFilter -Protocol TCP |
Where-Object LocalPort -eq 3389 |
Get-NetFirewallRule |
Set-NetFirewallRule -RemoteAddress AnyYou can then connect on 203.0.113.10:3389 again and fix the VPN calmly.
Troubleshooting
- Tunnel shows a handshake never completed: UDP 51820 is blocked or the keys are swapped. Check the firewall rule and that each side holds the other side's public key.
- Handshake works but RDP to 10.8.0.1 fails: the RDP rule's profile may not cover the WireGuard network. Check the rule's Profile is
Any. - Tunnel is gone after reboot: it was started from the app, not installed as a service. Run the
/installtunnelservicecommand. - Works at home, not on another network: some networks block outbound UDP. Use a different network, or keep an IP allow rule as described in Allow RDP port 3389 only from your IP.
Next steps
- Add more devices: Add WireGuard clients.
- Further hardening: Secure Remote Desktop on Windows Server.
