Web Security

Exposed Ports and Network Exposure: What to Keep Off the Public Internet

Every port your server leaves open to the internet is a door someone can try to walk through. A web server needs a couple of them open. A database needs none. This guide covers which ports should never face the public internet, how attackers find the ones that do, and the handful of controls that shrink your exposure to almost nothing.

SiteSecurityScore Team·10 min read·Updated Jun 28, 2026
Rows of network switch ports with cables, representing the many ports a server can expose to a network

What open ports are#

A port is a numbered endpoint on a server where a particular service listens for connections. When a web server answers requests on port 443, or a database listens on port 3306, that number is how the operating system knows which program a new connection belongs to. A port is described as open when a service is actively listening on it and accepting connections. Web traffic uses 80 and 443, secure shell uses 22, MySQL uses 3306, and so on through a long standardized list.

The security question is not whether a port is open, but who can reach it. A database listening on port 3306 is normal and necessary. The same database reachable on port 3306 from anywhere on the internet is a serious problem. An internet facing port is one that any of the billions of hosts on the public internet can attempt to connect to, and every such port is effectively a door into the machine that an attacker can knock on.

This is why the guiding principle is to expose as few ports as possible. The set of services reachable from the internet is your attack surface, and each additional open port adds something an attacker can probe, fingerprint, and attempt to exploit. A public web server genuinely needs 80 and 443 open. Almost everything else, from databases to caches to management interfaces, should be reachable only from a trusted network and never from the open internet.

Exposed directly vs reached through a gateway

EXPOSED: PORT 3306 OPEN TO THE INTERNETInternetscanners, botsdirect connection to port 3306Databasereachable by anyonePROTECTED: ONLY 443 OPEN, DATABASE ON LOCALHOSTInternet443 onlyFirewall + web serveronly 80 and 443 inboundprivate networkDatabasenot internet facingThe database does the same job in both cases. Only its reachability changed.

Ports to keep off the internet#

Some ports are dangerous to expose because the services behind them were built to trust whoever can reach them. They assume the network itself is the security boundary, so putting them on the public internet removes the one thing they were counting on. Databases are the textbook case, and management interfaces are a close second.

Database ports

  • MySQL and MariaDB on 3306, where an exposed instance gives an attacker a direct login prompt to brute force or, if credentials are weak or absent, a straight path to the data.
  • PostgreSQL on 5432, with the same exposure profile and frequently a default database holding production records.
  • MongoDB on 27017, which historically shipped with no authentication and a default bind address that listened on every interface, a combination that fueled mass ransom attacks.
  • Redis on 6379, which has no authentication by default and was designed as an in-memory store for trusted networks, never for direct internet exposure.

Management interfaces and legacy protocols

  • RDP on 3389, the Windows Remote Desktop protocol, which is one of the most common entry points for ransomware because it grants interactive control of the whole machine.
  • Web admin panels and dashboards, such as database GUIs, container orchestrators, and monitoring consoles, which often sit behind weak or default credentials.
  • Telnet on 23 and FTP on 21, older plaintext protocols that send credentials in the clear and have no place on the modern internet.

Secure shell on port 22 sits in a middle category. It is designed to be exposed and is far safer than the protocols above, but it still attracts constant brute force traffic, so it benefits from key-based authentication and ideally an IP allowlist or a bastion in front of it rather than being left open to everyone.

How attackers discover them#

Exposed ports do not stay hidden, because the entire internet is scanned continuously. A port scanner is a tool that connects to a range of ports on a target and records which ones respond, which reveals exactly what is listening. Attackers run these against blocks of IP addresses, and the public address space is small enough that the whole of it gets swept many times a day.

They rarely need to do the scanning themselves. Internet-wide scan services such as Shodan and Censys continuously index every reachable host on the internet along with the service banner behind each open port. A banner is the short identifying string a service sends when you connect, often including its software name and version. Searching one of these services for a product like MongoDB returns tens of thousands of live instances, each tagged with its version and whether authentication is enabled. Finding an exposed database is a search query, not a research project.

The speed is the part people underestimate. Expose RDP on a fresh server and automated tooling will typically find and begin probing it within minutes, long before you have finished configuring anything. There is no quiet period in which a misconfiguration sits unnoticed. The moment a risky port opens, the clock starts.

Obscurity is not a defense

Moving a service to a non standard port slows down only the laziest scanning. Tools like Shodan and Censys fingerprint services by their banners regardless of port number, so a database on port 47213 is still indexed as a database. Reducing exposure means restricting who can reach the port, not hoping nobody guesses it.

The real risks#

The worst outcomes need no exploit at all, just a service that trusts the connection. Many databases historically shipped with no authentication, so an exposed instance lets anyone who connects read, change, or delete everything in it. In late 2016 and through 2017, automated scripts swept the internet for open MongoDB instances, wiped tens of thousands of them, and left ransom notes demanding payment for the data's return. Researchers tracked well over twenty thousand affected databases, and the only thing the victims had in common was an open port 27017 with no password.

An exposed Redis can be worse than data loss. Because Redis exposes a CONFIG command that can change where it writes its data file, an attacker who reaches an unauthenticated instance can point it at a sensitive location and write a file the system will later execute, such as a cron job or an SSH key. That turns a database exposure into remote code execution on the host, which is how many exposed Redis servers end up mining cryptocurrency for someone else.

Where a service does require a login, exposure turns into a brute force problem instead. An open RDP or SSH port invites relentless automated guessing, and a single weak or reused password is enough. Exposed RDP in particular is a leading initial access vector for ransomware crews, precisely because it hands over an interactive desktop session on the machine once they are in. The pattern across all of these is the same. The network was supposed to keep untrusted parties out, and the open port let them in.

