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.
$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:$falseFor 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:
# 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, NextHopThe 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.
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/0with0.0.0.0/1, 128.0.0.0/1. That covers exactly the same addresses, but does not trigger the kill switch.
[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 = 25Leave ::/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.
& "C:\Program Files\WireGuard\wireguard.exe" /installtunnelservice "C:\WireGuard\wg0.conf"Verify both directions
Invoke-RestMethod https://api.ipify.org # should now print the VPN's IPThen 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:
route 198.51.100.7 255.255.255.255 net_gatewaynet_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
AllowedIPsto the address ranges of the services that need the VPN. The default route stays untouched. In OpenVPN,route-nopullplus your ownroutelines 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.
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[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/32sudo ufw allow 51820/udp # if ufw is active
sudo systemctl enable --now wg-quick@wg0The 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 thePersistent Routessection ofroute print -4. - Sites still see the server’s own IP.
AllowedIPsdoes 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 = 1380to[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.