
Frequentemente recebo reclamações de que os usuários não conseguem redefinir suas VMs no meu host de virtualização. Então decidi configurar alguma forma de matar VM, sem dar acesso total ao console QEMU aos usuários. Aqui está minha ideia:
while true ; do
nc -l $USERPORT > /dev/null
echo "quit" | nc 127.0.0.1 $QEMUCONSOLE
done
$USERPORT
é a porta de disparo pessoal de cada usuário. A conectividade com essa porta é protegida por stunnel
autenticação baseada em certificado. É seguro em nível de produção? Quero dizer, netcat
o servidor executado assim pode ser explorado com algum tipo de sobrecarga de buffer, etc.? Não estou falando necessariamente de escalada de privilégios, mas também de qualquer forma grave de desestabilização do sistema, por exemplo. preenchendo RAM ou algo assim.
EDITAR:
Como a resposta inicial foi bastante detalhada e relacionada ao script bash geral, acho que postarei o script real (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
Responder1
São USERPORT
variáveis QEMUCONSOLE
de ambiente exportadas reais? Se não veja "Existem convenções de nomenclatura para variáveis em scripts de shell?"
Além disso, como você está preocupado com a segurança, você está ciente daImplicações de segurança de esquecer de citar uma variável em shells bash/POSIX?
A seguir, você considerou as implicações se o primeiro nc
comando aqui não conseguir se vincular a essa porta (como se outro processo já estivesse escutando na porta)? Você não verifica seu status de saída de forma alguma. Eu esperaria que você obtivesse um loop contínuo enviando "quit" para o QEMUCONSOLE um grande número de vezes por segundo.
Eu diria que énãoprodução pronta. Eu nem me preocuparia com "segurança" ainda porque você ainda não lidou com casos extremos básicos, então éfrágilindependentemente de poder ser explorado remotamente ou não.