Setup Bitwarden in a jail for local useage

ezra

Contributor
Joined
Jan 15, 2015
Messages
124
Hello!

I've made some steps to host your own bitwarden password server inside a jail.

I'm using this on my LAN with my mobile devices connected to a VPN to securely access my LAN remotely.

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

All credit goes to https://github.com/jcs/rubywarden

** Make sure to:
* Create user "_rubywarden" when promted else it will fail (need to figure out how to auto fill username)
* Fill in Certificate details, or not (just enter through)
* Letsencrypt on request, not advisable to open this jail up to the internet...

# Create jail and login
Code:
iocage create -n bitwarden -r 11.2-RELEASE vnet="on" boot="on" dhcp="on" bpf="yes"
iocage console bitwarden


# Install deps
Code:
setenv ASSUME_ALWAYS_YES yes
pkg update
pkg install ruby rubygem-bundler sqlite3 nginx git sudo nano bash
gem install bundler


* Create install script
Code:
nano /tmp/install.sh


Paste this and control + x to save and exit
Code:
########################
#!/bin/bash
# Setup SSL + nginx
openssl req -x509 -nodes -days 3650 -newkey rsa:2048 -keyout /usr/local/etc/nginx/cert.key -out /usr/local/etc/nginx/cert.crt
echo

# Add user
echo "Set the user below to: _rubywarden"
echo "Enter every line, no need for other configs, only your password
echo
adduser
cd /home/_rubywarden

# Clone repo
sudo -u _rubywarden git clone https://github.com/jcs/rubywarden.git

# Install bundle rubywarden
cd rubywarden
sudo -u _rubywarden bundle install --path vendor/bundle

# Create the initial database and the required tables
sudo -u _rubywarden mkdir db/production
sudo -u _rubywarden env RUBYWARDEN_ENV=production bundle exec rake db:migrate


Code:
bash /tmp/install.sh


* Edit nginx.conf
Code:
cat /dev/null > /usr/local/etc/nginx/nginx.conf

Code:
nano  /usr/local/etc/nginx/nginx.conf


Paste this and control + x to save and exit
Code:
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/rubywarden.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;

      # Fix the “It appears that your reverse proxy set up is broken" error.
      proxy_pass          http://localhost:4567;
      proxy_read_timeout  90;

      proxy_redirect      http://localhost:4567 https://localhost;
    }
  }

}


Now start nginx:
Code:
sysrc nginx_enable="YES"
service nginx start


* Run the server with this ( Need help setting up an RC.D script for this one)
Code:
cd /home/_rubywarden/rubywarden
/usr/local/bin/sudo -u _rubywarden env RUBYWARDEN_ENV=production RUBYWARDEN_ALLOW_SIGNUPS=1 bundle exec rackup -p 4567 config.ru


* Now use your app and set the server to: https://JAIL-IP (No need to set url vars)

* Now create a user and password

* To update your instance of Rubywarden, fetch the latest code:

Code:
iocage console bitwarden
cd /home/_rubywarden/rubywarden
git pull --ff-only
exit
iocage restart bitwarden


* From https://github.com/jcs/rubywarden:

2-Factor Authentication

The Bitwarden browser extensions and mobile apps support accounts that require 2FA, by prompting you for the current code after successfully logging in. To activate Time-based One-Time Passwords (TOTP) on your account after you've signed up in the previous steps, run the tools/activate_totp.rb program on the server:
sudo -u _rubywarden env RUBYWARDEN_ENV=production bundle exec ruby /home/_rubywarden/rubywarden/tools/activate_totp.rb -u you@example.com

You'll be shown a data: URL that has a PNG-encoded QR code, which you must copy and paste into a browser, then scan with your mobile TOTP authenticator apps (assuming it supports scanning from the camera). Once scanned, the activation program will ask you to enter the current TOTP being shown in the app for verification, and then save the TOTP secret to your account in the SQLite database. Your security_stamp will be reset, forcing a new login on any devices that are logged into your account. Those devices will now prompt for a TOTP code upon future logins.[/CODE]
 
Last edited:

gt2416

Patron
Joined
Feb 4, 2018
Messages
262
Hey thanks for the guide. However Im not able to get it to work. After the setup and launching bit warden the only thing I can see on my browser is
<h1>Not Found</h1>
I tried following your guide from github as well and get the same error.
On the console I get "GET / HTTP/1.1" 404 18 0.0152"

Also your start command ends with config.r, I think you meant config.ru
Thanks !
 

ezra

Contributor
Joined
Jan 15, 2015
Messages
124
Hey! could you provide some logs of the install? And good catch of the config.ru
 

gt2416

Patron
Joined
Feb 4, 2018
Messages
262
Ignore my last post I forgot its only api access and not the webapp. Using my phones app everything works smoothly. Thanks !
 