How to reduce exposure#

Reducing exposure is mostly about defaulting to closed and opening only what genuinely needs to be public. The first layer is a firewall or cloud security group that denies inbound traffic by default. A web server then allows 80 and 443, and your administrative access path, and nothing else. In a cloud environment, the database's security group should permit traffic only from the application tier rather than from 0.0.0.0/0.

Firewall and security group rules
# Default deny inbound, allow only what the public needs.

# Linux (ufw): allow web traffic and SSH, deny the rest
sudo ufw default deny incoming
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw allow 22/tcp
sudo ufw enable

# AWS security group: HTTPS open to all, database open only
# to the app tier's security group, never to 0.0.0.0/0
#   Inbound  443  tcp  0.0.0.0/0          (public web)
#   Inbound 5432  tcp  sg-app-tier-xxxx   (app servers only)

The second layer is to stop internal services from listening on a public address at all. Binding a database to 127.0.0.1 or a private interface means it physically cannot accept a connection from the internet, no matter what a firewall rule says. This belt-and-braces approach protects you when a firewall is misconfigured or removed by mistake.

Bind services to localhost
# Bind a service to localhost so it never listens on a public address.

# PostgreSQL (postgresql.conf)
listen_addresses = 'localhost'

# MySQL / MariaDB (my.cnf)
bind-address = 127.0.0.1

# Redis (redis.conf), bind to loopback and require a password
bind 127.0.0.1
requirepass a-long-random-secret

# MongoDB (mongod.conf)
net:
  bindIp: 127.0.0.1

The controls that matter most

  • Reach administrative services through a VPN or a bastion host rather than exposing RDP, SSH, or admin panels directly to the internet.
  • Put any management interface behind real authentication and an IP allowlist, so a leaked URL is not enough to reach it.
  • Close ports for services you no longer run, since yesterday's test database is today's forgotten open port.
  • Audit your exposure on a schedule, because a single console change or a new instance can reopen something you had locked down.

Watch the default bind address

A service that binds to 0.0.0.0 listens on every network interface, including the public one. Containers and quick start configs often default to this for convenience. Always confirm the bind address, because a database can be locked down by a firewall today and silently exposed the moment that firewall changes.

How to check your exposure#

Checking your own exposure works from two angles. From the inside, list what is actually listening on the host and on which interface. From the outside, scan the server the way an attacker would and confirm that only your intended ports answer. The two views should agree, and any gap between them is worth investigating.

Check listening and reachable ports
# See which ports your own host actually exposes.

# What is listening locally, and on which interface
ss -tlnp
# 0.0.0.0:5432  means Postgres faces every interface, so fix it.
# 127.0.0.1:5432 means it is bound to localhost, which is good.

# Scan from an outside machine to confirm what is reachable
nmap -Pn -p- your-server-ip
# Anything other than your intended public ports needs closing.

The OWASP Foundation's guidance on attack surface management is a useful reference for thinking about exposure systematically rather than host by host. You can read more in the OWASP Attack Surface Analysis Cheat Sheet.

A one time scan tells you what is exposed today, but cloud environments change constantly and a new instance or a tweaked security group can reopen a port overnight. SiteSecurityScore looks at your internet facing exposure as part of a scan and can keep watching over time, so a port that opens after your last review surfaces as a finding rather than waiting to be discovered by someone scanning for victims.

FAQ#

What is an open port and why does it matter?

An open port is a numbered endpoint on a server where a service is listening for connections, such as 443 for HTTPS or 3306 for MySQL. A port that is reachable from the internet is something any host on the internet can try to connect to. Each open port is a door into the machine, so the security rule of thumb is to expose only the ports that genuinely need public access and keep everything else behind a firewall or bound to localhost.

Which ports should never be exposed to the public internet?

Database ports are the clearest example, including MySQL on 3306, PostgreSQL on 5432, MongoDB on 27017, and Redis on 6379. Remote management interfaces are just as risky, especially RDP on 3389 and any web admin panel. Older plaintext protocols like Telnet on 23 and FTP on 21 also belong on the list. These services are meant for trusted internal networks, not the open internet, and exposing them invites automated attacks within minutes.

How do attackers find exposed ports?

Attackers run port scanners against ranges of IP addresses to see which ports respond, and they lean on internet-wide scan services like Shodan and Censys that continuously index every reachable host and the service banners behind each open port. A search on one of these services for a product such as MongoDB returns tens of thousands of live instances complete with version numbers and whether authentication is enabled, so finding a target takes seconds rather than effort.

What is the real risk of an exposed database port?

Many databases ship with no authentication or weak defaults and were designed to trust the local network. An exposed instance with no password lets anyone connect and read, modify, or delete everything in it. In the 2017 MongoDB ransom wave, automated scripts found tens of thousands of open instances, wiped them, and left ransom notes. An exposed Redis can be even worse, since its CONFIG command can be abused to write files and reach remote code execution on the host.

How do I reduce my network exposure?

Default to denying inbound traffic and open only the ports a service truly needs, such as 80 and 443 for a web server. Bind databases and internal services to localhost or a private network interface so they never listen on a public address. Reach administrative services through a VPN or a bastion host rather than exposing them directly, put any management panel behind authentication and an IP allowlist, and close ports for services you no longer run.

References

Was this helpful?

See What Your Site Exposes to the Internet

Run a free scan to check your internet facing exposure and security headers in one pass, then turn on monitoring so a newly opened port gets flagged before someone else finds it.