VMHeaven

Guides

Use a VPN on a Windows RDP server without locking yourself out

A full-tunnel VPN on a Windows VPS reroutes your RDP replies and cuts you off. Keep RDP reachable with a bypass route, split tunnelling and a failsafe.

Updated 19 Sept 2026~8 min read

People put a VPN on a Windows VPS to give scrapers, browsers or automation a different outgoing IP, to reach region-locked services, or to keep the server’s own address out of their requests. Almost everyone meets the same problem the first time: the moment the VPN connects, the RDP window freezes and the server cannot be reached again.

The VPN is not broken. Your RDP session reaches the server on its public IP. A full-tunnel VPN then sends all outgoing traffic into the tunnel, including the replies to you. Those replies now leave from the VPN’s IP, your computer does not recognise them, and the session dies. Many VPN configs add a kill switch on top that blocks everything outside the tunnel. The fix is to keep your own traffic out of the tunnel, or to tunnel only what needs it.

Before you connect anything: a way back in

  • Open the provider’s VNC console. It shows the server’s screen through the hypervisor, not the network, so it keeps working however badly the routing goes. Every VMHeaven VPS has one in the panel.
  • Set a dead-man switch. A scheduled task that takes the tunnel down after ten minutes. If you lose RDP, wait, and you are back. If everything works, delete the task.
PowerShell (Administrator) · WireGuard failsafe
$action  = New-ScheduledTaskAction -Execute "C:\Program Files\WireGuard\wireguard.exe" -Argument "/uninstalltunnelservice wg0"
$trigger = New-ScheduledTaskTrigger -Once -At (Get-Date).AddMinutes(10)
Register-ScheduledTask -TaskName "vpn-failsafe" -Action $action -Trigger $trigger -User "NT AUTHORITY\SYSTEM" -RunLevel Highest

# once you are sure RDP survives the tunnel
Unregister-ScheduledTask -TaskName "vpn-failsafe" -Confirm:$false

For OpenVPN, use taskkill.exe with the argument /im openvpn.exe /f as the action instead.

Collect two addresses

You need the public IP you connect from, and the gateway the server uses without the VPN. Run this on the server while connected over RDP:

PowerShell
# your client IP, as the server sees it
Get-NetTCPConnection -LocalPort 3389 -State Established | Select-Object RemoteAddress

# the server's normal default gateway and interface
Get-NetRoute -DestinationPrefix 0.0.0.0/0 | Select-Object InterfaceAlias, NextHop

The examples below use 198.51.100.7 for your client IP and 192.0.2.1 for the gateway. If you moved RDP off 3389, use your port in the first command.

The fix: a bypass route for your own IP

Windows always uses the most specific route that matches. A single-address route (/32) to your client IP through the normal gateway beats any route the VPN installs. Your RDP replies then leave the normal way, and everything else goes through the tunnel.

cmd or PowerShell (Administrator)
route -p add 198.51.100.7 mask 255.255.255.255 192.0.2.1
route print -4     # check it under "Persistent Routes"

-p keeps it across reboots. Add it before the VPN connects. If your home IP changes from time to time, route your provider’s whole range instead (a /24 or larger), or use the own-server setup below.

WireGuard (recommended)

Install WireGuard for Windows from wireguard.com, then import the .conf file from your VPN provider or your own server. Most commercial VPNs let you download one from the account page. Use it instead of the provider’s app: those apps enable kill switches and firewall rules that you cannot easily control on a server.

Turn off the kill switch

When a tunnel has one peer with AllowedIPs = 0.0.0.0/0, WireGuard for Windows enables Block untunneled traffic (kill-switch). Its firewall rules drop everything outside the tunnel, including your bypass route and RDP. On a server you have two ways out:

  • Untick that box in the tunnel editor, or
  • replace 0.0.0.0/0 with 0.0.0.0/1, 128.0.0.0/1. That covers exactly the same addresses, but does not trigger the kill switch.
wg0.conf
[Interface]
PrivateKey = <your private key>
Address = 10.64.0.2/32
DNS = 10.64.0.1

[Peer]
PublicKey = <server public key>
Endpoint = vpn.example.net:51820
AllowedIPs = 0.0.0.0/1, 128.0.0.0/1
PersistentKeepalive = 25

Leave ::/0 out unless you need IPv6 through the tunnel, and connect RDP over IPv4. Otherwise you need a matching IPv6 bypass route as well. Also delete any PostUp/PostDown lines that add Windows Firewall block rules. Some providers include them as a kill switch of their own.

Start it at boot

Save the config somewhere only administrators can read, then install it as a service. The tunnel name comes from the file name, here wg0, which the failsafe task above uses.

PowerShell (Administrator)
& "C:\Program Files\WireGuard\wireguard.exe" /installtunnelservice "C:\WireGuard\wg0.conf"

