Technology

Firewall Configuration on VPS Servers with ufw, firewalld and iptables

If you are running a VPS, your firewall is not a nice-to-have add‑on; it is one of the core layers that decides who can talk to your server and how. Whether you host a small WordPress site, a Laravel API, a game server or a full e‑commerce stack, a properly configured firewall often makes the difference between a noisy, constantly attacked machine and a calm, predictable environment. On Linux‑based VPS servers, three tools show up again and again: ufw, firewalld and iptables. Each solves the same problem with a slightly different philosophy and complexity level.

In this guide, we will walk through how these tools fit together, when to use which, and how to build practical, repeatable firewall configurations for real VPS workloads. We will keep the focus on concrete rules and command examples that you can paste, tweak and apply to your own servers at dchost.com or elsewhere. By the end, you should be able to lock down a fresh VPS in minutes, avoid the most common mistakes (like locking yourself out of SSH), and extend your rules safely as your architecture grows.

İçindekiler

How Linux Firewalls Really Work Under the Hood

Before choosing between ufw, firewalld and iptables, it helps to understand what is actually happening inside the kernel. All three are primarily front‑ends to the same packet‑filtering engine.

Netfilter, iptables and nftables in one minute

Linux uses a subsystem called netfilter to inspect, filter and mangle network packets. Tools like iptables and the newer nftables are user‑space interfaces that load rules into netfilter. In many current distributions, even ufw and firewalld end up generating iptables or nftables rules behind the scenes.

Key concepts you will see across all tools:

  • Tables: Groups of rules for different purposes (e.g. filter for allow/deny, nat for port forwarding).
  • Chains: Ordered lists of rules applied at specific stages (e.g. INPUT for packets going into the server, OUTPUT for packets leaving, FORWARD for packets routed through).
  • Policies: Default action if a packet reaches the end of a chain (often ACCEPT or DROP).
  • Stateful filtering: Using connection tracking to allow established and related traffic, instead of manually opening reply ports.

If these feel abstract, keep reading; we will translate them into concrete ufw, firewalld and iptables commands shortly.

Why the firewall is part of a bigger security picture

A firewall is not the only security control on a VPS. You should combine it with:

  • Secure SSH access (keys, non‑root logins, possibly hardware keys).
  • Up‑to‑date software and OS patches.
  • HTTP security headers and TLS best practices for web apps. You can see real examples in our guide on how to correctly set HSTS, CSP and other HTTP security headers.
  • Application‑level protections (WAF, rate limiting, strong authentication).

On a new VPS, we usually touch three areas within the first few hours: system updates, user/SSH hardening and firewall. We covered the full first‑day checklist in detail in our article about the first 24 hours on a new VPS; here we will dive deeper into the firewall part.

Choosing Between ufw, firewalld and iptables

All three tools ultimately manipulate netfilter rules. The main question is how much abstraction and automation you want.

ufw: Simple and ideal for single‑purpose servers

ufw (Uncomplicated Firewall) focuses on ease of use. It is common on Ubuntu and many Debian‑based systems. Pros:

  • Very easy syntax for common tasks like opening ports or whitelisting IP ranges.
  • Good fit for single‑server setups: WordPress, small APIs, game servers, panels.
  • Plays nicely with tools like Fail2ban and many hosting panel scripts.

Limitations:

  • Less expressive than raw iptables for very complex setups.
  • Less integrated with concept of network zones compared to firewalld.

firewalld: Zones and services for dynamic environments

firewalld is the default on many RPM‑based distributions (AlmaLinux, Rocky Linux, CentOS Stream, Fedora). It introduces:

  • Zones (public, internal, dmz, trusted, etc.), each with its own policy.
  • Services defined by name (e.g. http, https, ssh) instead of raw port numbers.
  • Support for dynamic rule reloads without dropping connections.

It is a great fit for VPS setups where you might have multiple interfaces, VLANs, or plan to expand into more complex architectures later.

iptables: Maximum control and complexity

iptables is the classic, low‑level interface. You talk directly in terms of tables, chains and rules. Advantages:

  • Full control: anything netfilter can do, you can express with iptables.
  • Better for advanced needs: custom NAT, load balancers, VPN gateways, or non‑standard protocols.

