Self-Hosted Bookmarks using DAV and httpd on OpenBSD

       699 words, 4 minutes

I’ve long time used NextCloud and the floccus iOS App and Firefox plugin to store, manage and use my bookmarks. In reality, I don’t use the NC interface. I only use floccus ; and it works really well.

In my journey to quit NextCloud, the only acceptable option to keep using floccus was getting a DAV self-hosted share. But, AFAIK, httpd(8) does not provide a DAV feature (yet?).

I already use Baikal to self-host my calendars and addressbooks and it’s working great. So here’s a quick’n’dirty way to provide DAV using OpenBSD’s httpd(8) and sabre/dav.

Install the PHP environment

sabre/dav is a PHP framework so start by installing it.

# pkg_add php%8.1

# mkdir /var/www/etc
# cp -p /etc/{hosts,resolv.conf} /var/www/etc/

# rcctl enable php81_fpm
# rcctl start php81_fpm

Then build the hosting directory and grab the material.

# pkg_add composer

# cd /var/www
# install -d -g daemon -o root -m 0755 sabre-dav
# cd sabre-dav
# composer require sabre-dav/dav ~4.4.0

Setup the DAV web-space

sabre-dav is not an application. It’s a framework. This means that we now need to write some code to actually do DAV things. The documentation example provides a single-user DAV code model. But anyone knowing about the URL and calling server.php would be able to create/delete/rename/manage the files. This is not what we want.

What we want is authenticated access, users data separation, ofuscated URLs and users, keep the code simple.

Ofuscated URLs and users

We don’t want DAV space and credentials to be easily guessable. So we use randomly generated strings for those. One can use shell commands to do so:

# date | sha512 | cut -c 4-24

Authenticated access

This is achieved by using httpd(8) and htpasswd feature.

Create credentials:

# htpasswd 0Fusc4ted.htpasswd Not4User
Retype Password: 

# chown -R www:www 0Fusc4ted.htpasswd

Configure httpd(8):

# vi /etc/httpd.conf
location "/sabre-dav/0Fusc4ted.php*" {
  root "/sabre-dav"
  request strip 1
  fastcgi socket "/run/php-fpm.sock"
  authenticate with "/sabre-dav/0Fusc4ted.htpasswd"

# rcctl reload httpd.conf

I am not using it but if you wished to grant access to several users on the same DAV space, you could either add credentials to the htpasswd file or add authenticate with directives to the http location.

Note that any of the granted creadentials will have the same read/write access to the data…

Users data separation

Each set of users will have access to a dedicated sub-directory.

# mkdir 0Fusc4ted

# chown -R www:www 0Fusc4ted

Keep the code simple.

We have a single PHP that detects as much info as possible. This PHP file replaces the server.php example. Its name is used to provide access to the directory with the same name.

# vi 0Fusc4ted.php

// Get script name to auto complete directories
$path=explode("/",$_SERVER['SCRIPT_NAME']); $fileName=end($path);
$path=explode(".",$fileName);               $dirName=$path[0];

use Sabre\DAV;

// The autoloader
require 'vendor/autoload.php';

// Now we're creating a whole bunch of objects
$rootDirectory = new DAV\FS\Directory($dirName);

// The server object is responsible for making sense
// out of the WebDAV protocol
$server = new DAV\Server($rootDirectory);

// If your server is not on your webroot,
// make sure the following line has the correct information

// The lock manager is responsible for making sure
// users don't overwrite each others changes.
$lockBackend = new DAV\Locks\Backend\File($dirName.'/locks');
$lockPlugin = new DAV\Locks\Plugin($lockBackend);

// This ensures that we get a pretty index in the browser,
// but it is optional.
$server->addPlugin(new DAV\Browser\Plugin());

// All we need to do now, is to fire up the server

Add more DAV spaces

Using this organization, I can simply add new DAV shares using the following process:

Play with DAV

Everything is not setup to enjoy the DAV web-spaces. Use your DAV client of choice to connect to something like and manage your files.

# cadaver
dav:/sabre-dav/0Fusc4ted.php/> mkdir test
Creating `test': succeeded.
dav:/sabre-dav/0Fusc4ted.php/> exit
Connection to `' closed.

Using Floccus is just a matter of configuring the account:

Happy bookmarking!