Tables in nftables hold chains. Each table only has one address family and only applies
to packets of this family. Tables can have one of six families.
Chains are containers for rules. They exist in two kinds, base chains and regular chains.
A base chain is an entry point for packets from the networking stack, a regular chain may
be used as jump target and is used for better rule organization.
warning alert:
Warning
Configuring rules over ssh, by creating a base chain with policy drop will cause loss of connectivity. Ensure that a rule allowing ssh has been added to the base chain prior to setting the base cahin's policy to drop
Rationale
If a base chain doesn't exist with a hook for input, forward, and delete, packets that would
flow through those chains will not be touched by nftables.
# Remediation is applicable only in certain platforms
if dpkg-query --show --showformat='${db:Status-Status}\n' 'nftables' 2>/dev/null | grep -q installed; then
#Name of the table
var_nftables_table='<xccdf-1.2:sub xmlns:xccdf-1.2="http://checklists.nist.gov/xccdf/1.2" idref="xccdf_org.ssgproject.content_value_var_nftables_table" use="legacy"/>'
#Familiy of the table
var_nftables_family='<xccdf-1.2:sub xmlns:xccdf-1.2="http://checklists.nist.gov/xccdf/1.2" idref="xccdf_org.ssgproject.content_value_var_nftables_family" use="legacy"/>'
#Name(s) of base chain
var_nftables_base_chain_names='<xccdf-1.2:sub xmlns:xccdf-1.2="http://checklists.nist.gov/xccdf/1.2" idref="xccdf_org.ssgproject.content_value_var_nftables_base_chain_names" use="legacy"/>'
#Type(s) of base chain
var_nftables_base_chain_types='<xccdf-1.2:sub xmlns:xccdf-1.2="http://checklists.nist.gov/xccdf/1.2" idref="xccdf_org.ssgproject.content_value_var_nftables_base_chain_types" use="legacy"/>'
# Hooks for base chain
var_nftables_base_chain_hooks='<xccdf-1.2:sub xmlns:xccdf-1.2="http://checklists.nist.gov/xccdf/1.2" idref="xccdf_org.ssgproject.content_value_var_nftables_base_chain_hooks" use="legacy"/>'
#Priority
var_nftables_base_chain_priorities='<xccdf-1.2:sub xmlns:xccdf-1.2="http://checklists.nist.gov/xccdf/1.2" idref="xccdf_org.ssgproject.content_value_var_nftables_base_chain_priorities" use="legacy"/>'
#Policy
var_nftables_base_chain_policies='<xccdf-1.2:sub xmlns:xccdf-1.2="http://checklists.nist.gov/xccdf/1.2" idref="xccdf_org.ssgproject.content_value_var_nftables_base_chain_policies" use="legacy"/>'
#Transfer some of strings to arrays
IFS="," read -r -a names <<< "$var_nftables_base_chain_names"
IFS="," read -r -a types <<< "$var_nftables_base_chain_types"
IFS="," read -r -a hooks <<< "$var_nftables_base_chain_hooks"
IFS="," read -r -a priorities <<< "$var_nftables_base_chain_priorities"
IFS="," read -r -a policies <<< "$var_nftables_base_chain_policies"
my_cmd="nft list tables | grep '$var_nftables_family $var_nftables_table'"
eval IS_TABLE_EXIST=\$\($my_cmd\)
if [ -z "$IS_TABLE_EXIST" ]
then
# We create a table and add chains to it
nft create table "$var_nftables_family" "$var_nftables_table"
num_of_chains=${#names[@]}
for ((i=0; i < num_of_chains; i++))
do
chain_to_add="add chain $var_nftables_family $var_nftables_table ${names[$i]} { type ${types[$i]} hook ${hooks[$i]} priority ${priorities[$i]} ; policy ${policies[$i]} ; }"
my_cmd="nft '$chain_to_add'"
eval $my_cmd
done
else
# We add missing chains to the existing table
num_of_chains=${#names[@]}
for ((i=0; i < num_of_chains; i++))
do
IS_CHAIN_EXIST=$(nft list table "$var_nftables_family" "$var_nftables_table" | grep "hook ${hooks[$i]}")
if [ -z "$IS_CHAIN_EXIST" ]
then
chain_to_add="add chain '$var_nftables_family' '$var_nftables_table' ${names[$i]} { type ${types[$i]} hook ${hooks[$i]} priority ${priorities[$i]} ; policy ${policies[$i]} ; }"
my_cmd="nft '$chain_to_add'"
eval $my_cmd
fi
done
fi
else
>&2 echo 'Remediation is not applicable, nothing was done'
fi