Bitwarden: an organization’s password manager self-hosted version installation on an AWS EC2
Tags: passwords, security, ssl
Published: 2019-05-01 12:46:07

---
title: Bitwarden: an organization’s password manager self-hosted version installation on an AWS EC2
published: true
tags: passwords,security,SSL
canonical_url: https://rtfm.co.ua/en/bitwarden-an-organizations-password-manager-self-hosted-version-installation-on-an-aws-ec2/
---

![](https://rtfm.co.ua/wp-content/uploads/2019/04/bitwarden-logo-png.png)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>>>](https://bitwarden.com/).

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>>>](https://help.bitwarden.com/article/install-on-premise/#install-bitwarden) and full – [here>>>](https://help.bitwarden.com/article/install-on-premise/#manual-docker-installations).

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](https://rtfm.co.ua/aws-bekap-ebs-po-raspisaniyu-cherez-cloudwatch-rules-ili-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>>>](https://wiki.debian.org/Cloud/AmazonEC2Image/Stretch).

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}]'
```

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
```

#### 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}]'
```

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
```

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
```

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
```

#### 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:

[![](https://rtfm.co.ua/wp-content/uploads/2019/04/Screenshot_20190430_130854.png "Bitwarden: менеджер паролей организации - установка на AWS EC2 с EBS, NGINX с SSL")](https://rtfm.co.ua/wp-content/uploads/2019/04/Screenshot_20190430_130854.png)

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_:

[![](https://rtfm.co.ua/wp-content/uploads/2019/04/Screenshot_20190430_131106.png "Bitwarden: менеджер паролей организации - установка на AWS EC2 с EBS, NGINX с SSL")](https://rtfm.co.ua/wp-content/uploads/2019/04/Screenshot_20190430_131106.png)

[![](https://rtfm.co.ua/wp-content/uploads/2019/04/Screenshot_20190430_131130.png "Bitwarden: менеджер паролей организации - установка на AWS EC2 с EBS, NGINX с SSL")](https://rtfm.co.ua/wp-content/uploads/2019/04/Screenshot_20190430_131130.png)

#### Mounting EBS

Log in to the server:

```
$ ssh admin@34.240.14.78 -i setevoy-testing-eu-west-1.pem
```

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
```

`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
```

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.
```

Create a file system:

```
root@ip-172-31-36-249:/home/admin# mkfs.ext4 /dev/nvme1n1p1
```

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
```

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
```

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"
```

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
```

Unmount partition mounted manually:

```
root@ip-172-31-36-249:/home/admin# umount /bitwarden/
```

And mount it back using `fstab`:

```
root@ip-172-31-36-249:/home/admin# mount -a
```

Check:

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

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
```

### DNS

Create a domain name to be used:

[![](https://rtfm.co.ua/wp-content/uploads/2019/04/Screenshot_20190430_134008.png "Bitwarden: менеджер паролей организации - установка на AWS EC2 с EBS, NGINX с SSL")](https://rtfm.co.ua/wp-content/uploads/2019/04/Screenshot_20190430_134008.png)

### 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
```

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
...
```

#### NGINX

Install NGINX:

```
root@ip-172-31-36-249:/home/admin# apt -y install nginx
```

Generate a key for the SSL:

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

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";
    }
}
```

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
```

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
```

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
```

Check:

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

Add the `admin` user to the `docker` group:

```
root@ip-172-31-36-249:/home/admin# usermod -aG docker admin
```

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
```

### Bitwarden installation

Go to the [bitwarden.com/host](https://bitwarden.com/host/) and get keys:

[![](https://rtfm.co.ua/wp-content/uploads/2019/04/Screenshot_20190430_141155.png "Bitwarden: менеджер паролей организации - установка на AWS EC2 с EBS, NGINX с SSL")](https://rtfm.co.ua/wp-content/uploads/2019/04/Screenshot_20190430_141155.png)

[![](https://rtfm.co.ua/wp-content/uploads/2019/04/Screenshot_20190430_141214.png "Bitwarden: менеджер паролей организации - установка на AWS EC2 с EBS, NGINX с SSL")](https://rtfm.co.ua/wp-content/uploads/2019/04/Screenshot_20190430_141214.png)

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
```

This script will download files from the [https://github.com/bitwarden/server](https://github.com/bitwarden/server) repository and then will call the [https://github.com/bitwarden/server/blob/master/scripts/run.sh](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`. |
```

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`
```

#### 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
```

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
...
```

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
...
```

Update applications configs:

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

Start Bitwarden:

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

Check in a browser:

[![](https://rtfm.co.ua/wp-content/uploads/2019/04/Screenshot_20190430_143833.png "Bitwarden: менеджер паролей организации - установка на AWS EC2 с EBS, NGINX с SSL")](https://rtfm.co.ua/wp-content/uploads/2019/04/Screenshot_20190430_143833.png)

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
```

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"
}
]
```

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](https://rtfm.co.ua/aws-ses-simple-email-service-i-workmail-nastrojka-akkaunta-i-otpravka-pochty/), 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
...
```

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

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

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
```

#### Registration in the Bitwarden

Now you can register in your Bitwarden installation.

Click on the _Create account_:

[![](https://rtfm.co.ua/wp-content/uploads/2019/04/Screenshot_20190430_171223.png "Bitwarden: менеджер паролей организации - установка на AWS EC2 с EBS, NGINX с SSL")](https://rtfm.co.ua/wp-content/uploads/2019/04/Screenshot_20190430_171223.png)

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](https://help.bitwarden.com/article/admin-portal/) 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
...
```

Restart service:

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

And go to the _https://dev.bitwarden.setevoy.org.ua/admin_ page:

[![](https://rtfm.co.ua/wp-content/uploads/2019/04/Screenshot_20190430_155258.png "Bitwarden: менеджер паролей организации - установка на AWS EC2 с EBS, NGINX с SSL")](https://rtfm.co.ua/wp-content/uploads/2019/04/Screenshot_20190430_155258.png)

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

[![](https://rtfm.co.ua/wp-content/uploads/2019/04/Screenshot_20190430_171646.png "Bitwarden: менеджер паролей организации - установка на AWS EC2 с EBS, NGINX с SSL")](https://rtfm.co.ua/wp-content/uploads/2019/04/Screenshot_20190430_171646.png)

[![](https://rtfm.co.ua/wp-content/uploads/2019/04/Screenshot_20190430_171732.png "Bitwarden: менеджер паролей организации - установка на AWS EC2 с EBS, NGINX с SSL")](https://rtfm.co.ua/wp-content/uploads/2019/04/Screenshot_20190430_171732.png)

#### Users settings

Log in using common _Log In_ form and will see usual userspace:

[![](https://rtfm.co.ua/wp-content/uploads/2019/04/Screenshot_20190430_171934.png "Bitwarden: менеджер паролей организации - установка на AWS EC2 с EBS, NGINX с SSL")](https://rtfm.co.ua/wp-content/uploads/2019/04/Screenshot_20190430_171934.png)

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

[![](https://rtfm.co.ua/wp-content/uploads/2019/04/Screenshot_20190430_172154.png "Bitwarden: менеджер паролей организации - установка на AWS EC2 с EBS, NGINX с SSL")](https://rtfm.co.ua/wp-content/uploads/2019/04/Screenshot_20190430_172154.png)

Adding passwords manually:

[![](https://rtfm.co.ua/wp-content/uploads/2019/04/Screenshot_20190430_172527.png "Bitwarden: менеджер паролей организации - установка на AWS EC2 с EBS, NGINX с SSL")](https://rtfm.co.ua/wp-content/uploads/2019/04/Screenshot_20190430_172527.png)

Getting a password:

[![](https://rtfm.co.ua/wp-content/uploads/2019/04/Screenshot_20190430_172605.png "Bitwarden: менеджер паролей организации - установка на AWS EC2 с EBS, NGINX с SSL")](https://rtfm.co.ua/wp-content/uploads/2019/04/Screenshot_20190430_172605.png)

### Working with Bitwarden

#### Chrome plugin

Install Chrome extension from the [Chrome webstore](https://chrome.google.com/webstore/detail/bitwarden-free-password-m/nngceckbapebfimnlniiiahkandclblb?hl=en):

[![](https://rtfm.co.ua/wp-content/uploads/2019/04/Screenshot_20190430_173858.png "Bitwarden: менеджер паролей организации - установка на AWS EC2 с EBS, NGINX с SSL")](https://rtfm.co.ua/wp-content/uploads/2019/04/Screenshot_20190430_173858.png)

Click on the _Settings_:

[![](https://rtfm.co.ua/wp-content/uploads/2019/04/Screenshot_20190430_174015.png "Bitwarden: менеджер паролей организации - установка на AWS EC2 с EBS, NGINX с SSL")](https://rtfm.co.ua/wp-content/uploads/2019/04/Screenshot_20190430_174015.png)

Set your server’s URL:

[![](https://rtfm.co.ua/wp-content/uploads/2019/04/Screenshot_20190430_174059.png "Bitwarden: менеджер паролей организации - установка на AWS EC2 с EBS, NGINX с SSL")](https://rtfm.co.ua/wp-content/uploads/2019/04/Screenshot_20190430_174059.png)

Log in:

[![](https://rtfm.co.ua/wp-content/uploads/2019/04/Screenshot_20190430_174139.png "Bitwarden: менеджер паролей организации - установка на AWS EC2 с EBS, NGINX с SSL")](https://rtfm.co.ua/wp-content/uploads/2019/04/Screenshot_20190430_174139.png)

And get all your passwords directly from a browser:

[![](https://rtfm.co.ua/wp-content/uploads/2019/04/Screenshot_20190430_174217.png "Bitwarden: менеджер паролей организации - установка на AWS EC2 с EBS, NGINX с SSL")](https://rtfm.co.ua/wp-content/uploads/2019/04/Screenshot_20190430_174217.png)

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

[![](https://rtfm.co.ua/wp-content/uploads/2019/05/Screenshot_20190501_105832.png "Bitwarden: менеджер паролей организации - установка на AWS EC2 с EBS, NGINX с SSL")](https://rtfm.co.ua/wp-content/uploads/2019/05/Screenshot_20190501_105832.png)

#### Linux desktop

I guess it has clients for any Linux-based systems

In Arch Linux can be installed from [AUR](https://aur.archlinux.org/packages/bitwarden-bin/):

```
$ yaourt -S bitwarden-bin
```

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

[![](https://rtfm.co.ua/wp-content/uploads/2019/04/Screenshot_20190430_174623.png "Bitwarden: менеджер паролей организации - установка на AWS EC2 с EBS, NGINX с SSL")](https://rtfm.co.ua/wp-content/uploads/2019/04/Screenshot_20190430_174623.png)

[![](https://rtfm.co.ua/wp-content/uploads/2019/04/Screenshot_20190430_174709.png "Bitwarden: менеджер паролей организации - установка на AWS EC2 с EBS, NGINX с SSL")](https://rtfm.co.ua/wp-content/uploads/2019/04/Screenshot_20190430_174709.png)

#### Import from KeePass

Let’s check how import is working

In your KeePass export data to an XML file:

[![](https://rtfm.co.ua/wp-content/uploads/2019/05/Screenshot_20190501_120003.png "Bitwarden: менеджер паролей организации - установка self-hosted версии на AWS EC2 с EBS, с NGINX и Let's Encrypt SSL")](https://rtfm.co.ua/wp-content/uploads/2019/05/Screenshot_20190501_120003.png)

Then go to the Bitwarden – _Tools > Import data_:

[![](https://rtfm.co.ua/wp-content/uploads/2019/05/Screenshot_20190501_120109.png "Bitwarden: менеджер паролей организации - установка self-hosted версии на AWS EC2 с EBS, с NGINX и Let's Encrypt SSL")](https://rtfm.co.ua/wp-content/uploads/2019/05/Screenshot_20190501_120109.png)

[![](https://rtfm.co.ua/wp-content/uploads/2019/05/Screenshot_20190501_120142.png "Bitwarden: менеджер паролей организации - установка self-hosted версии на AWS EC2 с EBS, с NGINX и Let's Encrypt SSL")](https://rtfm.co.ua/wp-content/uploads/2019/05/Screenshot_20190501_120142.png)

Ready – even with directories structure:

[![](https://rtfm.co.ua/wp-content/uploads/2019/05/Screenshot_20190501_120206.png "Bitwarden: менеджер паролей организации - установка self-hosted версии на AWS EC2 с EBS, с NGINX и Let's Encrypt SSL")](https://rtfm.co.ua/wp-content/uploads/2019/05/Screenshot_20190501_120206.png)

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:

[![](https://rtfm.co.ua/wp-content/uploads/2019/05/Screenshot_20190501_121058.png "Bitwarden: менеджер паролей организации - установка self-hosted версии на AWS EC2 с EBS, с NGINX и Let's Encrypt SSL")](https://rtfm.co.ua/wp-content/uploads/2019/05/Screenshot_20190501_121058.png)

[![](https://rtfm.co.ua/wp-content/uploads/2019/05/Screenshot_20190501_121118.png "Bitwarden: менеджер паролей организации - установка self-hosted версии на AWS EC2 с EBS, с NGINX и Let's Encrypt SSL")](https://rtfm.co.ua/wp-content/uploads/2019/05/Screenshot_20190501_121118.png)

#### 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](https://rtfm.co.ua/aws-bekap-ebs-po-raspisaniyu-cherez-cloudwatch-rules-ili-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. …
12. Profit!

[![](https://rtfm.co.ua/wp-content/uploads/2019/05/Screenshot_20190501_124549.png "Bitwarden: менеджер паролей организации - установка self-hosted версии на AWS EC2 с EBS, с NGINX и Let's Encrypt SSL")](https://rtfm.co.ua/wp-content/uploads/2019/05/Screenshot_20190501_124549.png)

That’s all for now.

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

### Similar posts
 
- <small>04/25/2019</small> [Linux: GPG-keys, Pass – passwords manager, and passwords import from the KeePass database](https://dev.to/setevoy/linux-gpg-keys-the-pass-passwords-manager-and-passwords-import-from-the-keepass-database-1j8f)<small></small>  
- <small>03/22/2019</small> [TestRail: QA Test Case Management installation on Linux](https://dev.to/setevoy/testrail-qa-test-case-management-installation-on-linux-5caa)<small></small>  
- <small>02/10/2018</small> [Ansible: миграция RTFM 2.10 – Let’s Encrypt, NGINX SSL, hostname и exim](https://rtfm.co.ua/ansible-migraciya-rtfm-2-10-lets-encrypt-nginx-ssl-hostname-i-exim/)<small></small>