Skip to content
Back to Blog
Security10 min read

Server Hardening Checklist 2026: [Solved] 9 Open Ports

Nine specific ports attackers scan first and the exact commands to close them. Lock down your VPS before automated bots find exposed services.

Written by Abdul AbrorTechnical Hosting Support Engineer
Server Hardening Checklist 2026: [Solved] 9 Open Ports
On this page

Automated scanners hit every new VPS within minutes of provisioning. They look for the same nine ports, always in the same order, hoping you left a default service exposed.

I've restored dozens of servers after compromise, and the entry point is usually one of these: an outdated panel listening on 2082, an open MySQL port, or Telnet still running because nobody thought to check. This checklist gives you the exact commands to close them and the firewall rules to keep them closed.

Why these nine ports matter

Attackers don't waste time. Mass scans target ports known to run services with frequent CVEs or weak defaults. If you're running a hosting server, half these ports are open right now unless you've explicitly closed them.

Check what's listening before you start:

sudo ss -tulnp

That shows every open port and the process behind it. Compare it against this list.

1. Close Telnet (port 23)

Telnet sends credentials in plaintext. There is no reason to run it on a production server in 2026.

Disable the service:

sudo systemctl stop telnet.socket
sudo systemctl disable telnet.socket

If the package is installed, remove it:

sudo yum remove telnet-server  # RHEL/CentOS
sudo apt remove telnetd         # Debian/Ubuntu

Block the port in your firewall:

sudo firewall-cmd --permanent --remove-service=telnet
sudo firewall-cmd --reload

SSH replaced Telnet decades ago. Use that.

2. Restrict SSH (port 22)

You need SSH, but you don't need it open to the world. Changing the port helps a little; restricting source IPs helps more.

Edit /etc/ssh/sshd_config:

Port 2299
PermitRootLogin no
PasswordAuthentication no
AllowUsers youruser

Restart SSH:

sudo systemctl restart sshd

Update your firewall to allow the new port and your office IP only:

sudo firewall-cmd --permanent --remove-service=ssh
sudo firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="203.0.113.5/32" port protocol="tcp" port="2299" accept'
sudo firewall-cmd --reload

Key-based auth is non-negotiable. If you're still using passwords, generate a key pair today.

3. Close FTP (ports 20, 21)

FTP is unencrypted and complicated to secure behind NAT. SFTP does everything FTP does, using your existing SSH setup.

Stop and disable FTP:

sudo systemctl stop vsftpd
sudo systemctl disable vsftpd

Remove the package if you won't use it:

sudo yum remove vsftpd

Block both ports:

sudo firewall-cmd --permanent --remove-service=ftp
sudo firewall-cmd --reload

If clients insist on FTP, give them SFTP credentials instead. It's the same workflow without the cleartext credentials.

4. Bind MySQL to localhost (port 3306)

MySQL listens on all interfaces by default in some distros. That's a problem if your database holds customer data and sits on a public IP.

Edit /etc/my.cnf or /etc/mysql/my.cnf:

[mysqld]
bind-address = 127.0.0.1

Restart MySQL:

sudo systemctl restart mysqld

Verify it's only listening locally:

sudo ss -tlnp | grep 3306

You should see 127.0.0.1:3306, not 0.0.0.0:3306. If your app server and database server are separate, use a private VLAN and bind to the private IP instead.

5. Disable remote PostgreSQL (port 5432)

Same principle as MySQL. PostgreSQL often ships with remote access enabled if you installed it from a repository that targets development environments.

Edit /var/lib/pgsql/data/postgresql.conf:

listen_addresses = 'localhost'

Restart PostgreSQL:

sudo systemctl restart postgresql

Check pg_hba.conf and remove any lines allowing remote hosts unless you're running a replica. The default trust authentication for local connections is fine; remote trust is not.

6. Close cPanel/WHM HTTP ports (2082, 2086, 2095)

If you're running cPanel, you need HTTPS access (2083, 2087, 2096). You don't need the HTTP variants, and leaving them open exposes session cookies to interception.

Disable HTTP access in WHM:

  1. Go to WHM > Tweak Settings
  2. Under Redirection, enable Always redirect users to the SSL/TLS ports
  3. Save

Then block the HTTP ports:

sudo firewall-cmd --permanent --remove-port=2082/tcp
sudo firewall-cmd --permanent --remove-port=2086/tcp
sudo firewall-cmd --permanent --remove-port=2095/tcp
sudo firewall-cmd --reload

