DEV Community

Arseny Zinchenko
Arseny Zinchenko

Posted on • Originally published at rtfm.co.ua on

2 1

Bitwarden: an organization’s password manager self-hosted version installation on an AWS EC2

We consider Bitwarden as a passwords keeper for our project with the main goal to have an ability to have separated access to secrets by user roles and/or ACLs.

I.e. Pass or KeePass are good for self-usage by one person but they have no main things – a normal web-interface and role-based access to data. There are 1Password/LastPass of course, but they keep data on their own servers which is not too good for me.

Bitwarden is Opensource and can be used as a Cloud-based version or can be installed on your own server.

It has personal Free-version and paid with additional features.

Besides the personal usage, it can be used for Business with user roles – will try it later.

The home page is here>>>.

The main things I did like in Bitwarden:

  • has desktop applications for для Linux, macOS, Windows
  • all browsers extensions
  • applications for Android and iOS
  • RESTful API (in Enterprise version), i.e. theoretically can be used from Jenkins to populate its secrets
  • has CLI utilities
  • MFA authorization
  • roles/groups based access (Enterprise version)
  • File Storage
  • data import from other passwords managers (Chrome, KeePass, 1Password etc)

Quick installation documentation available here here>>> and full – here>>>.

In this post, Bitwarden will be installed on an AWS EC2 instance with additional EBS volume mounted to /bitwarden where Bitwarden will store its data and which will be backed up by AWS Data Lifecycle Manager.

On the EC2 will have NGINX running as a frontend and SSL sessions with a certificate from Let’s Encrypt will be terminated here.

Although Bitwarden is running in a Docker Compose stack with its own NGINX and Let’s Encrypt certificates support – I’ll do it in a more traditional way, i.e. NGINX on a host will proxy requests to the NGINX in the Bitwarden’s stack, and this NGINX in its turn will proxy requests to its internal services.

Contents

  • AWS
    • Creating EC2
    • Creating EBS
    • Security Group
    • Mounting EBS
  • DNS
  • The host’s set up
    • Let’s Encrypt
    • NGINX
    • Docker and Docker Compose
  • Bitwarden installation
    • Bitwarden configuration
    • Email configuration
    • Registration in the Bitwarden
    • Bitwarden Admin and users
    • Users settings
  • Working with Bitwarden
    • Chrome plugin
    • Linux desktop
    • Import from KeePass
    • Multi-factor authorization
    • Backuping and restoring Bitwarden storage

AWS

Creating EC2

Will use Debian here. AMIs can be found here>>>.

At first, I started t3.nano but this wasn’t enough – an instance just hangs up after starting Bitwarden which is not surprising knowing that fact that it uses MSSQL and has 9 containers running. And Bitwarden itself is Bitwarden is .NET application written in C#.

Run an EC2 with the t3.medium type:

$ aws --profile bm-backend  ec2 run-instances --region eu-west-1 --image-id ami-01820e22b83de8d0d --key-name setevoy-testing --instance-type t3.medium --tag-specifications 'ResourceType=instance,Tags=[{Key=Name,Value=bitwarden-dev}]'
Enter fullscreen mode Exit fullscreen mode

Get its Availability Zone:

$ aws --profile bm-backend ec2 describe-instances --region eu-west-1 --filters "Name=tag:Name,Values=bitwarden-dev" --query "Reservations[\*].Instances[\*].[Placement.AvailabilityZone]" --output text

eu-west-1a
Enter fullscreen mode Exit fullscreen mode

Creating EBS

Create an EBS volume (by default the standard i.e. HDD will be used, if you want to have SSD – add --volume-type gp2):

$ aws --profile bm-backend ec2 create-volume --region eu-west-1 --availability-zone eu-west-1a --size 5 --tag-specifications 'ResourceType=volume,Tags=[{Key=Name,Value=bitwarden-dev-ebs}]'
Enter fullscreen mode Exit fullscreen mode

Here we set the same region (--region eu-west-1) and the same Availability Zone (--availability-zone eu-west-1a) where the ЕС2 was started and the disk size is 5 GiB.

