Backing Up My Bitwarden Database

| Comments

I’ve been using Bitwarden for a little over a month so far. I’m enjoying the experience, and I haven’t had any problems, so I expect that I will continue to use Bitwarden as my password manager for the foreseeable future.

That means I need a way to back up my Bitwarden database. Keeping my passwords backed up happened for free when I was using Keepass. Your Keepass database is just a securely encrypted file, and my cloud storage solution kept a copy of that file on each of my computers, my phone, and my tablets. There was also 90-days’ worth of history stored on my Seafile server.

Bitwarden is different. There is no password database file. From my perspective, everything is magically stored on the server. How am I going to keep a backup? Can I automate it? Where should I store the backup?

While I’m at it, I figured this would be a good time to update the backup process for my ssh and GnuPG keys as well!

When will I need to use a Bitwarden backup?

I did some testing for my own peace of mind. I disconnected my laptop from the network, completely shut down my web browser, and fired it back up again. I wanted to make sure that I had access to all my passwords even when the Bitwarden servers aren’t available.

As you would expect, this worked just fine. I can access my passwords, and I was able to export a CSV dump of my database without access to the Internet. What does this mean?

My Bitwarden backup script in action

It means that I will still be able to dump my passwords even if the Bitwarden company disappears off the face of the Earth over-night.

I don’t need daily backups, but that would be nice. In practice, I probably only need a backup any time one of my core passwords changes. If I lose my Slashdot password, they’ll let me reset it via email. If I lose my Gmail password, it would be a huge pain in the butt!

The Bitwarden CLI

The Bitwarden command-line tool seems pretty good, but its export functionality falls short of what I was hoping for. The command-line tool, the native application, and the browser plugin all have similar limitations, but I was able to set up something that will get the job done.

Exporting requires that you decrypt your vault. It would be nice if you could just pull your vault out of the app in its existing, unreadable state, but I wasn’t really expecting to be able to do that.

The Bitwarden CLI can export a CSV or JSON file, but it has to write to a file. You cannot export to STDOUT. I was hoping to be able to do something like this:

bw export --output - | gpg --output myvault.csv.gpg -e -r thehead@patshead.com

You can’t do this. Bitwarden’s CLI doesn’t respect the tradition of using - as the filename to designate STDOUT.

Ugh. I don’t want my plaintext passwords to touch the disk.

I finally found a use for my USB drive with Brian’s face on it!

If I can’t encrypt the exported data before it touches the disk, then I guess I’m going to have to store Bitwarden’s CSV file on an encrypted disk. The export is going to be a manual process anyway, since it will require me to enter my passphrase, so why not use an encrypted USB flash drive?

I encrypted the flash drive using LUKS. If you’re on Windows, you could probably use something like Veracrypt. You could most certainly use a GUI to configure your LUKS encrypted disk, but I have absolutely no idea how to do that. These are the commands that I used:

1
2
3
4
cryptsetup luksFormat /dev/sdb
cryptsetup open /dev/sdb TemporaryName
mkfs.ext4 /dev/mapper/TemporaryName
cryptsetup luksClose TemporaryName

I may as well back up my ssh and GnuPG keys

I don’t often make backups of my ssh or GnuPG keys. I could write 2,000 words about my key-management practices, but I will try to be brief.

My ssh keys allow me to log into machines that are extremely important to me: my blog’s web server, my virtual machine host, or my NAS. I have at least one unique ssh key on my laptop, desktop, and tablet. If any one of those three computers is lost or compromised, I can easily remove its corresponding public key from all my servers.

Since I have different keys on three different computers that can log in to all my servers, I don’t need backups of my ssh private keys. If my laptop dies, I can simply generate a new key and update all my servers using one of the other two good keys.

GnuPG is different. While my ssh keys identify who I am and which machine I’m using, my PGP key only identifies me. There is no replacing my root PGP key. If I lose that private key, I’m probably in trouble. All sorts of backups and important files would become completely lost.

My PGP key doesn’t change very often. In fact, I’m long overdue for a fresh key! I even have a hard copy of my PGP key printed out.

Even though my PGP and ssh keys are encrypted and have strong passphrases, I don’t feel comfortable storing them anywhere in the cloud. As long as I’m going to be backing up my Bitwarden passwords to a USB flash drive, I may as well include my desktop’s ssh and GnuPG keys, right? It only requires an extra tar command or two!

I’m not sure that was brief.

My backup script

You don’t need to script any of this, but I did. I’m lazy. I can’t automate the entire process, but at least I can automate some of it!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
#! /bin/bash

dir=/root/usbbackup  # bw cli snap won't write to /tmp
uuid=277ab83d-cb1d-4687-99dd-14544a6f3ace
datestamp=$(date +%F)

gpgdir=/home/wonko/Seafile/backups
gpgrecipient=thehead@patshead.com

cryptsetup open /dev/disk/by-uuid/$uuid usbbackup || exit 1

mkdir $dir || exit 1

mount /dev/mapper/usbbackup $dir || exit 1

## backup ssh and GnuPG keys and configuration
tar cf $dir/ssh-$datestamp.tar /home/wonko/.ssh
tar cf $dir/gnupg-$datestamp.tar /home/wonko/.gnupg
tar cf $dir/ssh-$datestamp.tar /home/wonko/.ssh

/snap/bin/bw unlock  # I don't know why I need this, but I do?!
export BW_SESSION=$(/snap/bin/bw login thehead@patshead.com --raw)

/snap/bin/bw export --output $dir/bw-$datestamp.csv

/snap/bin/bw logout

gpg --output $gpgdir/bw-$datestamp.csv.gpg -e -r $gpgrecipient $dir/bw-$datestamp.csv

echo New files on USB drive at $dir:
ls -l $dir/*$datestamp*

echo New Seafile GPG files:
ls -l $gpgdir/*$datestamp*

umount $dir || exit 1
rmdir $dir || exit 1
sync # for paranoia
cryptsetup luksClose usbbackup || exit 1
sync # for more paranoia!

echo Backup complete, USB drive synced and unmounted.

My backup script isn’t exciting or sexy, but I figured somebody might ask about it, so here it is!

Conclusion

I feel a little safer. My passwords can survive if my house burns down or Bitwarden’s hosting goes out of business. Even if both catastrophes occur on the same day, there will still be a GnuPG encrypted copy of my passwords stored on my Seafile server.

What do you think? Are you using Bitwarden? What are you doing to keep your passwords safe? Do you have a semi-automated backup process like mine, or do you manually export your database every once in a while? Let me know in the comments, or stop by the Butter, What?! Discord server to chat with me about it!

Comments