Act 1: Background
OpenBSD.
Much of the software developed by the operating system’s developers is focussed on minimising potential
security issues, such as developing the pledge()
syscall to drop program capabilities and privleges,
or their development of LibreTLS following the Heartbleed incident, or even disabling SMT by default.
The OpenBSD developers eventually grew tired of patching web servers to drop privileges and chroot to the webroot (having done so with both Apache and Nginx), so they instead opted to write their own simple HTTP server. This chroot turns out to be a little bit of problem, though.
If you poke at it enough, you might discover that this website is hosted on an OpenBSD server. Given that httpd is part of the base system, I decided to give it a try since the whole point of this server when I set it up was to explore OpenBSD. A year and half has gone by, and projects on this server have come and gone, but not the web server. I wanted to try out setting up cgit, and while there was some struggle to set it up (since you can’t directly use references like the Arch Wiki), I eventually got it going. Enough background, though, what actually was the questionable decision?
Act 2: In Which Markdown Forces My Hand
Markdown is nice for quick writing and not fussing about with other things. This website is implemented
with Hugo and Markdown documents, for example. It’s also good for writing READMEs in git repositories.
SourceHut and GitHub take care of rendering your README.md files without you even giving it thought. On
the other hand, cgit requires some fiddling. The cgitrc
file can have an about-filter
option
specified, which expects the path to a script. The script should then execute a program or another
script which takes the file to convert to HTML on stdin and return the converted HTML on stdout.
On other platforms, cgit ships with a set of Python scripts which can convert various file types into rendered HTML, notably Markdown. These scripts to do not ship with cgit from OpenBSD’s ports collection – and why should they? Python is not available inside the webroot and thus unvailable in the httpd process' chroot.
I wanted my Markdown-written READMEs to be rendered into HTML, so I needed a solution to this.
Act 3: Basiclaly Building a New System
There is a program called lowdown
available in the ports collection. It is a simple binary written in
C that is can take the place of the Python script from upstream cgit. The only trouble is, it’s dynamically
linked to a few things.
|
|
Now, I could have cloned the ports tree and build lowdown statically, but my server is running low on disk
space. I chose to make do with what I had. Copying the binary is not enough, though. We need the rest of the
dynamically linked libraries. So we create /var/www/usr/lib
and /var/www/usr/libexec
and copy the libraries
into those directories.
Some issues remain though.
Since cgit expects a script, executing the script is bound to fail since there is no /bin/sh
in the webroot.
bash
has too many linked libraries and we want to minimise the amount of mess we make. Let’s take a look at
one of the shells that forms part of the base system, ksh
:
|
|
Perfect! No other linked libraries. We’ll copy this into the webroot and use this as our shell. Now let’s take a look at the default about-formatting.sh script from upstream cgit:
|
|
If we try to let cgit call this script as is, it’s going to fail every time. The reason being, commands like
dirname
, printf
, and tr
are still unavailable. Ignoring the dirname
line, we just need to copy in
printf
and tr
.
From here, we set our cgitrc file to point to this script, and let the final script be:
|
|
After all of this work, cgit should render our README.md file into HTML. Sadly, it does not do syntax highlighting. Another problem for different day, I suppose.