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:
- Go to WHM > Tweak Settings
- Under Redirection, enable Always redirect users to the SSL/TLS ports
- 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:
- Open
regedit - Navigate to
HKLM\System\CurrentControlSet\Control\Terminal Server\WinStations\RDP-Tcp - Change
PortNumberto a high port like49152 - Restart the server
Restrict access by IP in Windows Firewall:
- Open Windows Defender Firewall with Advanced Security
- Find the Remote Desktop inbound rule
- Edit Scope and set Remote IP address to your office IP
Enable Network Level Authentication:
- Open System Properties > Remote
- 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.
![Server Hardening Checklist 2026: [Solved] 9 Open Ports](/images/blog/server-hardening-checklist-2026-solved-9-open-ports.jpg)