Remote Desktop Protocol (RDP) is the most targeted service on any public-facing Windows server. Botnets continuously scan the internet for port 3389, and ransomware operators routinely buy stolen RDP credentials or brute-force their way in. The good news is that Windows Server ships with the tools to stop almost all of these attacks. This article covers seven hardening steps — from account lockout to RD Gateway — that collectively block 99% of automated brute-force attempts. If you are still choosing a provider, our Windows VPS comparison table flags providers that include firewall and DDoS protection in the base plan.
How RDP Brute-Force Attacks Work
Understanding the attack pattern helps you choose the right defenses. A typical campaign follows this sequence:
- A scanner finds your server because port 3389 responds. The entire IPv4 range is swept continuously — no prior knowledge of your IP is needed.
- The attacker tries common usernames (
Administrator,admin,user) against dictionaries of leaked passwords and default credentials. - Sophisticated attackers throttle to a few attempts per minute per source IP to stay under lockout thresholds, spreading the load across hundreds of botnet nodes.
- A single successful login — even to a low-privilege account — is enough to start reconnaissance, install persistence, and move laterally.
The key insight: single-IP defenses are not enough because the traffic comes from thousands of addresses. You need layered controls that make the attempts fail regardless of the source.
Step 1: Configure Account Lockout Policy
The account lockout policy is your first line of defense. It limits how many failed logon attempts are allowed before the account is temporarily locked. Open secpol.msc and navigate to Account Policies → Account Lockout Policy, or set it via Group Policy:
| Setting | Recommended Value |
|---|---|
| Account lockout threshold | 5 invalid attempts |
| Account lockout duration | 15 minutes |
| Reset account lockout counter after | 15 minutes |
Set these via PowerShell on a standalone server:
net accounts /lockoutthreshold:5 /lockoutduration:15 /lockoutwindow:15
Watch for lockout denial-of-service: an attacker who knows your admin account name can lock it repeatedly. Keep a second break-glass account outside the policy and monitor Event ID 4740 (account locked out).
Step 2: Rename the Built-In Administrator Account
The default Administrator account has a well-known SID (S-1-5-21-…-500). Attackers target it first because it is always present and always has elevated privileges. Rename it and create a separate local admin account with a different name for daily use:
# Rename the built-in Administrator account
$admin = Get-LocalUser -Name "Administrator"
Rename-LocalUser -InputObject $admin -NewName "X-Admin-$(Get-Random -Maximum 99999)"
Then create a new account for your own daily administration and add it to the Administrators group. Use the renamed account only as a break-glass recovery option.
Step 3: Enable Network Level Authentication (NLA)
NLA forces the client to authenticate before a full RDP session is created. With NLA off, an attacker completes the RDP handshake and reaches the Windows logon screen, which historically enabled “BlueKeep”-class vulnerabilities and lets attackers hammer the credential prompt with less noise. With NLA on, the connection is rejected unless the client presents valid credentials up front:
# Verify NLA is enabled
Get-ItemProperty "HKLM:\SYSTEM\CurrentControlSet\Control\Terminal Server\WinStations\RDP-Tcp" |
Select-Object UserAuthentication, SecurityLayer
# UserAuthentication should be 1, SecurityLayer should be 2
NLA is enabled by default on Windows Server 2022/2025, but templates and imaging pipelines occasionally disable it. Confirm it during every server build.
Step 4: Restrict RDP Access by Firewall and IP
The single most effective control is restricting which IP addresses can reach port 3389. If your team connects from a static office IP or a VPN endpoint, whitelist only those addresses:
# Remove the default "allow all" rule
Remove-NetFirewallRule -DisplayName "Remote Desktop*"
# Create a scoped rule
New-NetFirewallRule -DisplayName "RDP - Office IP" `
-Direction Inbound -Protocol TCP -LocalPort 3389 `
-RemoteAddress "203.0.113.0/24" -Action Allow
If you cannot whitelist specific IPs, at minimum restrict the RDP firewall rule to your VPN subnet. Many VPS providers also offer security groups — use them as a first line of defense before the Windows firewall even sees the traffic.
Step 5: Change the Default RDP Port
Changing port 3389 to a non-standard port is cosmetic against a targeted attack, but it eliminates the vast majority of automated scanner noise. On a server exposed to the internet, this alone can reduce failed logins from 20,000/day to under 100/day:
# Change RDP port from 3389 to 3390 (or any other port)
Set-ItemProperty "HKLM:\SYSTEM\CurrentControlSet\Control\Terminal Server\WinStations\RDP-Tcp" -Name PortNumber -Value 3390
# Update the firewall rule
New-NetFirewallRule -DisplayName "RDP - Custom Port 3390" `
-Direction Inbound -Protocol TCP -LocalPort 3390 -Action Allow
Do not forget to update your RDP client connection settings to use the new port: your-server:3390.
Step 6: Use a Remote Desktop Gateway or VPN
For the strongest protection, do not expose RDP at all. Instead, route RDP through a Remote Desktop Gateway (RD Gateway) or a VPN. An RD Gateway terminates TLS on port 443, hides the session host, and lets you enforce MFA at the gateway. For single servers, a WireGuard or SSTP VPN with RDP bound to the VPN interface only is the strongest configuration you can build with built-in tools. The practical effect: the public interface never sees an RDP connection attempt, which makes the lockout policy and port change almost redundant in practice.
Step 7: Monitor and Audit RDP Logins
Even with all the above controls in place, monitoring tells you if something slipped through. Key Event IDs to track:
| Event ID | Description |
|---|---|
| 4625 | Failed logon attempt |
| 4624 (Logon Type 10) | Successful RDP logon |
| 4740 | Account locked out |
| 4648 | Logon using explicit credentials |
Quick check for recent failed logins:
Get-WinEvent -FilterHashtable @{LogName='Security'; Id=4625} -MaxEvents 50 |
Select TimeCreated, @{n='User';e={$_.Properties[5].Value}}, @{n='SourceIP';e={$_.Properties[18].Value}}
Set up a scheduled task that alerts when the failed-login rate exceeds a threshold — for example, 50 failed attempts in 10 minutes. Forward these events to a SIEM or a simple log aggregator for long-term trend analysis.
Putting It Together
These seven steps form a layered defense that works together. Account lockout stops brute-force guessing. Renaming the admin account removes the most common target. NLA eliminates pre-auth attack surface. IP restriction and port change reduce noise. VPN or Gateway hides RDP entirely. Monitoring catches anything that gets through. Apply all seven before the server ever gets a public IP, and you can skip most of the “RDP honeypot” anxiety. When you are choosing a provider, compare Windows VPS plans and check which ones include security-group support and DDoS protection — worth having when 3389 has to face the internet.



