DEV Community

sjdonado
sjdonado

Posted on

Self-Hosted Password Manager with Dokku

Why?

I relied on 1Password for the last few years, it is robust, and very user-friendly. However, these types of services are prime targets for attacks, one popular example is the Lastpass case. It is definitely not cool to have your sensitive info spread in another data breach. Also, privacy is precious nowadays, whoever has the data, has the power.

While exploring Open Source alternatives, I found vaultwarden, an unofficial Bitwarden-compatible server written in Rust.

Migrating data manually is a tedious process, so I first checked how it would be like with Bitwarden. Surprise, surprise, they have it all! You don't have to do it by hand, it already supports the most popular password managers.

Web - Import Data Page
Bitwarden Import Data Page

PS: It was a relief to discover a well-done user interface, here's a spoiler:

macOS app
macos App

To make it cost effective, I decided to use my current Dokku setup, hosted on Google Cloud and powered by Ubuntu 20.04. If you haven't heard of Dokku, this is your chance to try it out https://dokku.com/docs/getting-started/installation/.

So, having in mind the advantages and the infra required, here's how I did it.

Prerequisites

Before we get started, check that you already have the following:

  • A server with Dokku installed.
  • A domain name (letsencrypt will check it).
  • Local machine with Docker, Git and any SSH client.

Step by Step

1. Create Dokku App

Set your app name and link to the domain (the Dokku Proxy plugin is built in since version 0.5.0)

dokku apps:create bitwarden

# example: dokku domains:set bitwarden mypasswords.sjdonado.de
dokku domains:set bitwarden yourdomain.com
Enter fullscreen mode Exit fullscreen mode

2. Set up TLS certificates

The Let's Encrypt plugin automates the generation and renewal of our certificates


# plugin installation requires root, hence the user change
sudo dokku plugin:install https://github.com/dokku/dokku-letsencrypt.git

dokku letsencrypt:enable bitwarden
# enable the automatic renewal of certificates 
dokku letsencrypt:cron-job --add

# replace proxy port, default: 5000
dokku config:set bitwarden DOKKU_PROXY_PORT_MAP="http:80:80 https:443:80"
Enter fullscreen mode Exit fullscreen mode

3. Set up database

We'll use the PostgreSQL plugin

# setup plugin
sudo dokku plugin:install https://github.com/dokku/dokku-postgres.git

# create a new database for our app
dokku postgres:create bitwarden

# link the postgres service to the app, DATABASE_URL will be attached to the ENV variables automatically. 
dokku postgres:link bitwarden bitwarden
Enter fullscreen mode Exit fullscreen mode

4. Set up persistent storage

We can use the built-in Dokku storage plugin

dokku storage:ensure-directory bitwarden

dokku storage:mount bitwarden /var/lib/dokku/data/storage/bitwarden:/data
Enter fullscreen mode Exit fullscreen mode

5. Set up ENV variables

By default, Bitwarden is open to public signups, although we can restrict it to invitation-only by setting SIGNUPS_ALLOWED to false and providing a valid ADMIN_TOKEN.

We're gonna use argon2 to generate a PHC string for the ADMIN_TOKEN ENV variable

# skip this line if you are a linux user
docker run --rm -it ubuntu

$ apt update && apt install openssl argon2
$ echo -n "MySecretPassword" | argon2 "$(openssl rand -base64 32)" -e -id -k 65540 -t 3 -p 4
# output: $argon2id$v=19$m=65540,t=3,p=4$bXBGMENBZUVzT3VUSFErTzQzK25Jck1BN2Z0amFuWjdSdVlIQVZqYzAzYz0$T9m73OdD2mz9+aJKLuOAdbvoARdaKxtOZ+jZcSL9/N0
Enter fullscreen mode Exit fullscreen mode

For the SMTP_ variables, feel free to use your own SMTP server or comercial solutions with free-tier such as sendgrid

dokku config:set bitwarden \
  DOMAIN=https://mypasswords.sjdonado.de \
  SIGNUPS_ALLOWED=false \
  ADMIN_TOKEN='$argon2id...' \
  SMTP_HOST=smtp.sjdonado.de \
  SMTP_FROM=vaultwarden@sjdonado.de \
  SMTP_PORT=587 \
  SMTP_SECURITY=starttls \
  SMTP_USERNAME= \
  SMTP_PASSWORD=
Enter fullscreen mode Exit fullscreen mode

6. Create the Dockerfile

Let's create a new folder for the project, the Dockerfile and initialise git

mkdir yourfolder && cd yourfolder
git init
touch Dockerfile
Enter fullscreen mode Exit fullscreen mode

yourfolder/Dockerfile

FROM vaultwarden/server:latest

EXPOSE 80

ENV DB=postgresql
Enter fullscreen mode Exit fullscreen mode

7. Deploy

We are almost there! Before to push the changes, we have to set the dokku remote url

git remote add dokku-bitwarden dokku@yourdomain.com:bitwarden
Enter fullscreen mode Exit fullscreen mode

And finally

git add -A && git commit -m "My bitwarden Dockerfile"
git push dokku master

# output:
git push using:  dokku master
Enumerating objects: 6, done.
Counting objects: 100% (6/6), done.
Delta compression using up to 8 threads
Compressing objects: 100% (3/3), done.
Writing objects: 100% (6/6), 551 bytes | 551.00 KiB/s, done.
Total 6 (delta 0), reused 0 (delta 0), pack-reused 0
-----> Cleaning up...
-----> Building bitwarden from Dockerfile
remote: #1 [internal] load build definition from Dockerfile
remote: #1 transferring dockerfile: 65B done
remote: #1 DONE 0.0s
remote: 
remote: #2 [internal] load .dockerignore
remote: #2 transferring context: 2B done
remote: #2 DONE 0.1s
...
Enter fullscreen mode Exit fullscreen mode

8. That's it

Now you can access the admin panel via https://yourdomain.com/admin with your MySecretPassword (from step 5) and send invitations by email ๐Ÿ˜Ž.

Admin Portal

NOTE: Be sure to add your domain when installing the official Bitwarden apps/extensions.

Chrome Extension
Chrome Extension example

Wrapping up

We've explored the process of setting up a self-hosted password manager using Dokku. This can be easily replicated on any IaaS provider.

Now, you can have peace of mind knowing that your passwords are securely stored and easily accessible whenever and wherever you need them.

gif

Source code available on Github.


Go check my website https://sjdonado.de, drop me a line. Suggestions are more than welcome in the comments box.

Happy hacking!

Top comments (1)

Collapse
 
vdias profile image
VDIAS

Vaultwarden directly and public exposed... Not a good idea!!!