I'm receiving complaints quite often that users can't hard-reset their VMs on my virtualization host. So I decided to set up some way of killing VM, without giving full access to QEMU console to users. Here's my idea:
while true ; do
nc -l $USERPORT > /dev/null
echo "quit" | nc 127.0.0.1 $QEMUCONSOLE
done
$USERPORT
is personal trigger port of every user. Connectivity to such port is protected by stunnel
with certificate based authentication. Is it production-level secure? I mean can netcat
server run like this be exploited with some kind of buffer hogging etc? I'm not talking necessarily about privilege escalation but also about any form of serious system destabilization eg. by filling up RAM or something.
EDIT:
Since initial response was quite detailed and related to general bash scripting I guess I'll post actual script (code above was more like pseudocode as I wanted to avoid getting into too much detail)
#!/bin/bash
if [ ! -e "$HOME/kvm" ] ; then
>&2 echo "kvm dir not detected - creating"
/common/spawnVM.sh
if [ x"$?" != x"0" ] ; then
>&2 echo "qemu image creation failed - aborting"
exit 1 ; fi
fi
cd $HOME
VNCDISP=`cat /common/stunnelsrv.conf | grep "\[.*\]\|connect" | sed -e '$!N;s/\n/ /' | grep "^\[${USER:2}\]" | grep -o ":[0-9]\+" | grep -o "[0-9]$"`
if [ x"$VNCDISP" = x"" ] ; then
>&2 echo "stunnel section not found"
exit 2 ; fi
MONITORPORT="6`printf '%.3d' $VNCDISP`"
CMDPORT=`cat /common/stunnelsrv.conf | grep "\[.*\]\|connect" | sed -e '$!N;s/\n/ /' | grep "^\[cmd-${USER:2}\]" | grep -o ":[0-9]\+" | grep -o "[0-9]\+"`
TAPNAME="tap${USER:2}"
ip link show dev "$TAPNAME" > /dev/null
if [ x"$?" != x"0" ] ; then
>&2 echo "tap device not found"
exit 3 ; fi
NICMACADDR="`/common/qemu-mac-hasher.py \"$USER\"`"
CDISO=/common/arch.iso
if [ -e ./kvm/boot.iso ] ; then
CDISO=./kvm/boot.iso ; fi
if [ x"$CMDPORT" = x"" ] ; then
>&2 echo "stunnel cmd section not found - skip"
else
{
nc -l 127.0.0.1 -p "$CMDPORT" > /dev/null
if [ x"$?" != x"0" ] ; then
>&2 echo "error occured while running cmd"
else
echo "quit" | nc 127.0.0.1 "$MONITORPORT"
fi
} &
fi
echo "Params: VNC :$VNCDISP TAP $TAPNAME MAC $NICMACADDR MONITOR $MONITORPORT CMD $CMDPORT"
DISPLAY=:0
qemu-system-x86_64 -enable-kvm -machine type=pc,accel=kvm -monitor telnet:127.0.0.1:$MONITORPORT,server,nowait \
-nographic -vga virtio -vnc 127.0.0.1:$VNCDISP -usbdevice tablet -cpu host -smp 2 -m 4G -device virtio-balloon \
-boot menu=on -cdrom $CDISO -drive file=./kvm/root-$USER.img,format=qcow2,if=virtio,cache=off \
-net nic,model=virtio -net tap,ifname=$TAPNAME,script=no,downscript=no
echo "Waiting for reboot interrupt... ($0)"
sleep 10
exec $0
exit 0
echo > /dev/tcp/127.0.0.1/(someone else's trigger port)
would immediately hard reset that other user's machine. Sounds pretty not smart. – Wildcard Dec 01 '17 at 01:30stunnel
with certificate based authentication which used to provide VNC access to VM. Now it also provides that trigger port so it's behind auth – Lapsio Dec 01 '17 at 01:49qemu
console over stunnel because I don't want users to fiddle withballoon
or other devices on their own so I just need to give them ability to hard reset VM. I used to just do it manually but After getting more than 1 reset request weekly I got a bit tired, especially considering this host has semi-airgapped hardened networking so I actually always had to go to server room and kill VMs manually. And driving 1h just to reset VM wasn't fun for me nor user who had to wait 1h for reset. – Lapsio Dec 01 '17 at 02:01