Estou recebendo reclamações com bastante frequência de que os usuários não podem redefinir suas VMs no meu host de virtualização. Então, decidi configurar uma maneira de matar a VM, sem dar acesso total ao console do QEMU aos usuários. Aqui está a minha ideia:
while true ; do
nc -l $USERPORT > /dev/null
echo "quit" | nc 127.0.0.1 $QEMUCONSOLE
done
$USERPORT
é a porta de acionador pessoal de todos os usuários. A conectividade a essa porta é protegida por stunnel
com autenticação baseada em certificado. É seguro em nível de produção? Quero dizer, o netcat
server run como este pode ser explorado com algum tipo de buffer hogging etc? Eu não estou falando necessariamente sobre escalação de privilégios, mas também sobre qualquer forma de desestabilização séria do sistema, por exemplo. preenchendo RAM ou algo assim.
EDITAR :
Como a resposta inicial foi bem detalhada e relacionada ao script geral, acho que postarei scripts reais (o código acima era mais parecido com pseudocódigo, pois eu queria evitar entrar em muitos detalhes)
#!/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