Discopter Pi Guide

Chapter 12: Setting Up Vaultwarden as a Password Manager

Password managers are essential to modern use of the internet. A new data breach is announced almost every day with often millions of user account credentials winding up for sale on the Dark Web. All but the most incompetent websites store passwords as hash values in their database. This means that many data breaches do not result in a password compromise as the hacker only gains access to the password hash. You should never count on that protecting you, however, as often the hashes are compromised as well. Purchasers of these data will often use the unhashed username to identify other online accounts and attempt to login using the compromised password for non-breached services. Even without a data breach, many users are lazy and use common patterns in their password, such as the word “password.” Sometimes, users will try to be sneaky and slip in some numbers and special characters but “P@$$w0rd” is only slightly more secure. Personal information, like family member or pet names, is also common and often easy to obtain from a victim. Password managers allow you to create and store complex passwords. These passwords are often impossible to remember, so not even the user knows their password. The benefit is that a dictionary or social engineering attack on a password is next to impossible to achieve (under current computing technology).

Password managers can be broadly categorized as follows:

Type 1: Browsers

Chrome, Edge, Firefox, and their derivatives all include password managers. Although this is very convenient and allows for easy synching across devices (assuming you are logged into your browser), it is a very insecure method. Although the passwords are stored in an encrypted database on your device, the encryption keys are unencrypted and saved in easy to predict locations. This is akin to locking up your house tight but then setting the key under the doormat. Other issues include being locked down to that particular browser and having far fewer utilities for generating passwords.

Type 2: Offline

KeePass is a well-known offline password manager. It's very secure and can be used to generate complex passwords on whichever device it is installed on. The problem with offline password managers is that by being offline, each installation is independent of the others. If you have KeePass on your computer and KeePass on your phone, adding a password to one will not synch across devices without work on your part. Many users put their password database in a cloud platform like DropBox. But once you do that, you're no longer using an offline password manager.

Type 3: Online

Some are free but most have some sort of a per month or per year cost associated with them. Many commercial VPN providers also offer a password manager, either included with the VPN or as an added premium feature. NordPass, for example, is available to NordVPN subscribers for an additional fee. The primary advantage of online password managers is synching across devices. A user can generate a password on their mobile device NordPass app and have it immediately available to use on their computer. The primary disadvantage of online password managers is that you are entrusting your passwords to a third party. Your passwords live on their servers. The providers may or may not have the ability to decrypt your passwords, and their claims may or may not be trustworthy. To use our house example again, using an online password manager is perhaps similar to paying someone to follow you around and carry your keys. They might not ever copy your keys when you aren't looking. They might not ever use your keys to get into your house. But you're still trusting them with your housekeys. If you could carry them on your person instead, wouldn't that be better?

Before moving on, let's specifically address Apple. Apple devices come with a password manager called iCloud Keychain. It's associated with your iCloud account and so would be considered an online password manager. Although the iCloud Keychain password database is stored in the AES 256-bit inner vault, much of the rest of iCloud's data is encrypted to 128-bits. End-to-end encryption is available but must be specifically enabled. Apple should be commended for offering a very easy-to-use encrypted cloud platform that benefits the many non-technically sophisticated Apple users who would otherwise not be benefiting from encrypted storage. It does further lock in users to the Apple ecosystem and creates a single point of failure should a compromise occur. Apple users, even those using iCloud Keychain, could still benefit from self-hosting their data.

We're going to be creating a solution that is the best of all of all three of the password manager types by self-hosting a password manager. The password manager will work in our chosen browser as a browser extension. We will own all of the data and have it reside on a device that we control, like an offline password manager. But, it will synch across all of our devices, just like an online password manager. The way we'll do this is by installing a version of Bitwarden designed for Docker called Vaultwarden.

A docker-compose.yml file can be very short or very long. There are many optional parameters that we can specify. We're going to keep it simple. Here are some of the parameters we're going to set:

Two key parameters we are not setting:

With all of that explained, we're finally ready to install Vaultwarden. Once it is installed, we'll test it, enable the Admin panel, and prepare it for local access only, should that be our use case.

Step 1: Download and Build Container

  1. Get the latest image of Vaultwarden from the Docker database:
    docker pull vaultwarden/server:latest
  2. In your home directory, create a new directory for your Vaultwarden docker-compose file:
    mkdir ~/vaultwarden
  3. Create docker-compose.yml in nano:
    nano ~/vaultwarden/docker-compose.yml
  4. Copy and paste the contents below:
    version: '3.7'
    services:
      bitwarden:
        image: vaultwarden/server:latest
        container_name: vaultwarden
        restart: always
        ports:
          - "0.0.0.0:8080:80"
          - "0.0.0.0:3012:3012"
        volumes:
          - ./bw-data/:/data/
  5. Save and exit with ctrl+X.
  6. Change to the vaultwarden directory, if not already in it:
    cd ~/vaultwarden
  7. Run the following command to build the container:
    docker-compose up -d
    The -d or --detach flag builds the container in the background. Without it, your terminal session will be taken over by the container.
  8. After a minute or two, try to access the web interface. In your browser, go to your Raspberry Pi's IP address and the first port you specified. For example, if your Pi is 192.168.8.2 and you used port 8080, as per the example, you would navigate to http://192.168.8.2:8080.
  9. You may need to temporarily open a port with sudo ufw allow 8080 comment ‘vaultwarden', but once fully configured, you can delete this rule.

