summaryrefslogtreecommitdiffstats
path: root/core/modules/run-virt/data/opt/openslx/vmchooser/scripts/set-firewall
blob: 111c46629e4a6cb9c0ea81f5b78b7d75534d2425 (plain) (blame)
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
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
#!/bin/bash

# Do not rename/move this script, or change fwtool.c accordingly

[ "$UID" = "0" ] || exit 1

declare -rg RULES="$( mktemp )"
declare -rg AUTORULES="$( mktemp )"
declare -rg REMOTERULES="$( mktemp )"
declare -rg LOGFILE="$( mktemp )"

[ -n "$RULES" ] || exit 2

trap 'rm -f -- "$RULES" "$AUTORULES" "$REMOTERULES" "$LOGFILE"' EXIT

[ -n "$1" ] || exit 3

[ "${#1}" -ge 10 ] || exit 4
[ "${#1}" -lt 40 ] || exit 5

. /opt/openslx/config

for TOOL in iptables ip6tables; do
	$TOOL -w -F runvirt-INPUT || $TOOL -w -N runvirt-INPUT
	$TOOL -w -F runvirt-OUTPUT || $TOOL -w -N runvirt-OUTPUT

	if ! $TOOL -w -C INPUT -i br0 -j runvirt-INPUT; then
		$TOOL -w -A INPUT -i br0 -j runvirt-INPUT
	fi
	if ! $TOOL -w -C OUTPUT -o br0 -j runvirt-OUTPUT; then
		$TOOL -w -A OUTPUT -o br0 -j runvirt-OUTPUT
	fi
	if ! $TOOL -w -C FORWARD -i br0 -j runvirt-INPUT; then
		$TOOL -w -A FORWARD -i br0 -j runvirt-INPUT
	fi
	if ! $TOOL -w -C FORWARD -o br0 -j runvirt-OUTPUT; then
		$TOOL -w -A FORWARD -o br0 -j runvirt-OUTPUT
	fi
	$TOOL -A runvirt-INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
	$TOOL -A runvirt-OUTPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
done


parse_uri () {
	local scheme
	ip="${1,,}"
	scheme="${ip%%://*}"
	ip="${ip#*://}"
	port="${ip##*:}"
	if [[ "$port" =~ ^[0-9]+$ ]]; then
		ip="${ip%:*}"
	elif [ "$scheme" = "ldaps" ]; then
		port=636
	else
		port=389
	fi
	(( port >= 0 && port <= 65535 )) || port=0
}

add_ips () {
	# add_ips "IN/OUT" "IP1 IP2 IPn" "PORT" "ACCEPT/REJECT"
	local ip port port_def
	port_def="$3"
	[ -z "$1" -o -z "$2" -o -z "$port_def" -o -z "$4" ] && return 1
	for ip in $2; do
		port="${ip#*:}"
		if (( port > 0 && port < 65536 )) 2> /dev/null; then
			ip="${ip%:*}"
		else
			port="$port_def"
		fi
		echo "$1 ${ip} ${port} $4" >> "${AUTORULES}"
	done
}

add_ips "IN" "127.0.0.0/8" 0 "ACCEPT"
add_ips "OUT" "127.0.0.0/8" 0 "ACCEPT"
add_ips "OUT" "$SLX_DNS" 53 "ACCEPT"
add_ips "OUT" "$SLX_DNBD3_SERVERS" 5003 "ACCEPT"
add_ips "OUT" "$SLX_DNBD3_FALLBACK" 5003 "ACCEPT"
add_ips "OUT" "$SLX_KCL_SERVERS $SLX_PXE_SERVER_IP" 0 "ACCEPT"

# sssd
sssd="$( < /etc/sssd/sssd.conf  grep -P '^\s*ldap_(backup_)?uri\s*=' | sed -r 's/^[^=]*=//' )"
sssd="${sssd//,/ }"
for uri in $sssd; do
	parse_uri "$uri"
	add_ips "OUT" "$ip" "$port" "ACCEPT"
done

