Skip to content
WindowsHow-To Published Updated 5 min readViews unavailable

How to Configure Remote Desktop Securely on Windows

Enabling Remote Desktop the right way — Network Level Authentication, a non-default port, and firewall scoping — rather than exposing RDP openly.

Remote Desktop Protocol (RDP) is powerful and convenient, but exposing it carelessly is one of the most common ways Windows machines get compromised. This walks through enabling it with the security settings that actually matter.

Step 1: enable Remote Desktop

System Settings → System → Remote Desktop → toggle On

Or via PowerShell (as Administrator):

Set-ItemProperty -Path 'HKLM:\System\CurrentControlSet\Control\Terminal Server' -Name "fDenyTSConnections" -Value 0

Step 2: confirm Network Level Authentication is enabled

System Settings → Remote Desktop → Advanced settings →
  "Require devices to use Network Level Authentication"

Network Level Authentication (NLA) requires a user to authenticate before a full remote desktop session is even established — meaningfully reducing exposure to a wide class of pre-authentication attacks compared to allowing the full RDP session negotiation to begin before checking credentials.

Step 3: restrict which users can connect

System Properties → Remote tab → Select Users →
  add only specific accounts that need RDP access

By default, members of the local Administrators group can connect — explicitly limiting this to only the specific accounts that genuinely need remote access reduces the practical attack surface if any other account’s credentials are ever compromised.

Step 4: never expose RDP’s default port directly to the internet

RDP’s well-known default port (3389) is constantly scanned by automated attack tools across the entire internet — if remote access from outside your local network is genuinely needed, it should go through a VPN first, with RDP only reachable from inside that VPN’s network, not through a port forwarded directly from your router to the internet.

Step 5: if a non-VPN approach is truly required, at minimum change the default port

Registry: HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\
          Terminal Server\WinStations\RDP-Tcp\PortNumber

This is a weak, “security through obscurity” measure on its own — automated scanners routinely check other common ports too — but it does filter out a meaningful fraction of the least sophisticated automated scanning traffic, and should never be considered a substitute for a VPN-based approach.

Step 6: enable account lockout policy to blunt brute-force attempts

secpol.msc → Account Policies → Account Lockout Policy →
  set "Account lockout threshold" to a reasonably low number

Locking an account out after a small number of failed attempts makes brute-force password guessing against RDP significantly less viable, regardless of what other protections are in place.

Step 7: enable and review RDP connection logging

Event Viewer → Windows Logs → Security →
  filter for Event ID 4624 (successful logon) and 4625
  (failed logon)

Reviewing successful and failed RDP logon attempts periodically can reveal an ongoing attack (a burst of failed attempts from an unfamiliar location) well before it succeeds.

Step 8: use Windows Firewall to scope access by source IP, if connections come from known locations

New-NetFirewallRule -DisplayName "RDP - Office Only" -Direction Inbound -Protocol TCP -LocalPort 3389 -RemoteAddress 203.0.113.0/24 -Action Allow

If remote connections only ever originate from a known, fixed set of IP ranges (an office network, a specific ISP), scoping the firewall rule to only allow those sources meaningfully narrows the exposure even before considering a VPN.

Why NLA and network exposure matter more than any other single setting

Of everything covered here, requiring NLA and never exposing RDP directly to the open internet are the two changes with the largest actual security impact — NLA closes off pre-authentication attack surface, and routing access through a VPN eliminates the “constantly scanned by the entire internet” exposure that makes RDP such a common attack target in the first place. Every other step here is a meaningful but secondary layer on top of those two.

Requiring multi-factor authentication on top of NLA

NLA confirms a valid username and password before establishing the session, but a password alone remains vulnerable to credential theft through phishing or reuse from an unrelated breach — layering multi-factor authentication in front of RDP access (via Azure AD/Entra ID Conditional Access for domain-joined machines, or a third-party MFA gateway sitting in front of the RDP endpoint) closes this specific remaining gap. For any RDP access genuinely exposed beyond a fully trusted internal network — even when routed through a VPN, since a compromised VPN credential alone shouldn’t be sufficient to reach a sensitive server — requiring a second factor specifically for the RDP session itself, not just the VPN connection in front of it, is worth the additional setup for anything genuinely sensitive.

Restricting RDP to a specific set of client applications, not just source IPs

Beyond scoping by source IP address (Step 8), Windows Firewall and Group Policy both support restricting which local applications are permitted to actually establish outbound or inbound RDP connections at all, useful in a locked-down enterprise environment specifically trying to prevent RDP being used as a lateral-movement technique by an attacker already present elsewhere on the network. This is a more advanced, environment-specific hardening measure beyond what a typical individual or small-business RDP setup needs, but worth knowing exists for an organization with a genuine concern about RDP-based lateral movement as part of its specific threat model.

Auditing active RDP sessions directly

query session
qwinsta

For confirming exactly who currently has an active or disconnected RDP session on a machine — useful both for routine administration and for confirming no unexpected session exists after investigating a potential compromise — query session (or the older qwinsta alias) lists every current session, its state, and the associated username directly from the command line, without needing to check Event Viewer’s logon history or rely solely on the graphical Task Manager session view.

Related:

Sources:

Comments