#!/bin/bash . `dirname $0`/functions option confdir standard_option /etc/nftables option config standard_option rules.conf option hashsize standard_option 65536 option conntrack option_conntrack option modprobe multiple_option option bin reserved_option /usr/sbin/nft option cmdline reserved_option conntrack_args=( ) function do_help { echo "Usage: ${0##*/} " echo "List of config.rc options (name, type, default value, current value) :" echo echo " - confdir : dir ; def='/etc/nftables' ; cur=$opt_confdir" echo " - config : file ; def='rules.conf' ; cur=$opt_config" echo " - hashsize : integer ; def=65536 ; cur=$opt_hashsize" echo " - conntrack: var=val ; eg: max=1048576 ; cur='${conntrack_args[@]}'" echo " - modprobe : mod arg ; eg: nf_nat_ftp ; cur='${opt_modprobe[@]}'" echo echo "The configuration file is $opt_confdir/$opt_current/conf-$(uname -n).ipt" echo exit 1 } ############################################################################### # internal functions ############################################################################### # checks wether the core firewall modules are loaded # returns 0 if they are, 1 if not. function check_modules { test -d /sys/module/nf_tables/. } # loads the extra firewall modules. It is assumed that these modules are not # loaded yet (check with check_modules) if unsure. function load_modules { local arg # now load all user-supplied modules arg=0 while [ $arg -lt ${#opt_modprobe[*]} ]; do if [ "${opt_modprobe[$arg]}" != "#" ]; then /sbin/modprobe ${opt_modprobe[$arg]} || { echo "Warning: could not load module ${opt_modprobe[$arg]}"; return 1; } fi arg=$[$arg+1] done return 0 } # unloads all firewall modules unconditionally. Note: this can take some time # if the session cache is heavily loaded. function unload_modules { nft flush ruleset recursive_rmmod nf_nat_masquerade_ipv4 recursive_rmmod nf_nat_masquerade_ipv6 recursive_rmmod nf_nat_ipv4 recursive_rmmod nf_nat_ipv6 recursive_rmmod nf_conntrack recursive_rmmod nftables recursive_rmmod nfnetlink } # applies the various conntrack settings. Assumes the module to be loaded. It # returns 0 on success, otherwise 1. function apply_conntrack_settings { local arg var val local sys=/proc/sys/net/ipv4/netfilter if [ ! -e /proc/sys/net/ipv4/netfilter ]; then echo "Warning: netfilter not loaded!" return 1 fi if [ ! -e /proc/sys/net/ipv4/nf_conntrack_max ]; then echo "Warning: conntrack not loaded!" return 1 fi if [ -e /sys/module/nf_conntrack/parameters/hashsize ]; then echo $opt_hashsize > /sys/module/nf_conntrack/parameters/hashsize fi for arg in "${conntrack_args[@]}"; do var=${arg%%=*} ; val=${arg##*=} if [ -e "$sys/nf_conntrack_$var" ]; then echo "$val" > "$sys/nf_conntrack_$var" else echo "Warning: no equivalent sysctl for 'conntrack $var' in configuration file $CONFIG." fi done return 0 } # this function loads the specified policy file, then updates the various # conntrack settings, assuming that nft will have caused the conntrack # module to be loaded if needed. It returns 0 if the policy could be loaded, # or 1 if not. function load_rules { [ -n "$1" ] || return 1 [ -r "$opt_confdir/$1" ] || return 1 if ! /usr/sbin/nft -f "$opt_confdir/$1"; then return 1 fi if [ -e /proc/sys/net/ipv4/nf_conntrack_max ]; then apply_conntrack_settings fi return 0 } # flushes all firewall rules in all tables. # this function assumes that the firewall modules are already loaded. function flush_rules { /usr/sbin/nft flush ruleset return 0 } # loads policy from file $1. returns 0 on success, 1 on failure. function verbose_load { echo -n "nftables: loading policy... " if load_rules $1; then echo "OK." return 0 fi echo "FAILED." return 1 } ############################################################################### # special functions to handle config parameters ############################################################################### # usage: conntrack '=' # eg: conntrack max=12000 function option_conntrack { local arg shift arg="$*" if [ -z "$arg" -o -n "${arg//*=*/}" ]; then echo "nftables: unknown argument 'conntrack $*' in configuration file $CONFIG." return 1 fi set -- ${arg/=/ } conntrack_args=( "${conntrack_args[@]}" "$1=$2" ) } ############################################################################### # exported functions ############################################################################### # checks wether the firewall modules are loaded function do_status { if check_modules; then echo "nftables modules are loaded." return 0 fi echo "nftables modules are not loaded." return 1 } # load current configuration, blocking traffic and starting with empty rules function do_start { if ! [ -r "$opt_confdir/$opt_config" ]; then echo "nftables: rules file $opt_confdir/$opt_config absent, not loading." return 0 fi if ! check_modules; then echo -n "nftables: loading modules... " if ! load_modules; then echo "FAILED" return 1 else echo "OK." fi fi echo -n "nftables: flushing all rules... " flush_rules echo "OK." verbose_load "$opt_config" } # stops the firewall and unloads the modules function do_stop { if check_modules; then echo -n "nftables: flushing all rules... " ; flush_rules ; echo "OK." echo -n "nftables: unloading modules... " ; unload_modules ; echo "OK." else echo "nftables: already stopped." fi return 0 } # reloads configuration without blocking traffic function do_reload { if ! check_modules; then echo -n "nftables: loading modules... " if ! load_modules; then echo "FAILED" return 1 else echo "OK." fi fi verbose_load "$opt_config" } load_config