Technology

VPS Firewall Configuration: 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 reduces unnecessary network exposure; services you allow through still need their own protections. 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 to adapt to your server’s services, SSH port and existing firewall configuration, at dchost.com or elsewhere. The aim is to build a minimal firewall baseline, avoid common mistakes such as locking yourself out of SSH, and extend your rules as your architecture grows.

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 underlying these tools, using iptables terminology:

  • 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 built‑in 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 and suitable authentication).
  • Up-to-date software and OS patches.
  • HTTP security headers and TLS; see our HSTS and CSP guide.
  • Application-level protections such as a WAF, rate limiting and strong authentication.

On a new VPS, prioritize three areas: system updates, user/SSH hardening and the 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 such as WordPress, small APIs and game servers.
  • For Fail2ban or a hosting panel, verify the supported firewall integration rather than assuming compatibility with ufw.

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 associate interfaces and sources with a policy.
  • Services define named port/protocol allowances; inspect their contents.
  • Runtime and permanent configuration are separate. Reload keeps connection state but replaces runtime configuration with permanent configuration; it is not a guarantee of uninterrupted access.

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: Low‑level control and complexity

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

  • Direct control over iptables tables, chains and rules.
  • 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 --version reports whether the command uses legacy or nf_tables. Check both IPv4 and IPv6 command families, keep the backend consistent and do not change it during a firewall rollout. UFW uses iptables; an iptables-nft compatibility frontend is distinct from writing native nft rules.

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 or nftables rules, depending on the backend, 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. A minimal baseline for a typical VPS is:

  • Restrict incoming access and allow outgoing traffic for this host baseline; account for essential ICMP/ICMPv6.
  • Choose one SSH policy up front: trusted source addresses, or public access with connection limiting. Adding a narrow allowance does not remove an existing broad one.
  • Allow only required services. Typical web ports are 80/tcp and 443/tcp; if this server is the HTTP/3 endpoint, also allow its listening UDP port, commonly 443/udp.
  • Allow established/related traffic but test fresh connections: a surviving session does not prove that new access works.
  • Verify IPv4 and IPv6 separately. Source-specific rules apply only to their address family.

This default-deny inbound approach is one part of 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

This UFW section uses Ubuntu 24.04 LTS and ufw 0.36.2 syntax. The walkthrough assumes ufw will manage a new host and is currently inactive; do not apply all three tool walkthroughs to the same server. If another tool or hosting panel already manages the rules, use its supported workflow instead. Before changing remote access rules, confirm you have a working console or other recovery path independent of SSH. All following command examples use a root shell; use sudo to obtain that shell if required.

Step 1: Install and check status

Check whether ufw is installed and active; image defaults vary:

ufw version
ufw status verbose

If the package is missing, review the installation before continuing:

apt update
apt install ufw

Before creating rules, check IPV6=yes in /etc/default/ufw. This enables UFW’s IPv6 rule handling; it does not configure an IPv6 address or route in the operating system.

Step 2: Set default policies

The sequence assumes a new, inactive UFW configuration. On an active host, first inspect existing rules and protect the actual management path with tested recovery access; do not blindly change its policy. For the new host:

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

Step 3: Choose SSH access before enabling UFW

This example uses connection limiting for publicly reachable SSH. If a fixed management source policy is appropriate, use the IPv4/IPv6 source rules below instead of a broad limit/allow rule. Check the real listening port. Application profiles such as OpenSSH must be installed and have matching ports before they can be used.

ufw limit 22/tcp

For SSH already listening on 2222/tcp, use this rule instead of the port 22 rule. This firewall rule does not change SSH’s listening port.

ufw limit 2222/tcp

Step 4: Allow web traffic and other services

For a classic HTTPS web server:

ufw allow 80/tcp
ufw allow 443/tcp

Prefer a local socket, private network or VPN for a database. If a specific client must connect over the host interface, replace the documentation address with its actual authorized source address:

ufw allow from 203.0.113.10 to any port 3306 proto tcp

This allows the example IPv4 address 203.0.113.10 to connect to MySQL on TCP port 3306. Replace it with the authorized client’s address. Other clients are blocked only if the default-deny policy is active and no other rule permits their access.

Step 5: Enable ufw

Check the actual SSH port, source policy, IPv6 setting and required services, then enable the new host configuration. Keep the original session and independent console available while testing a fresh connection from another client:

