Skip to content

Simple Firewall

Overview

Welma provides Simple Firewall feature, which implements a secure and default-deny network policy built on top of the Linux kernel nftables framework.

The Simple Firewall provides:

Runtime architecture

Default ruleset

The baseline ruleset enforces the following behavior:

  • Input Traffic: Block all packets, except packets for the loopback, established and related connextions
  • Output Traffic: Accept loopback packets, all UDP packets and only TCP packets with SYN flag
  • Forward Traffic: Block all packets

All other packets are dropped and logged with a limit of 180 log per minute with a burst of first 300 records.

Boot Integration

The firewall is loaded during early boot through a dedicated systemd service. It runs before network-pre.target to ensure firewall rules are active before any network interface is configured. This guarantees that no packet is processed without firewall filtering from the moment networking becomes available.

Service Ordering

networking services (e.g., systemd-networkd)

        ^
        |

network-pre.target

        ^
        |

simple-firewall.service

If simple-firewall fails to load, dependent services can be prevented from starting. See Systemd Dependency Enforcement.

Yocto Configuration

The Simple Firewall is activated by default as an image feature in your conf/local.conf:

EXTRA_IMAGE_FEATURES += "simple-firewall"

The default ruleset configuration is defined in the simple-firewall recipe, inside the file: recipes-filter/basic-firewall/files/simple-firewall.conf.

To customize this default configuration, you may override this file in your Yocto layer.

Warning

The sfw tool extends the default firewall configuration based on chains definition. If you decide to customise the default configuration and continue using sfw, the input_handler and output_handler chains must retain their current definition so that rules can be inserted into them at runtime

Systemd Dependency Enforcement

To ensure some systemd units never run without firewall protection, the recipe can install systemd drop-in files for selected units using SYSTEMD_UNITS_REQUIRING_FIREWALL configuration variable defined in the simple-firewall recipe.

Drop-in Behavior

For each listed unit in SYSTEMD_UNITS_REQUIRING_FIREWALL, the following drop-in file is installed under /lib/systemd/system/<unit-name>.d/simple-firewall-dropin.conf:

simple-firewall-dropin.conf
[Unit]
# Make this unit depend on simple-firewall.service so that
# a failure of simple-firewall.service causes this unit to
# fail as well
Requires=simple-firewall.service

This enforces:

  • The unit will not start if the firewall fails
  • The firewall is always initialized first

By default, Welma installs systemd drop-in file for the network manager systemd-networkd:

SYSTEMD_UNITS_REQUIRING_FIREWALL = "systemd-networkd.service"

This prevents network configuration from starting unless firewall rules are successfully applied.

sfw tool

Purpose

The sfw (Simple FireWall) tool provides a higher-level, simplified syntax for defining firewall exceptions without writing raw nftables rules. It is designed to:

  • Reduce nftables complexity
  • Provide readable service-oriented rules
  • Integrate automatically with the default firewall

sfw Configuration Loading

At boot:

  • Default firewall configuration is loaded
  • sfw processes the configuration files located under /etc/simple-firewall.d/ with the .sfw extension
  • Files are loaded in lexical order (to control rule priority via filename prefixes)
  • Generated nftables rules are appended to the active ruleset

This preserves the secure baseline while allowing controlled openings.

Configuration Syntax

An .sfw configuration file is structured by traffic direction sections:

INPUT
        <rule 1>
        <rule 2>
        ...
OUTPUT
        <rule 1>
        <rule 2>
        ...
With: - INPUT: Defines allowed inbound traffic - OUTPUT: Defines allowed outbound traffic

Note

Forwarding is not exposed via sfw

Rule Parameters

Supported parameters include:

  • protocol: Network protocol, supported values are tcp, udp, icmp and icmpv6
  • saddr: Source IP Address
  • sport: Source Port
  • daddr: Destination IP Address
  • dport: Destination Port
  • if: Network Interface Name

Service names are resolved via standard system service definitions by nft.

Example:

99-welma-dev.sfw
INPUT
        protocol=tcp dport=ssh
        protocol=icmp
        protocol=icmpv6

OUTPUT
        protocol=icmp
        protocol=icmpv6

In this example, the 99-welma-dev.sfw configuration file permits inbound SSH connections and allows ICMP echo traffic (ping) over both IPv4 and IPv6, for both incoming and outgoing directions.

Each sfw rule is converted into nftables syntax and injected after the running default ruleset, ensuring they act as explicit exceptions.

Advanced Firewall Configuration

In addition to the simplified configuration handled by sfw, Simple Firewall feature supports loading native nftables rules for advanced use cases that require the full expressiveness of nft syntax.

Configuration Location

Raw nftables rule files must be placed in /etc/simple-firewall.d/ using .nft extension. This ensures:

  • Only files with the .nft extension are processed
  • Multiple files are supported

.nft rules are loaded by the default configuration ruleset file using the following directive:

simple-firewall.conf
include "/etc/simple-firewall.d/*.nft"

Load Order in Runtime Stack

The firewall applies rules in the following sequence at boot:

1. Default firewall ruleset (secure baseline)
2. nftables rules from /etc/simple-firewall.d/*.nft
3. sfw translated rules

This ordering ensures:

  • The default deny policy is always established first
  • Advanced or overriding behaviors are applied next
  • sfw opening exceptions are appended last