CyberSpec

Ports that should never face the internet

RDP, database ports and container control planes end up publicly reachable the same handful of ways — almost never by decision.

CyberSpec

2 min read

A perimeter of mostly sealed port slots with three left open, one of them passing traffic straight through to the internal services behind it

Nobody decides to publish their database to the internet. Yet the ports that should never face the internet turn up on external scans constantly, and they get there by a small, repeatable set of accidents rather than by anyone choosing badly.

The short list

Remote access. RDP on 3389 remains one of the most reliably reported ransomware entry points, year after year, because a credential-stuffing run against it needs no exploit at all. Telnet on 23 and VNC on 5900 are the same argument with worse authentication.

File sharing. SMB on 445 is what WannaCry travelled on. There is no version of "our Windows file share is on the public internet" that ends well.

Databases. MySQL 3306, PostgreSQL 5432, MSSQL 1433, MongoDB 27017, Elasticsearch 9200, Redis 6379, memcached 11211. Redis has refused external connections in its default protected mode since 3.2, but a config that binds 0.0.0.0 disables that; MongoDB and Elasticsearch have both been swept wholesale by automated ransom and wipe campaigns targeting nothing more sophisticated than an open port with no auth. Exposed memcached on UDP also makes you a DDoS amplifier for someone else.

Control planes. The unauthenticated Docker API on 2375, the Kubernetes API on 6443, kubelet on 10250, etcd on 2379. These are worse than a database port: reaching them is not access to data, it is access to scheduling arbitrary containers on your hardware.

How they get there

Five causes cover nearly all of it.

  • A 0.0.0.0/0 rule added to debug something at 2am, which nobody removed.
  • A host rebuilt from an image and attached to the wrong security group.
  • Docker publishing a port with -p, which writes its own iptables rules ahead of the host firewall — your UFW rules are intact and irrelevant.
  • IPv6 reaching a service the equivalent IPv4 rule was written to block.
  • A daemon bound to 0.0.0.0 by default in its shipped config, on a host whose network was assumed to be private.

Every one of these is invisible from inside. The firewall config says the right thing, the security group looks correct in isolation, and the service is listening exactly where it was told to.

Check reachability, not configuration

The only assertion worth making is that a port is not reachable, and the only way to make it is from outside, against both address families, on a schedule rather than during an incident.

That means a full-range TCP sweep, not just the top 1000 — control planes and databases sit well outside the common ports. It means the answer must be a diff: a scan result you cannot compare against last week's tells you what is open, but not that something opened. New listener on a host that had none is a signal in its own right, before anyone knows whether the software behind it is vulnerable.

Severity ratings do not help here either. An open Redis port has no CVE attached; it is a configuration state, which is exactly the class of problem a severity-sorted queue buries.

Conclusion

The exposure you should worry about is rarely a novel vulnerability. It is a service that was never supposed to be listening where it is, running perfectly, doing exactly what it was configured to do — for anyone who asks.

CyberSpec runs scheduled external scans and tracks the open-port set per asset over time, so a newly exposed service registers as a change rather than as something you notice eventually. See network scanning.

Related