
Я часто получаю жалобы на то, что пользователи не могут выполнить жесткий сброс своих виртуальных машин на моем хосте виртуализации. Поэтому я решил настроить какой-то способ уничтожения виртуальных машин, не предоставляя пользователям полный доступ к консоли QEMU. Вот моя идея:
while true ; do
nc -l $USERPORT > /dev/null
echo "quit" | nc 127.0.0.1 $QEMUCONSOLE
done
$USERPORT
является персональным триггерным портом каждого пользователя. Подключение к такому порту защищено stunnel
аутентификацией на основе сертификата. Является ли это безопасным на уровне производства? Я имею в виду, может ли netcat
работающий таким образом сервер быть использован с каким-либо видом переполнения буфера и т. д.? Я не обязательно говорю о повышении привилегий, но также о любой форме серьезной дестабилизации системы, например, путем заполнения оперативной памяти или чего-то в этом роде.
РЕДАКТИРОВАТЬ:
Поскольку первоначальный ответ был довольно подробным и касался общих вопросов написания скриптов bash, я, пожалуй, опубликую сам скрипт (приведенный выше код больше похож на псевдокод, поскольку я хотел избежать излишних подробностей).
#!/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
решение1
Являются ли USERPORT
фактически QEMUCONSOLE
экспортированные переменные среды? Если нет, см. "Существуют ли соглашения об именовании переменных в скриптах оболочки?"
Кроме того, поскольку вы беспокоитесь о безопасности, знаете ли вы оПоследствия для безопасности, если забыть заключить переменную в кавычки в оболочках bash/POSIX?
Далее, вы учли последствия, если первая nc
команда здесь не сможет привязаться к этому порту (например, если другой процесс уже прослушивает порт)? Вы никак не проверяете его статус выхода. Я бы ожидал, что вы получите непрерывный цикл, отправляющий "quit" в QEMUCONSOLE огромное количество раз в секунду.
Я бы сказал, что это такнетготов к производству. Я бы пока даже не беспокоился о «безопасности», потому что вы изначально не обрабатывали базовые пограничные случаи, так что этохрупкийнезависимо от того, можно ли его эксплуатировать удаленно или нет.