← Back to Blog

Open Ports on Your Server: Security Risks You're Ignoring

Every open port on your server is a door. Some of those doors need to be open — port 80 and 443 for your website, for example. But many servers have database ports, admin interfaces, and development tools exposed to the entire internet without the operators even realizing it. Attackers find them in seconds using tools like Shodan and Censys. Here is what you need to know.

How Attackers Find Your Open Ports

You might think your obscure service on port 9200 is safe because "nobody knows it's there." That assumption is dangerously wrong. The entire IPv4 address space can be scanned in under an hour, and several services do exactly that continuously.

Shodan: The Search Engine for Exposed Services

Shodan continuously scans the entire internet and indexes every open port, banner, and service it finds. An attacker does not need to scan your server — Shodan has already done it. A simple search like port:6379 country:US returns thousands of exposed Redis instances. port:9200 product:elasticsearch returns unprotected Elasticsearch clusters with all their data.

Shodan captures the service banner, which often reveals software versions, configuration details, and sometimes authentication status. For example, a Redis banner that shows redis_version:7.0.12 without requiring auth tells an attacker everything they need.

Censys and Other Scanners

Censys is another internet-wide scanner that focuses on TLS certificates and service discovery. BinaryEdge and ZoomEye provide similar capabilities. Between these services, your open ports are indexed from multiple angles within hours of being exposed.

Nmap: Manual Scanning

When attackers target a specific organization, they use nmap for targeted reconnaissance:

# Quick scan of common ports
nmap -sV -sC -T4 target.com

# Full port scan (all 65535 ports)
nmap -p- -sV target.com

# UDP scan (slower but finds DNS, SNMP, etc.)
nmap -sU --top-ports 100 target.com

Use our Port Lookup tool to understand what each port number is used for and its security implications.

The Most Dangerous Open Ports

Port 22 — SSH

SSH is how you manage your server remotely. It needs to be accessible, but leaving it open to the entire internet invites brute force attacks. Automated bots continuously try common username/password combinations against every SSH server they find.

Risk level: Medium (if using key-based auth), Critical (if using password auth)

# Secure SSH configuration (/etc/ssh/sshd_config)
PermitRootLogin no
PasswordAuthentication no      # Key-based auth only
PubkeyAuthentication yes
MaxAuthTries 3
LoginGraceTime 30
AllowUsers deploy admin        # Whitelist specific users

# Optional: Change default port (security through obscurity, but reduces noise)
Port 2222
  • Use SSH key authentication only. Disable password authentication entirely.
  • Restrict SSH access by IP using firewall rules or AllowUsers directives.
  • Install fail2ban to automatically block IPs after failed login attempts.
  • Consider using a VPN or bastion host for SSH access instead of exposing it directly.

Read our SSH Keys Explained guide and generate a secure key with Ed25519 SSH key generation.

Port 3306 — MySQL

MySQL's default port. If accessible from the internet, attackers can brute force credentials, exploit known MySQL vulnerabilities, or exfiltrate your entire database. There is almost never a legitimate reason for MySQL to be publicly accessible.

Risk level: Critical

# MySQL: Bind to localhost only (/etc/mysql/mysql.conf.d/mysqld.cnf)
bind-address = 127.0.0.1

# Or bind to specific internal IP for multi-server setups
bind-address = 10.0.1.5

# Verify no external access
mysql -u root -p -e "SELECT user, host FROM mysql.user;"
# Ensure no entries have host = '%' (allows any IP)

Port 5432 — PostgreSQL

Same risk as MySQL. PostgreSQL's pg_hba.conf controls access, but the default configuration on some distributions allows remote connections.

# PostgreSQL: Restrict in pg_hba.conf
# TYPE  DATABASE  USER  ADDRESS       METHOD
local   all       all                 peer
host    all       all   127.0.0.1/32  scram-sha-256
host    all       all   10.0.0.0/8    scram-sha-256
# DO NOT add: host all all 0.0.0.0/0 md5  <-- This allows the world

Port 6379 — Redis

Redis is arguably the most dangerous service to expose. By default, Redis has no authentication. An exposed Redis instance allows an attacker to read all cached data, write arbitrary data, and in many configurations, execute commands on the server itself using the CONFIG SET and MODULE LOAD commands. This has been used to plant SSH keys and gain full shell access.

Risk level: Critical