Users will be redirected to HTTPS automatically. No reason to leave the cleartext route available.

7. Turn off DNS recursion or bind to private IPs (port 53)

An open recursive resolver gets abused for DDoS amplification attacks within hours. If you're running BIND or another DNS server, it should answer only for your own zones.

Edit /etc/named.conf:

options {
    recursion no;
    allow-query { localhost; 10.0.0.0/8; };
};

Restart named:

sudo systemctl restart named

If you're using the server's DNS only for internal resolution, bind it to the private interface. If you're serving public DNS, disable recursion and restrict queries to your authoritative zones.

Test from an external IP to confirm recursion is off:

dig @your-server-ip example.com

You should get a REFUSED response.

8. Restrict SMTP or disable relay (port 25)

Port 25 is the number one target for spammers. If you're running a mail server, it needs to accept inbound mail. It should never relay outbound mail for unauthenticated users.

In Postfix, check /etc/postfix/main.cf:

smtpd_relay_restrictions = permit_mynetworks, permit_sasl_authenticated, reject_unauth_destination
mynetworks = 127.0.0.0/8 [::1]/128

Reload Postfix:

sudo systemctl reload postfix

If you're not running a mail server at all, stop it:

sudo systemctl stop postfix
sudo systemctl disable postfix

Block port 25 outbound on application servers to prevent compromised scripts from sending spam:

sudo firewall-cmd --permanent --direct --add-rule ipv4 filter OUTPUT 0 -p tcp --dport 25 -j REJECT
sudo firewall-cmd --reload

9. Close or restrict RDP if running Windows (port 3389)

If you're hardening a Windows VPS, RDP is the SSH equivalent. It needs similar restrictions.

Change the default port by editing the registry:

  1. Open regedit
  2. Navigate to HKLM\System\CurrentControlSet\Control\Terminal Server\WinStations\RDP-Tcp
  3. Change PortNumber to a high port like 49152
  4. Restart the server

Restrict access by IP in Windows Firewall:

  1. Open Windows Defender Firewall with Advanced Security
  2. Find the Remote Desktop inbound rule
  3. Edit Scope and set Remote IP address to your office IP

Enable Network Level Authentication:

  1. Open System Properties > Remote
  2. Check Allow connections only from computers running Remote Desktop with Network Level Authentication

Brute-force RDP attacks are constant. Restricting by IP cuts them to zero.

What about UFW and iptables?

I used firewall-cmd in the examples because it's the default on RHEL-based systems. If you're on Ubuntu or Debian, translate the rules to UFW or iptables.

UFW equivalent for blocking a port:

sudo ufw deny 23/tcp
sudo ufw reload

Iptables equivalent:

sudo iptables -A INPUT -p tcp --dport 23 -j DROP
sudo iptables-save | sudo tee /etc/iptables/rules.v4

The firewall tool doesn't matter. What matters is that you have rules in place and you've tested them.

Testing your changes

After you close ports, scan your own server from an external IP. Use nmap from your workstation:

nmap -p- your-server-ip

That scans all 65535 ports. It takes a few minutes. You should see only the services you intended to expose: HTTPS, SSH on a custom port, and maybe SMTP if you're running mail.

If something you need is now blocked, adjust the firewall rules. If something you didn't expect is open, figure out what's listening and decide whether to close the service or restrict it by IP.

Run the scan monthly. Services get installed, configs get reset, and old ports come back.

Start with the network scan

Run ss -tulnp right now and see what's listening. Pick the three highest-risk ports from this list and close them today. Then schedule a monthly review to make sure they stay closed and nothing new has appeared.

Automated scanners never stop. But if the ports they're looking for aren't there, they move on to the next target.

FAQ

Do I need to close these ports if I'm behind Cloudflare?

Cloudflare proxies HTTP/HTTPS traffic. It doesn't hide your origin IP, and it doesn't protect SSH, MySQL, or any other non-web service. Close the ports regardless.

Will changing the SSH port really help?

It stops low-effort bots. Attackers who care will find your SSH port in seconds, but you'll eliminate 99% of the log noise and brute-force attempts. Combine it with key-auth and IP restrictions for real security.

What if I need remote database access?

Use an SSH tunnel. Connect to the server over SSH, then forward the database port to your local machine. That gives you encrypted remote access without exposing the database to the internet.

Should I block ping (ICMP)?

No. Blocking ICMP breaks path MTU discovery and makes troubleshooting harder. It doesn't improve security in any meaningful way.