# firewalld — Dynamic Firewall Management on Linux

> Practical guide to firewalld — zones, services, ports and rich rules with firewall-cmd, runtime and permanent rules on RHEL, Fedora and CentOS.

Source: https://www.jpkc.com/db/en/cheatsheets/security/firewalld/

<!-- PROSE:intro -->
firewalld is the dynamic firewall daemon of RHEL, Fedora and CentOS, driven from the command line with `firewall-cmd`. Under the hood it builds on nftables (formerly iptables) and organises rules into **zones** – trust levels such as `public` or `trusted` that you assign interfaces, services and ports to. The crucial distinction is between **runtime** and **permanent**: changes without `--permanent` apply instantly but are lost on `--reload` or a reboot. This guide walks you through the commands you reach for daily, from zone status through services and ports to rich rules and NAT.
<!-- PROSE:intro:end -->

## Status & Zones

`firewall-cmd --state` — Check if firewalld is running.

```bash
firewall-cmd --state
```

`firewall-cmd --get-active-zones` — Show active zones and their interfaces.

```bash
firewall-cmd --get-active-zones
```

`firewall-cmd --get-default-zone` — Show the default zone.

```bash
firewall-cmd --get-default-zone
```

`firewall-cmd --set-default-zone=<zone>` — Change the default zone. It affects every interface without an explicit zone, so check the current default before switching.

```bash
firewall-cmd --set-default-zone=public
```

`firewall-cmd --list-all` — List all settings for the default zone.

```bash
firewall-cmd --list-all
```

`firewall-cmd --zone=<zone> --list-all` — List all settings for a specific zone.

```bash
firewall-cmd --zone=public --list-all
```

`firewall-cmd --get-zones` — List all available zones.

```bash
firewall-cmd --get-zones
```

## Services

`firewall-cmd --add-service=<service>` — Allow a service. Runtime only: lost on `--reload` or reboot. Use the `trusted` zone and broad `--add-service` rules sparingly.

```bash
firewall-cmd --add-service=http
```

`firewall-cmd --add-service=<service> --permanent` — Allow a service permanently.

```bash
firewall-cmd --add-service=https --permanent
```

`firewall-cmd --remove-service=<service> --permanent` — Remove a service permanently.

```bash
firewall-cmd --remove-service=ftp --permanent
```

`firewall-cmd --list-services` — List currently allowed services.

```bash
firewall-cmd --list-services
```

`firewall-cmd --get-services` — List all available predefined services.

```bash
firewall-cmd --get-services
```

`firewall-cmd --info-service=<service>` — Show details about a service (ports, protocols).

```bash
firewall-cmd --info-service=ssh
```

## Ports

`firewall-cmd --add-port=<port>/<proto> --permanent` — Open a port permanently.

```bash
firewall-cmd --add-port=8080/tcp --permanent
```

`firewall-cmd --add-port=<start>-<end>/<proto> --permanent` — Open a range of ports permanently.

```bash
firewall-cmd --add-port=3000-3100/tcp --permanent
```

`firewall-cmd --remove-port=<port>/<proto> --permanent` — Close a port permanently.

```bash
firewall-cmd --remove-port=8080/tcp --permanent
```

`firewall-cmd --list-ports` — List all open ports.

```bash
firewall-cmd --list-ports
```

## Rich Rules

`firewall-cmd --add-rich-rule='rule family=ipv4 source address=<ip> accept' --permanent` — Allow all traffic from a specific IP.

```bash
firewall-cmd --add-rich-rule='rule family=ipv4 source address=10.0.0.5 accept' --permanent
```

`firewall-cmd --add-rich-rule='rule family=ipv4 source address=<ip> drop' --permanent` — Block all traffic from a specific IP.

```bash
firewall-cmd --add-rich-rule='rule family=ipv4 source address=192.168.1.100 drop' --permanent
```

`firewall-cmd --add-rich-rule='rule family=ipv4 source address=<ip> port port=<port> protocol=tcp accept' --permanent` — Allow a specific IP to access a port.

```bash
firewall-cmd --add-rich-rule='rule family=ipv4 source address=10.0.0.0/24 port port=3306 protocol=tcp accept' --permanent
```

`firewall-cmd --list-rich-rules` — List all rich rules.

```bash
firewall-cmd --list-rich-rules
```

`firewall-cmd --remove-rich-rule='<rule>' --permanent` — Remove a rich rule.

```bash
firewall-cmd --remove-rich-rule='rule family=ipv4 source address=10.0.0.5 accept' --permanent
```

## Masquerade & Forwarding

`firewall-cmd --add-masquerade --permanent` — Enable masquerading (NAT).

```bash
firewall-cmd --add-masquerade --permanent
```

`firewall-cmd --add-forward-port=port=<src>:proto=tcp:toport=<dest> --permanent` — Forward a local port to another local port.

```bash
firewall-cmd --add-forward-port=port=80:proto=tcp:toport=8080 --permanent
```

`firewall-cmd --add-forward-port=port=<src>:proto=tcp:toaddr=<ip>:toport=<dest> --permanent` — Forward a port to a remote host.

```bash
firewall-cmd --add-forward-port=port=80:proto=tcp:toaddr=192.168.1.10:toport=8080 --permanent
```

`firewall-cmd --query-masquerade` — Check if masquerading is enabled.

```bash
firewall-cmd --query-masquerade
```

## Runtime vs. Permanent

`firewall-cmd --reload` — Reload the firewall to apply permanent changes. Unsaved runtime changes are dropped in the process – to make a rule stick, combine `--permanent` with a following `--reload`.

```bash
firewall-cmd --reload
```

`firewall-cmd --runtime-to-permanent` — Save current runtime rules as permanent.

```bash
firewall-cmd --runtime-to-permanent
```

`firewall-cmd --panic-on` — Enable panic mode (block all traffic). Cuts existing connections immediately – on a remote server this locks out your own SSH session.

```bash
firewall-cmd --panic-on
```

`firewall-cmd --panic-off` — Disable panic mode.

```bash
firewall-cmd --panic-off
```

`firewall-cmd --complete-reload` — Complete reload that drops all runtime rules.

```bash
firewall-cmd --complete-reload
```

<!-- PROSE:outro -->
## Conclusion

firewalld hides the nftables syntax and turns firewall management into a game of zones, services and ports. The most common pitfall remains the difference between runtime and permanent: feel free to test a rule at runtime first, but commit it with `--permanent` and reload the firewall once it works – otherwise it is gone after the next reboot.

## Further Reading

- [firewalld – official documentation](https://firewalld.org/documentation/) – concepts, zones and examples
- [firewall-cmd(1) – manual page](https://man7.org/linux/man-pages/man1/firewall-cmd.1.html) – every option at a glance
- [firewalld – Wikipedia](https://en.wikipedia.org/wiki/Firewalld) – background and history
<!-- PROSE:outro:end -->

## Related Commands

- [age](https://www.jpkc.com/db/en/cheatsheets/security/age/) – modern, simple file encryption
- [clamav](https://www.jpkc.com/db/en/cheatsheets/security/clamav/) – open-source antivirus scanner
- [fail2ban](https://www.jpkc.com/db/en/cheatsheets/security/fail2ban/) – ban IPs after failed login attempts

