Self-hosting Bitwarden / VaultWarden on FreeBSD

The time has come for me to consider another application for my TOTP data (think 6-digit codes produced by Google Authenticator or an RSA device. I’ve been using an app called 2STP – I have long liked it. Support for it ended about 7 years ago, yet it continued to slug along on my phone and on my watch.

Recently, it stopped working on my watch. That was the tipping point.

I decided to move to BitWarden. I’ll use BitWarden apps on my phone and watch, and use VaultWarden for the storage engine. VaultWarden is a “Bitwarden server API implementation written in Rust compatible with upstream Bitwarden clients”.

In this post:

  • FreeBSD 14.1
  • vaultwarden 1.32.0_2
  • BitWarden 2024.7.1 (8086)

I also referred to a blog post by Ben Lavery-Griffiths.

Installing

I created a new jail dedicated to this task. Those steps are outside the scope of this post.

When installing, I did the following

pkg install vaultwarden
cp /usr/local/etc/rc.conf.d/vaultwarden.sample /usr/local/etc/rc.conf.d/vaultwarden

/usr/local/etc/rc.conf.d/vaultwarden contains configuration settings for vaultwarden – I’m not sure how this works. It doesn’t seems to be the traditional rc.conf settings I expect to see. However, it does work. Really, all it’s doing is setting a bunch of environment variables. I suspect that’s what VaultWarden is expecting.

Things I changed in that file:

-ROCKET_ADDRESS=127.0.0.1
+ROCKET_ADDRESS=127.0.0.81

This was in a jail and I wanted something other than 127.0.0.1

Without the following, I could not create a new account.

-SIGNUPS_ALLOWED='false'
+SIGNUPS_ALLOWED='true'

I changed it back later.

I don’t run an smtp service here (it’s dma only), so I supplied values for SMTP_HOST & SMTP_FROM

I also set DOMAIN to the hostname I’m using for my service.

Starting

Here is the start:

[root@bw:~] $ service vaultwarden enable
vaultwarden enabled in /etc/rc.conf
[root@bw:~] $ service vaultwarden start
Starting vaultwarden.

From /var/log/daemon.log:

Sep 29 21:07:30 bw vaultwarden[84275]: [2024-09-29 21:07:30.121][rocket::server][WARN] Received SIGTERM. Requesting shutdown.
Sep 29 21:07:30 bw vaultwarden[84275]: [2024-09-29 21:07:30.122][vaultwarden][INFO] Vaultwarden process exited!
Sep 29 21:07:30 bw vaultwarden[3529]: /--------------------------------------------------------------------\
Sep 29 21:07:30 bw vaultwarden[3529]: |                        Starting Vaultwarden                        |
Sep 29 21:07:30 bw vaultwarden[3529]: |--------------------------------------------------------------------|
Sep 29 21:07:30 bw vaultwarden[3529]: | This is an *unofficial* Bitwarden implementation, DO NOT use the   |
Sep 29 21:07:30 bw vaultwarden[3529]: | official channels to report bugs/features, regardless of client.   |
Sep 29 21:07:30 bw vaultwarden[3529]: | Send usage/configuration questions or feature requests to:         |
Sep 29 21:07:30 bw vaultwarden[3529]: |   https://github.com/dani-garcia/vaultwarden/discussions or        |
Sep 29 21:07:30 bw vaultwarden[3529]: |   https://vaultwarden.discourse.group/                             |
Sep 29 21:07:30 bw vaultwarden[3529]: | Report suspected bugs/issues in the software itself at:            |
Sep 29 21:07:30 bw vaultwarden[3529]: |   https://github.com/dani-garcia/vaultwarden/issues/new            |
Sep 29 21:07:30 bw vaultwarden[3529]: \--------------------------------------------------------------------/
Sep 29 21:07:30 bw vaultwarden[3529]: 
Sep 29 21:07:30 bw vaultwarden[3529]: [DEPRECATED]: `SMTP_SSL` or `SMTP_EXPLICIT_TLS` is set. Please use `SMTP_SECURITY` instead.
Sep 29 21:07:30 bw vaultwarden[3529]: [2024-09-29 21:07:30.258][start][INFO] Rocket has launched from http://127.0.0.81:4567

Note the expect IP address there.

This is what is looks like:

[root@bw:~] $ ps auwwx
USER   PID %CPU %MEM    VSZ   RSS TT  STAT STARTED    TIME COMMAND
www  39535 66.8  0.0 364276 38096  -  SJ   19:52   0:01.31 /usr/local/bin/vaultwarden
root 26703  0.0  0.0  12876  2728  -  SsJ  19:29   0:00.01 /usr/sbin/syslogd -s
root 26746  0.0  0.0  12916  2500  -  IsJ  19:29   0:00.01 /usr/sbin/cron -s
www  39534  0.0  0.0  12828  2300  -  SsJ  19:52   0:00.00 daemon: /usr/local/bin/vaultwarden[39535] (daemon)
root 26759  0.0  0.0  13376  3232  2  IJ   19:29   0:00.02 /bin/sh -i
root 38654  0.0  0.0  14840  4416  2  IJ   19:51   0:00.02 zsh
root 38766  0.0  0.0  14356  4272  2  SJ   19:51   0:00.02 bash
root 39543  0.0  0.0  13452  2976  2  R+J  19:52   0:00.00 ps auwwx
[root@bw:~] $ 

TLS? Who wants TLS?

The docs recommend a reverse proxy to implement TLS. Here we go:

pkg install nginx

This is my nginx configuration:

    server {
        listen 80;
        server_name mine.example.com;
        return 301 https://$server_name$request_uri;
    }

    server {
        listen 443 ssl;
	http2 on;

        ssl_certificate     /usr/local/etc/ssl/mine.example.com.cer;
        ssl_certificate_key /usr/local/etc/ssl/mine.example.com.key;

	server_name mine.example.com;

	location / {
		proxy_pass http://127.0.0.81:4567;
	}

	access_log /var/log/nginx/mine.example.com-access.log;
	error_log  /var/log/nginx/mine.example.com-error.log;
    }

There’s that same IP address and port number again. Look for yours in the logs.

Once nginx was running, Here’s what was listening:

[root@bw:~] $ sockstat -4
USER     COMMAND    PID   FD  PROTO  LOCAL ADDRESS         FOREIGN ADDRESS      
www      nginx      84281 8   tcp4   *:80                  *:*
www      nginx      84281 9   tcp4   *:443                 *:*
www      nginx      84281 12  tcp4   203.0.113.231:443     203.0.113.82:60294
root     nginx      84280 8   tcp4   *:80                  *:*
root     nginx      84280 9   tcp4   *:443                 *:*
www      vaultwarde 84276 34  tcp4   127.0.0.81:4567       *:*
root     syslogd    84242 5   udp4   *:514                 *:*

Here’s some of the stuff I saw in the logs, nothing relevant here, just showing.

[root@bw:/var/log] $ tail -F /var/log/daemon.log 
Sep 29 21:06:16 bw vaultwarden[84275]: [2024-09-29 21:06:16.563][request][INFO] POST /identity/accounts/register
Sep 29 21:06:16 bw vaultwarden[84275]: [2024-09-29 21:06:16.564][vaultwarden::api::core::accounts][ERROR] Registration not allowed or user already exists
Sep 29 21:06:16 bw vaultwarden[84275]: [2024-09-29 21:06:16.564][response][INFO] (identity_register) POST /identity/accounts/register => 400 Bad Request

The rest of the signup

After browsing to https:///mine.example.com, I created myself an account, and it all just worked.

In my BitWarden app, I signed in by pointing to a self hosted install, using the same URL. It also just worked.

The data to backup

The data I think I need to backup:

[root@bw:/usr/local/www/vaultwarden/data] $ ls -l
total 172
drwxr-xr-x  2 www www      2 Sep 29 19:52 attachments
-rw-r--r--  1 www www 335872 Oct  1 00:26 db.sqlite3
-rw-r--r--  1 www www  32768 Oct  1 00:26 db.sqlite3-shm
-rw-r--r--  1 www www      0 Oct  1 00:26 db.sqlite3-wal
drwxr-xr-x  2 www www      2 Sep 29 19:52 icon_cache
-rw-r--r--  1 www www   1675 Sep 29 19:52 rsa_key.pem
drwxr-xr-x  2 www www      2 Sep 29 19:52 sends
drwxr-xr-x  2 www www      2 Sep 29 19:52 tmp

I’m sure the main stuff to backup is the db.* files. Yet, I’m sure it should all be backed up. It’s about 88K – easily accommodated. See the backup docs.

I have yet to do this, and I’m relying on my jail-based backups. Oh. I see I have to implement those backups on that host.

Things to fix up

Everything logs to both /var/log/daemon.log and /var/log/messages – this is hardcoded in the rc.d script. I’d prefer that to be removed and configurable via /etc/rc.conf settings

Copying data

For copying data out of 2STP, I used https://github.com/ewdurbin/evacuate_2stp

Future use

I need to decide if I’m going to continue using this implementation or switch to letting BitWarden host my 88K of data.

Is it worth the effort required to maintain etc?

I still plan to sign up with BitWarden and give them money, regardless.

Website Pin Facebook Twitter Myspace Friendfeed Technorati del.icio.us Digg Google StumbleUpon Premium Responsive

2 thoughts on “Self-hosting Bitwarden / VaultWarden on FreeBSD”

  1. I am a long time happy user of OTP Auth [1] on iOS (also available for iPadOS and WatchOS). The features I like:
    – Folders can be created to organize the entries
    – Tabbing an entry will put the code into the clipboard (and then could be pasted on macOS)
    – Selected entries can be added to the Widget
    – In edit mode the secret and QR Code can be shown again
    – With the Pro version (in-App purchase, $3.99) custom icons or emojis can be assigned to entries
    – Password protected exports / backup
    – Supports iCloud sync (I am not using that yet)

    I just discovered that a desktop [2] version also is available. I guess I should consider that with iCloud Sync as well. I aware that this kind of is not the preferred idea of 2FA, but also the copy & paste between iPhone and Mac is probably not.
    [1] https://apps.apple.com/app/otp-auth/id659877384
    [2] https://apps.apple.com/app/otp-auth/id1471867429

Leave a Comment

Scroll to Top