ufw enable

Confirm with:

ufw status numbered
ufw status verbose
ufw show raw

Step 6: Source-restricted SSH and existing broad rules

UFW 0.36.2 connection limiting denies an address that attempts to initiate six or more connections within 30 seconds. It is not authentication or a comprehensive brute-force defense. To restrict SSH to fixed management sources instead, use the following pair in place of the public limit/allow rule. Replace both documentation addresses and port 22 with your actual management sources and listening port. Omit the IPv6 SSH rule if IPv6 management is not needed.

ufw allow from 203.0.113.10 to any port 22 proto tcp
ufw allow from 2001:db8::10 to any port 22 proto tcp

On an active host, add the source rules first with recovery access ready, then remove the old broad allow/limit/profile rules. The first matching rule wins; a broad allowance remains a separate access path even after a narrower one is added. Numbered deletion removes only the selected IPv4 or IPv6 row and shifts later numbers, so inspect the list after each deletion. Test fresh permitted and forbidden connections before saving the change record. For WordPress or PHP apps, ufw can be combined with Fail2ban and application hardening; verify the supported integration described in our WordPress hardening checklist.

Step 7: IPv6 with ufw

The setting checked before rule creation belongs in /etc/default/ufw, with the uppercase key shown below. If enabling IPv6 handling on an existing configuration, review or recreate missing IPv6 counterparts before relying on them. Inspect the file with your editor:

nano /etc/default/ufw

Set:

IPV6=yes

With rules and recovery ready, reload an active UFW configuration after an approved configuration change; disabling protection first is unnecessary for this workflow:

ufw reload

After IPv6 support is correctly configured, inspect the active IPv4 and IPv6 rules separately. Rules restricted to an IPv4 address, such as the MySQL example above, do not authorize an IPv6 client.

Configuring firewalld on a VPS

On the RHEL 9 family, firewalld is a common choice. This section uses the 1.3.x command interface. Verify the installed version and backend; current upstream documentation lists nftables as the default backend.

Step 1: Confirm firewalld is running

firewall-cmd --version
systemctl status firewalld

If it is missing, review installation of the distribution’s firewalld package. If it is installed but not active, review its saved rules and confirm that they permit your actual SSH port before starting it. firewall-offline-cmd --check-config checks saved configuration syntax/semantics, not connectivity. Keep tested console access available while activating the firewall:

systemctl enable --now firewalld

Step 2: Check the current zone and interfaces

List active zones:

firewall-cmd --get-default-zone
firewall-cmd --get-active-zones

A hypothetical output is:

public
  interfaces: eth0

The following examples assume that the public-facing interface is assigned to public. Use the zone reported for your interface rather than assuming this example matches your server.

Step 3: Inspect the zone target and permit management sources

The runtime-first sequence below assumes the active public zone already uses target default: it behaves like REJECT for unmatched traffic while implicitly allowing ICMP. Review existing services, ports, sources, rich rules and policies too. A target change does not remove other allowances. The target option is permanent-only; inspect it with:

firewall-cmd --zone=public --list-all
firewall-cmd --permanent --zone=public --get-target

Do not change a working zone to DROP just to match a generic checklist: ICMPv6 and recovery consequences need separate review. If correcting a different saved target, firewall-cmd --permanent --zone=public --set-target=default is valid only in permanent configuration; stage every needed saved access rule, run --check-config, and plan the reload with console recovery. Do not silently apply that target change inside the following runtime-first example.

For this example, replace the documentation addresses with actual IPv4 and IPv6 management sources and port 22 with the SSH listening port. Omit the IPv6 SSH allowance if it is not needed. Add these runtime rules:

firewall-cmd --zone=public --add-rich-rule='rule family="ipv4" source address="203.0.113.10/32" port port="22" protocol="tcp" accept'
firewall-cmd --zone=public --add-rich-rule='rule family="ipv6" source address="2001:db8::10/128" port port="22" protocol="tcp" accept'

With the new source allowances in place and console access ready, remove existing broad SSH service/port allowances. The standard public zone may already allow the ssh service. Run the matching removal only when that broad allowance actually exists:

firewall-cmd --zone=public --remove-service=ssh
firewall-cmd --zone=public --remove-port=22/tcp

