diff options
Diffstat (limited to 'scripts/sh')
-rw-r--r-- | scripts/sh/pf.sh | 129 |
1 files changed, 129 insertions, 0 deletions
diff --git a/scripts/sh/pf.sh b/scripts/sh/pf.sh new file mode 100644 index 0000000..0014168 --- /dev/null +++ b/scripts/sh/pf.sh @@ -0,0 +1,129 @@ +#!/bin/sh +# +# Helps you edit a production packet filter configuration and reduces the risk of doing something really bad. +# +# Author: Georg Pfuetzenreuter <georg@lysergic.dev> +# Last edit: 02/11/2021 +# +# This assumes .ssh/config being configured to ssh into your router with a user having write access to /tmp/* and $prodfile as well as having doas permissions for `pfctl -f $prodfile`. + +editor="$(which vim)" +prodfile="/etc/pf.conf" +backupfile="/tmp/pf.conf.bak-$(date -u +%d%m%y-%H%M)" +stagefile="/tmp/pf.conf-work-$USER-$(date -u +%d%m%y-%H%M)" + +gethostaddress () { + ssh -G "$host" |grep hostname |awk '{print $2}' |head -n1 +} + +init () { + hostaddress=$(gethostaddress) + if nc -nz $hostaddress 22 2>/dev/null; then + workfile="/tmp/pf.conf.$host-$USER-$(date -u +%d%m%y-%H%M)" + ssh -q $host cp $prodfile $backupfile + scp -q $host:$prodfile $workfile + edit + else + echo "Host not reachable." + fi +} + + +edit () { + if [ ! -f "$workfile" ]; then + echo "Could not create workfile." + exit 1 + else + $editor "$workfile" + scp -q $workfile $host:$stagefile + check + fi +} + +check () { + echo "$stagefile" + ssh -q $host pfctl -nf $stagefile + result="$?" + case $result in + 0 ) edit_ok + ;; + 1 ) edit_failed + ;; + * ) echo "$result - Unhandled condition. Aborting." && exit 1 + ;; + esac +} + +edit_ok () { + echo "Syntax OK. Type YES to deploy changes or anything else to abort." + read choice + if [ "$choice" = "YES" ]; then + deploy + else + #rollback + abort + fi +} + +edit_failed () { + echo "Syntax error. [e]dit or [a]bort?" + read choice + if [ "$choice" = "e" ]; then + edit + elif [ "$choice" = "a" ]; then + abort + echo "OK. Exiting." + else + echo "Invalid choice. Let's try this again." + edit_failed + fi +} + +abort () { + rm $workfile + ssh -q $host rm $stagefile +} + +rollback () { + ssh -q $host cp $backupfile $prodfile + ssh -q $host pfctl -nf $prodfile + result="$?" + case $result in + 0 ) echo "Rollback ok." && exit + ;; + 1 ) echo "Rollback failed. You NEED to investigate this." + ;; + * ) echo "Unhandled rollback return code. Investigate this!" + ;; + esac + +} + +deploy () { + ssh -q $host cp $stagefile $prodfile + ssh -q $host pfctl -nf $prodfile + result="$?" + case $result in + 0 ) + ssh -q $host doas pfctl -f $prodfile + echo "OK." + ssh -q $host rm $stagefile + rm $workfile + ;; + 1 ) + echo "Deployment failed. Initiating rollback." + rollback + ;; + * ) echo "Unhandled condition. Investigate this! Initiating rollback." + rollback + ;; + esac +} + +if [ -z "$1" ]; then + echo "Missing argument. Specify a host." + exit 1 +else + host="$1" + init +fi |