initial commmit
This commit is contained in:
commit
8dcad1c178
155
nft-edit-ruleset
Executable file
155
nft-edit-ruleset
Executable file
@ -0,0 +1,155 @@
|
||||
#!/bin/bash
|
||||
# summary: Interactively edit the current nftables ruleset.
|
||||
# author: Tilman Kranz
|
||||
# authoremail: tilt@linuxfoo.de
|
||||
# license: MIT License (https://opensource.org/licenses/MIT)
|
||||
|
||||
##
|
||||
# Functions
|
||||
|
||||
cleanup() {
|
||||
! "$timeout" && test -n "$tmp_old" && rm -f "$tmp_old"
|
||||
test -n "$tmp" && rm -f "$tmp"
|
||||
}
|
||||
|
||||
at_int() {
|
||||
cleanup
|
||||
exit 1
|
||||
}
|
||||
|
||||
at_exit() {
|
||||
cleanup
|
||||
}
|
||||
|
||||
set_timeout() {
|
||||
local ruleset=$1
|
||||
local seconds=$2
|
||||
|
||||
systemd-run \
|
||||
--description="Reverting nftables ruleset changes by $0 (PID=$$)" \
|
||||
--on-active="$seconds" \
|
||||
--timer-property=AccuracySec=100ms \
|
||||
--quiet \
|
||||
bash -c "nft -f '$ruleset' ; rm -f '$ruleset'"
|
||||
}
|
||||
|
||||
##
|
||||
# Arguments
|
||||
|
||||
yes=false
|
||||
fail=false
|
||||
timeout=false
|
||||
|
||||
while true ; do
|
||||
case "$1" in
|
||||
-h|--help)
|
||||
cat << EOF
|
||||
Usage: $0 [--yes] [--fail] [--timeout NUM]
|
||||
Description:
|
||||
Interactively edit the current nftables ruleset using the editor specified
|
||||
by environment variable EDITOR (defaulting to vim). Optionally, revert
|
||||
changes after a timeout given in seconds.
|
||||
Options:
|
||||
- \`-f\`, \`--fail\`: Exit unsuccessfully if changes fail to apply.
|
||||
- \`-h\`, \`--help\`: Display this message and exit.
|
||||
- \`-t NUM\`, \`--timeout NUM\`: Revert changes after NUM seconds.
|
||||
- \`-y\`, \`--yes\`: No confirmation before applying changes.
|
||||
EOF
|
||||
exit 0
|
||||
;;
|
||||
-f|--fail)
|
||||
fail=true
|
||||
;;
|
||||
-y|--yes)
|
||||
yes=true
|
||||
;;
|
||||
-t|--timeout)
|
||||
if test "$#" -gt 0 ; then
|
||||
shift 1
|
||||
timeout=true
|
||||
timeout_secs=$1
|
||||
else
|
||||
echo "ERROR: Missing argument for option \`--timeout\`, aborted."
|
||||
exit 1
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
|
||||
if test "$#" -gt 0 ; then
|
||||
shift 1
|
||||
else
|
||||
break
|
||||
fi
|
||||
done
|
||||
|
||||
##
|
||||
# Main Program
|
||||
|
||||
if ! test -t ; then
|
||||
echo "ERROR: Not connected to a terminal; aborted."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
tmp_old=$(mktemp)
|
||||
tmp=$(mktemp)
|
||||
|
||||
trap at_int INT
|
||||
trap at_exit EXIT
|
||||
|
||||
printf 'flush ruleset\n\n' > "$tmp"
|
||||
|
||||
nft list ruleset >> "$tmp"
|
||||
|
||||
cat "$tmp" > "$tmp_old"
|
||||
|
||||
while true ; do
|
||||
editor=${EDITOR:-vim}
|
||||
|
||||
"$editor" "$tmp"
|
||||
|
||||
if diff "$tmp_old" "$tmp" ; then
|
||||
echo "No changes."
|
||||
exit 0
|
||||
else
|
||||
if ! "$yes" ; then
|
||||
read -p "Apply these changes? (Y|n) " -r answer
|
||||
|
||||
case "$answer" in
|
||||
''|y|Y)
|
||||
:
|
||||
;;
|
||||
*)
|
||||
echo "Aborting (user request)."
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
|
||||
if ! nft -c -f "$tmp" ; then
|
||||
if "$fail" ; then
|
||||
exit 1
|
||||
else
|
||||
read -p "Errors in changes detected (Ctrl-c to abort, ENTER to continue editing)" -r answer
|
||||
fi
|
||||
elif ! nft -f "$tmp" ; then
|
||||
if "$fail" ; then
|
||||
exit 1
|
||||
else
|
||||
read -p "Errors when applying changes (Ctrl-c to abort, ENTER to continue editing)" -r answer
|
||||
fi
|
||||
else
|
||||
set_timeout "$tmp_old" "$timeout_secs"
|
||||
fi
|
||||
|
||||
echo "Changes applied successfully."
|
||||
|
||||
if "$timeout" ; then
|
||||
exit 0
|
||||
fi
|
||||
fi
|
||||
done
|
||||
|
||||
##
|
||||
# Exit Codes
|
||||
# - 0: Success: No changes to apply or changes applied successfully.
|
||||
# - 1: Error: Usage error or failed or aborted changes.
|
Loading…
Reference in New Issue
Block a user