Check ID: networking_security_group_allows_rdp_from_internet
Provider: OpenStack
Service: networking
Severity: HIGH
Categories: internet-exposed, trust-boundaries
Resource type: OS::Neutron::SecurityGroup

What this check verifies

OpenStack security groups are evaluated to verify that RDP (port 3389) is not exposed to the Internet (0.0.0.0/0 or ::/0). Security groups act as virtual firewalls controlling Windows instance traffic. Unrestricted RDP access violates least privilege and creates significant attack surface. Best practices recommend restricting RDP to known IP ranges, RD Gateway, or VPN.

Risk

Unrestricted RDP exposes Windows instances to brute-force attacks, password spraying, and RDP vulnerabilities (BlueKeep, DejaBlue). Compromised sessions enable ransomware deployment, credential theft, privilege escalation, and lateral movement. Successful compromise leads to domain controller access, Active Directory enumeration, and organization-wide data exfiltration.

Recommendation

Restrict RDP access to known IP ranges using Remote Desktop Gateway or VPN instead of allowing 0.0.0.0/0. Enable Network Level Authentication (NLA) and implement multi-factor authentication for all RDP sessions. Deploy LAPS for unique local administrator passwords and patch Windows systems regularly to address RDP vulnerabilities.

Remediation

# Terraform: restrict RDP to known IP ranges, never 0.0.0.0/0

resource "openstack_networking_secgroup_v2" "windows_servers" {
  name        = "windows-servers-sg"
  description = "Security group for Windows application servers"
}

# GOOD: RDP restricted to corporate VPN IP range
resource "openstack_networking_secgroup_rule_v2" "rdp_from_vpn" {
  direction         = "ingress"
  ethertype         = "IPv4"
  protocol          = "tcp"
  port_range_min    = 3389
  port_range_max    = 3389
  remote_ip_prefix  = "10.8.0.0/24"  # VPN gateway range
  security_group_id = openstack_networking_secgroup_v2.windows_servers.id
}

# GOOD: RDP from RD Gateway security group (reference-based rule)
resource "openstack_networking_secgroup_rule_v2" "rdp_from_rd_gateway" {
  direction         = "ingress"
  ethertype         = "IPv4"
  protocol          = "tcp"
  port_range_min    = 3389
  port_range_max    = 3389
  remote_group_id   = openstack_networking_secgroup_v2.rd_gateway.id  # Reference
  security_group_id = openstack_networking_secgroup_v2.windows_servers.id
}

# Remote Desktop Gateway security group (least privilege)
resource "openstack_networking_secgroup_v2" "rd_gateway" {
  name        = "rd-gateway-sg"
  description = "Security group for Remote Desktop Gateway"
}

# RD Gateway accepts RDP from corporate network only
resource "openstack_networking_secgroup_rule_v2" "rd_gateway_rdp" {
  direction         = "ingress"
  ethertype         = "IPv4"
  protocol          = "tcp"
  port_range_min    = 3389
  port_range_max    = 3389
  remote_ip_prefix  = var.corporate_cidr  # e.g., 198.51.100.0/24
  security_group_id = openstack_networking_secgroup_v2.rd_gateway.id
}

# RD Gateway also needs HTTPS for external RDG clients
resource "openstack_networking_secgroup_rule_v2" "rd_gateway_https" {
  direction         = "ingress"
  ethertype         = "IPv4"
  protocol          = "tcp"
  port_range_min    = 443
  port_range_max    = 443
  remote_ip_prefix  = var.corporate_cidr  # Restrict to corporate IPs
  security_group_id = openstack_networking_secgroup_v2.rd_gateway.id
}

# BAD: Never do this - RDP from anywhere (0.0.0.0/0)
# resource "openstack_networking_secgroup_rule_v2" "rdp_from_anywhere" {
#   direction         = "ingress"
#   ethertype         = "IPv4"
#   protocol          = "tcp"
#   port_range_min    = 3389
#   port_range_max    = 3389
#   remote_ip_prefix  = "0.0.0.0/0"  # DANGEROUS - DO NOT USE
#   security_group_id = openstack_networking_secgroup_v2.windows_servers.id
# }

References

Where this check fires

This check runs on every scheduled scan against your OpenStack account. Findings appear at Cloud Security → Findings filterable by Check ID = networking_security_group_allows_rdp_from_internet. To re-evaluate after a fix, hit Run now on the account’s schedule under Cloud Security → Schedules — the next scan re-checks this control and marks the finding fixed or keeps it persistent.
← Back to OpenStack checks