# pam-slx-plug
for file in /opt/openslx/pam/slx-ldap.d/*; do
	[ -f "$file" ] || continue
	uris="$( grep -Po "(?<=LDAP_URI=')[^']*" "$file" )"
	for uri in $uris; do
		parse_uri "$uri"
		add_ips "OUT" "$ip" "$port" "ACCEPT"
	done
done

if [ -n "$SLX_VM_NFS" ]; then
	IP=
	if [ "${SLX_VM_NFS:0:2}" = '//' ]; then
		IP=${SLX_VM_NFS:2}
		IP=${IP%%/*}
	else
		IP=${SLX_VM_NFS%%:*}
	fi
	[ -n "$IP" ] && add_ips "OUT" "$IP" 0 "ACCEPT"
fi

sort -u "${AUTORULES}" > "${RULES}"

# determine the URL to download the netrules from
if [ -s /opt/openslx/vmchooser/config/resource_urls.conf ]; then
	. /opt/openslx/vmchooser/config/resource_urls.conf
fi
NETRULES_URL=
[ -n "$url_lecture_netrules" ] && NETRULES_URL="${url_lecture_netrules//%UUID%/${1}}"
[ -z "$NETRULES_URL" ] && NETRULES_URL="${SLX_VMCHOOSER_BASE_URL}/lecture/$1/netrules"
wget -T 8 -O - "${NETRULES_URL}" > "${REMOTERULES}" 2> "${LOGFILE}"
RET=$?

if [ "$RET" != "0" ]; then
	echo "wget exit code: $RET :-("
	grep -q "ERROR 404" "${LOGFILE}" && exit 0 # Old sat, doesn't support firewall rules
	echo "WGET error output:"
	cat "${LOGFILE}"
	echo "------------ Downloaded content follows"
	cat "${REMOTERULES}"
	exit 6
fi

# Download OK, append to rules
cat "${REMOTERULES}" >> "${RULES}"

declare -rg V4='^[0-9]+(\.[0-9]+)*(/[0-9]+)?$'
declare -rg V6='^([0-9a-fA-F]+|:)(:+[0-9a-fA-F]*)*(/[0-9]+)?$'

while read -r DIR DEST PORT ACTION GARBAGE || [ -n "$DIR" ]; do
	if [ -z "$DEST" -o -z "$PORT" -o -z "$ACTION" ]; then
		echo "Invalid rule: '$DIR $DEST $PORT $ACTION'"
		continue
	fi
	IPLINE1=" -w"
	IPLINE2=
	if [ "$DIR" = "IN" ]; then
		IPLINE1+=" -A runvirt-INPUT"
	elif [ "$DIR" = "OUT" ]; then
		IPLINE1+=" -A runvirt-OUTPUT"
	else
		continue
	fi
	if ! [[ $PORT =~ ^[0-9]+$ ]] || [ "$PORT" -gt 65535 ]; then
		echo "Invalid port: '$PORT'"
		continue
	fi
	if [ "$DEST" != "*" ]; then
		if [ "$DIR" = "OUT" ]; then
			IPLINE1+=" -d $DEST"
		else
			IPLINE1+=" -s $DEST"
		fi
	fi
	if [ "$PORT" != 0 ]; then
		IPLINE2+=" --dport $PORT"
	fi
	IPLINE2+=" -j $ACTION"
	# IPv6?
	if ! [[ $DEST =~ $V4 ]]; then
		if [ "$PORT" = 0 ]; then
			ip6tables $IPLINE1 $IPLINE2
		else
			ip6tables $IPLINE1 -p tcp $IPLINE2
			ip6tables $IPLINE1 -p udp $IPLINE2
		fi
	fi
	# IPv4
	if ! [[ $DEST =~ $V6 ]]; then
		if [ "$PORT" = 0 ]; then
			iptables $IPLINE1 $IPLINE2
		else
			iptables $IPLINE1 -p tcp $IPLINE2
			iptables $IPLINE1 -p udp $IPLINE2
		fi
	fi
done < "$RULES"

exit 0