Verify both directions

PowerShell
Invoke-RestMethod https://api.ipify.org     # should now print the VPN's IP

Then open a second RDP connection from your computer. If it connects while the tunnel is up, the setup is right, and you can remove the failsafe task.

OpenVPN

Provider .ovpn files usually contain, or receive from the server, redirect-gateway def1, which is the full-tunnel setting. Add the bypass straight into the config, so OpenVPN sets it up every time it connects:

append to the .ovpn file
route 198.51.100.7 255.255.255.255 net_gateway

net_gateway is OpenVPN’s name for the gateway that existed before the tunnel, so you do not even need to look it up. To connect at boot without anyone logged in, copy the file to C:\Program Files\OpenVPN\config-auto\, then run Set-Service OpenVPNService -StartupType Automatic and Start-Service OpenVPNService.

Only tunnel what needs it

A full tunnel has one more side effect that people notice later. Every service on the server’s public IP stops working for everyone who is not on your bypass list. That includes a web server, a game server or an API, because their replies leave through the tunnel too. If the VPS serves anything to the public, do not full-tunnel it:

  • Route only specific destinations. Set AllowedIPs to the address ranges of the services that need the VPN. The default route stays untouched. In OpenVPN, route-nopull plus your own route lines does the same.
  • Use a proxy per application. If only a browser or a scraper needs the other IP, a SOCKS5 or HTTP proxy set in that program changes nothing else on the machine.

With your own WireGuard server: RDP through the tunnel

If the VPN endpoint is a Linux server you control, there is a cleaner setup. Make your own computer a second peer and connect to RDP on the Windows server’s tunnel address. RDP then no longer depends on the public route at all, and you can even close the public RDP port.

Linux VPN server
sudo apt install -y wireguard iptables
umask 077
wg genkey | sudo tee /etc/wireguard/server.key | wg pubkey | sudo tee /etc/wireguard/server.pub
echo 'net.ipv4.ip_forward=1' | sudo tee /etc/sysctl.d/99-wireguard.conf
sudo sysctl --system
ip route show default      # note the interface name, e.g. eth0
/etc/wireguard/wg0.conf (Linux server)
[Interface]
Address = 10.8.0.1/24
ListenPort = 51820
PrivateKey = <contents of server.key>
PostUp   = iptables -A FORWARD -i wg0 -j ACCEPT; iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
PostDown = iptables -D FORWARD -i wg0 -j ACCEPT; iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE

# the Windows server
[Peer]
PublicKey = <Windows tunnel public key>
AllowedIPs = 10.8.0.2/32

# your own computer
[Peer]
PublicKey = <laptop public key>
AllowedIPs = 10.8.0.3/32
start it
sudo ufw allow 51820/udp        # if ufw is active
sudo systemctl enable --now wg-quick@wg0

The Windows server uses the config from the WireGuard section with Address = 10.8.0.2/32. Your computer gets Address = 10.8.0.3/32 and AllowedIPs = 10.8.0.0/24, so only the tunnel network goes through the tunnel. The WireGuard app generates each key pair and shows the public key in the tunnel editor. Connect RDP to 10.8.0.2, and make sure the Windows Firewall RDP rule applies to the tunnel adapter’s network profile (usually Public). Keep the bypass route in place until this path works.

Troubleshooting

  • RDP freezes the moment the tunnel comes up. The kill switch is on, or the bypass route is missing. Deactivate the tunnel from the VNC console and check both.
  • It worked until a reboot. The route was added without -p, or your home IP changed. Compare it with the Persistent Routes section of route print -4.
  • Sites still see the server’s own IP. AllowedIPs does not cover the default route, or the application uses IPv6 outside the tunnel.
  • DNS goes to the old resolver. Set DNS = in the [Interface] section.
  • Pages stall or large downloads hang. Lower the MTU: add MTU = 1380 to [Interface].

Running VPN clients on a VPS is normal, permitted use at VMHeaven. Our KVM plans deploy from a Windows Server template, and the VNC console is there for exactly this kind of experiment. If you are hardening RDP itself next, see how to change the RDP port and restrict it.

Frequently asked

Why does RDP disconnect when I turn on the VPN?

The VPN becomes the default route, so replies to your RDP client leave through the tunnel from a different IP and your client drops them. A kill switch can also block all traffic outside the tunnel.

How do I keep RDP working with a full-tunnel VPN?

Add a persistent host route for your own IP via the server's normal gateway ('route -p add <your-ip> mask 255.255.255.255 <gateway>') and disable WireGuard's kill switch, e.g. by using AllowedIPs 0.0.0.0/1, 128.0.0.0/1.

Will a VPN break other services on the server?

With a full tunnel, yes — replies from any public service leave through the tunnel. If the server serves the public, route only specific destinations through the VPN or use a per-application proxy.

More in Guides

See all