summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSimon Rettberg2016-08-04 16:01:53 +0200
committerSimon Rettberg2016-08-04 16:01:53 +0200
commit820d16d840f462bf1b614f487cef1ddb589084b4 (patch)
treef59a936c2f185412de136d81faaf5538e525dcd1
parent[kernel-vanilla] -> 4.4.16 (diff)
downloadtm-scripts-820d16d840f462bf1b614f487cef1ddb589084b4.tar.gz
tm-scripts-820d16d840f462bf1b614f487cef1ddb589084b4.tar.xz
tm-scripts-820d16d840f462bf1b614f487cef1ddb589084b4.zip
[run-virt] Implement automatic firewalling
-rw-r--r--remote/modules/run-virt/data/opt/openslx/scripts/includes/setup_firewall.inc12
-rw-r--r--remote/modules/run-virt/data/opt/openslx/scripts/pam_script_ses_close.d/runvirt-firewall-clear17
-rwxr-xr-xremote/modules/run-virt/data/opt/openslx/scripts/vmchooser-run_virt4
-rw-r--r--remote/modules/run-virt/data/opt/openslx/vmchooser/scripts/set-firewall130
-rw-r--r--remote/modules/run-virt/fwtool/main.c32
-rw-r--r--remote/modules/run-virt/module.build1
-rw-r--r--remote/modules/run-virt/module.conf1
7 files changed, 197 insertions, 0 deletions
diff --git a/remote/modules/run-virt/data/opt/openslx/scripts/includes/setup_firewall.inc b/remote/modules/run-virt/data/opt/openslx/scripts/includes/setup_firewall.inc
new file mode 100644
index 00000000..f0820ed7
--- /dev/null
+++ b/remote/modules/run-virt/data/opt/openslx/scripts/includes/setup_firewall.inc
@@ -0,0 +1,12 @@
+
+setup_firewall () {
+ local LOGF="${TMPDIR}/firewall.log"
+ local RET
+ [ "$DISPLAY" = ":0" ] || return 0 # For now, to avoid conflicts, we only do this on display :0
+ slxfwtool "$IMGUUID" > "$LOGF" 2>&1
+ RET=$?
+ if [ "$RET" != "0" ]; then
+ slxlog "runvirt-firewall" "Error setting up firewall rules for lecture $IMGUUID (Exit code $RET)" "$LOGF"
+ fi
+ return 0
+}
diff --git a/remote/modules/run-virt/data/opt/openslx/scripts/pam_script_ses_close.d/runvirt-firewall-clear b/remote/modules/run-virt/data/opt/openslx/scripts/pam_script_ses_close.d/runvirt-firewall-clear
new file mode 100644
index 00000000..dab08190
--- /dev/null
+++ b/remote/modules/run-virt/data/opt/openslx/scripts/pam_script_ses_close.d/runvirt-firewall-clear
@@ -0,0 +1,17 @@
+#!/bin/ash
+
+# Sourced by pam_script_ses_close
+
+runvirt_fw_clear () {
+ iptables -w -F runvirt-INPUT
+ ip6tables -w -F runvirt-INPUT
+ iptables -w -F runvirt-OUTPUT
+ ip6tables -w -F runvirt-OUTPUT
+}
+
+if [ "x$PAM_TTY" = "x:0" ]; then
+ runvirt_fw_clear > /dev/null 2>&1
+fi
+
+true
+
diff --git a/remote/modules/run-virt/data/opt/openslx/scripts/vmchooser-run_virt b/remote/modules/run-virt/data/opt/openslx/scripts/vmchooser-run_virt
index 5353d21a..ea3cfe8e 100755
--- a/remote/modules/run-virt/data/opt/openslx/scripts/vmchooser-run_virt
+++ b/remote/modules/run-virt/data/opt/openslx/scripts/vmchooser-run_virt
@@ -64,6 +64,10 @@ else
# This include does not currently work. TODO.
# source ${RUNVIRTINCLUDEDIR}/check_runvirt_needed_files.inc && filecheck
+ # Firewall
+ source "${RUNVIRTINCLUDEDIR}/setup_firewall.inc" || writelog "Could not source setup_firewall"
+ setup_firewall || writelog "Could not run setup_firewall"
+
# Read needed variables from XML file
source ${RUNVIRTINCLUDEDIR}/get_xml_file_variables.inc
diff --git a/remote/modules/run-virt/data/opt/openslx/vmchooser/scripts/set-firewall b/remote/modules/run-virt/data/opt/openslx/vmchooser/scripts/set-firewall
new file mode 100644
index 00000000..02ba2b5c
--- /dev/null
+++ b/remote/modules/run-virt/data/opt/openslx/vmchooser/scripts/set-firewall
@@ -0,0 +1,130 @@
+#!/bin/bash
+
+# Do not rename/move this script, or change fwtool.c accordingly
+
+[ "$UID" = "0" ] || exit 1
+
+declare -rg RULES=$(mktemp)
+
+[ -n "$RULES" ] || exit 2
+
+[ -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 -j ACCEPT
+ $TOOL -A runvirt-OUTPUT -m conntrack --ctstate ESTABLISHED -j ACCEPT
+done
+
+declare -rg AUTORULES=$(mktemp)
+
+add_ips () {
+ # add_ips "IN/OUT" "IP1 IP2 IPn" "PORT" "ACCEPT/REJECT"
+ local IP
+ [ -z "$1" -o -z "$2" -o -z "$3" -o -z "$4" ] && return 1
+ for IP in $2; do
+ echo "$1 $IP $3 $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_KCL_SERVERS $SLX_SERVER_IP" 0 "ACCEPT"
+
+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}"
+
+wget -T 6 --no-verbose -O - "${SLX_VMCHOOSER_BASE_URL}/lecture/$1/netrules" >> "${RULES}" 2> "${AUTORULES}"
+RET=$?
+
+if [ "$RET" != "0" ]; then
+ echo "wget exit code: $RET :-("
+ grep -q "ERROR 404" "${AUTORULES}" && exit 0
+ exit 6
+fi
+
+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
+
diff --git a/remote/modules/run-virt/fwtool/main.c b/remote/modules/run-virt/fwtool/main.c
new file mode 100644
index 00000000..9e272384
--- /dev/null
+++ b/remote/modules/run-virt/fwtool/main.c
@@ -0,0 +1,32 @@
+#define _GNU_SOURCE
+#include <stdio.h>
+#include <string.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+int main(int argc, char **argv)
+{
+ if (argc < 2) {
+ puts("Nee\n");
+ return 1;
+ }
+ char * const nargv[] = {
+ "bash",
+ "/opt/openslx/vmchooser/scripts/set-firewall",
+ argv[1],
+ 0
+ };
+ char * const nenv[] = {
+ "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/opt/openslx/sbin:/opt/openslx/bin",
+ "HOME=/root",
+ "LC_ALL=C",
+ "LANG=C",
+ 0
+ };
+
+ setresuid(0, 0, 0);
+ setregid(0, 0);
+
+ execve("/bin/bash", nargv, nenv);
+}
+
diff --git a/remote/modules/run-virt/module.build b/remote/modules/run-virt/module.build
index e9b0d581..eb718599 100644
--- a/remote/modules/run-virt/module.build
+++ b/remote/modules/run-virt/module.build
@@ -11,6 +11,7 @@ build () {
# Compile pwdaemon
mkdir -p "${MODULE_BUILD_DIR}/opt/openslx/bin"
gcc -std=gnu99 -o "${MODULE_BUILD_DIR}/opt/openslx/bin/pwdaemon" -Os "${MODULE_DIR}/pw_daemon.c" || perror "Could not compile the pwdaemon"
+ gcc -std=gnu99 -o "${MODULE_BUILD_DIR}/opt/openslx/bin/slxfwtool" -Os "${MODULE_DIR}/fwtool/main.c" || perror "Could not compile slxfwtool"
}
post_copy() {
diff --git a/remote/modules/run-virt/module.conf b/remote/modules/run-virt/module.conf
index b52fae0e..73155f89 100644
--- a/remote/modules/run-virt/module.conf
+++ b/remote/modules/run-virt/module.conf
@@ -2,5 +2,6 @@ REQUIRED_BINARIES="
lsusb
mcopy
pwdaemon
+ slxfwtool
"