Get this EBS ID:

$ aws --profile bm-backend ec2 describe-volumes --region eu-west-1  --filters "Name=tag:Name,Values=bitwarden-dev-ebs" --query "Volumes[\*].VolumeId" --output text

vol-0621e68897eb2a3d8
Enter fullscreen mode Exit fullscreen mode

And ID of the EC2:

$ aws --profile bm-backend ec2 describe-instances --region eu-west-1 --filters "Name=tag:Name,Values=bitwarden-dev" --query "Reservations[\*].Instances[\*].InstanceId" --output text

i-0ac18e298768e2c4b
Enter fullscreen mode Exit fullscreen mode

Attach this EBS to the EC2:

$ aws --profile bm-backend ec2 attach-volume --region eu-west-1 --volume-id vol-0621e68897eb2a3d8 --instance-id i-0ac18e298768e2c4b --device xvdb
Enter fullscreen mode Exit fullscreen mode

Security Group

Create a Security Group – here via WebUI to make it quickly.

During creating this SG pay attention on a VPC ID – must be the same as used for your EC2:

Allow access to the 80 port from anywhere to make Let’s Encrypt authorization working.

443 and 22 ports allowed from our office only.

Attache this SG to the EC2 – Networking > Change Security Group:

Mounting EBS

Log in to the server:

$ ssh admin@34.240.14.78 -i setevoy-testing-eu-west-1.pem
Enter fullscreen mode Exit fullscreen mode

Check disks:

$ admin@ip-172-31-36-249:~$ lsblk
NAME        MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
nvme0n1     259:0    0   8G  0 disk
└─nvme0n1p1 259:1    0   8G  0 part /
nvme1n1     259:2    0   5G  0 disk
Enter fullscreen mode Exit fullscreen mode

nvme1n1 is our EBS.

Create /bitwarden directory:

admin@ip-172-31-36-249:~$ sudo -s
root@ip-172-31-36-249:/home/admin# mkdir /bitwarden
Enter fullscreen mode Exit fullscreen mode

Create a partition on the /dev/nvme1n1:

root@ip-172-31-36-249:/home/admin# sgdisk -n 1 /dev/nvme1n1
Creating new GPT entries.
The operation has completed successfully.
Enter fullscreen mode Exit fullscreen mode

Create a file system:

root@ip-172-31-36-249:/home/admin# mkfs.ext4 /dev/nvme1n1p1
Enter fullscreen mode Exit fullscreen mode

Check partitions now:

root@ip-172-31-36-249:/home/admin# fdisk /dev/nvme1n1
...
Device         Start      End  Sectors Size Type
/dev/nvme1n1p1  2048 10485726 10483679   5G Linux filesystem
Enter fullscreen mode Exit fullscreen mode

Mount it to the /bitwarden:

root@ip-172-31-36-249:/home/admin# mount /dev/nvme1n1p1 /bitwarden/
root@ip-172-31-36-249:/home/admin# ls -l /bitwarden/
total 16
drwx------ 2 root root 16384 Apr 30 10:15 lost+found
Enter fullscreen mode Exit fullscreen mode

Get partition’s ID:

root@ip-172-31-36-249:/home/admin# blkid /dev/nvme1n1p1
/dev/nvme1n1p1: UUID="5e3972d4-c742-4224-80d6-8239e5201ae1" TYPE="ext4" PARTUUID="929f264c-ac03-4f9f-9071-056c1511de0e"
Enter fullscreen mode Exit fullscreen mode

Using this UUID add a new mount point to the /etc/fstab with the --nofail option:

root@ip-172-31-36-249:/home/admin# cat /etc/fstab
UUID=3866caa4-0449-4478-899b-60eb6f71dd26       /       ext4    rw,discard,errors=remount-ro    0       1
UUID="5e3972d4-c742-4224-80d6-8239e5201ae1" /bitwarden ext4 nofail 0 0
Enter fullscreen mode Exit fullscreen mode

Unmount partition mounted manually:

