-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathztlockdown
More file actions
executable file
·158 lines (129 loc) · 4.18 KB
/
ztlockdown
File metadata and controls
executable file
·158 lines (129 loc) · 4.18 KB
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
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
#!/bin/bash
#
# A QAD script that disables general (but not host-specific) ssh access
# from the internet, whitelists a set of hosts (including the current
# ssh client IP) for ssh access, and attempts to replicate any existing
# public internet firewall holes on a set of secure networks.
# This assumes ufw.
# NETWORKS is a newline- or comma-separated list of network prefixes that are
# considered secure and which should have general access.
# WHITELIST is a newline- or comma-separated list of hosts that are considered
# secure and should have ssh access.
SCRIPT_DIR=$(dirname "${BASH_SOURCE[0]}")
# shellcheck disable=SC1090
. "$SCRIPT_DIR/poshlib/poshlib.sh" || exit 1
use strict
use utils
UFW_RETRY_LIMIT=5
### TODO: why does the first "ufw allow" on CentOS throw "ERROR: problem running"?
centos_safe_ufw() {
retry_count=0
while [[ $retry_count -lt $UFW_RETRY_LIMIT ]] && ! ufw "$@"; do
(( ++retry_count ))
done
[[ $retry_count -lt $UFW_RETRY_LIMIT ]] || die 3 "ufw threw errors too many times in succession"
}
if [[ $(whoami) != "root" ]]; then
# If we are not root, become root. Non-root invocation is useful
# because most methods of obtaining root reset the environment.
# Duplicate any required envars on the other side of the sudo.
exec sudo SSH_CONNECTION="${SSH_CONNECTION}" /bin/bash "$0"
fi
APT=
YUM=
if [[ -d /etc/apt ]]; then
APT=true
elif [[ -d /etc/yum ]]; then
YUM=true
else
die 99 "Distribution not supported!"
fi
NETWORKS=""
WHITELIST=""
if [[ -f /etc/ztlockdown ]]; then
# shellcheck disable=SC1091
. /etc/ztlockdown
fi
if [[ -f ~/.ztlockdown ]]; then
# shellcheck disable=SC1090
. ~/.ztlockdown
fi
# canonicalise
NETWORKS=$(echo "$NETWORKS"|tr ' ,' '_ ')
WHITELIST=$(echo "$WHITELIST"|tr ' ,' '_ ')
if [[ $APT ]]; then
if [ ! -x /usr/sbin/ufw ]; then
if [ -z "$(find /var/cache/apt/pkgcache.bin -mmin -60)" ]; then
apt-get update
fi
apt-get install ufw
fi
elif [[ $YUM ]]; then
yum -y --setopt=skip_missing_names_on_install=False install ufw
systemctl enable ufw
fi
if ufw app info OpenSSH >&/dev/null ; then
SSH_PROFILE="OpenSSH"
elif ufw app info SSH >&/dev/null ; then
SSH_PROFILE="SSH"
else
die 8 "SSH UFW profile not found. Aborting"
fi
remote_host=${SSH_CONNECTION%% *}
[ -n "${remote_host}" ] || die 3 "Cannot whitelist current SSH connection. It is unsafe to continue."
# Add the current remote host to the whitelist
WHITELIST="${remote_host}_Autodetected_ssh_connection
${WHITELIST}"
# Now whitelist our friendly hosts BEFORE enabling ufw.
for host in $WHITELIST; do
echo "Whitelisting ${host%%_*} (${host#*_})"
centos_safe_ufw allow to any app "$SSH_PROFILE" from "${host%%_*}" comment "${host#*_}"
done
# Also whitelist incoming packets on the standard zerotier port.
centos_safe_ufw allow to any port 9993 comment zerotier
# This is dangerous. Bloody CentOS
ufw enable <<< y || ufw enable <<< y || ufw enable <<< y
for network in $NETWORKS; do
network_prefix=${network%%_*}
network_name=${network#*_}
echo "Adding ${network_prefix} (${network_name})"
### TODO: use "ufw show added", which is more reliably parseable
### TODO: why are we doing any of this?
# for i in $(ufw status | grep 'ALLOW\s*Anywhere' | grep -v '(v6)'); do
for i in ; do
UFW_TO=${i%ALLOW*}
j=${i#*ALLOW}
UFW_FROM=${j%\#*}
if [[ "$UFW_FROM" != "$j" ]]; then
# there was a comment; preserve it
UFW_COMMENT=${j#*\#}
else
UFW_COMMENT=""
fi
case "$UFW_TO" in
22 )
echo -n
;;
*\ on\ * )
centos_safe_ufw allow from "$network_prefix" comment "($network_name) ${UFW_COMMENT}"
;;
* )
centos_safe_ufw allow from "$network_prefix" to any port "$UFW_TO" comment "($network_name) ${UFW_COMMENT}"
;;
esac
done
# add ssh access anyway
centos_safe_ufw allow from "$network_prefix" to any app "$SSH_PROFILE" comment "($network_name)"
if [ -d /etc/sshguard ]; then
echo "$network_prefix" >> /etc/sshguard/whitelist
fi
done
# And try to delete all instances of generic ssh access
centos_safe_ufw delete allow "$SSH_PROFILE"
centos_safe_ufw delete allow 22
centos_safe_ufw delete allow 22/tcp
echo "Current firewall status - check for sanity"
# use -n to prevent delays
iptables -L -v -n
iptables -L -v -n -t nat
ufw status