Any Windows server with Remote Desktop open to the internet is under constant attack: automated tools try common usernames and leaked passwords around the clock. A weak password will eventually fall, and successful RDP compromises are a leading entry point for ransomware. Here’s how to see the attacks and shut them down, from quick wins to the most robust setup.
See what’s happening
Failed logons are logged as Event ID 4625 in the Security log. Count them with PowerShell:
Get-WinEvent -FilterHashtable @{LogName='Security'; Id=4625; StartTime=(Get-Date).AddHours(-24)} |
ForEach-Object { $_.Properties[19].Value } |
Group-Object | Sort-Object Count -Descending | Select-Object -First 15 Count, Name
This lists the source IPs with the most failures in the last 24 hours. Thousands of attempts per day on a server with RDP on port 3389 is normal — which is exactly the problem. (If the list is empty, check that logon failure auditing is enabled — see Windows audit logon events.)
Successful logons are Event ID 4624 (logon type 10 = RemoteInteractive). Review them for logins you don’t recognise.
Layer 1: strong credentials (non-negotiable)
- Long, unique passwords for every account that can use RDP — 16+ characters or a passphrase. Brute-force tools work from lists of leaked and common passwords; a random long password isn’t on them.
- No
Administratoraccount — rename or disable it and use a personal admin account. The built-in Administrator isn’t subject to lockout by default. - Only necessary users in the Remote Desktop Users group.
Layer 2: account lockout
Lock accounts after repeated failures (Local Security Policy → Account Lockout Policy, or):
net accounts /lockoutthreshold:5 /lockoutduration:30 /lockoutwindow:30
Five wrong guesses lock the account for 30 minutes, making brute force impractically slow. Downside: attackers can deliberately lock out a known username. That’s another reason not to use guessable usernames.
Layer 3: Network Level Authentication
NLA requires authentication before a full RDP session is created, reducing resource use and exposure to pre-authentication vulnerabilities. It’s on by default on current Windows Server; confirm:
(Get-CimInstance -Namespace root/CIMV2/TerminalServices -ClassName Win32_TSGeneralSetting -Filter "TerminalName='RDP-Tcp'").UserAuthenticationRequired
1 means enabled. See RDP Network Level Authentication.
Layer 4: change the port
Moving RDP off 3389 cuts automated attempts dramatically. It’s obscurity, not security, but it makes logs readable and reduces lockout noise. See changing the RDP port.
Layer 5: restrict who can connect
The single most effective measure: only allow RDP from your IP addresses. Edit the firewall rule’s remote address scope:
Set-NetFirewallRule -DisplayGroup "Remote Desktop" -RemoteAddress 198.51.100.25, 203.0.113.0/24
(For a custom port rule, use Set-NetFirewallRule -DisplayName "RDP TCP 53389" -RemoteAddress ….)
If your home IP changes, you’ll need the VPS VNC console to update the rule — or use one of the options below.
Layer 6: automatic IP blocking
Like Fail2Ban on Linux, tools for Windows watch Event ID 4625 and add firewall rules to block offending IPs:
- IPBan (open source) — runs as a service, configurable thresholds, also covers SQL Server and other services.
- RdpGuard (commercial) — similar, with a GUI.
- EvlWatcher (open source) — lightweight.
A simple PowerShell approach is also possible: a scheduled task that reads recent 4625 events and adds IPs with more than N failures to a blocking firewall rule. Dedicated tools handle expiry and whitelisting more reliably, though.
Layer 7: don’t expose RDP at all
The strongest setups keep port 3389 closed to the internet entirely:
- VPN first: run WireGuard (on the Windows server itself, or on a small Linux VPS), connect to the VPN, then RDP to the private address. The RDP firewall rule allows only the VPN subnet.
- SSH tunnel: enable the built-in OpenSSH Server on Windows, then
ssh -L 3389:localhost:3389 user@serverand connect RDP tolocalhost. See OpenSSH on Windows Server. - Remote Desktop Gateway: RDP wrapped in HTTPS on port 443, with its own authorization policies — suited to organisations. See RD Gateway.
- Mesh VPN: Tailscale or similar puts the server on a private network reachable only by your devices.
Layer 8: keep Windows patched
Some of the worst RDP attacks (BlueKeep, for example) exploited vulnerabilities, not passwords. Keep Windows Update current — see Windows Update with PowerShell.
Checklist
- Strong unique passwords; built-in Administrator disabled/renamed
- Account lockout policy set
- NLA enabled
- RDP restricted to known IPs, VPN, or SSH tunnel
- Automatic blocking for repeated failures
- Non-default port (optional)
- Windows fully patched
- Event ID 4624 logons reviewed regularly
If you suspect a compromise
Look for unknown accounts (Get-LocalUser), unfamiliar scheduled tasks, new services, disabled Defender, and successful logons from unknown IPs. If an attacker had admin access, the safe path is to reinstall the server and restore data from a clean backup. Change all passwords that were used on it.
Our Windows VPS plans include a VNC console in the control panel, so you can always get back in after tightening firewall rules — even if you lock RDP down completely.