Firewall

Overview

The firewall section contains the configuration for the appliance firewall to filter traffic. The appliance firewall makes use of the Linux kernel packet classification framework nftables, thus it is highly recommended that you familiarize yourself with nftables by reading the following short overview: nftables in 10 minutes.

The following documentation assumes that you are familiar with the basic nftables concepts of tables, chains, and rules.

Note

The appliance firewall only affects traffic to and from the appliance host itself. Traffic that is forwarded by the appliance as part of the SCION dataplane and IP-in-SCION tunneling cannot be filtered by the appliance firewall.

Configuration

There are two main methodologies for access control using a firewall. Blacklisting allows all traffic and drops only specific packets, whitelisting on the other hand drops all the traffic by default and only accepts what you specify. The appliance’s firewall configuration contains tables of chains, which in turn contain the actual rules for enforcing the desired filtering. Four different firewall modes are available to the user to configure the desired behavior:

  • AUTO mode is the default mode and generates set of rules based on the rest of the appliance configuration. AUTO mode mostly locks down the appliance to only allow traffic required for the appliance to function properly. If you do not have any special requirements, this is the recommended mode.

  • PREPEND mode uses the rules generated by the AUTO mode and allows prepending additional rules to the generated ones. This mode is useful if you want to add custom rules to the appliance firewall without having to reconfigure the whole firewall.

  • CUSTOM mode does not generate any rules and allows the user to configure the appliance firewall from scratch. This mode is useful if you want to have full control over the appliance firewall.

  • UNMANAGED mode disables the appliance firewall and does not interfere with existing firewall configurations. This mode should only be used when transitioning from iptables to the appliance-managed firewall.

The generated rules for the AUTO and PREPEND modes are a set of firewall rules based on the other sections of the appliance configuration. Check the auto rule generation section for more information. The following describes the available configuration options independent of the selected mode, followed by the configuration options for each mode.

mode

The mode declares how the appliance firewall is operating. Possible values are AUTO, PREPEND, CUSTOM, and UNMANAGED.

Tip

The AUTO mode is a good way to secure your appliance while CUSTOM mode offers more flexibility. We recommend that you use AUTO or PREPEND unless you have very specific requirements.

Tables

This section describes the table configuration.

tables

The tables section is used to configure a list of tables using the nftables table syntax. A table contains a list of chains, but has otherwise no effect on the packet filtering.

name

The name of the table. This can be any string and has no effect on the processing of packets.

family

The family type of the table. The packets seen by the table depends on the family type. Available family types are INET for IPv4 and IPv6 packets, IP for IPv4 packets, and IP6 for IPv6 packets.

chains

Chains are a list of chains using the nftables chains syntax. Each chain contains rules for the desired packet filtering behavior. A chain can be either a base chain (registered into the Netfilter hooks) or a regular chain (reachable via jump statements).

counters

A list of named counters which counts the number of packets and the total bytes. Counters need to be attached to rules to count the number of packets and total bytes that were matched by a given rule.

Chains

This section describes the chain configuration. The required fields depend on the type of chain to configure. Base chains attached to the netfilter hooks require the fields chaintype, hook, policy, and priority (default 0). Regular chains can only be reached using a jump statement and therefore only include the name and the rules.

In PREPEND mode, only a single base chain per hook can be defined. Furthermore, the base chains for the INPUT and FORWARD hooks - default_input and default_forward - are already defined by the appliance and cannot be redefined. Only rules can be prepended to these chains.

name

The name of the chain. When using PREPEND mode the names for the base chains of the INPUT and FORWARD hooks must be default_input respectively default_forward. Other base chain names can be arbitrary. In CUSTOM mode, all names can be arbitrary. For regular chains, any name can be used regardless of the mode.

chaintype

Specify the chain type. Possible values are FILTER, ROUTE and NAT. Only used for base chains.

hook

Specify the netfilter hook for the base chain. Possible values are INPUT, FORWARD, OUTPUT, PREROUTING and POSTROUTING. Only used for base chains.

policy

Specify the default verdict if the packet reaches the end of the chain. Possible values are ACCEPT or DROP. Only used for base chains.

priority

Specify the priority of the chain (default 0). Lower numbers have higher priority, e.g., a priority of -100 has higher priority than 0, which in turn has higher priority than 10. Only used for base chains.

rules

The rules define actions on the packet if they match the specified criteria.

Rules

This section describes the rule configuration.

rule

The rule string can contain zero or more expressions followed by one or more statements as documented by nftables. The expressions are evaluated from left to right and if a packet matches all expressions, the statements are executed. Please refer to the nftable documentation for further information (examples for expressions and statements).

comment

Informational comment for the rule.

sequence_id

The sequence ID determines the order of the rules within the chain.

Firewall Modes

AUTO

This mode does not allow any customization. The appliance uses the default table called appliance of type INET with the generated rules. This mode is the default mode and does not need to be specified explicitly. If you want to specify the mode explicitly the tables section must be empty.

