Table of Contents

ACL rules with nftables

The routing daemon runs in a separate network namespace (router in the examples), so access to rib interfaces must be restricted with firewall rules inside this netns. firewalld is not suitable for this: it cannot be run as a second instance in another netns and managed with firewall-cmd. Therefore, rules for the router netns are set directly with nftables. Below, they are loaded at system startup by a separate systemd unit.

firewalld must use nftables as its backend: the FirewallBackend=nftables parameter in /etc/firewalld/firewalld.conf.
All commands are run as root (via sudo).

Step 1. Create the rules file

File: /etc/nftables/bgp-allow.nft. The file name can be anything; it is specified later in the systemd unit.

#!/usr/sbin/nft -f

flush ruleset

# IP addresses of BGP peers allowed to connect
define bgp_ipv4_peers = {
    172.16.25.168
}

table inet filter {
    chain INPUT {
        type filter hook input priority filter; policy drop;

        ct state established,related accept
        iif lo accept

        # Allow all traffic from BGP peers
        ip saddr $bgp_ipv4_peers accept

        # Stricter option: allow only BGP (TCP 179) from peers
        #tcp dport 179 ip saddr $bgp_ipv4_peers accept
    }
}
The chain policy is drop: everything that is not explicitly allowed is dropped. If other protocols are used in the router netns, add rules that allow them. For example:
  • for OSPF — ip protocol ospf accept;
  • for IPv6 — meta l4proto ipv6-icmp accept, otherwise Neighbor Discovery stops working.
The flush ruleset command clears rules only in the netns where the file is executed. The main system rules are not affected.

Step 2. Restrict file permissions

chmod 600 /etc/nftables/bgp-allow.nft

Step 3. Create a systemd unit

File: /etc/systemd/system/nftables.netns.service

[Unit]
Description=nftables rules for netns router
Documentation=man:nft(8)
# Unit that starts the routing daemon in netns router
Wants=bird.netns.service
After=bird.netns.service

[Service]
Type=oneshot
ProtectSystem=full
ProtectHome=true
# Specify the file name from step 1 and the netns name from the router_netns parameter
ExecStart=/sbin/ip netns exec router /usr/sbin/nft -f /etc/nftables/bgp-allow.nft
ExecReload=/sbin/ip netns exec router /usr/sbin/nft 'flush ruleset; include "/etc/nftables/bgp-allow.nft";'
ExecStop=/sbin/ip netns exec router /usr/sbin/nft flush ruleset
RemainAfterExit=yes

[Install]
WantedBy=multi-user.target

Step 4. Reload the systemd configuration

systemctl daemon-reload

Step 5. Start the unit and enable it at startup

systemctl enable --now nftables.netns.service

Step 6. Check that the rules are loaded in the router netns

ip netns exec router nft list ruleset