#!/sbin/runscript # Copyright 2014 Nicholas Vinson # Copyright 1999-2014 Gentoo Foundation # Distributed under the terms of the GNU General Public License v2 extra_commands="clear list panic save" extra_started_commands="reload" depend() { need localmount #434774 before net } start_pre() { checkkernel || return 1 checkconfig || return 1 return 0 } clear() { if use_legacy; then clear_legacy return 0 fi nft flush ruleset } list() { if use_legacy; then list_legacy return 0 fi nft list ruleset } panic() { checkkernel || return 1 if service_started ${RC_SVCNAME}; then rc-service ${RC_SVCNAME} stop fi ebegin "Dropping all packets" clear if nft create table ip filter >/dev/null 2>&1; then nft -f /var/lib/nftables/rules-panic.ip fi if nft create table ip6 filter >/dev/null 2>&1; then nft -f /var/lib/nftables/rules-panic.ip6 fi } reload() { checkkernel || return 1 ebegin "Flushing firewall" clear start } save() { ebegin "Saving nftables state" checkpath -q -d "$(dirname "${NFTABLES_SAVE}")" checkpath -q -m 0600 -f "${NFTABLES_SAVE}" local tmp_save="${NFTABLES_SAVE}.tmp" if use_legacy; then save_legacy ${tmp_save} else nft list ruleset > ${tmp_save} fi mv ${tmp_save} ${NFTABLES_SAVE} } start() { ebegin "Loading nftables state and starting firewall" clear nft -f ${NFTABLES_SAVE} eend $? } stop() { if yesno ${SAVE_ON_STOP:-yes}; then save || return 1 fi ebegin "Stopping firewall" clear eend $? } ################################################################################ # # SUPPORT FUNCTIONS # ################################################################################ checkconfig() { if [ ! -f ${NFTABLES_SAVE} ]; then eerror "Not starting nftables. First create some rules then run:" eerror "rc-service nftables save" return 1 fi return 0 } checkkernel() { if ! nft list tables >/dev/null 2>&1; then eerror "Your kernel lacks nftables support, please load" eerror "appropriate modules and try again." return 1 fi return 0 } use_legacy() { local major_ver minor_ver major_ver=`uname -r | cut -d '.' -f1` minor_ver=`uname -r | cut -d '.' -f2` [[ $major_ver -ge 4 || $major_ver -eq 3 && $minor_ver -ge 18 ]] && return 1 return 0 } ################################################################################ # # LEGACY COMMAND FUNCTIONS # ################################################################################ clear_legacy() { local l3f line table chain first_line first_line=1 if manualwalk; then for l3f in $(getfamilies); do nft list tables ${l3f} | while read line; do table=$(echo ${line} | sed "s/table[ \t]*//") deletetable ${l3f} ${table} done done else nft list tables | while read line; do l3f=$(echo ${line} | cut -d ' ' -f2) table=$(echo ${line} | cut -d ' ' -f3) deletetable ${l3f} ${table} done fi } list_legacy() { local l3f if manualwalk; then for l3f in $(getfamilies); do nft list tables ${l3f} | while read line; do line=$(echo ${line} | sed "s/table/table ${l3f}/") echo "$(nft list ${line})" done done else nft list tables | while read line; do echo "$(nft list ${line})" done fi } save_legacy() { tmp_save=$1 touch "${tmp_save}" if manualwalk; then for l3f in $(getfamilies); do nft list tables ${l3f} | while read line; do line=$(echo ${line} | sed "s/table/table ${l3f}/") nft ${SAVE_OPTIONS} list ${line} >> ${tmp_save} done done else nft list tables | while read line; do nft ${SAVE_OPTIONS} list ${line} >> "${tmp_save}" done fi } ################################################################################ # # LEGACY SUPPORT FUNCTIONS # ################################################################################ CHECK_TABLE_NAME="GENTOO_CHECK_TABLE" getfamilies() { local l3f families for l3f in ip arp ip6 bridge inet; do if nft create table ${l3f} ${CHECK_TABLE_NAME} > /dev/null 2>&1; then families="${families}${l3f} " nft delete table ${l3f} ${CHECK_TABLE_NAME} fi done echo ${families} } manualwalk() { local result l3f=`getfamilies | cut -d ' ' -f1` nft create table ${l3f} ${CHECK_TABLE_NAME} nft list tables | read line if [ $(echo $line | wc -w) -lt 3 ]; then result=0 fi result=1 nft delete table ${l3f} ${CHECK_TABLE_NAME} return $result } deletetable() { # family is $1 # table name is $2 nft flush table $1 $2 nft list table $1 $2 | while read l; do chain=$(echo $l | grep -o 'chain [^[:space:]]\+' | cut -d ' ' -f2) if [ -n "${chain}" ]; then nft flush chain $1 $2 ${chain} nft delete chain $1 $2 ${chain} fi done nft delete table $1 $2 }