Inspect other zones, policies and rich rules for additional broad access paths. Then test fresh SSH connections from authorized sources and rejection from unauthorized ones over each family. For custom SSH port 2222, substitute that port in both rich rules; do not add an extra broad 2222/tcp rule. If a broad 2222/tcp allowance already exists, remove that actual allowance with firewall-cmd --zone=public --remove-port=2222/tcp; removing port 22 alone does not restrict the custom port.

Step 4: Allow HTTP/HTTPS and other services

Add web service allowances to runtime only when the host serves them:

firewall-cmd --zone=public --add-service=http
firewall-cmd --zone=public --add-service=https

For a custom TCP service intended to be reachable through the public zone, for example on port 8080:

firewall-cmd --zone=public --add-port=8080/tcp

Step 5: Using rich rules for IP‑based restrictions

Firewalld rich rules allow more complex matching. This example permits MySQL from 203.0.113.10; replace it with the authorized client’s IPv4 address. Exclusive access also requires a restrictive zone policy and no broader MySQL allowances, including over IPv6.

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

Step 6: Zones for private interfaces

Review how the interface is managed before changing its binding. If your VPS has separate public and private interfaces, you can assign the private interface to internal and review that zone’s allowed services. Replace eth1 below with the actual private interface; a private VLAN alone is not a reason to permit every service.

firewall-cmd --zone=internal --change-interface=eth1

NetworkManager supplies assignments from connection profiles; ensure that the saved profile matches the intended zone and test reconnect/reboot behavior. Never move the public management interface into another zone as an incidental part of this example.

If every client reaching the internal zone is authorized to access MySQL, allow the service there. Otherwise, use client-specific restrictions instead of this zone-wide allowance:

firewall-cmd --zone=internal --add-service=mysql

Once the whole runtime policy, zone bindings and both address families pass permitted/forbidden connection tests, save it. --runtime-to-permanent overwrites the entire permanent configuration with runtime; inspect unrelated runtime changes first. Reload then loads that saved state:

firewall-cmd --runtime-to-permanent &&
firewall-cmd --check-config &&
firewall-cmd --reload &&
firewall-cmd --zone=public --list-all

Repeat fresh connection tests after reload and during a planned reboot. A surviving established session is not enough. A private zone is a grouping mechanism, not proof that all clients in it are trusted.

Configuring iptables Directly

This example uses iptables 1.8.10 syntax, available in Ubuntu 24.04. It is for a new static-address host with no container, panel, VPN, Fail2ban automation or routing rules. DHCP address renewal needs separate allowances; do not apply this static-host template to a DHCP-dependent image. Both address families receive the same access policy. Confirm the actual legacy/nf_tables backend and that iptables-apply/ip6tables-apply are installed; do not change backends during rollout.

Step 1: Prepare backups and a complete IPv4 filter file

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

  • Allow loopback and established/related traffic.
  • Permit ICMP and source-restricted SSH; expose HTTP/HTTPS only where required.
  • Drop other inbound traffic and forwarded traffic for this non-routing host; allow outgoing traffic.

Do not flush live rules and then set DROP before adding allowances. Prepare complete restore files first. The following root-shell commands create a new review directory and back up both full rulesets; do not overwrite an existing directory or backup. Confirm working independent console access before continuing. Stop if directory creation or either backup fails:

umask 077
iptables --version
ip6tables --version
mkdir /root/firewall-review &&
iptables-save > /root/firewall-review/before.v4 &&
ip6tables-save > /root/firewall-review/before.v6

Save the following text as /root/firewall-review/rules.v4; it is restore-file data, not a shell script. Replace the documentation management address and SSH port first. Applying it replaces the whole filter table, including existing chains: it is unsuitable for hosts managed by another firewall, Docker or a panel.

*filter
:INPUT DROP [0:0]
:FORWARD DROP [0:0]
:OUTPUT ACCEPT [0:0]
-A INPUT -i lo -j ACCEPT
-A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
-A INPUT -m conntrack --ctstate INVALID -j DROP
-A INPUT -p icmp -j ACCEPT
-A INPUT -p tcp -s 203.0.113.10/32 --dport 22 -m conntrack --ctstate NEW -j ACCEPT
-A INPUT -p tcp --dport 80 -m conntrack --ctstate NEW -j ACCEPT
-A INPUT -p tcp --dport 443 -m conntrack --ctstate NEW -j ACCEPT
COMMIT

