Security

Put Remote Desktop behind a WireGuard VPN

Install WireGuard on your Windows server, connect your own computer as a client, then limit the RDP port 3389 rule to the VPN subnet so only VPN users can reach the login screen.

AdvancedWindows server5 min read

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, server 10.8.0.1, your computer 10.8.0.2
  • WireGuard port: UDP 51820

Install WireGuard on the server

  1. Connect to the server over RDP as usual at 203.0.113.10:3389.
  2. In a browser on the server, open the official site wireguard.com/install and download the Windows installer.
  3. Run it. This installs the WireGuard app and the wg.exe tool in C:\Program Files\WireGuard.

Create keys

Each side needs its own key pair. On the server, in PowerShell as Administrator:

PowerShell
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:

INI
[Interface]
PrivateKey = SERVER_PRIVATE_KEY
Address = 10.8.0.1/24
ListenPort = 51820

[Peer]
PublicKey = CLIENT_PUBLIC_KEY
AllowedIPs = 10.8.0.2/32

Install it as a service so it starts at boot, before anyone logs in:

PowerShell
& 'C:\Program Files\WireGuard\wireguard.exe' /installtunnelservice 'C:\ProgramData\WireGuard\wg0.conf'

Allow WireGuard's port through Windows Firewall:

PowerShell
New-NetFirewallRule -DisplayName "WireGuard (UDP 51820)" `
  -Direction Inbound -Protocol UDP -LocalPort 51820 -Action Allow

Connect a client

In the WireGuard app on your computer, create a tunnel with this content:

INI
[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 = 25

AllowedIPs = 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:3389

Do 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:

PowerShell
Get-NetFirewallPortFilter -Protocol TCP |
  Where-Object LocalPort -eq 3389 |
  Get-NetFirewallRule |
  Set-NetFirewallRule -RemoteAddress 10.8.0.0/24

If you also allow UDP 3389, restrict that rule the same way with -Protocol UDP. Check the result:

PowerShell
Get-NetFirewallPortFilter -Protocol TCP |
  Where-Object LocalPort -eq 3389 |
  Get-NetFirewallRule |
  Get-NetFirewallAddressFilter

RemoteAddress 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

  1. With the VPN on, connect to 10.8.0.1:3389. It should work.
  2. Turn the VPN off and test the public address from your computer:
PowerShell
   Test-NetConnection 203.0.113.10 -Port 3389

TcpTestSucceeded: False means RDP is now hidden from the internet.

  1. 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:

PowerShell
Get-NetFirewallPortFilter -Protocol TCP |
  Where-Object LocalPort -eq 3389 |
  Get-NetFirewallRule |
  Set-NetFirewallRule -RemoteAddress Any

You 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 /installtunnelservice command.
  • 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

Was this guide helpful?

Still stuck?

Ask MdmHost AI for a quick answer, or open a ticket and our team will take a look. We are here 24/7.