
Ich erhalte häufig Beschwerden, dass Benutzer ihre VMs auf meinem Virtualisierungshost nicht zurücksetzen können. Daher habe ich beschlossen, eine Möglichkeit einzurichten, VMs zu beenden, ohne den Benutzern vollen Zugriff auf die QEMU-Konsole zu gewähren. Hier ist meine Idee:
while true ; do
nc -l $USERPORT > /dev/null
echo "quit" | nc 127.0.0.1 $QEMUCONSOLE
done
$USERPORT
ist der persönliche Trigger-Port jedes Benutzers. Die Verbindung zu diesem Port ist durch stunnel
eine zertifikatsbasierte Authentifizierung geschützt. Ist das auf Produktionsebene sicher? Ich meine, kann netcat
ein so betriebener Server mit einer Art Pufferbeanspruchung usw. ausgenutzt werden? Ich spreche nicht unbedingt von einer Rechteausweitung, sondern auch von jeder Form einer ernsthaften Destabilisierung des Systems, z. B. durch Auffüllen des RAM oder Ähnlichem.
BEARBEITEN:
Da die erste Antwort recht ausführlich war und sich auf allgemeines Bash-Scripting bezog, werde ich wohl das eigentliche Skript posten (der obige Code war eher Pseudocode, da ich nicht zu sehr ins Detail gehen wollte).
#!/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
Antwort1
Sind USERPORT
tatsächlich QEMUCONSOLE
Umgebungsvariablen exportiert? Falls nicht, siehe "Gibt es Namenskonventionen für Variablen in Shell-Skripten?"
Und da Sie sich um die Sicherheit sorgen, sind Sie sich derSicherheitsimplikationen, wenn vergessen wird, eine Variable in Bash/POSIX-Shells in Anführungszeichen zu setzen?
Als nächstes: Haben Sie die Konsequenzen bedacht, wenn der erste nc
Befehl hier nicht an diesen Port gebunden werden kann (z. B. wenn ein anderer Prozess bereits auf dem Port lauscht)? Sie überprüfen seinen Beendigungsstatus in keiner Weise. Ich würde erwarten, dass Sie eine Endlosschleife erhalten, die jede Sekunde eine große Anzahl von Malen „quit“ an QEMUCONSOLE sendet.
Ich würde sagen, es istnichtproduktionsbereit. Ich würde mir noch nicht einmal Gedanken über "sicher" machen, da Sie noch keine grundlegenden Randfälle behandelt haben, also ist eszerbrechlichunabhängig davon, ob es aus der Ferne ausgenutzt werden kann oder nicht.