Skip to content

Instantly share code, notes, and snippets.

@tavinus
Last active October 1, 2024 12:18
Show Gist options
  • Save tavinus/59c314f4ccd70879db7f11074eacb6cc to your computer and use it in GitHub Desktop.
Save tavinus/59c314f4ccd70879db7f11074eacb6cc to your computer and use it in GitHub Desktop.
Debian 10 BitwardenRS install (no docker)

Bitwarden RS Debian 10 Install

This is how I installed the Rust implementation of bitwarden into a Proxmox Debian 10 LXC Container. It should work on any Debian 10 install (virtual or metal). I dislike running docker inside LXC containers for obvious reasons, so this is how I did it.

References

Prepare Base System

$ sudo apt update
$ sudo apt upgrade
$ sudo apt install git nano curl wget htop pkg-config openssl libssl1.1 libssl-dev
$ sudo apt install build-essential # not necessary??

Install Node and Rust From Their Distribution Sites

Do not use your distribution's Rust and Node packages.
Install Rust and Node from their own sites.

You can install either/both globally to the entire system, or just localized within a user's home directory. In the example below I install Rust/Cargo to a user directory and Node globally, in /opt/node

$ curl https://sh.rustup.rs -sSf | sh
$ echo 'export PATH=~/.cargo/bin:$PATH' >> ~/.bashrc
$ export PATH=~/.cargo/bin:$PATH 
$ which rustc
/home/bitwarden/.cargo/bin/cargo
$ wget https://nodejs.org/dist/latest-v9.x/node-v9.11.2-linux-x64.tar.xz
$ tar -xvf node-v9.11.2-linux-x64.tar.xz
$ sudo mv node-v9.11.2-linux-x64 /opt/
$ sudo ln -sf /opt/node-v9.11.2-linux-x64 /opt/node
$ echo 'export PATH=/opt/node/bin:$PATH' >> ~/.bashrc
$ export PATH=/opt/node/bin:$PATH
$ which npm
/opt/node/bin/npm
$ npm i npm@latest -g

Build bitwarden_rs

Now you're all set to do the bitwarden_rs installation. Start by cloning the bitwarden_rs repository and using cargo to build. This assumes you are doing a small-scale installation using sqlite as your backend database. This keeps things simple as you won't need to set up MySQL/MariaDB

$ git clone https://github.com/dani-garcia/bitwarden_rs && pushd bitwarden_rs 
$ cargo clean && cargo build --features sqlite --release
$ file target/release/bitwarden_rs 
target/release/bitwarden_rs: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked ...

Almost done now, just build the web-vault component, available from the BitWarden project

Patch, Build and Install web-vault Component

NOTE You can now avoid patching and simply use one of these prepatched branches

If you don’t want to use a prepatched build, follow these steps..

$ pushd target/release/
$ git clone https://github.com/bitwarden/web.git web-vault.git && cd web-vault.git

Now you need to apply a patch from bitwarden_rs. You can see the available patches here. Pick one that is recent, for example, v2.15.1.patch. Then use the following to set the current branch of web-vault.git to match that of the patch you chose. Then apply the patch and build

MAKE SURE YOU HAVE AT LEAST 2GB RAM TO BUILD

This is only needed to BUILD, NOT to RUN

$ git checkout v2.15.1 
$ wget https://raw.githubusercontent.com/dani-garcia/bw_web_builds/master/patches/v2.15.1.patch
$ git apply v2.15.1.patch
$ npm run sub:init && npm install && npm run dist

Pretty much done now, just copy the build/ directory into the bitwarden_rs release/ directory as web-vault

$ cp -a build ../web-vault

Run It

Now we can test-run or compilation

$ cd ..
$ mkdir data
$ ./bitwarden_rs 
/--------------------------------------------------------------------\
|                       Starting Bitwarden_RS                        |
|                      Version 1.16.3-7167e443                       |
|--------------------------------------------------------------------|
| This is an *unofficial* Bitwarden implementation, DO NOT use the   |
| official channels to report bugs/features, regardless of client.   |
| Send usage/configuration questions or feature requests to:         |
|   https://bitwardenrs.discourse.group/                             |
| Report suspected bugs/issues in the software itself at:            |
|   https://github.com/dani-garcia/bitwarden_rs/issues/new           |
\--------------------------------------------------------------------/