# Redis: Secure configuration (/etc/redis/redis.conf)
bind 127.0.0.1 -::1           # Listen on localhost only
protected-mode yes              # Reject connections from non-localhost
requirepass your-strong-password-here
rename-command FLUSHALL ""      # Disable dangerous commands
rename-command FLUSHDB ""
rename-command CONFIG ""
rename-command DEBUG ""

In 2024, Shodan indexed over 30,000 Redis instances exposed to the internet without authentication. Many contained session tokens, cached user data, and application secrets.

Port 9200/9300 — Elasticsearch

Elasticsearch's REST API (9200) and cluster communication port (9300). Default Elasticsearch installations before version 8 had no authentication. Even today, many clusters run without security enabled. An exposed Elasticsearch cluster leaks all indexed data and allows arbitrary queries.

Risk level: Critical

# Elasticsearch: Enable security (elasticsearch.yml)
xpack.security.enabled: true
xpack.security.transport.ssl.enabled: true
network.host: 127.0.0.1        # Bind to localhost
# Or use firewall rules to restrict to application server IPs

Port 27017 — MongoDB

MongoDB's default port. The infamous "MongoDB apocalypse" of 2017 saw tens of thousands of exposed MongoDB instances wiped and held for ransom. The problem persists in 2026 because developers still deploy MongoDB with default settings that allow unauthenticated access.

Risk level: Critical

# MongoDB: Enable authentication (mongod.conf)
security:
  authorization: enabled
net:
  bindIp: 127.0.0.1
  port: 27017

Other Commonly Exposed Ports

  • Port 8080/8443 — Application servers: Tomcat, Jenkins, development servers. Often have default credentials or debug endpoints.
  • Port 11211 — Memcached: No authentication by default. Used in DDoS amplification attacks.
  • Port 5601 — Kibana: The Elasticsearch dashboard. Exposes your data and sometimes allows arbitrary Elasticsearch queries.
  • Port 2375/2376 — Docker API: An exposed Docker socket allows an attacker to create containers with host filesystem access, effectively giving them root on your server.
  • Port 5900 — VNC: Remote desktop with often weak or no authentication.
  • Port 161/162 — SNMP: Network management protocol. Default community strings ("public"/"private") expose device configurations.

Find Your Open Ports Instantly

Our Exposure Checker uses Shodan to discover open ports on your server and flags dangerous services. No port scanning required — results in seconds.

Run Free Exposure Check

How to Close Open Ports

AWS Security Groups

If you are on AWS, security groups are your primary firewall. The principle is simple: only allow the ports you need, from the IPs that need them.

# Recommended security group rules for a web server
# Inbound:
Port 80   (HTTP)   - Source: 0.0.0.0/0    (public)
Port 443  (HTTPS)  - Source: 0.0.0.0/0    (public)
Port 22   (SSH)    - Source: your-ip/32   (your office IP only)

# Everything else: DENIED by default (implicit deny)

# Database server security group:
Port 3306 (MySQL)  - Source: sg-webapp     (web server SG only)
# NO public access

Linux Firewall (UFW)

# UFW (Uncomplicated Firewall) - Ubuntu/Debian
sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw allow from 10.0.0.0/8 to any port 22   # SSH from internal only
sudo ufw enable
sudo ufw status verbose

Linux Firewall (iptables/nftables)

# iptables: Allow only web traffic and SSH from specific IP
iptables -A INPUT -p tcp --dport 80 -j ACCEPT
iptables -A INPUT -p tcp --dport 443 -j ACCEPT
iptables -A INPUT -p tcp --dport 22 -s 203.0.113.50 -j ACCEPT
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -A INPUT -i lo -j ACCEPT
iptables -P INPUT DROP

Service-Level Binding

Even with firewall rules, you should bind services to 127.0.0.1 (localhost) whenever possible. This is defense in depth: even if a firewall rule is misconfigured, the service itself rejects external connections.

# Verify what's listening on all interfaces (0.0.0.0)
ss -tlnp | grep "0.0.0.0"
# or
netstat -tlnp | grep "0.0.0.0"

# Any service showing 0.0.0.0:PORT is accessible from outside
# Change its config to bind to 127.0.0.1 instead

Auditing Your Open Ports

Regular auditing is essential. Ports get opened during debugging and never closed. A new service gets installed with default settings. A developer opens port 9200 to test Elasticsearch and forgets about it.

