Hosting your own password manager using open source software

November 3rd, 2016

For the past few years, I've been managing my passwords using Lastpass. While it's been a great service, I still have two key issues with it - it's closed source, and I'm storing all of my passwords on someone else's "cloud" service. I also found it difficult to use because of the free service not supporting mobile devices, but that changed between me setting everything up and writing this post!

An excellent solution to this is Keepass - it's open source under the GPLv2, and while by default it's designed to run directly from a local file, it also supports working with remote files through a variety of backends. To top it off, there's a great web client, KeeWeb - let's self-host it!

One supported backend is WebDav - this is a simple file management protocol that's an extension of HTTP, so it's easy to set this up on an existing web server. For this post, I'll be using Apache, but this should be adaptable to nginx or most other web servers.

To start, you'll want to make a new VirtualHost. In all of my examples I'll use the domain example.com, and I'll assume your current directory is the DocumentRoot for this VirtualHost.

You'll need to set up HTTPS, so that the authentication data is encrypted - Let's Encrypt works well for this, and you can use certbot to automate obtaining and installing the certificates.

While KeePass includes encryption for our password storage, we also want another layer of password protection over the WebDav storage, to prevent unauthorised users from adding other files, or changing our password database. For this, I used HTTP authentication - my system authenticates against my AD server, but for this post I'll just be using HTTP basic authentication.

To start, you'll want to add a .htpasswd file for the credentials to be stored in - I put mine in /etc/apache2 using the following command:

sudo htpasswd -c /etc/apache2/.htpasswd username
sudo chown www-data:www-data /etc/apache2/.htpasswd
sudo chmod 600 /etc/apache2/.htpasswd

This will prompt you to enter a password, and will save it to that file. The permissions are also then changed to allow Apache to read the file, and to prevent other users from reading it.

You can then add the following to your VirtualHost configuration, to enable the authentication:

<Location "/">
  AuthType "Basic"
  AuthName "Password Manager"
  AuthBasicProvider file
  AuthUserFile "/etc/apache2/.htpasswd"
  Require valid-user
</Location>

To start with WebDav, you'll need to enable the required apache modules, and create a directory for our password databases, ensuring the www-data user has write permissions on the webdav directory:

sudo a2enmod dav_fs

mkdir webdav
chown www-data:www-data webdav/
chmod 700 webdav/

The following can then be added to your VirtualHost config to enable WebDav on this folder.

<Location "/webdav">
  DAV On
  Options Indexes
</Location>

You can now grab a copy of KeePass, and create a new local database. You can then save this to your new WebDav storage, by going to File > Save As, and then Save to URL. You can specify https://example.com/webdav/DatabaseName.kdbx as your URL, and it should be saved! You can now open this URL using KeeWeb on another device, and keep everything synchronised between devices. You can repeat this as many times as you'd like for different databases.

However, another great feature of Lastpass that we're still missing is the ability to access all of our passwords through a web UI, should KeePass not be installed on a device that needs to access passwords. KeeWeb is a lovely web-based client that's compatible with KeePass files, and it's contained within a single HTML file, so it's very easy to set up.

You can download the KeeWeb repo (you'll need Git) using the following command:

git clone -b gh-pages https://github.com/keeweb/keeweb.git

Downloading KeeWeb via Git also makes it easy to get any new versions - just run git pull.

KeeWeb will now be accessible at https://example.com/keeweb/. However, currently you manually have to specify the WebDav file, which is a pain - KeeWeb allows us to provide a configuration file for this. You'll want to create a file called config.json in your DocumentRoot (not inside the keeweb directory), and add the following JSON, adding sections for each database file as required. You can read more about this file on the KeeWeb wiki.

{
  "settings": {},
  "files": [
    {
      "storage": "webdav",
      "name": "Database Name",
      "path": "/webdav/DatabaseName.kdbx"
    }
  ]
}

You can specify this config file argument in the URL, by going to /keeweb/?config=/config.json. However, this is a pain to use - you can easily add a redirect in from the root (using RedirectMatch to ensure it only matches the root).

RedirectMatch 301 ^/$ /keeweb/?config=/config.json

After restarting Apache to apply everything, you can now to go the site, and login with your basic auth credentials. You'll be presented with the KeeWeb UI, allowing you to open your KeePass databases and manage your passwords. Enjoy your new private password manager!