<a href="https://mirage.io">MirageOS</a>, an operating system developed from scratch in the
functional and statically typed language <a href="https://ocaml.org">OCaml</a>. I've not
used much OCaml before, but some other functional programming languages.
Since then, I spend nearly every day on developing OCaml libraries (with varying success on being happy
with my code). In contrast to Dylan, there are more than two people developing MirageOS.</p>
<p>The idea is straightforward: use a hypervisor, and its hardware
abstractions (virtualised input/output and network device), and execute the
OCaml runtime directly on it. No C library included (since May 2015, see <a href="http://lists.xenproject.org/archives/html/mirageos-devel/2014-05/msg00070.html">this
thread</a>).
The virtual machine, based on the OCaml runtime and composed of OCaml libraries,
uses a single address space and runs in ring 0.</p>
<p>As mentioned above, all code which runs in ring 0 needs to be carefully
developed and checked since a flaw in it can jeopardise the security properties
of the entire system: the TCP/IP library should not have access to the private
key used for the TLS handshake. If we trust the OCaml runtime, especially its
memory management, there is no way for the TCP/IP library to access the memory
of the TLS subsystem: the TLS API does not expose the private key via an API
call, and being in a memory safe language, a library cannot read arbitrary
memory. There is no real need to isolate each library into a separate address
spaces. In my opinion, using capabilities for memory access would be a great
improvement, similar to <a href="http://www.barrelfish.org">barrelfish</a>. OCaml has a C
foreign function call interface which can be used to read arbitrary memory --
you have to take care that all C bits of the system are not malicious (it is
fortunately difficult to embed C code into MirageOS, thus only few bits written
in C are in MirageOS (such as (loop and allocation free) <a href="https://github.com/mirleft/ocaml-nocrypto/tree/f076d4e75c56054d79b876e00b6bded06d90df86/src/native">crypto
primitives</a>).
To further read up on the topic, there is a <a href="https://matildah.github.io/posts/2016-01-30-unikernel-security.html">nice article about the
security</a>.</p>
<p>This website is 12MB in size (and I didn't even bother to strip yet), which
includes the static CSS and JavaScript (bootstrap, jquery, fonts), <a href="https://github.com/mirage/ocaml-cohttp">HTTP</a>, <a href="https://github.com/mirleft/ocaml-tls">TLS</a> (also <a href="https://github.com/mirleft/ocaml-x509">X.509</a>, <a href="https://github.com/mirleft/ocaml-asn1-combinators">ASN.1</a>, <a href="https://github.com/mirleft/ocaml-nocrypto">crypto</a>), <a href="https://github.com/mirage/ocaml-git/">git</a> (and <a href="https://github.com/mirage/irmin">irmin</a>), <a href="https://github.com/mirage/mirage-tcpip">TCP/IP</a> libraries.
The memory management in MirageOS is
straightforward: the hypervisor provides the OCaml runtime with a chunk of memory, which
immediately takes all of it.</p>
<p>This is much simpler to configure and deploy than a UNIX operating system:
There is no virtual memory, no process management, no file
system (the markdown content is held in memory with irmin!), no user management in the image.</p>
<p>At compile (configuration) time, the TLS keys are baked into the image, in addition to the url of the remote
git repository, the IPv4 address and ports the image should use:
The full command line for configuring this website is: <code>mirage configure --no-opam --xen -i Posts -n "full stack engineer" -r git://git.robur.io/hannes/hannes.robur.coop.git --dhcp false --network 0 --ip 198.167.222.205 --netmask 255.255.255.0 --gateways 198.167.222.1 --tls 443 --port 80</code>.
It relies on the fact that the TLS certificate chain and private key are in the <code>tls/</code> subdirectory, which is transformed to code and included in the image (using <a href="https://github.com/mirage/ocaml-crunch">crunch</a>). An improvement would be to <a href="https://github.com/mirage/mirage/issues/489">use an ELF section</a>, but there is no code yet.
After configuring and installing the required dependencies, a <code>make</code> builds the statically linked image.</p>
<p>Deployment is done via <code>xl create canopy.xl</code>. The file <code>canopy.xl</code> is automatically generated by <code>mirage --configure</code> (but might need modifications). It contains the full path to the image, the name of the bridge
interface, and how much memory the image can use:</p>
<pre><code>name = 'canopy'
kernel = 'mir-canopy.xen'
builder = 'linux'
memory = 256
on_crash = 'preserve'
vif = [ 'bridge=br0' ]
</code></pre>
<p>To rephrase: instead of running on a multi-purpose operating system including processes, file system, etc., this website uses a
set of libraries, which are compiled and statically
linked into the virtual machine image.</p>
<p>MirageOS uses the module system of OCaml to define how interfaces should be, thus an
application developer does not need to care whether they are using the TCP/IP
stack written in OCaml, or the sockets API of a UNIX operating system. This
also allows to compile and debug your library on UNIX using off-the-shelf tools
before deploying it as a virtual machine (NB: this is a lie, since there is code
which is only executed when running on Xen, and this code can be buggy) ;).</p>
<p>Most of the MirageOS ecosystem is developed under MIT/ISC/BSD license, which
allows everybody to use it for whichever project they want.</p>
<p>Did I mention that by using less code the attack vector shrinks? In
addition to that, using a memory safe programming language, where the developer
does not need to care about memory management and bounds checks, immediately removes
several classes of security problems (namely spatial and temporal memory
issues), once the runtime is trusted.
The OCaml runtime was reviewed by the French <a href="http://www.ssi.gouv.fr/agence/publication/lafosec-securite-et-langages-fonctionnels/">Agence nationale de la sécurité des systèmes d’information</a> in 2013,
leading to some changes, such as separation of immutable strings (<code>String</code>) from mutable byte vectors (<code>Bytes</code>).</p>
<p>The attack surface is still big enough: logical issues, resource management, and there is no access
control. This website does not need access control, publishing of content is protected by relying on GitHub's
access control.</p>
<p>I hope I gave some insight into what the purpose of an operating systems is, and
how MirageOS fits into the picture. I'm interested in feedback, either via
<a href="https://twitter.com/h4nnes">twitter</a> or via eMail.</p>
<li>this website is based on <a href="https://github.com/Engil/Canopy">Canopy</a>, the content is stored as markdown in a <a href="https://git.robur.io/hannes/hannes.robur.coop">git repository</a>
</li>
<li>it was running in a <a href="https://FreeBSD.org">FreeBSD</a> jail, but when I compiled too much the underlying <a href="https://www.freebsd.org/doc/en_US.ISO8859-1/books/handbook/zfs.html">zfs file system</a> wasn't happy (and is now hanging in kernel space in a read)
</li>
<li>no remote power switch (borrowed to a friend 3 weeks ago), nobody was willing to go to the data centre and reboot
</li>
<li>I wanted to move it anyways to a host where I can deploy <a href="http://www.xenproject.org/">Xen</a> guest VMs
</li>
<li>turns out the Xen compilation and deployment mode needed some love:
<ul>
<li>I ported a newer <a href="https://github.com/hannesm/bin_prot/tree/113.33.00+xen">bin_prot</a> to xen
</li>
<li>I wrote a clean patch to <a href="https://github.com/Engil/Canopy/pull/15">serve via TLS</a> (including <a href="https://en.wikipedia.org/wiki/HTTP_Strict_Transport_Security">HSTS header</a> and redirecting HTTP (moved permanently) to HTTPS)
</li>
<li>I found a memory leak in the <a href="https://github.com/mirage/mirage-http/pull/23">mirage-http</a> library
</li>
</ul>
</li>
<li>I was travelling
</li>
<li>good news: it now works on Xen, and there is <a href="https://hannes.nqsb.io/atom">an atom feed</a>
</li>
<li>life of an "eat your own dogfood" full stack engineer ;)