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:char1
The part that we're interested in is the last part :
-chardev socket,id=char1,websocket=on,host=localhost,port=4555,server,nowait \
-serial chardev:char1
This 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 ?