summaryrefslogtreecommitdiffstats
path: root/scripts
diff options
context:
space:
mode:
Diffstat (limited to 'scripts')
-rw-r--r--scripts/sh/pf.sh129
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