Last edited:

ezra

Contributor
Joined
Jan 15, 2015
Messages
124
Hang on, your trying to access a Webui via the browser? That wont work, since there is none. Use an app for android/ios/browser to use the url for. There is no frontend!

Edit: Great!
If you come across a way to setup an RC script to auto start this, please share. Havent found a way yet.
 

gt2416

Patron
Joined
Feb 4, 2018
Messages
262
I've been trying but I just dont know enough about bundler.
If you can tell me a way to start bundle without first cd into the directory maybe I can figure it out.
I keep running into the error cant find .bundle dir. Even if I use cd /path/ && bundle exec.. Ill keep working on it though.
 

garm

Wizard
Joined
Aug 19, 2017
Messages
1,555
Awesome write up and kudos on introducing me to Bitwarden (!)

I need to migrate off my current passwd manager due to their horrible business model.. and this looks to fit the bill

I will try it out myself and suggest some improvements ;)

A first note is however to look at acme.sh for API driven Let’s Encrypt certificates, no need to expose the jail to the internet just to fetch certificates. But maybe that should be it’s own resource.

Edit: I spent 4 hours last night trying to make this neatly packaged in a jail but didn’t like the end result. I opted for an Ubuntu VM and the official docker deployment. However this is till an awesom product and I have already migrated my password manager. On iOS it looks to be feature complete with what I expect
 
Last edited:

danb35

Hall of Famer
Joined
Aug 16, 2011
Messages
15,456
But maybe that should be it’s own resource.
Like this one? OK, it's a different focus--but it does also cover using DNS validation with acme.sh...
 

garm

Wizard
Joined
Aug 19, 2017
Messages
1,555
Well ya, but I was thinking in more general purpose way. A dedicated jail to fetch certificates for any service that then also handles the distribution, and maybe that shouldn’t be covered in every service “how to”
 

ezra

Contributor
Joined
Jan 15, 2015
Messages
124
Well ya, but I was thinking in more general purpose way. A dedicated jail to fetch certificates for any service that then also handles the distribution, and maybe that shouldn’t be covered in every service “how to”

Glad you like it, all credits go to the devs mentioned above. I merely put this in work for a jail.

Your suggestion for a jail that handels it for multiple jails would have my preference.

Still looking for a way to create an RC script for this jail.
 

gt2416

Patron
Joined
Feb 4, 2018
Messages
262
Ive made some progress on the rc script, am just trying to find a way to set the env variables in the script.
For some reason defining them in _rubywarden .profile file and / or .cshrc file is not working. I've read tons of stuff on setting variables and it should.. not sure what im doing wrong but when I try sudo -u _rubywarden printenv they dont show up ..
Apart from that I've learned how start the program from any directory so should be able to add the command in crontab but thats not really elegant.
 

guermantes

Patron
Joined
Sep 27, 2017
Messages
213
A first note is however to look at acme.sh for API driven Let’s Encrypt certificates, no need to expose the jail to the internet just to fetch certificates.
Like this one? OK, it's a different focus--but it does also cover using DNS validation with acme.sh...

One question that has prevented me several times from going down the acme.sh route (because it just takes me so much time to try to answer my question myself):
I have a domain registered and I use it for email and the root domain is a production webserver elsewhere, outside of my home. Obviously I don't want to dispose of the webserver functionality. Do I need to get a new domain for these fun things (nextcloud/bitwarden on my home freenas) or is it enough to create a subdomain, e.g., nextwarden.example.com and only create DNS pointers to this subdomain running in a jail on my home freenas box?
 

gt2416

Patron
Joined
Feb 4, 2018
Messages
262
You set the variables in a “pre start” block. https://www.freebsd.org/doc/en_US.ISO8859-1/articles/rc-scripting/rcng-daemon-adv.html

My issue with rubywarden is that you don’t get the website, the official import tools and you don’t register the install with Bitwarden so you can’t unlock premium features. Best of luck with this project, I will stick to the official docker deployment.

I think one of the benefits for doing it with rubywarden is that all your data goes to your server only. But to each their own
The lack of the tools to migrate my passwords though is frustrating.

I get that I need a pre start block but I cant find an example of the syntax to use to list the variables. I also read on the man page you can set it with
${name}_env block but again cant find an example of the syntax. If you know that would be great thanks
 

garm

Wizard
Joined
Aug 19, 2017
Messages
1,555
Rubywarden isn’t a requirement for your passwords to be stored locally. You get the same isolation with the official “on premise hosting”. No need to trust a third party developer with your stuff.
 

danb35