[2020-08-27 09:22:05.121][bitwarden_rs][INFO] JWT keys don't exist, checking if OpenSSL is available...
OpenSSL 1.1.1d  10 Sep 2019
[2020-08-27 09:22:05.124][bitwarden_rs][INFO] OpenSSL detected, creating keys...
Generating RSA private key, 2048 bit long modulus (2 primes)
.......................................+++++
..+++++
e is 65537 (0x010001)
writing RSA key
writing RSA key
[2020-08-27 09:22:05.178][bitwarden_rs][INFO] Keys created correctly.
Running migration 20180114171611
Running migration 20180217205753
Running migration 20180427155151
Running migration 20180508161616
Running migration 20180525232323
Running migration 20180601112529
Running migration 20180711181453
Running migration 20180827172114
Running migration 20180910111213
Running migration 20180919144557
Running migration 20181127152651
Running migration 20190526216651
Running migration 20191010083032
Running migration 20191117011009
Running migration 20200313205045
Running migration 20200409235005
Running migration 20200701214531
Running migration 20200802025025
[2020-08-27 09:22:05.226][start][INFO] Rocket has launched from http://0.0.0.0:8000

Go ahead and browse to localhost on port 8000 and create a new user to confirm it is working. If you didn't encounter any errors throughout this process it should "just work"

Take a look at the .env or .env.template file for how you might do some basic or advanced settings changes, such as the ports the service will use, etc. This is a file that is essentially sourced by the shell before executing the bitwarden_rs process. When it runs, bitwarden_rs consults the environment variables for certain things

Use Ctrl - C to close the bitwarden server

Create Systemd Service

If you use the same names as defined below, there is no need to change the service file. It should just work without any modifications.

$ sudo cp ../../.env.template /etc/bitwarden_rs.env
$ sudo cp bitwarden_rs /usr/bin/bitwarden_rs
$ sudo chmod +x /usr/bin/bitwarden_rs
$ sudo useradd -m -d /var/lib/bitwarden_rs bitwarden_rs
$ sudo cp -R data /var/lib/bitwarden_rs/     # MOVE DATA OR
# $ sudo mkdir /var/lib/bitwarden_rs/data    # CREATE NEW
$ sudo cp -R web-vault /var/lib/bitwarden_rs/
$ sudo chown -R bitwarden_rs:bitwarden_rs /var/lib/bitwarden_rs

Create Service File

$ sudo nano /etc/systemd/system/bitwarden_rs.service

With the content

[Unit]
Description=Bitwarden Server (Rust Edition)
Documentation=https://github.com/dani-garcia/bitwarden_rs
# If you use a database like mariadb,mysql or postgresql, 
# you have to add them like the following and uncomment them 
# by removing the `# ` before it. This makes sure that your 
# database server is started before bitwarden_rs ("After") and has 
# started successfully before starting bitwarden_rs ("Requires").

# Only sqlite
After=network.target

# MariaDB
# After=network.target mariadb.service
# Requires=mariadb.service

# Mysql
# After=network.target mysqld.service
# Requires=mysqld.service

# PostgreSQL
# After=network.target postgresql.service
# Requires=postgresql.service


[Service]
# The user/group bitwarden_rs is run under. the working directory (see below) should allow write and read access to this user/group
User=bitwarden_rs
Group=bitwarden_rs
# The location of the .env file for configuration
EnvironmentFile=/etc/bitwarden_rs.env
# The location of the compiled binary
ExecStart=/usr/bin/bitwarden_rs
# Set reasonable connection and process limits
LimitNOFILE=1048576
LimitNPROC=64
# Isolate bitwarden_rs from the rest of the system
PrivateTmp=true
PrivateDevices=true
ProtectHome=true
ProtectSystem=strict
# Only allow writes to the following directory and set it to the working directory (user and password data are stored here)
WorkingDirectory=/var/lib/bitwarden_rs
ReadWriteDirectories=/var/lib/bitwarden_rs
# Allow bitwarden_rs to bind ports in the range of 0-1024
AmbientCapabilities=CAP_NET_BIND_SERVICE

[Install]
WantedBy=multi-user.target

Reload systemd

$ sudo systemctl daemon-reload

Usage

Start

$ sudo systemctl start bitwarden_rs.service

Enable autostart on boot

$ sudo systemctl enable bitwarden_rs.service

Other options are: stop, restart and disable the service.

Updating bitwarden_rs

After compiling the new version of bitwarden_rs, you can copy the compiled (new) binary and replace the existing (old) binary and then restart the service:

$ sudo systemctl restart bitwarden_rs.service

Uninstalling bitwarden_rs

Before doing anything else, you should stop and disable the service:

$ sudo systemctl disable --now bitwarden_rs.service

Then you can delete the binary, the .env file, the web-vault folder (if installed) and the user data (if necessary). Remember to also remove specially created users,groups and firewall rules (if needed) and the systemd file.

After removing the systemd file you should make systemd aware of it via:

$ sudo systemctl daemon-reload

Logging and status view

If you want to see the logging output, run

$ journalctl -u bitwarden_rs.service

or to see a more concise state of the service, run

$ systemctl status bitwarden_rs.service

Troubleshooting

