AI QA Monkey
AI Security Intelligence
Fix Guide

Open Port Remediation Playbook: Close Risky Services Fast

Port findings become real risk when they expose weakly controlled services. This playbook helps teams prioritize and remediate quickly while keeping critical business services available.

Step 1: classify every open port

  • Required public service (e.g., 443).
  • Required but restricted service (e.g., admin access via allowlisted IP).
  • Unnecessary exposure (close immediately).

Step 2: prioritize by exploitability

  • Credential brute-force targets (SSH/RDP).
  • Direct data services (MySQL/Postgres/Redis/MongoDB).
  • Misconfigured admin interfaces and legacy protocols.

Step 3: apply remediation controls

  • Disable services not required by architecture.
  • Enforce firewall deny-by-default policy.
  • Restrict access by IP or VPN.
  • Rotate credentials and enforce MFA where applicable.
# Remediation runbook
1) Inventory open ports and service owners
2) Close non-essential exposures
3) Restrict essential admin ports
4) Re-scan externally
5) Record evidence + change ticket

Firewall remediation commands by OS

# Linux — iptables
iptables -A INPUT -p tcp --dport 3306 -j DROP   # Block MySQL
iptables -A INPUT -p tcp --dport 6379 -j DROP   # Block Redis
iptables -A INPUT -p tcp --dport 27017 -j DROP  # Block MongoDB
iptables -A INPUT -p tcp --dport 5432 -j DROP   # Block PostgreSQL
iptables-save > /etc/iptables/rules.v4

# Linux — UFW
ufw deny 3306
ufw deny 6379
ufw deny 27017
ufw status verbose

# Restrict SSH to trusted IP only
ufw allow from YOUR.IP.ADDRESS to any port 22
ufw deny 22

Cloud provider security group rules

  • AWS EC2: Remove the inbound rule for the port in the Security Group console. Use VPC Security Groups to limit database ports to the application subnet only.
  • GCP: Remove the Firewall rule in VPC Networks > Firewall. Add a rule allowing only internal RFC1918 ranges for database ports.
  • Azure: In Network Security Group, delete the inbound rule and add a rule scoped to your application subnet.

Highest-risk ports to close immediately

  • 3389 (RDP): Never expose publicly. Use VPN + IP allowlist. Brute-forced within minutes of exposure.
  • 3306 (MySQL) / 5432 (PostgreSQL): Should only accept connections from application server subnet, never from 0.0.0.0/0.
  • 6379 (Redis): No authentication by default. Exposed Redis instances are trivially exploited for data theft and RCE.
  • 27017 (MongoDB): Historically exposed without auth. Immediately restrict to internal subnet.
  • 21 (FTP): Transmits credentials in plaintext. Replace with SFTP (port 22) and close FTP entirely.

Restricting SSH to prevent brute-force attacks

SSH (port 22) is the most-attacked service on the public internet. Exposed SSH with password authentication receives thousands of brute-force attempts per day within hours of a server going live.

  • Disable password authentication entirely: In /etc/ssh/sshd_config, set PasswordAuthentication no and PubkeyAuthentication yes. Only SSH key pairs should authenticate.
  • Change the default port: Moving SSH from 22 to a non-standard high port (e.g., 2222, 49200) eliminates the vast majority of automated scanners. Not a substitute for key auth, but reduces log noise dramatically.
  • Use AllowUsers or AllowGroups: Restrict SSH login to specific usernames. AllowUsers deploy ubuntu in sshd_config blocks all other system accounts from SSH access even if compromised.
  • Use fail2ban: Automatically ban IPs after repeated failed authentication attempts. Configure with a short ban time (10 minutes) and a low threshold (3 failures).
# /etc/ssh/sshd_config hardened configuration
Port 49200                     # Non-default port
PermitRootLogin no             # Never login as root
PasswordAuthentication no      # Key auth only
PubkeyAuthentication yes
AllowUsers deploy ubuntu       # Allowlisted users only
MaxAuthTries 3                 # Fail fast
ClientAliveInterval 300
ClientAliveCountMax 2
systemctl restart sshd

Database port hardening in detail

Database services should never accept connections from the public internet. The impact of an exposed database service with default credentials is immediate and catastrophic.

  • MySQL/MariaDB (3306): In /etc/mysql/mysql.conf.d/mysqld.cnf, set bind-address = 127.0.0.1 to accept only local connections. For multi-server setups, bind to the private network IP only.
  • PostgreSQL (5432): In postgresql.conf, set listen_addresses = 'localhost' or the private IP. In pg_hba.conf, restrict access to the application server IP only.
  • Redis (6379): Set bind 127.0.0.1 in redis.conf AND set a strong password with requirepass yourpassword. Disable the CONFIG command if not needed: rename-command CONFIG "".
  • MongoDB (27017): Enable authentication in mongod.conf: security: authorization: enabled. Bind to 127.0.0.1 only. Never use the default unauthenticated mode.

Verification after remediation

Firewall rules and service configuration changes do not always behave as expected. External verification is the only way to confirm that ports are actually closed from an attacker's perspective.

  • Run AI QA Monkey Open Port Scanner from outside your network immediately after applying changes.
  • Use nmap -sV -p 1-65535 yourdomain.com from an external server for comprehensive verification.
  • Re-scan after every infrastructure change: new EC2 instance, updated security group, load balancer addition, or cloud provider migration.
  • Document all open ports and their business justification. Review the list quarterly and close any port that no longer has a documented owner.

Building a port exposure policy

Ad-hoc remediation is not sustainable. A documented port policy prevents the same findings from recurring after every infrastructure change.

  • Approved public ports: 80 (HTTP redirect), 443 (HTTPS), and any required public APIs. All others are blocked by default.
  • Approved internal-only ports: Database ports, admin interfaces, monitoring (e.g., 9090 Prometheus), internal APIs. Restricted to private subnet CIDR or VPN IP range.
  • Change management requirement: Any new port opening requires a ticket with business justification, security review, and expiration date if temporary.
  • Automated enforcement: Use infrastructure-as-code (Terraform, Pulumi) to define security groups. Any manual change that deviates from the defined state triggers an alert.

Related guides

Verify port closure now

Run an external port scan to confirm all risky services are closed and get prioritized remediation for any remaining exposure.

Run Open Port Scan

Check Your Website Right Now

Run a free automated security scan — 75 checks in 60 seconds. No signup required.

Run Free Security Scan →