Downsides:

  • Steeper learning curve and easier to lock yourself out.
  • Large rule sets can get hard to manage without configuration management tools.

On modern systems, iptables may use the nf_tables backend internally, but from your perspective the commands look the same.

Practical rule of thumb

  • Just one web app, simple setup? Use ufw (Ubuntu/Debian) or firewalld (Alma/Rocky) and keep things readable.
  • Multiple networks, custom routing, VPN, or complex NAT? Consider managing core rules with iptables, or at least be comfortable reading generated iptables rules even if you use ufw/firewalld as the front‑end.
  • Want to go even further? We have a separate deep‑dive on nftables for advanced users: our nftables firewall cookbook for VPS.

Core Firewall Strategy for a VPS

Regardless of the tool, the strategy is similar. On most customer VPS setups at dchost.com, we start from a minimal baseline:

  1. Default deny incoming, default allow outgoing.
  2. Explicitly allow SSH from trusted IPs or ranges, with optional rate limiting.
  3. Allow only required application ports (e.g. 80/443 for a web server, 22 for SSH, 25/587/993 for a mail server, etc.).
  4. Enable connection tracking so replies to allowed connections are permitted automatically.
  5. Support IPv6 properly instead of forgetting it open or misconfigured.

This zero‑trust style aligns nicely with what we recommend in broader VPS hardening. If you want a full checklist that also covers SSH, file permissions and web stack settings, our article on securing a VPS server without drama pairs perfectly with this firewall guide.

Configuring ufw on a VPS

Let’s start with ufw because it is the simplest and very common on Ubuntu VPS servers.

Step 1: Install and check status

On Ubuntu, ufw is usually installed by default:

sudo ufw status verbose

If it says “inactive”, that’s normal on a fresh VPS. To install (if missing):

sudo apt update
sudo apt install ufw

Step 2: Set default policies

We recommend:

  • Deny all incoming by default.
  • Allow all outgoing by default (you can tighten this later if needed).
sudo ufw default deny incoming
sudo ufw default allow outgoing

Step 3: Allow SSH before enabling ufw

This part is critical: if you enable ufw without allowing SSH, you will lock yourself out. On most systems, SSH runs on port 22 and ufw knows the OpenSSH profile by name:

sudo ufw allow OpenSSH

If you have moved SSH to a custom port, for example 2222:

sudo ufw allow 2222/tcp

Step 4: Allow web traffic and other services

For a classic HTTPS web server:

sudo ufw allow 80/tcp
sudo ufw allow 443/tcp

For a database that must only be reachable from a specific IP (for example, an application server or your office IP):

sudo ufw allow from 203.0.113.10 to any port 3306 proto tcp

This lets 203.0.113.10 connect to MySQL on port 3306 but blocks everyone else.

Step 5: Enable ufw

Once your rules are in place:

sudo ufw enable

Confirm with:

sudo ufw status numbered

Step 6: Hardening SSH with ufw (optional but recommended)

For publicly reachable SSH, simple rate limiting helps against brute‑force attempts:

sudo ufw limit OpenSSH

This tells ufw to allow SSH but rate‑limit excessive connections from the same IP. For WordPress or PHP apps, we often combine ufw with Fail2ban and application hardening; you can see a firewall‑plus‑Fail2ban example in our WordPress hardening checklist that uses ufw and Fail2ban together.

Step 7: IPv6 with ufw

If your VPS has IPv6 (which we strongly recommend, especially given the ongoing IPv4 scarcity), make sure ufw is configured for it. Edit:

sudo nano /etc/ufw/ufw.conf

Set:

IPV6=yes

Then reload:

sudo ufw disable
sudo ufw enable

From now on, your rules will apply to both IPv4 and IPv6.

Configuring firewalld on a VPS

On AlmaLinux, Rocky Linux and similar systems, firewalld is the preferred tool. It uses zones and services to structure rules.

Step 1: Confirm firewalld is running

sudo systemctl status firewalld

If it is not active:

sudo systemctl enable --now firewalld

Step 2: Check the current zone and interfaces

List active zones:

