1

I'm receiving complaints quite often that users can't hard-reset their VMs on my virtualization host. So I decided to set up some way of killing VM, without giving full access to QEMU console to users. Here's my idea:

while true ; do
  nc -l $USERPORT > /dev/null
  echo "quit" | nc 127.0.0.1 $QEMUCONSOLE
done

$USERPORT is personal trigger port of every user. Connectivity to such port is protected by stunnel with certificate based authentication. Is it production-level secure? I mean can netcat server run like this be exploited with some kind of buffer hogging etc? I'm not talking necessarily about privilege escalation but also about any form of serious system destabilization eg. by filling up RAM or something.

EDIT:

Since initial response was quite detailed and related to general bash scripting I guess I'll post actual script (code above was more like pseudocode as I wanted to avoid getting into too much detail)

#!/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
Lapsio
  • 1,323

1 Answers1

4

Are USERPORT and QEMUCONSOLE actual exported environment variables? If not see "Are there naming conventions for variables in shell scripts?"

Also, since you're worried about security, are you aware of the Security implications of forgetting to quote a variable in bash/POSIX shells?

Next, have you considered the implications if the first nc command here is unable to bind to that port (such as if another process is listening on the port already)? You don't check its exit status in any way. I would expect you would get a continuous loop sending "quit" to the QEMUCONSOLE some huge number of times per second.

I would say it is not production ready. I wouldn't even worry about "secure" yet because you haven't handled basic edge cases in the first place, so it's fragile regardless of whether it can be remotely exploited or not.

Wildcard
  • 36,499
  • Thank you for input. It wasn't actual code I rather wanted to focus on netcat security itself rather than bash but your input about naming conventions and ignoring failed bind are really appreciated. I posted actual code. – Lapsio Dec 01 '17 at 00:53
  • @Lapsio, thanks. If I'm understanding your architecture right, this script would run in a loop as root, and then anyone on the box running echo > /dev/tcp/127.0.0.1/(someone else's trigger port) would immediately hard reset that other user's machine. Sounds pretty not smart. – Wildcard Dec 01 '17 at 01:30
  • There's no users on this box. I mean those scripts are run as specific users representing VMs but those accounts are not user accounts, they're technical accounts like nginx account for example. Long story short - logging to vm user account attaches existing screen session with qemu running or spawns new qemu using posted script. Those accounts don't have regular shell. It's just management organization. Ports are not exposed just like that. There's stunnel with certificate based authentication which used to provide VNC access to VM. Now it also provides that trigger port so it's behind auth – Lapsio Dec 01 '17 at 01:49
  • @Lapsio, okay. It sounds like what you really need is a security design review within your company. This is almost like legal advice: whatever general comments you find online may or may not apply to your specific case, and for actual legal advice you should just hire a lawyer who can review the specifics of your case. – Wildcard Dec 01 '17 at 01:59
  • I don't want to simply expose qemu console over stunnel because I don't want users to fiddle with balloon or other devices on their own so I just need to give them ability to hard reset VM. I used to just do it manually but After getting more than 1 reset request weekly I got a bit tired, especially considering this host has semi-airgapped hardened networking so I actually always had to go to server room and kill VMs manually. And driving 1h just to reset VM wasn't fun for me nor user who had to wait 1h for reset. – Lapsio Dec 01 '17 at 02:01
  • I'm learning about security. Setting up this stuff is part of educational process. It's not super commercial setup in corporation but amateur virtualization host. And while I trust all people using it I'm still attempting to learn administration and security while doing that so I don't want to rely security on my trust to users because it's not the goal. If this machine would get hacked I probably wouldn't get killed but still I want to explore Linux administration, security, networking and virtualization techniques to make it best I can. Question is about "security of netcat in scripts". – Lapsio Dec 01 '17 at 02:06
  • @Lapsio, perhaps you should ask a new question about "fine-tuned control of permissions for qemu console", then? Be sure to do your research first. – Wildcard Dec 01 '17 at 02:10