Reverse nft firewall rules after shutdown.

This commit is contained in:
redxef 2022-03-12 03:57:49 +01:00
parent be4e4da61e
commit 6fd1f9438a
Signed by: redxef
GPG key ID: 7DAC3AA211CBD921

111
net
View file

@ -26,6 +26,93 @@ find_next_subnet() {
echo "172.$i"
}
nft_rev() {
local family
local table
local chain
local protocol
local field
local port
local policy
local filter
local remove
source "$NET_CONF_FILE"
family="$3"
table="$4"
chain="$5"
if [[ "$chain" = 'INPUT' ]]; then
protocol="$6"
field="$7"
port="$8"
policy="$9"
filter="
.nftables[] | select(.rule) | .rule
| select(.family|test(\"$family\"))
| select(.table|test(\"$table\"))
| select(.chain|test(\"$chain\"))
| select(.expr[0]?.match?.op)
| select(.expr[0]?.match?.left?.payload?.protocol)
| select(.expr[0]?.match?.left?.payload?.field)
| select(.expr[0]?.match?.right)
| select(.expr[1]?.$policy == null)
| select(.expr[0].match.op == \"==\")
| select(.expr[0].match.left.payload.protocol == \"$protocol\")
| select(.expr[0].match.left.payload.field == \"$field\")
| select(.expr[0].match.right == $port)
| .handle
"
remove="
echo nft delete rule $table $chain handle \$handle
nft delete rule $table $chain handle \$handle
"
elif [[ "$chain" = 'FORWARD' ]]; then
key="$6"
ifname="$7"
policy="${13}"
filter="
.nftables[] | select(.rule) | .rule
| select(.family|test(\"$family\"))
| select(.table|test(\"$table\"))
| select(.chain|test(\"$chain\"))
| select(.expr[0]?.match?.op)
| select(.expr[0]?.match?.left?.meta?.key)
| select(.expr[0]?.match?.right)
| select(.expr[2]?.$policy == null)
| select(.expr[0].match.op == \"==\")
| select(.expr[0].match.left.meta.key == \"$key\")
| select(.expr[0].match.right == \"$ifname\")
| .handle
"
remove="
echo nft delete rule $table $chain handle \$handle
nft delete rule $table $chain handle \$handle
"
else
echo "Warning: Don't know how to reverse 'nft $@'" 1>&2
nft "$@"
return 0
fi
set +u
if [[ -z "$restore_nft_file" ]]; then
restore_nft_file="$(mktemp)"
echo "#!/usr/bin/env sh" > "$restore_nft_file"
chmod 700 "$restore_nft_file"
chown root:root "$restore_nft_file"
echo "restore_nft_file=$restore_nft_file" >> "$NET_CONF_FILE"
fi
set -u
echo "handle=\"\$(nft --json list ruleset | jq '$filter')\"" >> "$restore_nft_file"
echo "$remove" >> "$restore_nft_file"
nft "$@"
}
create() {
local next_subnet
@ -61,21 +148,21 @@ create() {
echo "nft_ruleset='$(nft -s list ruleset)'" >> "$NET_CONF_FILE"
# dhcp
nft add rule ip filter INPUT udp dport 67 accept
nft add rule ip filter INPUT tcp dport 67 accept
nft_rev add rule ip filter INPUT udp dport 67 accept
nft_rev add rule ip filter INPUT tcp dport 67 accept
# dns
nft add rule ip filter INPUT udp dport 53 accept
nft add rule ip filter INPUT tcp dport 53 accept
nft_rev add rule ip filter INPUT udp dport 53 accept
nft_rev add rule ip filter INPUT tcp dport 53 accept
# scream
nft add rule ip filter INPUT udp dport 4010 accept
nft add rule ip filter INPUT tcp dport 4010 accept
nft_rev add rule ip filter INPUT udp dport 4010 accept
nft_rev add rule ip filter INPUT tcp dport 4010 accept
# forward bridge
nft add rule ip filter FORWARD iifname "$bridge_name" \
nft_rev add rule ip filter FORWARD iifname "$bridge_name" \
counter packets 0 bytes 0 accept
nft add rule ip filter FORWARD oifname "$bridge_name" \
nft_rev add rule ip filter FORWARD oifname "$bridge_name" \
counter packets 0 bytes 0 accept
nft add rule ip nat POSTROUTING oifname "$(default_route)" \
nft_rev add rule ip nat POSTROUTING oifname "$(default_route)" \
counter masquerade
}
@ -85,8 +172,10 @@ delete() {
kill "$dnsmasq_pid"
ip link del "$tap_name"
ip link del "$bridge_name"
nft flush ruleset
nft -f - <<< "$nft_ruleset"
# nft flush ruleset
# nft -f - <<< "$nft_ruleset"
"$restore_nft_file"
rm "$restore_nft_file"
rm "$NET_CONF_FILE"
}