# Scan your own server from outside
nmap -sV -p- your-server-ip

# Check what Shodan already knows about you
# Visit: https://www.shodan.io/host/your-server-ip

# List all listening services on the server itself
ss -tlnp        # TCP listening sockets with process names
ss -ulnp        # UDP listening sockets with process names

Our Exposure Checker queries Shodan for your domain and reports all open ports with service details and risk levels. It is faster and easier than running nmap yourself. Use our IP Lookup to check your IP details and DNS Lookup to verify your DNS configuration.

Docker and Container Port Exposure

Docker adds a particularly dangerous dimension to port exposure. When you run docker run -p 3306:3306 mysql, Docker adds iptables rules that bypass UFW. Your firewall shows port 3306 as blocked, but Docker has exposed it anyway.

# DANGEROUS: Exposes port to all interfaces (0.0.0.0:3306)
docker run -p 3306:3306 mysql

# SAFE: Bind to localhost only
docker run -p 127.0.0.1:3306:3306 mysql

# In docker-compose.yml:
services:
  db:
    image: mysql:8
    ports:
      - "127.0.0.1:3306:3306"    # Localhost only
      # NOT: "3306:3306"          # This exposes to the world

Learn more about Docker networking in our Docker Networking Explained guide and convert your docker run commands to Compose with our Docker to Compose tool.

Cloud-Specific Considerations

  • AWS: Use security groups (stateful firewall) and NACLs (stateless, subnet-level). Put databases in private subnets with no internet gateway. Use VPC endpoints for AWS services instead of public endpoints.
  • GCP: Use VPC firewall rules. The default network allows SSH and RDP from anywhere — replace it with a custom network that denies all by default.
  • Azure: Use Network Security Groups (NSGs). Azure's default rules are more permissive than they should be. Review and restrict.
  • Kubernetes: Use NetworkPolicy resources to restrict pod-to-pod communication. By default, all pods in a cluster can talk to all other pods on any port. See our Kubernetes Basics guide.

Frequently Asked Questions

Is it safe to have port 22 (SSH) open to the internet?

With key-based authentication, disabled password auth, and fail2ban, SSH on port 22 is reasonably safe. It will attract constant brute force attempts, but key-based auth makes them ineffective. However, the safest approach is to restrict SSH to specific IPs via firewall rules, or use a VPN/bastion host. If you must keep SSH open to all IPs, at minimum disable password auth and root login. Read our SSH Keys Explained guide for proper setup.

How do I know if my database port is exposed?

Run nmap -p 3306,5432,27017,6379,9200 your-server-ip from an external machine. If any port shows "open," it is accessible from the internet. Alternatively, search your IP on Shodan. Or use our Exposure Checker, which queries Shodan automatically and flags all dangerous exposed ports.

Does changing the default port number improve security?

Marginally. Changing SSH from port 22 to port 2222 reduces automated bot noise by 90%, but it does not protect against targeted attacks. A full port scan with nmap finds non-standard ports in minutes. Treat port changes as noise reduction, not security. The real protection comes from authentication, firewall rules, and service configuration.

Can Cloudflare protect my open ports?

Only for HTTP/HTTPS traffic (ports 80 and 443). Cloudflare proxies web traffic but does not protect other ports. If your MySQL is exposed on port 3306, Cloudflare does not help. Your server's real IP can also be discovered through DNS history, email headers, and other methods, bypassing Cloudflare entirely. Always secure every port at the server/firewall level, regardless of whether you use Cloudflare.

Discover Your Exposed Services

Our Exposure Checker uses Shodan data to instantly find all open ports on your server, identify running services, and flag security risks. No scanning tools needed.

Run Free Exposure Check

The Bottom Line

The only ports that should face the internet are the ones required for your application to function — typically 80 (HTTP) and 443 (HTTPS). Everything else should be firewalled, bound to localhost, or placed in a private network. Database ports, cache services, admin panels, and development tools must never be publicly accessible. Audit your ports regularly, because a single misconfiguration or forgotten debug session can expose your entire infrastructure.

Related tools and articles: Exposure Checker, Port Lookup, IP Lookup, DNS Lookup, Common Port Numbers Guide, SSH Keys Explained, Docker Networking, Kubernetes Basics, and 70+ more free tools.