我经常收到投诉,称用户无法在我的虚拟化主机上硬重置其虚拟机。因此,我决定设置某种方式来终止 VM,而不向用户提供对 QEMU 控制台的完全访问权限。这是我的想法:
while true ; do
nc -l $USERPORT > /dev/null
echo "quit" | nc 127.0.0.1 $QEMUCONSOLE
done
$USERPORT
是每个用户的个人触发端口。与此类端口的连接受到stunnel
基于证书的身份验证的保护。生产级安全吗?我的意思是netcat
服务器像这样运行可以被某种缓冲区占用等利用吗?我不一定是在谈论特权升级,而是在谈论任何形式的严重系统不稳定,例如。通过填充 RAM 或其他东西。
编辑:
由于最初的响应非常详细并且与一般的 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
如果没有看到“shell 脚本中的变量有命名约定吗?”
另外,既然您担心安全问题,您是否知道忘记在 bash/POSIX shell 中引用变量的安全隐患?
nc
接下来,您是否考虑过如果此处的第一个命令无法绑定到该端口(例如另一个进程已经在侦听该端口)的影响?您不会以任何方式检查其退出状态。我希望你会得到一个连续的循环,每秒向 QEMUCONSOLE 发送“退出”很多次。
我想说的是不是生产准备就绪。我什至不会担心“安全”,因为你一开始还没有处理基本的边缘情况,所以它是脆弱的无论是否可以被远程利用。