Sandboxing options with older systemd versions

In RHEL 7 (and debian 8), the used systemd does not support some of the used isolation options. (#445,#363) This can result in one of the following errors:

Failed at step NAMESPACE spawning /home/bitwarden_rs/bitwarden_rs: Permission denied

or

Failed to parse protect system value

To work around this you can comment out some or all of these settings by putting a # in front of the lines containing PrivateTmp, PrivateDevices, ProtectHome, ProtectSystem and ReadWriteDirectories. While commenting out all of them will probably work, it's not recommended as these are security measures which are good to have. To see which options your systemd supports, look at the output of

$ systemctl --version

to determine your systemd version and compare with systemd/NEWS.md.

After editing your .service file, don't forget to

$ sudo systemctl daemon-reload

before (re-)starting your service.

Let's Encrypt Certificates

In this example I use acme.sh with Dynu as a DNS provider to generate the certificates. I like to use the DNS method because it requires zero network configuration. Acme.sh just needs outbound access to the internet and nothing else.

You should adjust the instructions to your provider/method of choice.
Check out acme.sh's Wiki for more info (browse the 40+ pages there).

My proxy usually runs in a separate VM/CT, if you are running nginx locally, you can change the destination IP to 127.0.0.1 (localhost).

Get acme.sh and create certificates

To install, you can use git or curl/wget. I prefer installing as root.

$ sudo su -
# git clone https://github.com/acmesh-official/acme.sh.git
# cd acme.sh

Possible install parameters

./acme.sh --install  \
--home ~/myacme \
--config-home ~/myacme/data \
--certhome  ~/mycerts \
--accountemail  "[email protected]" \
--accountkey  ~/myaccount.key \
--accountconf ~/myaccount.conf \
--useragent  "this is my client."

I usually just add the email

./acme.sh --install --accountemail "[email protected]"

You now have two folders at /root

  • /root/acme.sh - git clone with the installer (can be deleted after install, but I usually leave it there).
  • /root/.acme.sh - installed program and data (certs, methods, etc)

To use Dynu, you need to add an access token to the installed config file.

# cd ../.acme.sh
# nano account.conf

Add your DNS provider ID/Secret or other authentication method below your e-mail.
Web mode does not need this (but needs external access to internal port 80).

ACCOUNT_EMAIL='[email protected]'
Dynu_ClientId='245gb9ff-d5gh-7227-b656-4c63e2356df2'
Dynu_Secret='SADwerbnsdi23412ASDa294'

Now we can generate and install any certs we need.

JUST NEED THE DOMAIN/SUBDOMAIN/ALIAS CREATED IN DYNU FIRST

You can test-run on staging if you want (single or multiple domains)

# acme.sh --test --debug --debug --issue --dns dns_dynu -d bitwarden.mydomain.com

If you tested, you need to use --force to run again for real

# acme.sh --debug --debug --issue --dns dns_dynu -d bitwarden.mydomain.com --force

I prefer to create a separate folder for my certs

# mkdir /etc/ssl/localcerts/

Now we can tell acme.sh to install and to reload the webserver (or whatever is gonna use the certs).

# acme.sh --debug --installcert -d bitwarden.mydomain.com --certpath /etc/ssl/localcerts/bitwarden.mydomain.com.pem --keypath /etc/ssl/localcerts/bitwarden.mydomain.com.key --fullchainpath /etc/ssl/localcerts/bitwarden.mydomain.com-fullchain.cer --reloadcmd "systemctl reload nginx"

This completes the acme.sh part.

The script will regenerate certs automagically from cron, based on how you first generated your certs.

Nginx versions

Depending on your distro and how you installed nginx, the main configuration and each website configuration locations will vary. The example below shows a Debian-based install with the folders sites-enabled and sites-available inside /etc/nginx.

I usually install nginx from nginx.org instead of using the distro package.

Nginx Debian install from nginx.org

Install the prerequisites:

$ sudo apt install curl gnupg2 ca-certificates lsb-release

To set up the apt repository for stable nginx packages, run the following command:

$ echo "deb http://nginx.org/packages/debian `lsb_release -cs` nginx" | sudo tee /etc/apt/sources.list.d/nginx.list

If you would like to use mainline nginx packages, run the following command instead:

$ echo "deb http://nginx.org/packages/mainline/debian `lsb_release -cs` nginx" | sudo tee /etc/apt/sources.list.d/nginx.list

Next, import an official nginx signing key so apt could verify the packages authenticity:

$ curl -fsSL https://nginx.org/keys/nginx_signing.key | sudo apt-key add -

Verify that you now have the proper key:

$ sudo apt-key fingerprint ABF5BD827BD9BF62

The output should contain the full fingerprint 573B FD6B 3D8F BC64 1079 A6AB ABF5 BD82 7BD9 BF62 as follows:

pub   rsa2048 2011-08-19 [SC] [expires: 2024-06-14]
      573B FD6B 3D8F BC64 1079  A6AB ABF5 BD82 7BD9 BF62
uid   [ unknown] nginx signing key <[email protected]>

To install nginx, run the following commands:

$ sudo apt update
$ sudo apt install nginx

Create proxy

So, let's create a proxy that uses or generated certificates and redirects to our bitwarden instance.

$ sudo su -
# cd /etc/nginx/sites-available
# nano bitwarden.mydomain.com.config

The content I use

  • Change all bitwarden.mydomain.com to your bitwarden domain
  • Change the IP in proxy_pass and proxy_redirect to your bitwarden's IP
server {
    listen 80;
    listen [::]:80;
    server_name bitwarden.mydomain.com;
    return 301 https://$host$request_uri;
}

server {
    listen 443 ssl;
    server_name bitwarden.mydomain.com;

    ssl_certificate           /etc/ssl/localcerts/bitwarden.mydomain.com-fullchain.cer;
    ssl_certificate_key       /etc/ssl/localcerts/bitwarden.mydomain.com.key;

    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.mydomain.com.access.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.
      # THE IP/PORT OF YOU BITWARDEN INSTALL, OR USE 127.0.0.1 FOR LOCALHOST
      proxy_pass          http://10.0.10.50:8000;
      proxy_read_timeout  200;
      proxy_redirect      http://10.0.10.50:8000 https://bitwarden.mydomain.com;
    }
}

