Menu
User

DropVPS Team

Writer: Cooper Reagan

How to secure ubuntu 25.04 with firewalld zones and rules

How to secure ubuntu 25.04 with firewalld zones and rules

Publication Date

10/01/2025

Category

Articles

Reading Time

4 Min

Table of Contents

Lock down Ubuntu 25.04 with FirewallD’s zone-based policy. Replace UFW, enable persistent rules, and manage services and ports safely without locking yourself out. The steps below cover installation, zones, runtime vs permanent changes, rich rules, NAT and port forwarding, IPv6, logging, backups, and verification on a production-ready server.

Prepare the system and check UFW

Ensure you won’t conflict with UFW. Stop and disable it if active. Use sudo-capable user.

id
sudo ufw status verbose || true
sudo systemctl stop ufw || true
sudo systemctl disable ufw || true
sudo ufw disable || true
Status: inactive

Install and start FirewallD

Add firewalld, enable it on boot, and confirm it is running.

sudo apt update
sudo apt install -y firewalld
sudo systemctl enable --now firewalld
sudo systemctl status --no-pager firewalld
firewall-cmd --state
firewall-cmd --version
running
1.3.x

Runtime vs permanent changes

FirewallD keeps separate runtime and permanent configs. Apply permanent changes and reload to activate them.

# Example: sync runtime to disk, then reload
sudo firewall-cmd --runtime-to-permanent
sudo firewall-cmd --reload

Inspect zones and set the default zone

Zones define trust levels. Public is a safe default for internet-facing hosts.

firewall-cmd --get-default-zone
firewall-cmd --get-active-zones
firewall-cmd --get-zones
firewall-cmd --zone=public --list-all
sudo firewall-cmd --set-default-zone=public

Bind interfaces to zones

Attach network interfaces to the appropriate zone. This controls which rules apply to traffic on that interface.

ip -br a
# Replace eth0 with your interface name
sudo firewall-cmd --permanent --zone=public --add-interface=eth0
sudo firewall-cmd --reload
firewall-cmd --get-active-zones

Allow essential services safely

Allow SSH first to retain access, then add web services.

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

Open custom ports

Expose application ports explicitly with protocol and optional ranges.

# Single port
sudo firewall-cmd --permanent --zone=public --add-port=8080/tcp
# UDP range example
sudo firewall-cmd --permanent --zone=public --add-port=60000-60100/udp
sudo firewall-cmd --reload
firewall-cmd --zone=public --list-ports

Create rich rules (IP-based allow/deny)

Use rich rules for source-based filtering and finer control.

# Allow a trusted host
sudo firewall-cmd --permanent --zone=public \
  --add-rich-rule='rule family=ipv4 source address=203.0.113.10 accept'

# Drop a noisy subnet
sudo firewall-cmd --permanent --zone=public \
  --add-rich-rule='rule family=ipv4 source address=198.51.100.0/24 drop'

# Block SMTP from everywhere (example)
sudo firewall-cmd --permanent --zone=public \
  --add-rich-rule='rule family=ipv4 port port=25 protocol=tcp drop'

sudo firewall-cmd --reload
firewall-cmd --zone=public --list-rich-rules

Enable logging for denied packets

Turn on denied-packet logging and watch recent events for troubleshooting.

sudo firewall-cmd --set-log-denied=all
sudo journalctl -u firewalld -n 50 --no-pager
sudo journalctl -k | grep -i 'DPT=' | tail -n 20

Masquerading (NAT) and port forwarding

Enable NAT for egress when routing traffic, and forward ports to services.

# Enable IPv4 forwarding (runtime and persistent)
echo 'net.ipv4.ip_forward=1' | sudo tee /etc/sysctl.d/99-firewalld-ipforward.conf
sudo sysctl --system

# Turn on masquerade in the egress zone
sudo firewall-cmd --permanent --zone=public --add-masquerade

# Forward external TCP/80 to local TCP/8080
sudo firewall-cmd --permanent --zone=public \
  --add-forward-port=port=80:proto=tcp:toport=8080

sudo firewall-cmd --reload
firewall-cmd --zone=public --list-all

IPv6 considerations

Service/port rules apply to IPv4 and IPv6. Use rich rules with family=ipv6 for v6-specific policies.

# Example: allow IPv6 SSH from a subnet
sudo firewall-cmd --permanent --zone=public \
  --add-rich-rule='rule family=ipv6 source address=2001:db8:1234::/48 service name=ssh accept'
sudo firewall-cmd --reload

Panic mode and quick lockdown

Panic mode drops all incoming/outgoing connections immediately. Use only for emergencies.

# Enable, then disable once safe
sudo firewall-cmd --panic-on
sudo firewall-cmd --panic-off

Backup and restore FirewallD configuration

Archive the configuration directory to preserve services, zones, and policies.

sudo tar czf /root/firewalld-backup-$(date +%F).tar.gz /etc/firewalld
# Restore (overwrites current config)
# sudo tar xzf /root/firewalld-backup-YYYY-MM-DD.tar.gz -C /
# sudo firewall-cmd --reload

Test and verify exposure

Confirm open ports locally and from a remote host to validate policies.

ss -tulpen
sudo apt install -y nmap
nmap -p 22,80,443,8080 localhost
# From another host:
# nmap -Pn -p 22,80,443 your.server.ip

Create a custom service definition

Define reusable services with XML and enable them like built-ins.

# Create /etc/firewalld/services/myapp.xml
sudo tee /etc/firewalld/services/myapp.xml >/dev/null <<'XML'
<?xml version="1.0" encoding="utf-8"?>
<service>
  <short>MyApp</short>
  <description>Custom app on TCP/9000</description>
  <port protocol="tcp" port="9000"/>
</service>
XML

sudo firewall-cmd --reload
sudo firewall-cmd --permanent --zone=public --add-service=myapp
sudo firewall-cmd --reload
firewall-cmd --zone=public --list-services

FirewallD on Ubuntu 25.04 provides clear, auditable, and flexible network control using zones, services, ports, rich rules, and NAT. Keep SSH open, apply permanent rules, reload safely, log denies, and back up configs before changes. For more guides, visit dropvps.com

Linux VPS
U
Loading...

Related Posts