sudo firewall-cmd --get-active-zones

You will see something like:

public
  interfaces: eth0

The public zone is usually the default for your main interface.

Step 3: Set default target and allow SSH

By default, the public zone uses a reasonably restrictive policy, but let’s be explicit. To ensure we are denying by default and only allowing needed services:

sudo firewall-cmd --zone=public --set-target=DROP

Now, permit SSH in the public zone:

sudo firewall-cmd --zone=public --add-service=ssh --permanent

Reload to apply:

sudo firewall-cmd --reload

Step 4: Allow HTTP/HTTPS and other services

Firewalld ships with service definitions for common protocols. For a web server:

sudo firewall-cmd --zone=public --add-service=http --permanent
sudo firewall-cmd --zone=public --add-service=https --permanent
sudo firewall-cmd --reload

For a custom TCP port, e.g. 8080 for an internal API:

sudo firewall-cmd --zone=public --add-port=8080/tcp --permanent
sudo firewall-cmd --reload

Step 5: Using rich rules for IP‑based restrictions

Firewalld rich rules allow more complex matching. For example, permit MySQL only from 203.0.113.10:

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

Step 6: Zones for private interfaces

If your VPS has multiple interfaces (e.g. one public, one private VLAN), you can attach the private interface to a more permissive zone, such as internal or trusted:

sudo firewall-cmd --zone=internal --change-interface=eth1 --permanent
sudo firewall-cmd --reload

Then allow MySQL freely inside the internal zone:

sudo firewall-cmd --zone=internal --add-service=mysql --permanent
sudo firewall-cmd --reload

This kind of zoning becomes especially useful when you scale out to multiple VPSs (web, database, cache) in the same data center.

Configuring iptables Directly

If you need full control, or your distribution does not ship ufw/firewalld by default, you can configure iptables directly. Be extra careful: a typo can lock you out instantly.

Step 1: Basic IPv4 rules for a web server

This is a minimal set for a single‑interface VPS that should:

  • Allow established/related traffic (replies to existing connections).
  • Allow SSH (22), HTTP (80), HTTPS (443).
  • Drop everything else inbound.

You can test interactively:

sudo iptables -F
sudo iptables -P INPUT DROP
sudo iptables -P FORWARD DROP
sudo iptables -P OUTPUT ACCEPT

# Allow loopback
sudo iptables -A INPUT -i lo -j ACCEPT

# Allow established and related
sudo iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT

# Allow SSH
sudo iptables -A INPUT -p tcp --dport 22 -j ACCEPT

# Allow HTTP/HTTPS
sudo iptables -A INPUT -p tcp --dport 80 -j ACCEPT
sudo iptables -A INPUT -p tcp --dport 443 -j ACCEPT

Check the rules:

sudo iptables -L -n -v

Step 2: Restrict SSH to a specific IP

If you want only one IP to reach SSH:

sudo iptables -A INPUT -p tcp -s 203.0.113.10 --dport 22 -j ACCEPT

and omit the more general --dport 22 accept rule.

Step 3: Persistent iptables rules

On many distributions, iptables rules do not survive a reboot unless you save them. On Debian/Ubuntu, you can use iptables-persistent:

sudo apt install iptables-persistent
sudo netfilter-persistent save

On RHEL‑like systems, you can write rules into a script (e.g. /etc/iptables.rules) and load them via rc.local or a systemd unit on boot. Whatever method you choose, test a reboot window when you still have out‑of‑band access (for example, the VPS console in the dchost.com panel) so you can recover if something goes wrong.

Step 4: Don’t forget IPv6 (ip6tables)

If your VPS is IPv6‑enabled, you must mirror your firewall philosophy for IPv6 as well, otherwise you risk having a locked‑down IPv4 side and a wide‑open IPv6 side.

sudo ip6tables -F
sudo ip6tables -P INPUT DROP
sudo ip6tables -P FORWARD DROP
sudo ip6tables -P OUTPUT ACCEPT

sudo ip6tables -A INPUT -i lo -j ACCEPT
sudo ip6tables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT

sudo ip6tables -A INPUT -p tcp --dport 22 -j ACCEPT
sudo ip6tables -A INPUT -p tcp --dport 80 -j ACCEPT
sudo ip6tables -A INPUT -p tcp --dport 443 -j ACCEPT

If you want a deeper IPv6 perspective, including DNS, email and hosting side considerations, we covered it in our article on IPv6 setup and configuration for VPS servers.

Common Real‑World Scenarios and Tips

Running Docker on a VPS with a firewall

Docker manipulates iptables rules automatically, which can surprise you if you also manage iptables directly. A few guidelines:

  • With ufw or firewalld, it is usually safe to let Docker manage its own NAT and forward rules while you control which ports are exposed via Docker’s -p mappings.
  • If you write raw iptables rules, add them in a way that coexists with Docker chains (e.g. insert your rules at appropriate positions, avoid flushing tables indiscriminately).
  • Consider using a reverse proxy (Nginx, Caddy, Traefik) on the host and expose only that proxy’s ports at the firewall layer.

cPanel, DirectAdmin and other hosting panels

Many control panels install their own firewall helpers or expect certain ports to stay open (panel ports, mail ports, FTP/SFTP ports, etc.). When you use a panel on a VPS from dchost.com, make a list of:

  • Panel access ports (e.g. 2083 for cPanel’s HTTPS, depending on configuration).
  • Mail ports if you run your own mail server (25, 465, 587, 993, 995, etc.).
  • Passive FTP ranges if you still support FTP (ideally, use SFTP only).

Then explicitly allow only those ports you actually use. If you are moving away from FTP to SFTP for security, our step‑by‑step guide on switching from FTP to SFTP pairs well with tightening your firewall rules.

Rate limiting and brute‑force protection

Some attacks are not just about reaching a port, but about hammering it with repeated attempts. Your firewall can help:

  • ufw has the limit option for basic SSH rate limiting.
  • iptables can use the recent or hashlimit modules for more advanced rules.
  • You can combine firewall rules with Fail2ban to dynamically ban misbehaving IPs based on log patterns.

For HTTP‑level protections (bots, abusive crawlers, API overuse), you should complement your server‑side firewall with proper rate limiting at the web stack or CDN level. We covered real‑world strategies in our article on rate limiting for APIs and microservices with Nginx and Cloudflare.

Logging and monitoring your firewall

A firewall rule that drops traffic silently is only half useful; you also want visibility. Depending on your tool:

  • ufw can log to /var/log/ufw.log when logging is enabled (sudo ufw logging on).
  • firewalld can log via firewall-cmd --set-log-denied=all (or unicast/broadcast), integrating with systemd journals.
  • iptables can use the LOG target to send drops to syslog.

Once logs are flowing, integrate them into your monitoring stack. We have a dedicated playbook for this: VPS log management with Grafana Loki and Promtail shows how to centralise logs and build useful alerts.

Verification, Testing and Safe Change Management

Any firewall change can cut off legitimate traffic as easily as it blocks attacks. A small, disciplined workflow helps keep things safe.

Always test connectivity after changes

  • From your own machine, verify SSH and panel access after each rule change.
  • Use tools like curl -v or nc -vz to test specific ports from outside.
  • From the server, use ss -tulpn or netstat (if installed) to confirm which ports are actually listening.

Keep a rescue window open

When applying risky firewall changes on a production VPS:

  • Keep an active SSH session open while you experiment in another session.
  • On dchost.com VPS plans, have the console/serial access ready in your panel in case you lock out SSH.
  • Consider time‑limited rules first. Some admins use simple scripts that rollback to a known‑good ruleset if they do not confirm within N minutes.

Document and version your firewall rules

Once your firewall becomes more than a handful of rules, treat it like code:

  • Store your ufw/app profiles, firewalld zone definitions or iptables scripts in Git.
  • Write comments explaining why a rule exists, not just what it does.
  • Update documentation when services are added or removed; pruned firewall rules reduce attack surface.

Bringing It All Together on dchost.com VPS Servers

When you spin up a new VPS with us, you control the operating system, panel and stack, but the network perimeter is shared: our data center edge, DDoS protection and routing policies form the outer rings. Your firewall on the VPS is the inner, application‑aware ring you can fully own.

