blob: aab30ed486964f101a0ecc6357f27a8c92112c09 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
|
#!/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>
# Created: 02/11/2021
# Last edit: 05/12/2021
# Version: 2.0
#
# 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 nvim)"
difftool="/home/lysergic/lysergic-venv/bin/icdiff"
diffargs=( -L "CURRENT CONFIGURATION" -L "YOUR CONFIGURATION" -N -U2 )
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) ##we no longer parse ssh_config and rely on functioning DNS lookups
hostaddress="$host"
if nc -z $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
localbackupfile="${workfile}_original"
cp $workfile $localbackupfile
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
}
render_diff () {
$difftool "${diffargs[@]}" $localbackupfile $workfile
}
edit_ok () {
render_diff
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 && rm $stagefile"
echo "OK."
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
|