॥ श्री ॥

Firewall (firewalld)

Networking 2026-08-28

firewalld is active by default on Shani OS with a restrictive inbound policy. It manages nftables under the hood using a zone-based model — every interface belongs to a zone, and each zone has its own allow/deny rules. Do not mix direct nft commands with firewalld rules as they will conflict.

Pre-configured zones for KDE Connect, GSConnect, Waydroid, and Tailscale are included out of the box.

ZoneDefault assignmentPolicy
publicAll physical NICsDeny inbound, allow outbound
trustedwaydroid0Accept all

Status & Inspection

# Confirm firewall is running
sudo firewall-cmd --state

# Show all rules for the active zone
sudo firewall-cmd --list-all

# Show all zones with their rules
sudo firewall-cmd --list-all-zones

# Show active zones and their interfaces
sudo firewall-cmd --get-active-zones

# Show which zone an interface belongs to
sudo firewall-cmd --get-zone-of-interface=eth0

# Show the default zone
sudo firewall-cmd --get-default-zone

Opening Services & Ports

The --permanent flag writes the rule to disk so it survives reboots. Always follow with --reload to apply immediately to the running firewall.

# Allow a named service (uses built-in service definitions)
sudo firewall-cmd --add-service=http --permanent
sudo firewall-cmd --add-service=https --permanent
sudo firewall-cmd --add-service=ssh --permanent
sudo firewall-cmd --reload

# Allow a specific TCP/UDP port
sudo firewall-cmd --add-port=8080/tcp --permanent
sudo firewall-cmd --add-port=51820/udp --permanent   # WireGuard
sudo firewall-cmd --add-port=41641/udp --permanent   # Tailscale
sudo firewall-cmd --reload

# Remove a rule
sudo firewall-cmd --remove-service=http --permanent
sudo firewall-cmd --remove-port=8080/tcp --permanent
sudo firewall-cmd --reload

# List all available pre-defined service names
sudo firewall-cmd --get-services

Zones

Zones let you apply different rules to different network interfaces or source IP ranges — useful when a LAN interface and a VPN interface should have different trust levels.

# Move an interface to a different zone
sudo firewall-cmd --zone=trusted --change-interface=tailscale0 --permanent
sudo firewall-cmd --reload

# Add a source IP range to a zone (all traffic from that range uses that zone's rules)
sudo firewall-cmd --zone=trusted --add-source=192.168.1.0/24 --permanent
sudo firewall-cmd --reload

# Create a custom zone
sudo firewall-cmd --new-zone=homelab --permanent
sudo firewall-cmd --reload
sudo firewall-cmd --zone=homelab --add-service=http --permanent
sudo firewall-cmd --reload

Rich Rules

Rich rules allow more granular conditions — source IP, destination port, logging, and rate limiting.

# Allow SSH only from your LAN
sudo firewall-cmd --add-rich-rule='rule family="ipv4" source address="192.168.1.0/24" service name="ssh" accept' --permanent

# Block a specific IP entirely
sudo firewall-cmd --add-rich-rule='rule family="ipv4" source address="1.2.3.4" reject' --permanent

# Rate-limit new connections to port 443
sudo firewall-cmd --add-rich-rule='rule service name="https" limit value="50/m" accept' --permanent

# Log and drop traffic from a subnet
sudo firewall-cmd --add-rich-rule='rule family="ipv4" source address="10.0.0.0/8" log prefix="BLOCKED: " level="warning" drop' --permanent

sudo firewall-cmd --reload

Port Forwarding

# Forward incoming port 80 to localhost:8080
sudo firewall-cmd --add-forward-port=port=80:proto=tcp:toport=8080:toaddr=127.0.0.1 --permanent
sudo firewall-cmd --reload

Logging

# Enable logging of dropped packets
sudo firewall-cmd --set-log-denied=all --permanent
sudo firewall-cmd --reload

# View firewall-related kernel messages
sudo journalctl -k | grep -i "nft\|firewall\|REJECT\|DROP"

Runtime vs Permanent

# Show rules currently active (runtime)
sudo firewall-cmd --list-all

# Show what will be active after the next reload (permanent config on disk)
sudo firewall-cmd --list-all --permanent

# Sync runtime to match permanent config
sudo firewall-cmd --reload

# Make the current runtime config permanent without re-running each command
sudo firewall-cmd --runtime-to-permanent

Omit --permanent to test a rule without committing it — it disappears on the next --reload or reboot.


GUI

# Launch the graphical firewall manager (pre-installed)
sudo firewall-config

KDE Plasma additionally has Plasma Firewall (pre-installed), a native module in System Settings that's a simpler front-end to the same firewalld backend — good for basic zone/service toggling; use firewall-config or the CLI above for rich rules and advanced zone configuration.


Common Port Reference

ServicePortProtocol
SSH22TCP
HTTP80TCP
HTTPS443TCP
DNS53TCP/UDP
WireGuard51820UDP
Tailscale41641UDP
Syncthing22000TCP/UDP
KDE Connect1714–1764TCP/UDP
Minecraft25565TCP

Troubleshooting

IssueSolution
Service reachable locally but not from LANCheck --list-all to confirm the port/service is open; verify the interface is in the correct zone
Rule added but not workingDid you forget --reload? Runtime and permanent configs can diverge
ALREADY_ENABLED errorThe rule already exists permanently; inspect with --list-all --permanent
Port open but connection refusedThe service itself may not be running; check systemctl status <service>
Rules disappear after rebootRule was added without --permanent
fail2ban bans not appearing in firewallConfirm fail2ban's backend is firewalld; check sudo firewall-cmd --direct --get-all-rules
Waydroid has no networkCheck waydroid0 is in the trusted zone: sudo firewall-cmd --get-zone-of-interface=waydroid0
Podman/container networking brokenAdd the container bridge to trusted: sudo firewall-cmd --zone=trusted --add-interface=podman0 --permanent

See Also