A sensible progression for many customers looks like this:

  1. Start on Ubuntu or Debian with ufw, open only SSH and HTTP/HTTPS, and deploy your first site.
  2. As you grow into multi‑service stacks (separate database, cache, internal APIs), adopt firewalld zones or more structured ufw rules.
  3. For advanced setups (custom VPN, internal load balancers, multi‑network routing), maintain a curated iptables (or nftables) ruleset and integrate it into your configuration management.

Throughout that journey, you do not need to guess or reinvent everything on your own. We keep publishing practical, real‑world examples on our blog—covering everything from firewall design and SSH hardening to performance tuning and HTTPS security—so that each new VPS feels more like a repeatable pattern than a one‑off experiment.

If you are planning a new project and want to align firewall design with hosting architecture (single VPS, multi‑VPS, or a mix of VPS and colocation), you can always start with our articles on choosing between dedicated servers and VPS and on managed vs unmanaged VPS responsibilities, then layer this firewall guide on top.

The important part is consistency: choose a tool (ufw, firewalld or iptables), define a minimal, documented baseline, and evolve it carefully as your VPS and applications grow. With that mindset, your firewall stops being an obscure, fragile script and becomes a predictable, trusted component of your hosting stack.

Frequently Asked Questions

None is universally “better”; they target different comfort levels and use cases. ufw is ideal if you want a simple, readable syntax on Ubuntu or Debian and you mainly run one or two services (for example, a web server and SSH). firewalld suits AlmaLinux / Rocky Linux and more complex setups because it introduces zones and named services, and can reload rules dynamically. iptables gives you the most control, making it suitable for custom NAT, VPN gateways or complex routing, but it is easier to misconfigure. Many admins start with ufw or firewalld and only move to direct iptables when their architecture demands it.

Before enabling any firewall (ufw, firewalld or iptables), always add an explicit rule that allows SSH from your current IP or from the networks you trust. With ufw, run "sudo ufw allow OpenSSH" (or the custom port you use) prior to "sudo ufw enable". With firewalld, ensure the ssh service is allowed in your active zone using "firewall-cmd --add-service=ssh --permanent" and then reload. With iptables, add an INPUT rule that accepts TCP on your SSH port before setting the default policy to DROP. Keep a second SSH session open while applying changes, and know how to access the VPS console in your provider panel in case you need to roll back.

Yes, if your VPS has IPv6, you must treat it as a first‑class citizen in your firewall design. Otherwise, you can end up with a well‑locked IPv4 surface but a wide‑open IPv6 interface that attackers can reach. With ufw, ensure IPV6=yes in /etc/ufw/ufw.conf so rules apply to both families. With firewalld, IPv4 and IPv6 are handled within the same zone definitions, but you should still verify that your services and drops behave as expected over IPv6. With iptables, you need a separate ruleset using ip6tables. The pattern is the same—default DROP on INPUT, allow established traffic, then explicitly allow SSH, HTTP/HTTPS and anything else you genuinely need.

A VPS firewall controls traffic at the network and transport layers: IP addresses, ports and basic connection properties. A Web Application Firewall (WAF) such as ModSecurity or a CDN‑side WAF inspects HTTP traffic in detail (URLs, headers, payloads) to block SQL injection, XSS and other application‑layer attacks. The best practice is to use both layers together. Your VPS firewall exposes only ports you actually use (typically 80/443 and SSH) and may restrict management ports by IP. The WAF then protects your web application logic on those allowed ports. This layered approach complements TLS, HTTP security headers and rate limiting for a much stronger overall security posture.

Manual management is fine for one or two small VPS servers, as long as you document your rules carefully. But once you have multiple environments (staging, production) or several VPS instances, automation quickly becomes worthwhile. You can store ufw, firewalld or iptables configurations in Git, apply them using Ansible or similar tools, and review firewall changes like code. Automation also helps ensure new servers follow the same baseline (default‑deny inbound, explicit SSH and service rules, IPv6 parity). When combined with centralised logging and monitoring, it becomes much easier to detect drift, troubleshoot connectivity issues and keep your firewall in sync with application changes.