diff options
author | Simon Rettberg | 2016-08-04 16:01:53 +0200 |
---|---|---|
committer | Simon Rettberg | 2016-08-04 16:01:53 +0200 |
commit | 820d16d840f462bf1b614f487cef1ddb589084b4 (patch) | |
tree | f59a936c2f185412de136d81faaf5538e525dcd1 | |
parent | [kernel-vanilla] -> 4.4.16 (diff) | |
download | tm-scripts-820d16d840f462bf1b614f487cef1ddb589084b4.tar.gz tm-scripts-820d16d840f462bf1b614f487cef1ddb589084b4.tar.xz tm-scripts-820d16d840f462bf1b614f487cef1ddb589084b4.zip |
[run-virt] Implement automatic firewalling
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 " |