Advanced ruleset for dynamic environments

From nftables wiki
Revision as of 21:03, 26 January 2018 by Jeff.welling (talk | contribs)
Jump to navigation Jump to search

This page is an unvetted draft

Today's modern computing environments require features like Service Discovery and the environments themselves can be quite dynamic and rapidly changing. One of the ways nftables can help is by breaking firewall config into small pieces which can by dynamically generated by the likes of Consul and Consul Template, Vault, or config management like Chef Puppet or Ansible.

By default your Systemd service file likely lives in /lib/systemd/system/, the values suggested on this page are not default so you may wish to change those values. If you do, it's best practice to copy the nftables.service file to /etc/systemd/system where it will override the system-provided version without the need to modify files provided by the package.

There's nothing wrong with using a different layout, or even having everything in one file. This author prefers to split out rules and sets into individual files so that grouping them together by application or purpose is easier, you can use any configuration structure you wish.


/etc/nftables.start.conf

Creates tables

Loads /etc/nftables.conf

Called from Systemd service file for nftables in ExecStart=

The table creation statements are kept intentionally separate in this example so that its compatible with both config file formats. With the nftables-output config format, table creation statements cannot be used after the table is already created or an error is thrown, aborting the config reload.

Example contents of /etc/nft.conf.d/nftables.start.conf:

create table ip filter
create table ip nat
include "/etc/nftables.conf"


/etc/nftables.conf

Loads table-specific entries like /etc/nft.conf.d/nftables.ip.filter.conf and /etc/nft.conf.d/nftables.ip.nat.conf

Loads Sets main file /etc/nft.conf.d/sets.d/main.conf

Called from Systemd service file for nftables in ExecReload=

Example content of /etc/nftables.conf:

include "/etc/nft.conf.d/sets.d/main.conf"
include "/etc/nft.conf.d/nftables.ip.filter.conf"
include "/etc/nft.conf.d/nftables.ip.nat.conf"
include "/etc/nft.conf.d/nftables.test1.conf"
include "/etc/nft.conf.d/nftables.test2.conf"


/etc/nft.conf.d/sets.d/main.conf

Loads each individual Set, because nftables doesn't support wildcards in include statements (yet?)

Called only from the include in /etc/nftables.conf

Example content of /etc/nft.conf.d/sets.d/main.conf:

include "/etc/nft.conf.d/sets.d/trusted_ips1.conf"
include "/etc/nft.conf.d/sets.d/trusted_ips2.conf"
include "/etc/nft.conf.d/sets.d/family_ips.conf"

Example of an included set /etc/nft.conf.d/sets.d/trusted_ips1.conf:

table ip filter {
	set trusted_ips {
		type ipv4_addr
		elements = { 192.168.1.1}
	}
}

Example of included set /etc/nft.conf.d/sets.d/trusted_ips2.conf:

table ip filter {
	set trusted_ips {
		type ipv4_addr
		elements = { 192.168.2.2}
	}
}

Example of included set /etc/nft.conf.d/sets.d/family_ips.conf:

table ip filter {
	set family_ips {
		type ipv4_addr
		elements = { 192.168.3.3}
	}
}

Example of how the configuration is combined:

% nft list table ip filter
table ip filter {
	set trusted_ips {
		type ipv4_addr
		elements = { 192.168.2.2, 192.168.1.1}
	}
	set family_ips {
		type ipv4_addr
		elements = { 192.168.3.3}
	}
}


/etc/nft.conf.d/nftables.ip.filter.conf

Configures the 'ip filter' table

Called from /etc/nftables.conf

Example content:

flush table ip filter
table ip filter {
	set trusted_ips {
		type ipv4_addr
		elements = { 192.168.2.2, 192.168.1.1}
	}

	chain input {
		#This is required to get input traffic to process this chain
		type filter hook input priority 0; policy drop;

		#Accept all traffic from the LAN, and any traffic related to already-active connections
		ip saddr 192.168.1.0/24 counter packets 0 bytes 0 accept
		ct state established,related counter packets 6471 bytes 337740 accept

		#Accept SSH connections from everywhere, not just the LAN
		tcp dport ssh counter packets 0 bytes 0 accept

		#We want logs of the drops. If you don't, remove this line.
		log prefix "nft-input-drop " level debug counter packets 112 bytes 8404 drop
	}

	chain output {
		#This is required to get output traffic to process this chain
		type filter hook output priority 0; policy drop;

		#Accept all outbound traffic 
		oif "eth1" counter packets 0 bytes 0 accept

		#We want logs of the drops. If you don't, remove this line.
		log prefix "nft-output-drop " level debug counter packets 0 bytes 0 drop
	}

	chain forward {
		#This is required to get forward traffic to process this chain
		type filter hook forward priority 0; policy drop;

		#We want logs of the drops. If you don't, remove this line.
		log prefix "nft-forward-drop " level debug counter packets 104 bytes 4910 drop
	}
}


/etc/nft.conf.d/nftables.ip.nat.conf

Configures the 'ip nat' table

Called from /etc/nftables.conf

Example contents of /etc/nft.conf.d/nftables.ip.nat.conf:

flush table nat
table ip nat {
  chain prerouting {
    type filter hook prerouting priority 0
  }
  chain postrouting {
    type filter hook postrouting priority 100
  }
}