AUTO appliance firewall configuration

Simple configuration to use the firewall AUTO mode. You can also omit the firewall section.

{
  "firewall": {
    "mode": "AUTO"
  }
}

PREPEND

The appliance still uses the default table but allows prepending additional rules. The configuration only allows a single table named appliance of type INET.

In PREPEND mode, only a single base chain per hook can be defined. Furthermore, the base chains for the INPUT and FORWARD hooks - default_input and default_forward - are already defined by the appliance and cannot be redefined. Only rules can be prepended to these chains.

The rules you define in these chains are then prepended to the generated ones of the same hook by the appliance. For the OUTPUT, POSTROUTING, and PREROUTING hooks you can define at most one base chain per hook. You can still define arbitrary regular chains which can be reached via jump statements.

PREPEND appliance firewall configuration

This example shows how to configure the appliance firewall in PREPEND mode by defining a custom rule that gets executed before the generated rules for the default_input and default_forward chains. Furthermore, it defines a base chain for the POSTROUTING hook and a regular chain that can be reached via a jump statement.

{
  "firewall": {
    "mode": "PREPEND",
    "tables": [
      {
        "name": "appliance",
        "family": "INET",
        "chains": [
          {
            "name": "default_input",
            "rules": [
              {
                "comment": "custom input rule",
                "rule": "ip saddr 30.0.0.0/24 accept",
                "sequence_id": 0
              }
            ]
          },
          {
            "name": "default_forward",
            "rules": [
              {
                "comment": "custom forward rule",
                "rule": "ip saddr 10.0.0.0/24 jump my_regular_chain",
                "sequence_id": 0
              }
            ]
          },
          {
            "name": "my_postrouting_chain",
            "hook": "POSTROUTING",
            "chaintype": "NAT",
            "policy": "ACCEPT",
            "priority": 0,
            "rules": [
              {
                "comment": "source nat",
                "rule": "ip saddr 192.168.2.0/24 snat to 1.2.3.4",
                "sequence_id": 0
              }
            ]
          },
          {
            "name": "my_regular_chain",
            "rules": [
              {
                "comment": "accept if you reach this chain",
                "rule": "counter name \"accept_custom\" accept",
                "sequence_id": 0
              }
            ]
          }
        ],
        "counters": [
          {
            "name": "accept_custom"
          }
        ]
      }
    ]
  }
}

CUSTOM

This mode provides full control. The tables specified in the configuration are applied by the appliance without any modifications.

CUSTOM appliance firewall configuration

This example shows how to configure the appliance firewall in CUSTOM mode.

{
  "firewall": {
    "mode": "CUSTOM",
    "tables": [
      {
        "name": "my_custom_table",
        "family": "INET",
        "chains": [
          {
            "chaintype": "FILTER",
            "hook": "INPUT",
            "policy": "DROP",
            "priority": 0,
            "name": "my_custom_chain",
            "rules": [
              {
                "comment": "Connection initiated by the appliance",
                "rule": "ct state established,related counter name \"accept_conntrack\" accept",
                "sequence_id": 0
              },
              {
                "comment": "Appliance management API",
                "rule": "tcp dport 443 counter name \"accept_API\" accept",
                "sequence_id": 1
              },
              {
                "comment": "SSH connection",
                "rule": "tcp dport 22 counter name \"accept_ssh\" accept",
                "sequence_id": 2
              }
            ]
          }
        ],
        "counters": [
          {
            "name": "accept_conntrack"
          },
          {
            "name": "accept_API"
          },
          {
            "name": "accept_ssh"
          }
        ]
      }
    ]
  }
}

Named Counters

Each rule can include a non-verdict counter statement. Nftables distinguishes between anonymous and named counters. Named counters are defined on the table level and can be referenced in rules by their name (e.g. counter name “my_counter”). Anonymous counters are defined within the rule and can only be used in this rule.

Automatic Firewall Rule Generation

In AUTO and PREPEND mode, the appliance generates a set of firewall rules based on the other sections of the appliance configuration. The following traffic is allowed by default:

  • All established and related connections, i.e., connections that are initiated from the appliance itself.

  • Traffic on the default loopback interface lo.

  • Traffic on wireguard interfaces.

  • Traffic for port 22 (SSH) and the port of the management API (443 by default) on the management addresses.

  • Traffic for the configured telemetry endpoints.

  • SCION control plane and appliance cluster synchronization traffic.

  • BGP traffic for the configured BGP peers.

  • ICMP echo and neighbor discovery traffic.

Any other traffic that is not explicitly allowed by the rules above is dropped.

Limitations

As the appliance firewall is tightly coupled to nftables, the following limitations apply:

  • Similar to the counters, nftables supports sets. However, the appliance firewall does not support named sets but only anonymous sets. So if you want to use sets (e.g. tcp dport { 22, 23 }), you have to define them within the rule.