Hall of Famer
Joined
Aug 16, 2011
Messages
15,456
@ezra, thanks for posting this. I didn't follow it (decided to use a Ubuntu VM with the "official" Docker setup instead), but I hadn't known about Bitwarden previously, and it seems a significant step up from LastPass.
The lack of the tools to migrate my passwords though is frustrating.
I don't know if the method discussed here includes the web vault, but if it does, it can import CSVs from LastPass and a bunch of others.

If it doesn't include the web vault, maybe it would be worth trying to get bitwarden_rs running instead--it does include the web vault (as well as all the premium features you'd have to pay for with the "official" distribution). No idea off the top of my head how much work it would be to run in FreeBSD, though.
 

ezra

Contributor
Joined
Jan 15, 2015
Messages
124
The lack of the tools to migrate my passwords though is frustrating.

@ezra, thanks for posting this. I didn't follow it (decided to use a Ubuntu VM with the "official" Docker setup instead), but I hadn't known about Bitwarden previously, and it seems a significant step up from LastPass.

I don't know if the method discussed here includes the web vault, but if it does, it can import CSVs from LastPass and a bunch of others.

If it doesn't include the web vault, maybe it would be worth trying to get bitwarden_rs running instead--it does include the web vault (as well as all the premium features you'd have to pay for with the "official" distribution). No idea off the top of my head how much work it would be to run in FreeBSD, though.

You can use any client web/android/ios to import or use the guide below.

https://github.com/jcs/rubywarden
Migrating From Other Password Managers

This project inclues utilities that will import data exported from other password managers, convert it to its own data format, and then import it.

1Password

Export everything from 1Password in its "1Password Interchange Format". It should create a directory with a data.1pif file (which is unencrypted, so be careful with it). Once you have created your initial user account through Rubywarden, run the conversion tool with your account e-mail address:

Code:
sudo -u _rubywarden env RUBYWARDEN_ENV=production bundle exec ruby tools/1password_import.rb -f /path/to/data.1pif -u you@example.com


It will prompt you for the master password you already created, and then
convert and import as many items as it can.


This tool operates on the SQLite database directly (not through its REST API)
so you can run it offline.


Bitwarden (Official Apps)

Export your bitwarden vault via the web interface or the browser plugin, which
should prompt you to save a bitwarden_export_<datestamp>.csv file. Due to
limitations of the exporter, neither cards nor identities will be exported,
and any custom fields will lose their type (text, hidden, or boolean) and be
simply exported as text.


Once you have created your initial user account through Rubywarden, run the
conversion tool with your account e-mail address:


Code:
sudo -u _rubywarden env RUBYWARDEN_ENV=production bundle exec ruby tools/bitwarden_import.rb -f /path/to/data.csv -u you@example.com



It will prompt you for the master password you already created, and then
convert and import as many items as it can.


This tool operates on the SQLite database directly (not through its REST API)
so you can run it offline.


Keepass

In order to use the Keepass converter, you will need to install the necessary
dependency, using bundle install --with keepass.


There is no need to export your Keepass-database - you can use it as is.


Once you have created your initial user account through Rubywarden, run the
conversion tool with your account e-mail address:

Code:
sudo -u _rubywarden env RUBYWARDEN_ENV=production bundle exec ruby tools/keepass_import.rb -f /path/to/data.kdbx -u you@example.com


If your Keepass-database is secured using a keyfile, you can pass it using the -k parameter:

Code:
sudo -u _rubywarden env RUBYWARDEN_ENV=production bundle exec ruby tools/keepass_import.rb -f /path/to/data.kdbx -k /path/to/keyfile.key -u you@example.com


It will prompt you for the master password you already created, and then
convert and import as many items as it can.


This tool operates on the SQLite database directly (not through its REST API)
so you can run it offline.


Lastpass

Export everything from LastPass by going to your vault, "More Options",
"Advanced" and then "Export".
It will then export your details in a new browser window in CSV format, copy
and paste this data into a file accessible from your Rubywarden installation.
Unfortunately due to limitations in LastPass export the "extra fields" and
"attachments" data in the LastPass vault will not be converted.


Once you have created your initial user account through Rubywarden, run the
conversion tool with your account e-mail address:

Code:
sudo -u _rubywarden env RUBYWARDEN_ENV=production bundle exec ruby tools/lastpass_import.rb -f /path/to/data.csv -u you@example.com


It will prompt you for the master password you already created, and then convert and import as many items as it can.


This tool operates on the SQLite database directly (not through its REST API) so you can run it offline.
 

gt2416

Patron
Joined
Feb 4, 2018
Messages
262
Yes but only those 3. The official one has like 15 options. I had to migrate from Passman.
Anyway since I run FreeNAS on a hypervisor, I can spin up a docker vm with very little resource overhead.
 

garm

Wizard
Joined
Aug 19, 2017
Messages
1,555
For me it was unable to process my quite large 1password vaults. To many variations in field names for the csv export. The official deployment takes the native export and imports beautifully
 
Top