A host firewall decides which ports on the server accept connections from where. Without one, every service that happens to be listening — a database, a cache, a panel — is reachable by anyone who finds it. With one, the server accepts exactly the traffic it serves and drops the rest. Ubuntu and Debian use ufw; AlmaLinux and Rocky use firewalld. Both take ten minutes.
Before you start
Know what the server needs to accept. For a web server with SSH admin: 22, 80, 443. Add 25/465/587/993 if it hosts mail, 8443 for Plesk, 53 for DNS. What each port is for: TCP/IP ports every hosting admin should know.
And keep your current SSH session open until you have confirmed a second one connects through the new rules.
ufw (Ubuntu / Debian)
sudo apt install ufw -y
sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw allow OpenSSH # 22
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw enable
sudo ufw status verboseRestrict SSH to your own address (find it with curl -s ifconfig.me):
sudo ufw delete allow OpenSSH
sudo ufw allow from 198.51.100.7 to any port 22 proto tcpRate-limit SSH instead, if your IP changes — more than six connections in 30 seconds from one address gets dropped:
sudo ufw limit OpenSSHMail server and Plesk:
sudo ufw allow 25,465,587,993/tcp
sudo ufw allow from 198.51.100.7 to any port 8443 proto tcpApplication profiles (sudo ufw app list) group ports by name — Nginx Full, Postfix, Dovecot IMAP. Delete a rule with sudo ufw delete <number> after sudo ufw status numbered. Logging: sudo ufw logging on, entries in /var/log/ufw.log.
IPv6 is covered automatically as long as IPV6=yes in /etc/default/ufw (the default).
firewalld (AlmaLinux / Rocky)
firewalld is installed and running by default. It thinks in zones; the public zone applies to the server's interface.
sudo firewall-cmd --get-active-zones
sudo firewall-cmd --list-allAllow services (named) or ports:
sudo firewall-cmd --permanent --add-service={http,https}
sudo firewall-cmd --permanent --add-service={smtp,smtps,submission,imaps}
sudo firewall-cmd --permanent --add-port=8443/tcp
sudo firewall-cmd --reload--permanent writes the rule for after reboot; --reload applies it now. Without --permanent, the rule vanishes on reload.
Restrict SSH to an address with a rich rule, then remove the open service:
sudo firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="198.51.100.7" service name="ssh" accept'
sudo firewall-cmd --permanent --remove-service=ssh
sudo firewall-cmd --reloadRemove a port: --remove-port=8443/tcp. See what is set: --list-all.
Plesk's own firewall
Plesk has a Firewall extension (Tools & Settings → Firewall) that manages iptables with a rules editor and a Plesk-aware default set that already knows about the panel, mail and web ports. On a Plesk server, use it rather than ufw/firewalld directly, so the panel's rules and yours do not fight.
Things that are not open, and should not be
After configuring, check what is listening and compare with what is allowed:
sudo ss -tulpnMariaDB on 0.0.0.0:3306, Redis on 0.0.0.0:6379, or PHP-FPM on a TCP port should be bound to 127.0.0.1 in their own configs — the firewall blocking them is a second line of defence, not the first.
Test from outside
From another machine:
nmap -p 22,80,443,3306,6379,8443 203.0.113.10open for 80 and 443, filtered for everything else (or open for 22 only from your IP). If 3306 shows open, the firewall is not doing its job — check the ordering, or whether Docker has added its own rules ahead of yours (Docker bypasses ufw by default; the fix is DOCKER-USER chain rules or binding container ports to 127.0.0.1).
Provider firewalls
Many VPS providers offer a firewall in their panel that filters traffic before it reaches the VM. Use both: the provider's for the coarse rules (SSH from the office only), the host's for the fine ones. The provider's layer also keeps unwanted traffic off your bandwidth.
A firewall is one of the ten items in hardening a new VPS; on a VPSPioneer managed VPS it is configured before handover with the SSH and panel ports restricted to the addresses you give us.