|
|
|
#!/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
|
|
|
|
}
|
|
|
|
|
|
|
|
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
|
|
|
|
}
|
|
|
|
|
|
|
|
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
|
|
|
|
}
|
|
|
|
|
|
|
|
getfamilies() {
|
|
|
|
local families
|
|
|
|
for l3f in ip arp ip6 bridge inet; do
|
|
|
|
if nft list tables ${l3f} > /dev/null 2>&1; then
|
|
|
|
families="${families}${l3f} "
|
|
|
|
fi
|
|
|
|
done
|
|
|
|
echo ${families}
|
|
|
|
}
|
|
|
|
|
|
|
|
clearNFT() {
|
|
|
|
local l3f line table chain
|
|
|
|
|
|
|
|
for l3f in $(getfamilies); do
|
|
|
|
nft list tables ${l3f} | while read line; do
|
|
|
|
table=$(echo ${line} | sed "s/table[ \t]*//")
|
|
|
|
nft flush table ${l3f} ${table}
|
|
|
|
nft list table ${l3f} ${table} | while read l; do
|
|
|
|
chain=$(echo $l | grep -o 'chain [^[:space:]]\+' |\
|
|
|
|
cut -d ' ' -f2)
|
|
|
|
if [ -n "${chain}" ]; then
|
|
|
|
nft flush chain ${l3f} ${table} ${chain}
|
|
|
|
nft delete chain ${l3f} ${table} ${chain}
|
|
|
|
fi
|
|
|
|
done
|
|
|
|
nft delete table ${l3f} ${table}
|
|
|
|
done
|
|
|
|
done
|
|
|
|
}
|
|
|
|
|
|
|
|
addpanictable() {
|
|
|
|
local l3f=$1
|
|
|
|
nft add table ${l3f} panic
|
|
|
|
nft add chain ${l3f} panic input \{ type filter hook input priority 0\; \}
|
|
|
|
nft add chain ${l3f} panic output \{ type filter hook output priority 0\; \}
|
|
|
|
nft add chain ${l3f} panic forward \{ type filter hook forward priority 0\; \}
|
|
|
|
nft add rule ${l3f} panic input drop
|
|
|
|
nft add rule ${l3f} panic output drop
|
|
|
|
nft add rule ${l3f} panic forward drop
|
|
|
|
}
|
|
|
|
|
|
|
|
start_pre() {
|
|
|
|
checkkernel || return 1
|
|
|
|
checkconfig || return 1
|
|
|
|
return 0
|
|
|
|
}
|
|
|
|
|
|
|
|
start() {
|
|
|
|
ebegin "Loading nftables state and starting firewall"
|
|
|
|
clearNFT
|
|
|
|
nft -f ${NFTABLES_SAVE}
|
|
|
|
eend $?
|
|
|
|
}
|
|
|
|
|
|
|
|
stop() {
|
|
|
|
if yesno ${SAVE_ON_STOP:-yes}; then
|
|
|
|
save || return 1
|
|
|
|
fi
|
|
|
|
|
|
|
|
ebegin "Stopping firewall"
|
|
|
|
clearNFT
|
|
|
|
eend $?
|
|
|
|
}
|
|
|
|
|
|
|
|
reload() {
|
|
|
|
checkkernel || return 1
|
|
|
|
# checkrules || return 1
|
|
|
|
ebegin "Flushing firewall"
|
|
|
|
clearNFT
|
|
|
|
|
|
|
|
start
|
|
|
|
}
|
|
|
|
|
|
|
|
clear() {
|
|
|
|
clearNFT
|
|
|
|
}
|
|
|
|
|
|
|
|
list() {
|
|
|
|
local l3f
|
|
|
|
|
|
|
|
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
|
|
|
|
}
|
|
|
|
|
|
|
|
save() {
|
|
|
|
ebegin "Saving nftables state"
|
|
|
|
checkpath -q -d "$(dirname "${NFTABLES_SAVE}")"
|
|
|
|
checkpath -q -m 0600 -f "${NFTABLES_SAVE}"
|
|
|
|
|
|
|
|
local l3f line tmp_save="${NFTABLES_SAVE}.tmp"
|
|
|
|
|
|
|
|
touch "${tmp_save}"
|
|
|
|
for l3f in $(getfamilies); do
|
|
|
|
nft list tables ${l3f} | while read line; do
|
|
|
|
line=$(echo ${line} | sed "s/table/table ${l3f}/")
|
|
|
|
# The below substitution fixes an issue where nft -n output may not
|
|
|
|
# always be parsable by nft -f. For example, nft -n might print
|
|
|
|
#
|
|
|
|
# ip6 saddr ::1 ip6 daddr ::1 counter packets 0 bytes 0 accept
|
|
|
|
#
|
|
|
|
# but nft -f refuses to parse that string with error:
|
|
|
|
#
|
|
|
|
# In file included from internal:0:0-0:
|
|
|
|
# /var/lib/nftables/rules-save:1:1-2: Error: Could not process rule:
|
|
|
|
# Invalid argument
|
|
|
|
# table ip6 filter {
|
|
|
|
# ^^
|
|
|
|
echo "$(nft ${SAVE_OPTIONS} list ${line} |\
|
|
|
|
sed 's/\(::[0-9a-fA-F]\+\)\([^/]\)/\1\/128\2/g')" >> "${tmp_save}"
|
|
|
|
done
|
|
|
|
done
|
|
|
|
mv "${tmp_save}" "${NFTABLES_SAVE}"
|
|
|
|
}
|
|
|
|
|
|
|
|
panic() {
|
|
|
|
checkkernel || return 1
|
|
|
|
if service_started ${RC_SVCNAME}; then
|
|
|
|
rc-service ${RC_SVCNAME} stop
|
|
|
|
fi
|
|
|
|
|
|
|
|
ebegin "Dropping all packets"
|
|
|
|
clearNFT
|
|
|
|
|
|
|
|
local l3f
|
|
|
|
for l3f in $(getfamilies); do
|
|
|
|
case ${l3f} in
|
|
|
|
ip) addpanictable ${l3f} ;;
|
|
|
|
ip6) addpanictable ${l3f} ;;
|
|
|
|
esac
|
|
|
|
done
|
|
|
|
}
|