Inspect current state without changing it:

iptables -S
ip6tables -S
iptables -L -n -v

Step 2: Prepare the IPv6 file with matching SSH restrictions

Save the following as /root/firewall-review/rules.v6. Replace the IPv6 management source and SSH port consistently with IPv4; if IPv6 SSH is unnecessary, omit only that SSH line. Adding a narrow ACCEPT after an existing broad ACCEPT does not restrict access, which is why the candidate file contains only the selected management source.

*filter
:INPUT DROP [0:0]
:FORWARD DROP [0:0]
:OUTPUT ACCEPT [0:0]
-A INPUT -i lo -j ACCEPT
-A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
-A INPUT -m conntrack --ctstate INVALID -j DROP
-A INPUT -p ipv6-icmp -j ACCEPT
-A INPUT -p tcp -s 2001:db8::10/128 --dport 22 -m conntrack --ctstate NEW -j ACCEPT
-A INPUT -p tcp --dport 80 -m conntrack --ctstate NEW -j ACCEPT
-A INPUT -p tcp --dport 443 -m conntrack --ctstate NEW -j ACCEPT
COMMIT

The ICMPv6 rule accepts all ICMPv6 for this simple host baseline, preserving Neighbor Discovery and errors such as Packet Too Big. It is not the tightest ICMPv6 policy. A narrower type/source/hop-limit policy needs RFC 4890 and the actual host/router role. Preserve required IPv4 ICMP too. Verify both candidate files before any application:

iptables-restore --test < /root/firewall-review/rules.v4
ip6tables-restore --test < /root/firewall-review/rules.v6

--test parses and constructs without committing. A passing parse does not prove access. Rehearse with the same distribution/backend in an isolated environment; then use the timed-approval sequence below with a console and a second test client.

Step 3: Apply each family with timed approval

Apply IPv4 first. The 120-second timeout is illustrative; plan enough time for fresh permitted/forbidden SSH and web tests. Do not answer y until they pass:

iptables-apply -t 120 /root/firewall-review/rules.v4

Then apply IPv6 and independently test new management/web connections, expected denials and IPv6 network operation:

ip6tables-apply -t 120 /root/firewall-review/rules.v6

If confirmation does not arrive, each apply tool attempts to restore its own prior family. This is not one atomic IPv4/IPv6 transaction. If the second stage fails, the first confirmed family does not automatically roll back; restore both original backups from the console. A timer is not recovery protection against every tool/session/host failure. Confirm that your chosen VPS plan provides a suitable console or recovery method before relying on it.

iptables-restore < /root/firewall-review/before.v4
ip6tables-restore < /root/firewall-review/before.v6

Step 4: Save both tested families and verify after reboot

Only after both families pass the fresh connection and denial tests, install/configure the distribution’s persistence mechanism. On Ubuntu/Debian, iptables-persistent supplies the netfilter-persistent plugins; installation may ask whether to save current rules. Confirm the working state before accepting:

apt install iptables-persistent
netfilter-persistent save

Inspect /etc/iptables/rules.v4 and rules.v6, then verify that both reload after a planned reboot with console access ready. On RHEL-like systems use the supported mechanism for the chosen backend. Merely writing a file or mentioning rc.local does not configure boot loading.

For IPv6 addressing and route configuration, see our IPv6 setup and configuration guide for a VPS.

Common Real‑World Scenarios and Tips

Running Docker on a VPS with a firewall

Docker creates forwarding/NAT rules for container networking. Host INPUT policy alone does not describe published-port access. Use the documentation for the installed Docker version and backend:

  • Do not assume ufw or firewalld protects Docker-published ports. Published container traffic can bypass expected host filtering; Docker’s -p mappings and the actual packet path must be reviewed and tested separately.
  • Do not flush Docker-managed chains or disable Docker firewall management without a complete replacement design. DOCKER-USER guidance for its iptables backend differs from separate table/hook rules for Docker’s native nftables backend; current Docker documentation labels the latter experimental.
  • Consider using a reverse proxy (Nginx, Caddy, Traefik) on the host as the public entry point. Keep backend container ports off public interfaces rather than relying only on host firewall rules to hide them.

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 limit provides basic per-source connection limiting; do not leave an earlier broad allow rule that bypasses it.
  • iptables recent/hashlimit can express other policies, with backend/module-specific validation.
  • Fail2ban can respond to log patterns; verify the action’s firewall integration and test real ban/unban behavior.

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