Step 2: Enable the Admin Panel

  1. Within the Vaultwarden container is a mini version of Linux. We're going to “SSH” into it and run a command to generate an admin token. We'll use this token to login to the administrator section of our Vaultwarden instance. First, generate a hashed pseudorandom string of characters to act as our admin token.
    • docker exec -it <container name> /vaultwarden hash
  2. Set a strong password and enter it twice. It could be the password you plan on using for your Vaultwarden account.
  3. Copy the output of the hash to your clipboard data.
  4. Create a file called .env in the ~/vaultwarden directory
    • nano .env
  5. Paste the hash output and prepend it with a variable name, like the following:
    • VAULTWARDEN_ADMIN_TOKEN=<argon token surrounded by single quotes>
  6. Save and exit with ctrl+X.
  7. In the docker-compose.yml configurations below, note the new field for an environment variable.

Step 3, Option 1: VPN Only

  1. We need to generate a self-signed SSL certificate that our browser will use to authenticate the HTTPS session. Create a subdirectory in your vaultwarden directory to house the certificate files and then change into that directory.
    • mkdir ~/vaultwarden/certs
    • cd ~/vaultwarden/certs
  2. Run this command to generate a self-signed certificate:
    • openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -days 365 -nodes -subj "/CN=<Pi IP>"
  3. With our self-signed certificate, we now adjust our docker-compose.yml. Copy and paste the below:
    version: '3.7'
    services:
      bitwarden:
        image: vaultwarden/server:latest
        container_name: vaultwarden
        restart: always
        ports:
          - "0.0.0.0:8080:80"
          - "0.0.0.0:3012:3012"
        volumes:
          - ./bw-data/:/data
          - ./certs/cert.pem:/cert.pem:ro
          - ./certs/key.pem:/key.pem:ro
        environment:
          - ADMIN_TOKEN=${VAULTWARDEN_ADMIN_TOKEN}
          - ROCKET_TLS={certs="/cert.pem",key="/key.pem"}

Step 3, Option 2: Domain Name

  1. Ensure you have a valid DNS A record pointing to your public IP address.
  2. Update the docker-compose.yml to the following:
    version: '3.7'
    services:
      bitwarden:
        image: vaultwarden/server:latest
        container_name: vaultwarden
        restart: always
        ports:
          - "127.0.0.1:8080:80"
          - "127.0.0.1:3012:3012"
        volumes:
          - ./bw-data/:/data/
        environment:
          - ADMIN_TOKEN=${VAULTWARDEN_ADMIN_TOKEN}
  3. Before we can access Vaultwarden, we need to put it behind a reverse proxy. Skip to the next chapter and add routing for your Vaultwarden domain.
  4. Having set up the reverse proxy, your Vaultwarden instance is now accessible by whatever domain you set with your DNS record.

Step 4: Create an Account and Enable 2FA

  1. Whether via a local IP address or a domain name, navigate to your instance.
  2. Create an account. You need to provide an email address as a username. It's just a username and doesn't have to be a real email address. You may in fact want to not use your primary email address as someone trying to break in would now also need to figure out your username in addition to your password.
  3. Set a very, very strong password, particularly if you went with the domain name option. This is final layer of protection between you and all of your passwords. If there's one extremely complex 20+ character password that you can remember, this would be the place for it.
  4. Once logged in, go the settings menu in the top right and then security. Note the two-factor authentication options available. At the very least, select an authenticator app option. Consider using a hardware token like a Yubikey, if you have one.
  5. To access the admin panel, append /admin to the end of the URL. It will ask for your admin token. Enter the password you set when you created the argon hash in Step 2. There are a lot of settings here, so take some time to explore some of the options, both in the admin panel and the normal user settings.

Step 5: Download Mobile Apps and Browser Extensions

Vaultwarden is a Docker-specific implementation of Bitwarden. When downloading apps and extensions, you'll search for Bitwarden rather than Vaultwarden. All of the major browsers have Bitwarden extensions that will allow you to save and fill in passwords as if using a browser password manager. Both Android and iOS have Bitwarden apps. When opening them for the first time, select a custom server and put in the URL for your instance.

With all of the above accomplished, you now have a secure password manager, accessible anywhere in the world. Unlike a commercial password manager, you own all of your data. The consequences of this approach are that should your Raspberry Pi get corrupted or go offline, all of your passwords will be lost. If you haven't begun to take backup images of your SD card, now is the time to start. If you ever need to rollback a Vaultwarden-breaking change, you'll be able to quickly reconstitute your password manager.

In the next chapter, we're going to have our Pi act as a reverse proxy server. For those who went with the domain name route, you will have already skipped ahead to this chapter.