Create the symlink at sites-enabled

# cd ../sites-enabled
# ln -s ../sites-available/bitwarden.mydomain.com bitwarden.mydomain.com

Then you can restart or reload your nginx server

# systemctl restart nginx.service
# systemctl status nginx.service   # Ctrl+C to close

Now you can test/troubleshoot the HTTPS connection to you bitwarden instance.

Enable Admin interface

To enable the admin interface you need to set a valid token into your ENV file. You can find more info here

As they mention, you should probably enable this only after enabling SSL, to avoid MITM (man in the middle) attacks.

Generate a new token with openssl

$ openssl rand -base64 48
+sEY1rzwi+XNEcaXU1pI3Xiz4tiQ31SaD/9lQqgwPnOJhK5spz+VNhs72g3xkvbq

Save this! It will be the admin password

Copy the key created to paste into the config file

$ sudo nano /etc/bitwarden_rs.env

Uncomment or add

ADMIN_TOKEN=+sEY1rzwi+XNEcaXU1pI3Xiz4tiQ31SaD/9lQqgwPnOJhK5spz+VNhs72g3xkvbq

Restart bitwarden service

$ sudo systemctl restart bitwarden_rs.service

Open the admin page and login with the token https://bitwarden.mydomain.com/admin

@heinoldenhuis
Copy link

heinoldenhuis commented May 20, 2021

hello everyone, someone say who enable the admin panel ? when I access to localhost:8000/admin the page message are "The admin panel is disabled, please configure the 'ADMIN_TOKEN' variable to enable it" so, where I can read the ADMIN_TOKEN to enable it ? otherwise, good tutorial, thanks you :)

Hi,

In the section Enable Admin interface it is mentioned to generate an Admin token and add (or update if it exists) to your *.env extension file.

Also notice that localhost:8000/admin might not work if you access your bitwarden from another computer, so please use:
http://<server_ip/address>/admin or https://<server_ip/address>/admin if you use ssl.

Example:
afbeelding

@Ixod3
Copy link

Ixod3 commented May 20, 2021

hello everyone, someone say who enable the admin panel ? when I access to localhost:8000/admin the page message are "The admin panel is disabled, please configure the 'ADMIN_TOKEN' variable to enable it" so, where I can read the ADMIN_TOKEN to enable it ? otherwise, good tutorial, thanks you :)

Hi,

In the section Enable Admin interface it is mentioned to generate an Admin token and add (or update if it exists) to your *.env extension file.

Also notice that localhost:8000/admin might not work if you access your bitwarden from another computer, so please use:
http://<server_ip/address>/admin or https://<server_ip/address>/admin if you use ssl.

Example:
afbeelding

thank you @heinoldenhuis, I missed the administration paragraph when I read the tutorial :/ , now it's working ^^

@Tokukarin
Copy link

On Debian 10 cargo build fails without apt install build-essential so it is necessary & on Debian it is called "build-essential" and not "build-essentials".

error message for documentation:

error: linker `cc` not found
  |
  = note: No such file or directory (os error 2)

error: aborting due to previous error

error: could not compile `libc`

@tavinus
Copy link
Author

tavinus commented Jun 25, 2021

Fixed that @Tokukarin .. thanks

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment