Open Ports and Service Exposure: Assessment and Remediation
Identify unnecessarily exposed services, close risky ports, suppress version banners, and configure firewall rules to minimize your attack surface.
High-Risk Ports That Should Never Face the Internet
Certain services are designed for internal use. Exposing them to the internet creates direct, exploitable attack vectors regardless of patch level or password strength. Understanding your full external attack surface is the first step toward identifying and closing these gaps. If any of the following ports are reachable from the public internet, treat it as a priority remediation item.
Port 3306 (MySQL) -- MySQL listening on a public interface invites brute-force attacks and credential stuffing. Even with strong passwords, known SQL injection paths and authentication bypass vulnerabilities have allowed unauthenticated access in past releases. A database should accept connections only from application servers, never from the open internet.
Port 5432 (PostgreSQL) -- PostgreSQL relies on pg_hba.conf for access control. A single misconfigured line granting trust authentication to 0.0.0.0/0 gives anyone full access without a password. Even when properly configured, exposing the port lets attackers probe for version-specific exploits.
Port 6379 (Redis) -- Redis ships with no authentication enabled by default. An exposed Redis instance allows attackers to read and overwrite cached data, and in many configurations, write SSH keys or cron jobs to disk, achieving remote code execution within seconds of discovery.
Port 27017 (MongoDB) -- MongoDB without authentication enabled is the cause of thousands of documented data breaches. Attackers routinely scan for this port, export the entire database, delete it, and leave a ransom note. Enabling authentication alone is not sufficient if the port is public -- defense in depth demands network-level restriction.
Port 3389 (RDP) -- Remote Desktop Protocol exposed to the internet has been the initial access vector in a significant share of ransomware incidents. Even with Network Level Authentication enabled, brute-force attacks are constant, and critical vulnerabilities like BlueKeep have demonstrated unauthenticated remote code execution.
Port 445 (SMB) -- Server Message Block is the protocol behind Windows file sharing. SMB exposed to the internet enabled WannaCry and NotPetya to spread globally. EternalBlue and its variants remain in active exploitation. There is no legitimate reason to expose SMB beyond your network perimeter.
Firewall Rules: Blocking Unwanted Access
iptables (Linux)
The iptables firewall operates on a chain-based model. The INPUT chain governs incoming traffic. A sensible baseline allows established connections, loopback traffic, and only the specific ports you need, then drops everything else.
# Allow established and related connections
iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
# Allow loopback
iptables -A INPUT -i lo -j ACCEPT
# Allow SSH from a specific management subnet only
iptables -A INPUT -p tcp --dport 22 -s 10.0.1.0/24 -j ACCEPT
# Allow HTTP and HTTPS from anywhere
iptables -A INPUT -p tcp --dport 80 -j ACCEPT
iptables -A INPUT -p tcp --dport 443 -j ACCEPT
# Drop everything else
iptables -A INPUT -j DROP
On modern distributions, nftables replaces iptables with a cleaner syntax. The equivalent default-deny policy:
nft add rule inet filter input ct state established,related accept
nft add rule inet filter input iif lo accept
nft add rule inet filter input tcp dport 22 ip saddr 10.0.1.0/24 accept
nft add rule inet filter input tcp dport { 80, 443 } accept
nft add rule inet filter input drop
Persist rules across reboots with iptables-save > /etc/iptables/rules.v4 or by enabling the nftables systemd service.
Cloud Security Groups
In cloud environments, the security group is your first line of defense. The principle is the same: default deny, explicit allow.
AWS Security Groups -- Inbound rules are deny-all by default. Add rules only for required ports. Restrict SSH access to your office IP or VPN CIDR, never to 0.0.0.0/0. Use separate security groups for web servers, application tiers, and databases, and reference security group IDs in rules rather than IP ranges where possible.
Azure Network Security Groups (NSGs) -- Attach NSGs to subnets or individual NICs. Define inbound rules with priority numbers (lower number = higher priority). Use the VirtualNetwork service tag for internal traffic and restrict management ports to your bastion subnet.
GCP Firewall Rules -- GCP firewall rules apply at the VPC level and use target tags or service accounts. Create rules that allow port 443 for instances tagged web-server and restrict port 22 to your IAP (Identity-Aware Proxy) tunnel range. Deny rules take precedence at the same priority level.
Across all cloud providers, audit security groups regularly. A rule added for a one-time debugging session and never removed is a common source of unintended exposure.
Suppressing Version Banners
Service banners broadcast software names and version numbers to anyone who connects. This hands attackers a shortcut -- they can look up exact CVEs for your version instead of guessing. Suppress banners for every public-facing service.
Nginx -- Add the following to the http block in nginx.conf:
server_tokens off;
This removes the version number from the Server response header and from default error pages. The header will read Server: nginx instead of Server: nginx/1.24.0.
Apache -- In your Apache configuration or virtual host file:
ServerTokens Prod
ServerSignature Off
ServerTokens Prod reduces the Server header to just Apache. ServerSignature Off removes version information from server-generated pages like directory listings and error documents.
SSH -- OpenSSH broadcasts its version in the protocol banner. While the protocol version cannot be suppressed (it is required for the handshake), you can remove custom suffixes and distribution identifiers:
# In /etc/ssh/sshd_config
VersionAddendum none
Restart the SSH daemon after making changes. Note that the base version string (e.g., SSH-2.0-OpenSSH_9.6) is part of the protocol specification and cannot be fully removed, but VersionAddendum none prevents your OS distribution or custom strings from being appended.
Binding Services to Localhost
Many services default to listening on 0.0.0.0, meaning all network interfaces. If a service only needs to communicate with applications on the same machine, bind it to 127.0.0.1 so it is unreachable from the network entirely.
MySQL -- In /etc/mysql/mysql.conf.d/mysqld.cnf:
bind-address = 127.0.0.1
PostgreSQL -- In postgresql.conf:
listen_addresses = 'localhost'
Redis -- In redis.conf:
bind 127.0.0.1
MongoDB -- In mongod.conf:
net:
bindIp: 127.0.0.1
After changing bind addresses, restart the service and verify with ss or netstat (see the verification section below). Binding to localhost is the simplest and most reliable way to prevent external access to a service -- even if a firewall rule is misconfigured, the service itself will refuse connections from non-local addresses.
VPN and Bastion Host for Management Access
Administrative services like SSH and RDP should never be directly reachable from the internet. Instead, route all management access through a controlled entry point.
VPN -- A site-to-site or client-to-site VPN (WireGuard, OpenVPN, or a cloud-native solution like AWS Client VPN) places management ports behind an encrypted tunnel. SSH and RDP remain accessible only after authenticating to the VPN. This reduces the attack surface to a single, hardened entry point.
Bastion host (jump box) -- A bastion host is a single, minimal server that is the only machine with SSH access from the internet. All other servers accept SSH only from the bastion. This concentrates your audit logging and access controls. Harden the bastion aggressively: key-only authentication, fail2ban, and minimal installed software.
Cloud-native alternatives -- AWS Systems Manager Session Manager, Azure Bastion, and GCP Identity-Aware Proxy provide management access without exposing any port to the internet. These are preferable to self-managed bastion hosts when available.
Verification: Confirming Your Exposure
After making changes, verify from both inside and outside your network.
External Verification with Nmap
Run a port scan from a machine outside your network (a cloud instance or a colleague's network) to see exactly what the internet sees:
# Scan the 1000 most common ports
nmap -Pn your-server.example.com
# Scan all 65535 ports (slower but thorough)
nmap -Pn -p- your-server.example.com
# Check specific high-risk ports
nmap -Pn -p 3306,5432,6379,27017,3389,445 your-server.example.com
The -Pn flag skips host discovery and treats the target as online, which is necessary when ICMP is blocked. Every port should show as filtered (firewall dropping packets) or closed unless you intend it to be open.
Local Audit with ss and netstat
On the server itself, check which services are listening and on which interfaces:
# Show all listening TCP sockets with process names
ss -tlnp
# Equivalent using netstat
netstat -tlnp
Look at the Local Address column. An address of 0.0.0.0:3306 means MySQL is listening on all interfaces -- it should read 127.0.0.1:3306 if it only serves local applications. An address of :::6379 is the IPv6 equivalent of listening on all interfaces and requires the same remediation.
Run these checks after every infrastructure change, and schedule periodic external scans as part of your security posture assessment. A port that was properly firewalled last month may be exposed today due to a security group change, a new deployment, or a configuration management drift.
Continue Reading
Open Ports and Attack Surface: What Exposed Services Reveal
Every open port is a potential entry point. Learn how attackers enumerate services, why unnecessary exposure is dangerous, and how to minimize your external attack surface.
Shadow IT: Finding Your Unknown Internet-Facing Assets
Over half of SaaS applications used by organizations are adopted without security team involvement. Learn how external scanning, DNS enumeration, and certificate transparency monitoring discover the internet-facing assets you do not know about.
How Weak External Security Enables Ransomware Attacks
Ransomware operators exploit the same external security weaknesses that automated scanners detect. Learn how open ports, missing email authentication, weak TLS, and absent security headers create the entry points ransomware uses to breach your organization.