Enable only the log detail you need, verify collection and set retention limits. Logging is separate from the permit/drop decision:

  • ufw: ufw logging low enables rate-limited logging; whether records reach /var/log/ufw.log depends on the system’s logging configuration.
  • firewalld: --set-log-denied=unicast changes runtime and permanent settings and reloads the firewall. Review unsaved runtime changes before using it.
  • iptables: LOG is non-terminating: it records a packet and continues traversal. Add deliberate rate limiting and a separate drop/reject decision where required; inspect kernel journal/syslog routing.

Centralize logs and test useful alerts as part of monitoring. Promtail reached end of life on March 2, 2026; use a supported collector such as Grafana Alloy for new deployments. Our VPS log-management guide provides the broader retention and alerting context.

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 separate permitted and forbidden sources, test fresh SSH and required panel/application connections over IPv4 and IPv6.
  • Use client-side curl or nc to check actual service reachability and expected rejection.
  • Use server-side ss -tulpn to inspect listening sockets; a listening socket is not proof of external access.
  • Verify IPv6 Neighbor Discovery and path-MTU behavior, reload and planned boot persistence, with an independent recovery path ready.

Keep a rescue window open

When applying risky firewall changes on a production VPS:

  • Keep the original SSH session while testing fresh connections, but do not treat an existing session as an independent recovery path.
  • Confirm that the chosen provider plan actually includes a working console/rescue method and test it before changing access.
  • Rehearse timeout rollback and restoration on the same backend. iptables-apply protects one family per invocation; a failed second-family rollout requires an explicit decision to restore the first too.

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

On a VPS, clarify which network rules you control and which protections or recovery services the provider supplies under your plan. The host firewall controls network/transport access; it does not automatically inspect application requests like a WAF or replace upstream capacity protections.

A repeatable operating approach is:

  • Choose the distribution-supported manager and record current ownership, backend, sources and required ports.
  • Maintain matching IPv4/IPv6 intent, with private services constrained to actual authorized clients.
  • Review changes, test syntax and access, rehearse recovery, then verify reload and boot persistence. Growth alone does not require switching tools.

Keep rules, reasons and test records together. Store configuration in version control without credentials, use reviewable automation, and check drift when services or management addresses change.

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.

VPS firewall configuration works best as a documented access policy: choose ufw, firewalld or a directly managed ruleset, then verify sources, services and both address families. Keep recovery independent of the connection being changed, and combine the host firewall with updates, SSH authentication, logging and application protections.

Official references

Frequently Asked Questions

It limits unnecessary network access and complements updates, SSH authentication and application security. Permit only required sources and services. A firewall is not a guarantee against every attack, and provider protections or recovery access depend on the selected plan.

Use the distribution-supported tool and account for existing panels, automation and the host’s network role. UFW is a common simple Ubuntu option; firewalld offers zones on the RHEL family. Direct iptables requires more detailed ownership and testing. Avoid competing managers on the same chains; growth alone does not require migration.

Check the real listening port and observed management sources, and test an independent console and restoration plan first. Choose source restriction or connection limiting; an existing broad allow remains an access path. Test fresh allowed and forbidden connections over each family. iptables-apply and ip6tables-apply roll back separately; if the second family fails, explicitly restore the first confirmed family too when reverting the rollout.

Keep the access intent consistent, while accounting for family-specific rules and essential ICMPv6. UFW uses IPV6=yes in /etc/default/ufw; that setting does not configure OS addressing. IPv4 sources do not authorize IPv6 clients. Direct iptables needs an ip6tables file and persistence for both families. Preserve Neighbor Discovery and Packet Too Big messages and test actual IPv6 operation.

A WAF inspects HTTP requests; a host firewall controls network/transport access. Docker-published traffic can be diverted before UFW INPUT/OUTPUT rules, so inspect the packet path and documentation for the installed backend/version. A reverse proxy does not hide backend ports that are separately published on public interfaces.

Use reviewable, versioned configuration with test and recovery records. Save only after both families pass fresh access and denial checks. firewalld runtime-to-permanent overwrites permanent configuration with the whole runtime state; reload discards unsaved runtime changes. iptables-persistent saves both family files. Test reload and planned boot behavior with independent recovery ready.
↑