Register for the iXsystems Community to get an ad-free experience and exclusive discounts in our eBay Store.

How to build your own Bitwarden_rs jail

Joined
Sep 22, 2017
Messages
3
I have used https://www.ixsystems.com/community...in-a-jail-for-local-useage.73583/#post-510078 as a reference.
But wanted to avoid ruby and rubywarden and also wanted to use https://github.com/dani-garcia/bitwarden_rs
The setup is for local lan + vpn access, do not open it to the internet.

I have tested it with
Using the server with native bitwarden apps eg. iOS/firefox. With this setup nothing goes to their servers.

The post follows the building process described on https://github.com/dani-garcia/bitwarden_rs/wiki/Building-binary

Make sure to:
* Fill in Certificate details, or not (just enter through)
* Letsencrypt if dns is working on your local host

ssh into your freenas host

Code:
# create your jai as root and login
sudo iocage create -n bitwarden -r 11.2-RELEASE vnet="on" boot="on" dhcp="on" bpf="yes"
sudo iocage console bitwarden


Code:
# install runtime and build dependencies, this will ask some questions, jus say Y
pkg install  sqlite3 nginx git sudo vim-tiny bash node npm python27-2.7.17_1


Code:
# some npm dependency will need to have python2.7 and will fail with python3
cd /usr/local/bin/
# set the symlink 
ln -s /usr/local/bin/python2.7 python
cd - 


Code:
# Add new bitwardenrs user to the jail
echo "Set the user below to: bitwardenrs"
echo "Enter every line, no need for other configs, only your password
echo
adduser -s bash


Code:
# allow sudo, we will use it later
visudo
# ADD
bitwardenrs ALL=(ALL) ALL

# change to the new user to build and execute our service
su bitwardenrs
cd 
id
# should look like: uid=1001(bitwardenrs) gid=1001(bitwardenrs) groups=1001(bitwardenrs)



Code:
# install latest rust version, pkg version is outdated and can't build bitwarden_rs
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
# include the rust env variables
source $HOME/.cargo/env


In this sample I used my own ca but there is an other solution with LetsEncrypt https://wiki.freebsd.org/BernardSpil/LetsEncrypt
Code:
mkdir CA
cd CA

# generate the CA key
openssl genrsa -out server_rootCA.key 4096

# create certificate request
openssl req -x509 -new -nodes -key server_rootCA.key -sha256 -days 3650 -out server_rootCA.pem

# discover the default interface and its IP address (will only work with internet access)
export DEFAULT_INTERFACE=$(route get 1.1.1.1 | grep interface | cut -d \  -f 4)
export DEFAULT_IP=$(ifconfig $DEFAULT_INTERFACE | grep 'inet' | awk -F ' ' '{ print $2 }')

# construct the CA config file
cat << EOF > server_rootCA.csr.cnf
[req]
default_bits = 4096
prompt = no
default_md = sha256
distinguished_name = dn

[dn]
C=Some
ST=Some
L=Some
O=Some
OU=local_RootCA
emailAddress=.
CN = ${DEFAULT_IP}
EOF

# create the v3 extension config
cat << EOF > v3.ext
authorityKeyIdentifier=keyid,issuer
basicConstraints=CA:FALSE
keyUsage = digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment
subjectAltName = @alt_names

[alt_names]
IP = ${DEFAULT_IP}
EOF

# create the nginx server key
openssl req -new -sha256 -nodes -out server.csr -newkey rsa:4096 -keyout server.key -config <( cat server_rootCA.csr.cnf )
# create the nginx server certificate
openssl x509 -req -in server.csr -CA server_rootCA.pem -CAkey server_rootCA.key -CAcreateserial -out server.crt -days 3650 -sha256 -extfile v3.ext


Code:
# copy private key
sudo cp  server.key /usr/local/etc/nginx/cert.key
# copy server.crt
sudo cp server.crt /usr/local/etc/nginx/cert.crt


Code:
# got back to the users home
cd ..
echo

# and finnaly checkout the latest bitwarden_rs release 
git clone https://github.com/dani-garcia/bitwarden_rs/
cd bitwarden_rs/
git checkout "$(git tag --sort=v:refname | tail -n1)"

# and build it with sqlite support
cargo build --features sqlite --release
cargo install diesel_cli --no-default-features --features sqlite-bundled
cd ..


If you need web-vault, we will build it here
Code:
# WEB-VAULT
# clone the repository
git clone https://github.com/bitwarden/web.git web-vault
cd web-vault
# switch to the latest tag, is not working here, dani-garcia/bw_web_builds lacks v2.12.0 patch
# export WEB_VERSION="$(git tag --sort=v:refname | tail -n1)"
# lets use the last working version
export WEB_VERSION=v2.11.0
git checkout ${WEB_VERSION}

# download and apply the bitwarden_rs patch
curl https://raw.githubusercontent.com/dani-garcia/bw_web_builds/master/patches/${WEB_VERSION}.patch >${WEB_VERSION}.patch
git apply ${WEB_VERSION}.patch -v


Install dependencies and fix some issues.
Code:
# there is no native freebsd version from node-sass 4.11, lets bump it to 4.12.0
cat package.json |sed -e 's/"node-sass": "^4.11.0",/"node-sass": "^4.12.0",/' | tee package.json

# download submodules
npm run sub:init
# manually install angular/compiler-cli
npm i @angular/compiler-cli

# install all the other dependencies 
npm install

# sweetalert will fail with the latest angular2 so fix it
# https://github.com/t4t5/sweetalert/issues/738
# PATCH sweetalert.d.ts ....
cat <<EOF >node_modules/sweetalert/typings/sweetalert.d.ts
import swal, { SweetAlert } from "./core";

export default swal;
export as namespace swal;
EOF


Finally build the web-vault
Code:
npm run dist


At this point we have every componets and will have to put them together
Code:
cd
# copy bitwarden_rs dist
cp -r ~/bitwarden_rs/target/release bitwarden_rs_dist
cd bitwarden_rs_dist
# and copy the web-vault files
cp -r ../web-vault/build web-vault


Let's setup our nginx fronted server.
Code:
su # be root
bash

# create nginx.conf 
cat << EOF >/usr/local/etc/nginx/nginx.conf
worker_processes  1;

events {
    worker_connections  1024;
}

http {
    include       mime.types;
    default_type  application/octet-stream;
    sendfile        on;
    keepalive_timeout  65;

server {
    listen 80;
    return 301 https://\$host$request_uri;
}

server {

    listen 443;
    server_name localhost;

    ssl_certificate           /usr/local/etc/nginx/cert.crt;
    ssl_certificate_key       /usr/local/etc/nginx/cert.key;

    ssl on;
    ssl_session_cache  builtin:1000  shared:SSL:10m;
    ssl_protocols  TLSv1 TLSv1.1 TLSv1.2;
    ssl_ciphers HIGH:!aNULL:!eNULL:!EXPORT:!CAMELLIA:!DES:!MD5:!PSK:!RC4;
    ssl_prefer_server_ciphers on;

    access_log            /var/log/nginx/bitwarden_rs_web_vault.log;

    location / {
      proxy_set_header        Host \$host;
      proxy_set_header        X-Real-IP \$remote_addr;
      proxy_set_header        X-Forwarded-For \$proxy_add_x_forwarded_for;
      proxy_set_header        X-Forwarded-Proto \$scheme;

      proxy_pass          http://localhost:8000;
      proxy_read_timeout  90;

      proxy_redirect      http://localhost:8000 https://localhost;
    }
  }
}
EOF

# enable and start nginx 
sysrc nginx_enable="YES"
service nginx start


Create the bitwardenrs init script
Code:
mkdir -p /usr/local/etc/rc.conf.d/
# limit the rocket server only to localhost 
echo "ROCKET_ADDRESS=127.0.0.1" >/usr/local/etc/rc.conf.d/bitwardenrs

# 
cat <<EOF > /usr/local/etc/rc.d/bitwardenrs
#!/bin/sh

# PROVIDE: bitwardenrs
# REQUIRE: LOGIN DAEMON NETWORKING
# KEYWORD: jail rust

# Enable this script by adding:
# bitwardenrs_enable="YES"
# ... to /etc/rc.conf

. /etc/rc.subr

name="bitwardenrs"
rcvar="bitwardenrs_enable"
bitwardenrs_chdir=/home/bitwardenrs/bitwarden_rs_dist
# This is the tool init launches
command="/usr/sbin/daemon"

pidfile="/var/run/\${name}.pid"

# This is the tool daemon launches
task="./bitwarden_rs"
procname="/bin/bash"

command_args="-u bitwardenrs -p \${pidfile} \${task}"

load_rc_config $name
run_rc_command "\$1"
EOF

sudo sysrc bitwardenrs_enable="YES"
sudo chmod +x /usr/local/etc/rc.d/bitwardenrs
sudo service bitwardenrs start


If you made it here, you will have a working self singed cerificate "protected" web-vault with a working bitwarden_rs backend.
But because its a self signed cert you will have to import your CA cert into every client.
 

millst

FreeNAS Experienced
Joined
Feb 2, 2015
Messages
131
Thanks for the write-up. Wish you had done it sooner...might have saved me some time :)
 

adrianwi

FreeNAS Guru
Joined
Oct 15, 2013
Messages
1,083
Thanks for the guide. I might give it a try at some point, but I've recently installed Bitwarden via a Docker container(s) in a bhyve VM. If you already have Docker up and running, getting Bitwarden working is surprisingly simple!
 
Joined
Sep 22, 2017
Messages
3
Thanks for the guide. I might give it a try at some point, but I've recently installed Bitwarden via a Docker container(s) in a bhyve VM. If you already have Docker up and running, getting Bitwarden working is surprisingly simple!
Yes, if docker works then its easier, but you added +1 vm layer as well.
I had mixed experience with rancher on freenas but mostly bad, that's why I did it via jail.
 
Joined
Feb 27, 2020
Messages
2
Thank you, it works great.
How would you configure bitwarden_rs out of the default behavior properly ?
It doesn't create the config.json anywhere and I am having a hard time adding the env variables to be taken into account.
 

ornias

FreeNAS Experienced
Joined
Mar 6, 2020
Messages
164
Thank you, it works great.
How would you configure bitwarden_rs out of the default behavior properly ?
It doesn't create the config.json anywhere and I am having a hard time adding the env variables to be taken into account.
You can create a file `/usr/local/etc/rc/conf.d/bitwardenrs`
inside you can enter some exports:

Code:
export WEB_VAULT_ENABLED="true"
export SIGNUPS_ALLOWED="true"

 
Joined
Feb 27, 2020
Messages
2
Thanks ornias, sadly I still can't get it to work, trying to disable signups. You got /usr/local/etc/rc/conf.d/bitwardenrs to be taken into account after following Ghost231 process?
 

ornias

FreeNAS Experienced
Joined
Mar 6, 2020
Messages
164
Thanks ornias, sadly I still can't get it to work, trying to disable signups. You got /usr/local/etc/rc/conf.d/bitwardenrs to be taken into account after following Ghost231 process?
Yes and No....
I did use a mix of my own work (before @Ghost231, not posted publicly) and the work by @Ghost231.
But in general my solution worked just fine.

However: If you enter the admin page, these settings DO get overruled, as you can see in my example, I only tried to add the absolute minimum as an env. variable and the rest is added later using the admin gui.

 
Top