Advanced ruleset for dynamic environments: Difference between revisions
Jeff.welling (talk | contribs) (Added a use case) |
Jeff.welling (talk | contribs) m (Figured out and documented kernel versions for table creation implicit vs explicit) |
||
(One intermediate revision by the same user not shown) | |||
Line 3: | Line 3: | ||
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 [https://www.consul.io/ Consul] and [https://www.hashicorp.com/blog/introducing-consul-template Consul Template], [https://www.vaultproject.io/ Vault], or config management like [https://www.chef.io/solutions/infrastructure-automation/ Chef] [https://puppet.com/ Puppet] or [https://www.ansible.com/ Ansible]. | 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 [https://www.consul.io/ Consul] and [https://www.hashicorp.com/blog/introducing-consul-template Consul Template], [https://www.vaultproject.io/ Vault], or config management like [https://www.chef.io/solutions/infrastructure-automation/ Chef] [https://puppet.com/ Puppet] or [https://www.ansible.com/ Ansible]. | ||
An example use case would be if you had a number of servers, and you detected traffic on one host that you'd like to block across your entire fleet. You could add the IP to block into Consul, which will propagate it out and then Consul Template on each hosts updates nftables blacklist set definition with the new blacklisted IP and reloads nftables. | An example use case would be if you had a number of servers, and you detected traffic on one host that you'd like to block across your entire fleet. You could add the IP to block into Consul, which will propagate it out and then Consul Template on each hosts updates nftables blacklist set definition with the new blacklisted IP and reloads nftables. Alternatively if you don't trust Consul due to the lack of an execution guarantee, you could put the blocked IP in an Ansible var and deploy it everywhere through your configuration management system. | ||
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 [https://unix.stackexchange.com/questions/206315/what-is-difference-between-usr-lib-and-etc-systemd 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. | 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 [https://unix.stackexchange.com/questions/206315/what-is-difference-between-usr-lib-and-etc-systemd 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. | ||
Line 20: | Line 20: | ||
Called from Systemd service file for nftables in ''ExecStart='' | 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. | 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. | ||
'''Note:''' If you use Debian Stretch or a newer kernel (Linux Kernel >=4.9.0), this isn't necessary - the table creation will be handled implicitly so you can just add a 'flush ruleset' to ''/etc/nftables.conf'', update ''/etc/systemd/system/nftables.service'' so ''ExecStart='' points to ''/etc/nftables.conf'', and delete ''/etc/nftables.start.conf''. | |||
Example contents of ''/etc/nft.conf.d/nftables.start.conf'': | Example contents of ''/etc/nft.conf.d/nftables.start.conf'': |
Latest revision as of 01:32, 27 January 2018
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.
An example use case would be if you had a number of servers, and you detected traffic on one host that you'd like to block across your entire fleet. You could add the IP to block into Consul, which will propagate it out and then Consul Template on each hosts updates nftables blacklist set definition with the new blacklisted IP and reloads nftables. Alternatively if you don't trust Consul due to the lack of an execution guarantee, you could put the blocked IP in an Ansible var and deploy it everywhere through your configuration management system.
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.
TODO: Is /etc/nftables.start.conf really necessary? In a Debian test system on Linux 4.9.0, Debian Stretch, Nftables version v0.7, this file is not necessary - table creation is implicit from the table definition, for both 'inet' and 'ip' table types. This differs from my tests on the system I've lost access to at the moment, this needs to be explored once the host is reset. Note version numbers if the behaviour changed.
/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.
Note: If you use Debian Stretch or a newer kernel (Linux Kernel >=4.9.0), this isn't necessary - the table creation will be handled implicitly so you can just add a 'flush ruleset' to /etc/nftables.conf, update /etc/systemd/system/nftables.service so ExecStart= points to /etc/nftables.conf, and delete /etc/nftables.start.conf.
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
}
}