Windows Server RDP Connection Failed Due to Firewall

Overview

If a Windows Server can be accessed through Virtualizor → noVNC, but a direct Remote Desktop (RDP) connection fails, the issue may be caused by the Windows Firewall blocking inbound RDP traffic.

This guide explains how to:

  • Enable Remote Desktop
  • Start the Remote Desktop Services service
  • Open TCP/UDP port 3389
  • Verify that RDP is listening
  • Test port accessibility
  • Apply the fix using PowerShell
  • Manually configure the firewall
  • Configure the Virtualizor/Linux host firewall when required

1. Prerequisites

You must have:

  • Access to the Windows Server through Virtualizor noVNC/console
  • Administrator access to Windows
  • The server's public IP address

For Linux/Virtualizor node configuration, you need:

  • SSH/root access to the Virtualizor node

2. Check Whether RDP Is Enabled

Open PowerShell as Administrator and run:

Get-ItemProperty "HKLM:\SYSTEM\CurrentControlSet\Control\Terminal Server" -Name fDenyTSConnections

Expected result

fDenyTSConnections : 0

0 means RDP is enabled.

If it returns:

fDenyTSConnections : 1

enable RDP:

Set-ItemProperty `
    "HKLM:\SYSTEM\CurrentControlSet\Control\Terminal Server" `
    -Name fDenyTSConnections `
    -Value 0

3. Ensure Remote Desktop Services Is Running

Run:

Get-Service TermService

Expected:

Status   Name
------   ----
Running  TermService

If it is not running:

Set-Service TermService -StartupType Automatic
Start-Service TermService

4. Open Windows Firewall Port 3389

Recommended method

Create an explicit firewall rule for TCP 3389:

New-NetFirewallRule `
    -DisplayName "Allow RDP TCP 3389" `
    -Direction Inbound `
    -Protocol TCP `
    -LocalPort 3389 `
    -Action Allow `
    -Profile Any

For UDP:

New-NetFirewallRule `
    -DisplayName "Allow RDP UDP 3389" `
    -Direction Inbound `
    -Protocol UDP `
    -LocalPort 3389 `
    -Action Allow `
    -Profile Any

Note: TCP is the critical protocol for establishing a normal RDP connection. UDP can improve RDP performance and is therefore recommended.


5. Verify Port 3389 Is Listening

Run:

netstat -ano | findstr :3389

You should see something similar to:

TCP    0.0.0.0:3389      0.0.0.0:0      LISTENING
TCP    [::]:3389         [::]:0         LISTENING

If LISTENING appears, Windows is accepting connections on port 3389.


6. Test RDP Locally

From the Windows Server itself:

Test-NetConnection 127.0.0.1 -Port 3389

Expected:

TcpTestSucceeded : True

If this returns True, the RDP service and local TCP listener are working correctly.


7. Test RDP From an External Machine

From another computer, test the public IP.

Windows

Test-NetConnection SERVER_IP -Port 3389

Example:

Test-NetConnection 95.216.50.253 -Port 3389

Linux/macOS

nc -vz -w 5 SERVER_IP 3389

Example:

nc -vz -w 5 95.216.50.253 3389

Successful result

Connection to 95.216.50.253 3389 port [tcp/ms-wbt-server] succeeded!

Timeout / failed connection

If the connection times out, check:

  1. Windows Firewall
  2. Virtualizor node firewall
  3. NAT/port forwarding
  4. Provider firewall/security group
  5. Network/bridge configuration

8. Automated PowerShell Fix

For administrators who need a quick fix, use the following PowerShell script.

Save as:

enable-rdp.ps1
# ==========================================
# Windows Server RDP Firewall Fix
# ==========================================

$Port = 3389

Write-Host "Enabling Remote Desktop..." -ForegroundColor Cyan

# Enable RDP
Set-ItemProperty `
    -Path "HKLM:\SYSTEM\CurrentControlSet\Control\Terminal Server" `
    -Name "fDenyTSConnections" `
    -Type DWord `
    -Value 0

# Ensure RDP service is enabled and running
Write-Host "Starting Remote Desktop Services..." -ForegroundColor Cyan

Set-Service `
    -Name "TermService" `
    -StartupType Automatic

Start-Service `
    -Name "TermService" `
    -ErrorAction SilentlyContinue

# Allow TCP 3389
if (-not (Get-NetFirewallRule -DisplayName "Allow RDP TCP 3389" -ErrorAction SilentlyContinue)) {

    New-NetFirewallRule `
        -DisplayName "Allow RDP TCP 3389" `
        -Direction Inbound `
        -Protocol TCP `
        -LocalPort $Port `
        -Action Allow `
        -Profile Any

} else {

    Write-Host "TCP 3389 firewall rule already exists." -ForegroundColor Yellow
}

# Allow UDP 3389
if (-not (Get-NetFirewallRule -DisplayName "Allow RDP UDP 3389" -ErrorAction SilentlyContinue)) {

    New-NetFirewallRule `
        -DisplayName "Allow RDP UDP 3389" `
        -Direction Inbound `
        -Protocol UDP `
        -LocalPort $Port `
        -Action Allow `
        -Profile Any

} else {

    Write-Host "UDP 3389 firewall rule already exists." -ForegroundColor Yellow
}

Write-Host ""
Write-Host "==========================================" -ForegroundColor Green
Write-Host " RDP configuration completed successfully"
Write-Host "==========================================" -ForegroundColor Green

Write-Host ""
Write-Host "RDP Service:"
Get-Service TermService |
    Select-Object Status, Name, StartType

Write-Host ""
Write-Host "RDP Registry:"
Get-ItemProperty `
    "HKLM:\SYSTEM\CurrentControlSet\Control\Terminal Server" `
    -Name fDenyTSConnections

Write-Host ""
Write-Host "Port 3389:"
netstat -ano | findstr ":3389"

Run it from an Administrator PowerShell:

Set-ExecutionPolicy Bypass -Scope Process -Force
.\enable-rdp.ps1

9. Manual CMD Method

If PowerShell firewall cmdlets are unavailable, use netsh.

Enable RDP

reg add "HKLM\SYSTEM\CurrentControlSet\Control\Terminal Server" /v fDenyTSConnections /t REG_DWORD /d 0 /f

Start RDP service

sc config TermService start= auto
net start TermService

Allow TCP 3389

netsh advfirewall firewall add rule name="Allow RDP TCP 3389" dir=in action=allow protocol=TCP localport=3389

Allow UDP 3389

netsh advfirewall firewall add rule name="Allow RDP UDP 3389" dir=in action=allow protocol=UDP localport=3389

Verify

netstat -ano | findstr :3389

10. Virtualizor/Linux Node Firewall

If the Windows VM has a public IP directly assigned to it, normally the Windows firewall is the important layer.

If the VM uses NAT/private networking, the Virtualizor node may also need to allow/forward RDP traffic.

firewalld

firewall-cmd --permanent --add-port=3389/tcp
firewall-cmd --permanent --add-port=3389/udp
firewall-cmd --reload

Verify:

firewall-cmd --list-ports

UFW

ufw allow 3389/tcp
ufw allow 3389/udp
ufw reload

Verify:

ufw status

iptables

iptables -I INPUT -p tcp --dport 3389 -j ACCEPT
iptables -I INPUT -p udp --dport 3389 -j ACCEPT

Verify:

iptables -L INPUT -n -v | grep 3389

11. Bash Automation Script

For Linux/Virtualizor nodes:

#!/usr/bin/env bash

set -e

PORT=3389

if [ "$(id -u)" -ne 0 ]; then
    echo "ERROR: Run this script as root."
    exit 1
fi

echo "=========================================="
echo " RDP Firewall Configuration"
echo " TCP/UDP Port: $PORT"
echo "=========================================="

# firewalld
if command -v firewall-cmd >/dev/null 2>&1 &&
   systemctl is-active --quiet firewalld; then

    echo "[+] Configuring firewalld..."

    firewall-cmd --permanent --add-port="${PORT}/tcp"
    firewall-cmd --permanent --add-port="${PORT}/udp"
    firewall-cmd --reload

# UFW
elif command -v ufw >/dev/null 2>&1; then

    echo "[+] Configuring UFW..."

    ufw allow "${PORT}/tcp"
    ufw allow "${PORT}/udp"

# nftables
elif command -v nft >/dev/null 2>&1 &&
     systemctl is-active --quiet nftables 2>/dev/null; then

    echo "[+] Configuring nftables..."

    nft add rule inet filter input tcp dport "$PORT" accept 2>/dev/null || true
    nft add rule inet filter input udp dport "$PORT" accept 2>/dev/null || true

# iptables
elif command -v iptables >/dev/null 2>&1; then

    echo "[+] Configuring iptables..."

    iptables -C INPUT -p tcp --dport "$PORT" -j ACCEPT 2>/dev/null ||
        iptables -I INPUT -p tcp --dport "$PORT" -j ACCEPT

    iptables -C INPUT -p udp --dport "$PORT" -j ACCEPT 2>/dev/null ||
        iptables -I INPUT -p udp --dport "$PORT" -j ACCEPT

else

    echo "ERROR: No supported firewall detected."
    exit 1
fi

echo ""
echo "RDP port $PORT has been allowed."
echo "Test externally with:"
echo ""
echo "nc -vz -w 5 SERVER_IP $PORT"

12. Troubleshooting Flow

Use the following sequence when troubleshooting:

             RDP Connection
                    │
                    ▼
        Is RDP enabled?
          │             │
         NO            YES
          │             │
          ▼             ▼
      Enable RDP    TermService running?
                         │
                    ┌────┴────┐
                   NO         YES
                    │          │
                    ▼          ▼
                  Start    Port 3389
                  service   listening?
                              │
                         ┌────┴────┐
                        NO         YES
                         │          │
                         ▼          ▼
                      Fix RDP    Windows
                      listener   Firewall
                                   │
                                   ▼
                              Allow TCP 3389
                                   │
                                   ▼
                         External port test
                                   │
                          ┌────────┴────────┐
                         FAIL              PASS
                          │                  │
                          ▼                  ▼
                    Check Virtualizor    Check RDP
                    node/provider       authentication
                    firewall/NAT        /NLA/user

Important Security Note

Do not permanently disable Windows Firewall just to make RDP work.

Avoid:

netsh advfirewall set allprofiles state off

Instead, create an explicit inbound rule for 3389.

For production servers, an even better setup is to restrict RDP to trusted source IP addresses rather than exposing 3389 to the entire Internet.

  • 0 Users Found This Useful
Was this answer helpful?

Related Articles

How to fix installation issue of Virtualizor

In this tutorial, we are going to explain to you how to fix a problem with virtualizor on some...

How to Install SolusVM Master on CentOS 7.x?

SolusVM is a popular VPS hosting control panel and SolusVM master is used for controlling Slave...

Install Froxlor Server Management Panel 0.10.15

You can download shell installer which downloads the tarball, extracts it and sets up the basics....

Force Main IP Remote Detection (SolusVM)

If you have multiple IPs assigned to your KVM VPS and remote connections are only seeing your...

Disable IPv6 on CentOS 6/7/8 server - SolusVM

If you use some servers that have SolusVM that support IPv6 and get the problem could not send...