Running a web server in a usual monolithic operating system alongside with other services is the usual scenario. However, a web server can have many potential vectors
of attacks, DDOS, SQL injections and so on. Hence threatening the host operating system. An alternative approach, called unikernel, allows you to run an application in a self contained environment that provides more security and, by removing the biggest parts of an operating system, consumes less space.
For our example, we’ll use sthttpd (a fork of the for- mer thttpd) and a Xen environment. And for produc- ing an unikernel image, we’ll use rumprun.
Rumprun, building our software
Rumprun, which you can find in this repository https://github.com/rumpkernel/rumprun, provides a whole compilation toolchain, the NetBSD’s libc and a couple of few libraries to run our software for Xen or qemu (with or without KVM) for example. The steps to make it workable are to compile the software (and eventually its dependencies) with the rumprun toolchain then make a uniker- nel image.
First we need to compile all the libraries needed to make unikernel images va the
build-rr.sh shell script. This is pretty simple, we just need to type
build-rr.sh <platform where platform is xen or hw>.
Note: If you wish to build both hw and xen versions, I suggest you compile in two separated git local clones rather than in one alone.
First we need the NetBSD source:
> git submodule update --init > ./build-rr.sh xen
or if you have already the NetBSD source somewhere:
> ./build-rr.sh -s <path of NetBSD source> xen
After a couple of minutes, inside the app-tools subfolder, we should have our make, configure, linker, c and c++ … and all other necessary wrappers. I’d suggest that you add your PATH environment to this apptools folder.
Hence once inside sthttpd project folder, we can type
rumprun-xen-configure ./configure <your usual configure flags> which sets useful variables like CC/CXX ... host
> ac_cv_func_malloc_0_nonnull=yes rumprun-xen-configure ./ configure
> rumprun-xen-make install
We finally need to link our unikernel image (the applica- tion will be linked to rumpkernel libraries) via rumpbake script which can work only if the application was previous- ly compiled via the rumprun toolchain. So we can type:
rumpbake <target> <unikernel image name> <executable>
> rumpbake xen_pv xen-thttpd <path to shttpd executable>
We will need to have available inside the Xen environment the web static content to serve and eventually the sthttpd configuration and a user/group database. Then we can make two isos archives via NetBSD mkisofs, Linux genisoimage. one for the web content, we have already a www subfolder for it, and the other one for configuration purposes. Let’s have an etc folder which contains the
master.passwd/group file, pwd.db and spwd.db which contains a nobody user (directly grabbed from my NetBSD box) and a basic shttpd configuration file:
... dir=/www port=80
Launching the Xen instance and serving the content
Let’s assume we already configured a minimal Xen bridge, in our case the Xen instance will have a dynamic IP address for the sake of simplicity. To launch our unikernel im- age, we will use the rumprun wrapper. We can type
rump- run <target> -n <network interface setting> -M <memory settings in MB> -b <block device 1>... -b<block device N> -di <path to the unikernel image> <arguments for the unikernel image>
> rumprun xen -n inet,dhcp -M 128 -b etc.iso,/etc pb www. iso,/www -di xen-thttpd -D -C /etc/thttpd.conf
Note: If you are curious as to how Xen is launched, you can add the -D argument to rumprun which simply dumps the command in the standard output instead of launching it.
Now you should see, via xl list, your Xen instance named
Normally, you can now see the web contents from your usual web browser.
The unikernel approach is already used in production case, hence a well considered solution especially for better security and also if the service fails, the init process is faster. Hopefully, it will give you the curiosity at least to consider this approach in your own case.
The article comes from BSD Mag Vol 9 No 06, Issue 71