How do I set up a firewall on my VPS?

VPS 2 min read

A VPS is online from the very first moment and is constantly subjected to automated attempts on every open port. The firewall is one of the first and most important security measures: it controls which ports the server allows traffic through and from where that traffic originates.

The basic principle

Only allow the ports you actually use (for example, port 22 for SSH, and ports 80 and 443 for the web server); block all other incoming connections. Never expose the database (MySQL 3306, PostgreSQL 5432) or internal services (such as Redis) to the internet; if remote access is required, only allow it from your own IP address.

Important: always enable SSH before activating the firewall, otherwise you may lock yourself out of the server.

firewalld (AlmaLinux, Rocky Linux)

On RHEL-based systems, firewalld is the default firewall:

sudo systemctl enable --now firewalld
sudo firewall-cmd --permanent --add-service=ssh
sudo firewall-cmd --permanent --add-service=http
sudo firewall-cmd --permanent --add-service=https
sudo firewall-cmd --reload
sudo firewall-cmd --list-all

A port can only be accessed from a single IP address; for example, MySQL from your own office:

sudo firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="203.0.113.10" port port="3306" protocol="tcp" accept'
sudo firewall-cmd --reload

ufw (Ubuntu, Debian)

sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw allow OpenSSH
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw enable
sudo ufw status verbose

From a single IP address only: sudo ufw allow from 203.0.113.10 to any port 3306 proto tcp. On Debian, install it first: sudo apt install ufw.

IPv6

Our KVM VPSs are also assigned an IPv6 address, so the rules must also apply to IPv6 traffic. Both firewalld and ufw (with the default setting IPV6=yes) apply the rules to both protocols; if you use iptables directly, you will need ip6tables separately for IPv6. This is covered in the article on configuring IPv6 addresses on a VPS.

Docker and the firewall

Docker opens the published ports of containers (e.g. -p 8080:80) using its own iptables rules, and these bypass the ufw rules. If you only wish to access a container’s port locally, bind it to the local address: -p 127.0.0.1:8080:80, and route the traffic through a web server (reverse proxy).

Additional protection

  • Protection against brute-force attacks: fail2ban automatically blocks IP addresses that repeatedly attempt unsuccessful logins; its installation is explained in the article on configuring fail2ban.
  • SSH: key-based access and disabling password-based access; see the article on securing your SSH server.
  • Port change: moving SSH to a different port reduces log traffic, but does not in itself provide protection. On AlmaLinux, the new port must also be enabled in SELinux (semanage port -a -t ssh_port_t -p tcp 2222).

If you have locked yourself out of the server, please open a ticket via the client portal and we will help you regain access.

Back: VPS articles (12)