root@ip-172-31-36-249:/home/admin# umount /bitwarden/
Enter fullscreen mode Exit fullscreen mode

And mount it back using fstab:

root@ip-172-31-36-249:/home/admin# mount -a
Enter fullscreen mode Exit fullscreen mode

Check:

root@ip-172-31-36-249:/home/admin# findmnt /bitwarden/
TARGET     SOURCE         FSTYPE OPTIONS
/bitwarden /dev/nvme1n1p1 ext4   rw,relatime,data=ordered
Enter fullscreen mode Exit fullscreen mode

Can reboot instance now to check mount works properly now.

Also, install all updates:

root@ip-172-31-36-249:/home/admin# apt update && apt -y upgrade && reboot
Enter fullscreen mode Exit fullscreen mode

DNS

Create a domain name to be used:

The host’s set up

Let’s Encrypt

Install client:

root@ip-172-31-36-249:/home/admin# apt install -y git
root@ip-172-31-36-249:/home/admin# git clone https://github.com/letsencrypt/letsencrypt /opt/letsencrypt
Enter fullscreen mode Exit fullscreen mode

Get a certificate using standalone authenticator:

root@ip-172-31-36-249:/home/admin# /opt/letsencrypt/letsencrypt-auto certonly -d dev.bitwarden.setevoy.org.ua

Saving debug log to /var/log/letsencrypt/letsencrypt.log

How would you like to authenticate with the ACME CA?
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1: Spin up a temporary webserver (standalone)

2: Place files in webroot directory (webroot)
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

Select the appropriate number [1-2] then [enter] (press 'c' to cancel): 1
Plugins selected: Authenticator standalone, Installer None

Enter email address (used for urgent renewal and security notices) (Enter 'c' to
cancel): admin@example.com

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

Please read the Terms of Service at
https://letsencrypt.org/documents/LE-SA-v1.2-November-15-2017.pdf. You must
agree in order to register with the ACME server at
https://acme-v02.api.letsencrypt.org/directory

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
(A)gree/(C)ancel: A
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

Would you be willing to share your email address with the Electronic Frontier
Foundation, a founding partner of the Let's Encrypt project and the non-profit
organization that develops Certbot? We'd like to send you email about our work
encrypting the web, EFF news, campaigns, and ways to support digital freedom.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

(Y)es/(N)o: N

Obtaining a new certificate
Performing the following challenges:
http-01 challenge for dev.bitwarden.setevoy.org.ua
Waiting for verification...
Cleaning up challenges

IMPORTANT NOTES:

- Congratulations! Your certificate and chain have been saved at:
/etc/letsencrypt/live/dev.bitwarden.setevoy.org.ua/fullchain.pem
Your key file has been saved at:
/etc/letsencrypt/live/dev.bitwarden.setevoy.org.ua/privkey.pem
...
Enter fullscreen mode Exit fullscreen mode

NGINX

Install NGINX:

root@ip-172-31-36-249:/home/admin# apt -y install nginx
Enter fullscreen mode Exit fullscreen mode

Generate a key for the SSL:

root@ip-172-31-36-249:/home/admin# openssl dhparam -out /etc/nginx/dhparams.pem 2048
Enter fullscreen mode Exit fullscreen mode

Add a virtual host’s config – /etc/nginx/conf.d/dev.bitwarden.setevoy.org.ua.conf:

server {

    listen 80;

    server_name dev.bitwarden.setevoy.org.ua;

    # Lets Encrypt Webroot
    location ~ /.well-known {
        root /var/www/html;
        allow all;
    }

    location / {

        # office1
        allow 194.***.***.24/29;
        # office2
        allow 91.***.***.78/32;
        # arseny home
        allow 188.***.***.48/32;
        deny  all;

        return 301 https://dev.bitwarden.setevoy.org.ua;
    }
}
server {
    listen       443 ssl;
    server_name  dev.bitwarden.setevoy.org.ua;
    root /var/www/html;
    access_log  /var/log/nginx/dev.bitwarden.setevoy.org.ua-access.log;
    error_log /var/log/nginx/dev.bitwarden.setevoy.org.ua-error.log warn;

    # office1
    allow 194.***.***.24/29;
    # office2
    allow 91.***.***.78/32;
    # arseny home
    allow 188.***.***.48/32;
    deny  all;

    ssl_certificate /etc/letsencrypt/live/dev.bitwarden.setevoy.org.ua/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/dev.bitwarden.setevoy.org.ua/privkey.pem;
    ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
    ssl_prefer_server_ciphers on;
    ssl_dhparam /etc/nginx/dhparams.pem;
    ssl_ciphers "EECDH+AESGCM:EDH+AESGCM:ECDHE-RSA-AES128-GCM-SHA256:AES256+EECDH:DHE-RSA-AES128-GCM-SHA256:AES256+EDH:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA:ECDHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES128-SHA256:DHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES256-GCM-SHA384:AES128-GCM-SHA256:AES256-SHA256:AES128-SHA256:AES256-SHA:AES128-SHA:DES-CBC3-SHA:HIGH:!aNULL:!eNULL:!EXPORT:!DES:!MD5:!PSK:!RC4";
    ssl_session_timeout 1d;
    ssl_stapling on;
    ssl_stapling_verify on;
    location / {
        proxy_pass http://localhost:8000/;
        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;
        client_max_body_size 0;
        add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload";
        add_header Referrer-Policy "same-origin";
    }
}
Enter fullscreen mode Exit fullscreen mode

Check its syntax and reload configs:

root@ip-172-31-36-249:/home/admin# nginx  -t && systemctl reload nginx
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
Enter fullscreen mode Exit fullscreen mode

Check:

root@ip-172-31-36-249:/home/admin# curl -vL dev.bitwarden.setevoy.org.ua
...

