Implementing Dynamic DNS-based Windows Firewall Rules for RDP Access to Servers with Changing IPs


4 views

html

Managing remote access to servers via RDP becomes tricky when client machines (like home PCs) rely on dynamic IPs. While Windows Firewall natively supports IP-based rules, DNS-based filtering isn't directly available. Here's how to solve this elegantly.

Since Windows Firewall rules require IP addresses, we'll automate DNS resolution updates via PowerShell. This script resolves your DynDNS hostname and updates the firewall rule:

# PowerShell: Update-FirewallRule.ps1  
$dynDNSHostname = "yourhost.dyndns.org"  
$ruleName = "AllowRDP_FromHome"  
$currentIP = [System.Net.Dns]::GetHostAddresses($dynDNSHostname).IPAddressToString  

# Delete old rule if exists  
if (Get-NetFirewallRule -DisplayName $ruleName -ErrorAction SilentlyContinue) {  
    Remove-NetFirewallRule -DisplayName $ruleName  
}  

# Create new rule  
New-NetFirewallRule -DisplayName $ruleName   
    -Direction Inbound   
    -Protocol TCP   
    -LocalPort 3389   
    -RemoteAddress $currentIP   
    -Action Allow  

Create a scheduled task to run this hourly (adjust as needed):

# Command to register task (Admin PowerShell)  
$action = New-ScheduledTaskAction -Execute "PowerShell.exe"   
    -Argument "-File C:\scripts\Update-FirewallRule.ps1"  
$trigger = New-ScheduledTaskTrigger -Once -At (Get-Date)   
    -RepetitionInterval (New-TimeSpan -Hours 1)  
Register-ScheduledTask -TaskName "Update RDP Firewall Rule"   
    -Action $action -Trigger $trigger -RunLevel Highest  

For enterprise environments, consider these options:

  • Always-On VPN: Windows Server's native VPN with certificate authentication
  • Zero Trust: Cloudflare Access or Tailscale for certificate-based access

When using dynamic DNS updates:

  1. Restrict script execution to signed scripts
  2. Monitor DNS resolution failures
  3. Combine with RDP certificate authentication

When configuring Windows Firewall for remote access (like RDP), we typically create rules based on static IP addresses. This becomes problematic when dealing with dynamic IPs, even with services like DynDNS providing a consistent hostname. The Windows Firewall interface doesn't natively support domain name-based rules.

Here are several approaches to solve this problem:

1. Scheduled Task with PowerShell Script

Create a PowerShell script that periodically resolves your DynDNS hostname and updates the firewall rule:


# Update-FirewallRule.ps1
$hostname = "yourhost.dyndns.org"
$ip = [System.Net.Dns]::GetHostAddresses($hostname)[0].IPAddressToString
$ruleName = "Allow RDP from Home"

# Remove existing rule if it exists
Remove-NetFirewallRule -DisplayName $ruleName -ErrorAction SilentlyContinue

# Create new rule with current IP
New-NetFirewallRule -DisplayName $ruleName -Direction Inbound -LocalPort 3389 -Protocol TCP -Action Allow -RemoteAddress $ip

Schedule this to run every hour using Task Scheduler.

2. VPN Alternative

Setting up a VPN (like OpenVPN or WireGuard) would be more secure and reliable:

  • Configure your RackSpace server as a VPN endpoint
  • Only allow VPN port (1194 for OpenVPN) through the firewall
  • Connect to VPN first, then RDP to local VPN IP

3. Third-Party Firewall Solutions

Some advanced firewall products support dynamic DNS in rules:

  • Windows Defender Firewall with Advanced Security (through Group Policy)
  • Third-party firewalls like TinyWall or GlassWire

For a more robust PowerShell implementation that handles errors:


# Enhanced firewall rule updater
try {
    $hostname = "yourhost.dyndns.org"
    $ips = [System.Net.Dns]::GetHostAddresses($hostname)
    
    if ($ips.Count -eq 0) {
        throw "No IP addresses found for $hostname"
    }

    $ruleName = "Allow RDP from Home"
    $existingRule = Get-NetFirewallRule -DisplayName $ruleName -ErrorAction SilentlyContinue

    if ($existingRule) {
        $currentIPs = ($existingRule | Get-NetFirewallAddressFilter).RemoteAddress
        if ($ips.IPAddressToString -notin $currentIPs) {
            Set-NetFirewallRule -DisplayName $ruleName -RemoteAddress $ips.IPAddressToString
            Write-Host "Updated $ruleName with new IPs: $($ips.IPAddressToString -join ', ')"
        }
    }
    else {
        New-NetFirewallRule -DisplayName $ruleName -Direction Inbound -LocalPort 3389 -Protocol TCP -Action Allow -RemoteAddress $ips.IPAddressToString
        Write-Host "Created new rule $ruleName with IPs: $($ips.IPAddressToString -join ', ')"
    }
}
catch {
    Write-Error "Failed to update firewall rule: $_"
}

When implementing dynamic firewall rules:

  • Set the script to run with minimal privileges
  • Add logging to monitor IP changes
  • Consider rate-limiting to prevent abuse if DNS is compromised
  • For RDP, always use Network Level Authentication (NLA)