I discovered today that you can expose qemu virtual machines serial console
via websockets. Which is nice for remote exposure of VMs!
What are websockets
Websockets are an Upgrade of http (1.1) connections to a full duplex binary
communication protocol called WebSockets. This, as the name says can be used
from a browser. It can be used over TLS as well.
How to expose serial through websockets
qemu-system-x86_64 -m 2048 \
  -drive if=virtio,file=disk.qcow2,format=qcow2 \
  -enable-kvm \
  -netdev user,id=mynet0,hostfwd=tcp:127.0.0.1:7922-:22 \
  -device e1000,netdev=mynet0 \
  -nographic \
  -chardev socket,id=char1,websocket=on,host=localhost,port=4555,server,nowait \
  -serial chardev:char1The part that we're interested in is the last part :
  -chardev socket,id=char1,websocket=on,host=localhost,port=4555,server,nowait \
  -serial chardev:char1This basically creates a char device that is exposed as a websocket server on
localhost on port 4555 and it connects it as to the serial interface.
How to connect to it
Well, I tried using websocat with it, but websocat adds a \n on each data
received for some reason. So I found another tool that basically does it "the
easy way". Enter https://github.com/anisse/websocktty/
It basically sets terminal in raw mode and prints everything received from the
websocket to stdout.
And it reads messages from stdin and sends them through the websocket.
It uses golang.org/x/crypto/ssh/terminal to interact with the terminal and put
it in raw mode as well as github.com/gorilla/websocket to create websockets.
So, very easy!
A few disappointments
Unfortunately, the VM need to be configured to use the serial console. Which is not really the default for most OS nowadays.
This, however can be automated through usage of pre-configured OSes ISOs or
using ISO that support cloud-init to configure it. This is usually present in
cloud images available online.
Conclusion
We discovered a nice Qemu feature to expose serial console through websocket and how to use it remotely.
I might use this to do easy VMs provisionning through an API and make access to them easy.
Future work
What about other hypervisors ?
What about using other programming language for the client ?