* Connected to dev.bitwarden.setevoy.org.ua (34.240.14.78) port 80 (#0)
< HTTP/1.1 301 Moved Permanently
...
< Location: https://dev.bitwarden.setevoy.org.ua
...
curl: (7) Failed to connect to dev.bitwarden.setevoy.org.ua port 443: Connection timed out
Enter fullscreen mode Exit fullscreen mode

All good.

Connection timed out – as we have no backend running yet.

Docker and Docker Compose

To run Bitwarden need to have Docker and Docker Compose – install them.

Docker:

root@ip-172-31-36-249:/home/admin# curl -L get.docker.com | bash
Enter fullscreen mode Exit fullscreen mode

Check:

root@ip-172-31-36-249:/home/admin# docker -v
Docker version 18.09.5, build e8ff056dbc
Enter fullscreen mode Exit fullscreen mode

Add the admin user to the docker group:

root@ip-172-31-36-249:/home/admin# usermod -aG docker admin
Enter fullscreen mode Exit fullscreen mode

Install Docker Compose:

root@ip-172-31-36-249:/home/admin# curl -L "https://github.com/docker/compose/releases/download/1.24.0/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
root@ip-172-31-36-249:/home/admin# chmod +x /usr/local/bin/docker-compose
root@ip-172-31-36-249:/home/admin# docker-compose -v
docker-compose version 1.24.0, build 0aa59064
Enter fullscreen mode Exit fullscreen mode

Bitwarden installation

Go to the bitwarden.com/host and get keys:

Each Bitwarden needs to have own set of those keys.

Download installation, configuration, and management script:

root@ip-172-31-36-249:/home/admin# cd /bitwarden/
root@ip-172-31-36-249:/bitwarden# curl -s -o bitwarden.sh https://raw.githubusercontent.com/bitwarden/core/master/scripts/bitwarden.sh
root@ip-172-31-36-249:/bitwarden# chmod +x bitwarden.sh
Enter fullscreen mode Exit fullscreen mode

This script will download files from the https://github.com/bitwarden/server repository and then will call the https://github.com/bitwarden/server/blob/master/scripts/run.sh script with the install option.

All options for the bitwarden.sh:

| Command | Description |
| --- | --- |
| install | Start the installer. |
| start | Start all containers. |
| restart | Restart all containers (same as start). |
| stop | Stop all containers. |
| updatedb | Update/initialize the database. |
| update | Update all containers and the database. |
| updateself | Update this main script. |
| rebuild | Rebuild generated installation assets from `config.yml`. |
Enter fullscreen mode Exit fullscreen mode

Start installation:

root@ip-172-31-36-249:/bitwarden# ./bitwarden.sh install
...

(!) Enter the domain name for your Bitwarden instance (ex. bitwarden.company.com): dev.bitwarden.setevoy.org.ua

(!) Do you want to use Let's Encrypt to generate a free SSL certificate? (y/n): n

1.30.1: Pulling from bitwarden/setup
...
Status: Downloaded newer image for bitwarden/setup:1.30.1
...
(!) Enter your installation id (get at https://bitwarden.com/host): 46ec2f0b-\*\*\*-\*\*\*-aa3f00b8ab41
(!) Enter your installation key: OJ0\*\*\*fDD
(!) Do you have a SSL certificate to use? (y/n): y
...
(!) Is this a trusted SSL certificate (requires ca.crt, see docs)? (y/n): y
Generating key for IdentityServer.
Generating a RSA private key
...
writing new private key to 'identity.key'
-----
Building nginx config.
Building docker environment files.
Building docker environment override files.
Building FIDO U2F app id.
Building docker-compose.yml.
Installation complete
...

Next steps, run:

`./bitwarden.sh start`
Enter fullscreen mode Exit fullscreen mode

Bitwarden configuration

The script will save all Bitwarden’s data to the bwdata directory:

root@ip-172-31-36-249:/bitwarden# ll
total 24
-rwxr-xr-x  1 root   root     2535 Apr 30 11:07 bitwarden.sh
drwxr-xr-x 11 nobody nogroup  4096 Apr 30 11:13 bwdata

root@ip-172-31-36-249:/bitwarden# ll bwdata/
total 40
drwxr-xr-x 2 nobody nogroup 4096 Apr 30 11:10 ca-certificates
-rw-r--r-- 1 nobody nogroup 3323 Apr 30 11:13 config.yml
drwxr-xr-x 2 nobody nogroup 4096 Apr 30 11:13 docker
drwxr-xr-x 2 nobody nogroup 4096 Apr 30 11:13 env
drwxr-xr-x 2 nobody nogroup 4096 Apr 30 11:13 identity
drwxr-xr-x 2 nobody nogroup 4096 Apr 30 11:10 letsencrypt
drwxr-xr-x 2 nobody nogroup 4096 Apr 30 11:13 nginx
drwxr-xr-x 2 nobody nogroup 4096 Apr 30 11:10 scripts
drwxr-xr-x 3 nobody nogroup 4096 Apr 30 11:13 ssl
drwxr-xr-x 2 nobody nogroup 4096 Apr 30 11:13 web
Enter fullscreen mode Exit fullscreen mode

The main configuration file is the bwdata/config.yml.

Also, in the ./bwdata/env/global.override.env file additional variables can be set, will check them a bit later.

Docker Compose stack will be started using the ./bwdata/docker/docker-compose.yml file:

version: '3'
services:
  mssql:
    image: bitwarden/mssql:1.30.1
    container_name: bitwarden-mssql
    restart: always
    volumes:
      - ../mssql/data:/var/opt/mssql/data
      - ../logs/mssql:/var/opt/mssql/log
      - ../mssql/backups:/etc/bitwarden/mssql/backups
    env_file:
      - mssql.env
      - ../env/uid.env
      - ../env/mssql.override.env
  web:
    image: bitwarden/web:2.10.0
    container_name: bitwarden-web
    restart: always
    volumes:
      - ../web:/etc/bitwarden/web
    env_file:
      - global.env
      - ../env/uid.env
...
Enter fullscreen mode Exit fullscreen mode

Update the config.yml file – disable SSL as we have own NGINX with SSL and change HTTP and HTTPS ports:

...
# Docker compose file port mapping for HTTP. Leave empty to remove the port mapping.
# Learn more: https://docs.docker.com/compose/compose-file/#ports
http_port: 8000
# Docker compose file port mapping for HTTPS. Leave empty to remove the port mapping.
# Learn more: https://docs.docker.com/compose/compose-file/#ports
https_port: 8001
...
# Configure Nginx for SSL.
ssl: false
...
Enter fullscreen mode Exit fullscreen mode

Update applications configs:

root@ip-172-31-36-249:/bitwarden# ./bitwarden.sh rebuild
Enter fullscreen mode Exit fullscreen mode

Start Bitwarden:

root@ip-172-31-36-249:/bitwarden# ./bitwarden.sh start
...
Bitwarden is up and running!
Enter fullscreen mode Exit fullscreen mode

Check in a browser:

Check containers:

root@ip-172-31-36-249:/bitwarden# docker ps

CONTAINER ID        IMAGE                            COMMAND             CREATED             STATUS              PORTS                                                    NAMES

b196ee0f81ff        bitwarden/nginx:1.30.1           "/entrypoint.sh"    About an hour ago   Up About an hour    80/tcp, 0.0.0.0:5178->8080/tcp, 0.0.0.0:5179->8443/tcp   bitwarden-nginx

ef03f591491d        bitwarden/admin:1.30.1           "/entrypoint.sh"    About an hour ago   Up About an hour    5000/tcp                                                 bitwarden-admin

d4fa88921cce        bitwarden/api:1.30.1             "/entrypoint.sh"    About an hour ago   Up About an hour    5000/tcp                                                 bitwarden-api

408c5f0bd370        bitwarden/notifications:1.30.1   "/entrypoint.sh"    About an hour ago   Up About an hour    5000/tcp                                                 bitwarden-notifications

9bec10bc09d8        bitwarden/icons:1.30.1           "/entrypoint.sh"    About an hour ago   Up About an hour    5000/tcp                                                 bitwarden-icons

f87789cc4da4        bitwarden/mssql:1.30.1           "/entrypoint.sh"    About an hour ago   Up About an hour    1433/tcp                                                 bitwarden-mssql

143370f979c5        bitwarden/web:2.10.0             "/entrypoint.sh"    About an hour ago   Up About an hour    5000/tcp                                                 bitwarden-web

acdc220a7c29        bitwarden/identity:1.30.1        "/entrypoint.sh"    About an hour ago   Up About an hour    5000/tcp                                                 bitwarden-identity

925d047b6321        bitwarden/attachments:1.30.1     "/entrypoint.sh"    About an hour ago   Up About an hour    5000/tcp                                                 bitwarden-attachments
Enter fullscreen mode Exit fullscreen mode

In those containers, Bitwarden will mount directories from the host, for example mssql:

root@ip-172-31-36-249:/bitwarden# docker inspect bitwarden-mssql | jq .[].Mounts
[
{
  "Type": "bind",
  "Source": "/bitwarden/bwdata/logs/mssql",
  "Destination": "/var/opt/mssql/log",
  "Mode": "rw",
  "RW": true,
  "Propagation": "rprivate"
},
{
  "Type": "bind",
  "Source": "/bitwarden/bwdata/mssql/data",
  "Destination": "/var/opt/mssql/data",
  "Mode": "rw",
  "RW": true,
  "Propagation": "rprivate"
},
{
  "Type": "bind",
  "Source": "/bitwarden/bwdata/mssql/backups",
  "Destination": "/etc/bitwarden/mssql/backups",
  "Mode": "rw",
  "RW": true,
  "Propagation": "rprivate"
}
]
Enter fullscreen mode Exit fullscreen mode

Thus for a backup will be enough just to store the bwdata catalog.

Email configuration

Email settings are set in the bwdata/env/global.override.env file.

We will use AWS SES, update variables:

...
globalSettings__mail__replyToEmail=no-reply@example.com
globalSettings__mail__smtp__host=email-smtp.us-east-1.amazonaws.com
globalSettings__mail__smtp__port=587
globalSettings__mail__smtp__ssl=false
globalSettings__mail__smtp__username=AKI***MJI
globalSettings__mail__smtp__password=BKR***z2G
...
Enter fullscreen mode Exit fullscreen mode

Restart Bitwarden (rebuild needs to be done only after changes in the config.yml):

root@ip-172-31-36-249:/bitwarden# ./bitwarden.sh restart
Enter fullscreen mode Exit fullscreen mode

In case of email sending problems – check logs in the bwdata/logs/api/Api/ directory or from the bitwarden-api container

root@ip-172-31-36-249:/bitwarden# docker logs -f bitwarden-api
Enter fullscreen mode Exit fullscreen mode

Registration in the Bitwarden

Now you can register in your Bitwarden installation.

Click on the Create account:

Click Confirm.

Bitwarden Admin and users

Add an administrator mailbox to the bwdata/env/global.override.env file in the adminSettings__admins= field.

Note, that the documentation says:

These admin email addresses do not need to be registered with an account on your Bitwarden installation

After logging in with this mailbox – you’ll get an email with a link to proceed authorization to the admin page. This link will be valid for 15 minutes:

...
adminSettings__admins=admin@example.com,anotheradmin@example.com
...
Enter fullscreen mode Exit fullscreen mode

Restart service:

root@ip-172-31-36-249:/bitwarden# ./bitwarden.sh restart
Enter fullscreen mode Exit fullscreen mode

And go to the https://dev.bitwarden.setevoy.org.ua/admin page:

Log in with the mailbox specified in the adminSettings__admins, get an email, go by the link:

Users settings

Log in using common Log In form and will see usual userspace:

In the Tools you can import data from various passwords managers like KeePass:

Adding passwords manually:

Getting a password:

Working with Bitwarden

Chrome plugin

Install Chrome extension from the Chrome webstore:

Click on the Settings:

Set your server’s URL:

Log in:

And get all your passwords directly from a browser:

Also, it will suggest storing passwords during logins as a usual passwords manager:

Linux desktop

I guess it has clients for any Linux-based systems

In Arch Linux can be installed from AUR:

$ yaourt -S bitwarden-bin
Enter fullscreen mode Exit fullscreen mode

And log in in the same way as in the Chrome extension:

Import from KeePass

Let’s check how import is working

In your KeePass export data to an XML file:

Then go to the Bitwarden – Tools > Import data:

Ready – even with directories structure:

Export can be done in the same way – you can upload data from Bitwarden in a JSON or CSV file and the CSV can be imported to a local KeePass. Such an additional backup.

Keep in mind that the exported file will have all passwords unencrypted.

Multi-factor authorization

MFA can be configured in My account – Two-step Login, everything in a standard way here:

Backuping and restoring Bitwarden storage

Nobody wants to lose an organization’s all passwords so let’s check how backup and restore will works.

As we have /bitwarden mounted from a dedicated EBS volume then it can be daily snapshotted by AWS Data Lifecycle Manager and then in case of problems – a new volume can be created and mounted to a new EC2 instance with a new Bitwarden installation.

So steps to check are, quickly:

  1. create a snapshot manually
  2. create a new EBS using this snapshot
  3. start a new ЕС2
  4. attach this EBS and mount it to the /bitwarden
  5. obtain a Let’s Encrypt Certificate
  6. install NGINX, set up a virtual host
  7. install Docker, Docker Compose
  8. if a domain was changed – update /bitwarden/bwdata/config.yml, change the url parameter
  9. run ./bitwarden.sh rebuild
  10. run ./bitwarden.sh start
  11. Profit!

That’s all for now.

When will get a trial license – will play with user’s and roles.

Similar posts

Image of Datadog

Create and maintain end-to-end frontend tests

Learn best practices on creating frontend tests, testing on-premise apps, integrating tests into your CI/CD pipeline, and using Datadog’s testing tunnel.

Download The Guide

Top comments (0)

Sentry image

See why 4M developers consider Sentry, “not bad.”

Fixing code doesn’t have to be the worst part of your day. Learn how Sentry can help.

Learn more

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay