Jump to content
From ArchWiki

Related articles

- nftables

firewalld is a firewall daemon developed by Red Hat. It uses nftables by default. From project home page:

  Firewalld provides a dynamically managed firewall with support for network/firewall zones that define the trust level of network connections or interfaces. It has support for IPv4, IPv6 firewall settings, ethernet bridges and IP sets. There is a separation of runtime and permanent configuration options. It also provides an interface for services or applications to add firewall rules directly.

## Installation

Install the firewalld package.

## Usage

Enable and start `firewalld.service`.

You can control the firewall rules with the `firewall-cmd` console utility.

`firewall-offline-cmd` utility can be used to configure when firewalld is not running. It features similar syntax to `firewall-cmd`.

GUI is available as `firewall-config` which comes with firewalld package.

## Configuration

Configuration at run time can be changed using `firewall-cmd`.

Note: Most commands will only change runtime configuration and will not persist through restart. To make changes permanent there are two options:

- Use `--permanent` option. This will not change runtime configuration until the firewall service is restarted or rules are reloaded with `--reload` command.
- Change the runtime configuration and make it permanent as described in #Converting runtime configuration to permanent

### Zones

Zone is a collection of rules that can be applied to a specific interface.

To have an overview of the current zones and interfaces they are applied to:

    # firewall-cmd --get-active-zones

Some commands (such as adding/removing ports/services) require a zone to specified.

Zone can be specified by name by passing `--zone=zone_name` parameter.

If no zone is specified default zone is assumed.

#### Zone information

You can list all the zones with entirety their configuration:

    # firewall-cmd --list-all-zones

or just a specific zone

    # firewall-cmd --info-zone=zone_name

#### Changing zone of an interface

    # firewall-cmd --zone=zone --change-interface=interface_name

There `zone` is a new zone that you want to assign interface to.

##### Using NetworkManager to manage zones

NetworkManager can assign different connection profiles to different zones. This allows for example, adding a home WiFi connection to the "home" zone, a work WiFi connection to the "work" zone, and all other WiFi connections to the default "public" zone.

List connection profiles:

    $ nmcli connection show

Assign the "myssid" profile to the "home" zone:

    $ nmcli connection modify myssid connection.zone home

#### Default zones

When a new interface is connected the default zone will be applied. You can query the name of the default zone using:

    # firewall-cmd --get-default-zone

The default zone can be changed using following command.

    # firewall-cmd --set-default-zone=zone

Note: This change is always permanent.

### Services

Services are pre-made rules corresponding to a specific daemon. For example, the `ssh` service corresponds to SSH and opens ports 22 when assigned to a zone.

To get a list of available services, enter the following command:

    # firewall-cmd --get-services

You can query information about a particular service:

    # firewall-cmd --info-service service_name

#### Adding or removing services from a zone

To add a service to a zone:

    # firewall-cmd --zone=zone_name --add-service service_name

Removing a service:

    # firewall-cmd --zone=zone_name --remove-service service_name

### Ports

Ports can be directly opened on a specific zone.

    # firewall-cmd --zone=zone_name --add-port port_num/protocol

There `protocol` is either `tcp` or `udp`.

To close the port use `--remove-port` option with same port number and protocol.

### NAT masquerade

This command has the same effect as `iptables -t nat -A POSTROUTING -j MASQUERADE`:

    # firewall-cmd --zone=public --add-masquerade

Since version 1.0.0, to make NAT masquerade working between different firewall zones, you have to create a new policy object which is used to filter traffic between them:

    # firewall-cmd --new-policy NAT_int_to_ext --permanent
    # firewall-cmd --permanent --policy NAT_int_to_ext --add-ingress-zone internal
    # firewall-cmd --permanent --policy NAT_int_to_ext --add-egress-zone public
    # firewall-cmd --permanent --policy NAT_int_to_ext --set-target ACCEPT

### Port forwarding

If you have firewalld configured on a router, and you have enabled NAT masquerading as above, it is simple to set up port forwarding through firewalld:

    # firewall-cmd --zone=public --add-forward-port=port=12345:proto=tcp:toport=22:toaddr=10.20.30.40

This will forward port `12345/tcp` on the firewall's public interface to port `22` (standard SSH) on the internal system at IP address `10.20.30.40`. To remove this forwarded port:

    # firewall-cmd --zone=public --remove-forward-port=port=12345:proto=tcp:toport=22:toaddr=10.20.30.40

Unfortunately you have to type the entire forward declaration in order to remove it, specifying only the port and the protocol is not enough.

### Rich rules

With rich rules/rich language syntax more complex firewall rules can be created in an easy to understand way.

To add a rich rule:

    # firewall-cmd [--zone=zone_name] [--permanent] --add-rich-rule='rich_rule'

where `rich_rule` is a rich language rule.

For example, to allow all connection from network `192.168.1.0/24` to the NFS service:

    # firewall-cmd --add-rich-rule='rule family="ipv4" source address="192.168.1.0/24" service name="nfs" accept'

To allow connection from `192.168.2.3` to port `1234/tcp`:

    # firewall-cmd --add-rich-rule='rule family="ipv4" source address="192.168.2.3" port port="1234" protocol="tcp" accept'

For more rich language syntax, see firewalld.richlanguage(5).

To remove a rich rule:

    # firewall-cmd  [--zone=zone_name] [--permanent] --remove-rich-rule='rich_rule'

## Tips and tricks

### Port or service timeout

Service or port can be added for a limited amount of time using `--timeout=value` option passed during addition command. Value is either number of seconds, minutes if postfixed with `m` or hours `h`. For example, adding SSH service for 3 hours:

    # firewall-cmd --add-service ssh --timeout=3h

Note: Timeouts are mutually exclusive with --permanent changes to the firewall configuration. I.e., timeouts can only be applied to the runtime configuration, and are never permanent.

### Converting runtime configuration to permanent

You can make the runtime (current temporary) configuration permanent (meaning it persists through restarts)

    # firewall-cmd --runtime-to-permanent

### Check services details

The configuration files for the default supported services are located at `/usr/lib/firewalld/services/` and user-created service files would be in `/etc/firewalld/services/`.

### Removing the applet/tray icon

The applet is not packaged separately from firewalld. The auto start script located at `/etc/xdg/autostart/firewall-applet.desktop` can be hidden, however: see XDG Autostart#Directories. Alternatively, exclude the file from being installed by adding it to NoExtract in `/etc/pacman.conf`.

## See also

- firewall-cmd(1)
- Official documentation
- Fedora:Firewalld
- Fedora:Features/FirewalldRichLanguage

Category:

- Firewalls