nftables: Overriding the default configuration file

664 Views Asked by At

Imagine there's some application that does a silly thing, like configuring and over-writing all the firewall rules in /etc/nftables.conf and enabling said firewall with every update (even though the host itself is already behind a firewall and this is largely redundant).

This while there's some other things running on the same server which need to be accessed from external sources, like a backup client. While I could setup firewall rules to allow these other applications to function by modifying the default config and restarting the firewall they would continuously break.

I found putting the extra rules in a different file protects them from vandalism. Now I want nftables to load both files, but give the rules in my file priority. This seems like a simple task, but nftables is uniquely byzantinely complicated to do this with. Here's some of the requirements:

  • I do not know what the input chain actually is called on each server. It could be inet.input or ip4.INPUT or ip.input or ip4.Input. The closed-source stuff it's running probably comes from a windows environment where devs don't care, but linux be case-sensitive. The nftables definition is also case-sensitive and if misnamed my rules have no effect.

So far, my solution is the following:

First, I modify /lib/systemd/system/nftables.service to instead point to /etc/nftables.main.conf. Then change this file to include:

include "/etc/nftables.conf"
include "/etc/nftables/*"

Where the latter directory then contains my modifications to be applied on top of the default rules. Yet doing so seems to append the rules to the chains if named correctly.

  • Is there an easy way to prepend such a rule?
  • Is there an easy way to refer to "the ipv4 chain, earliest in the filtering process as possible", which will work reliably, even if the closed source messy program did a messy thing not having consistent chain names ?

An example file of what I'd like to prepend:

table inet filter {
    chain input {
        jump myappA
        jump myappB
    }
    chain myappA { 
        ip saddr 1.2.3.4 tcp dport {appA-agent, appA-scanner} accept comment "example app A"
    }
    chain myappB { 
        ip saddr 1.2.3.5 tcp dport {appBport} accept comment "example app B"
    }
}
0

There are 0 best solutions below