Bitwarden: менеджер паролей организации – установка self-hosted версии на AWS EC2

Автор: | 01/05/2019
 

Мы рассматриваем Bitwarden как менеджер паролей для проекта, основная цель которого – разделение доступа к различным секретам по ролям и/или ACL.

Т.е. Pass и/или KeePass – это хорошо для одного пользователя, но у них нет главного – нормального веб-интерфейса, и разделения доступа к секретам для пользователей, а всякие 1Password/LastPass не имеют возможности установки на свой сервер, а хранить данные “на стороне” не хочется.

Сам Bitwarden является Opensource, имеет возможность использования cloud-версии, или установки на свой сервер.

Есть персональная Free-версия, и платная – 1 уе/мес с дополнительными плюшками.

Кроме персональных лицензий – есть Business-версии, их возможности (а именно – организации и роли) попробую попозже.

Страница проекта  – тут>>>.

Основные возможности Bitwarden, которые заинтересовали:

  • есть десктопные клиенты для Linux, macOS, Windows
  • расширения для всех браузеров
  • клиенты для Android и iOS
  • RESTful API (в Enterprise версии), т.е. теоретически можно будет попробовать использовать его из Jenkins для заполнения секретов
  • наличие CLI-утилит
  • MFA-авторизация
  • роли/группы для разделения доступа (в Enterprise версии)
  • File Storage
  • импорт данных из других хранилищ (Chrome, KeePass, 1Password и т.д.)

Документация по быстрой установке есть тут>>>, и полная – тут>>>.

Устанавливать будем на AWS EC2, к которому будет подключен EBS, смонтированный в каталог /bitwarden, в котором Bitwarden будет хранить свои данные, и который будет бекапиться с помощью AWS Data Lifecycle Manager.

На EC2 будет работать NGINX в роли фронтенда, на нём же будет терминейтиться SSL с сертификатом от Let’s Encrypt.

Хотя сам Bitwarden запускается в Docker Compose стеке, в котором в том числе есть контейнер с NGINX и собственной поддержкой Let’s Encrypt сертификатов, но сделаю по более привычной схеме, т.е. на хосте будет NGINX с SSL, который по HTTP будет проксировать запросы на NGINX-контейнер Bitwarden-стека, который уже будет проксировать запросы дальше внутренним сервисам.

AWS

Запуск EC2

Используем Debian. Найти образ можно тут>>>.

Сначала я использовал t3.nano, но этого оказалось совсем мало – машина зависла напрочь при запуске Bitwarden-контейнеров, что не удививительно учитывая то, что база в MSSQL, и вообще стек включает в себя 9 контейнеров. Да и сам Bitwarden является .NET приложение на C#.

Запускаем EC2 с t3.medium:

[simterm]

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

[/simterm]

Получаем Availability Zone:

[simterm]

$ 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

[/simterm]

Создание EBS

Создаём EBS (по-умолчанию создаётся standart, т.е. HDD, если требуется SSD – то указываем --volume-type gp2):

[simterm]

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

[/simterm]

Тут указываем тот же регион (--region eu-west-1) и ту же Availability Zone (--availability-zone eu-west-1a), в которой создался ЕС2, и размер – 5 ГБ.

Получаем ID этого EBS:

[simterm]

$ 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

[/simterm]

И ID созданного EC2:

[simterm]

$ 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

[/simterm]

Подключаем этот EBS к EC2:

[simterm]

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

[/simterm]

Security Group

Создаём Security Group – тут уже через WebUI, что бы быстрее.

При создании обратите внимание на VPC ID – должна быть та же, в которой и ЕС2:

Порт 80 разрешаем отовсюду, что бы прошла авторизация Let’s Encrypt.

443 и 22 – только из офиса.

Подключаем SG к EC2 – Networking > Change Security Group:

Монтирование EBS

Логинимся на сервер:

[simterm]

$ ssh [email protected] -i setevoy-testing-eu-west-1.pem

[/simterm]

Проверяем диски:

[simterm]

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

[/simterm]

nvme1n1 – наш EBS.

Создаём каталог /bitwarden:

[simterm]

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

[/simterm]

Создаём раздел на /dev/nvme1n1:

[simterm]

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

[/simterm]

Создаём файловую систему:

[simterm]

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

[/simterm]

Проверяем разделы ещё раз:

[simterm]

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

[/simterm]

Монтируем его в /bitwarden:

[simterm]

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

[/simterm]

Получаем ID раздела:

[simterm]

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"

[/simterm]

Используя UUID – добавляем новую точку монтирования в /etc/fstab с опцией --nofail:

[simterm]

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

[/simterm]

Отмонтируем смонтированный вручную раздел:

[simterm]

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

[/simterm]

И монтируем через fstab:

[simterm]

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

[/simterm]

Проверяем:

[simterm]

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

[/simterm]

Можно перезагрузить машину для полной проверки, заодно – накатить все апдейты:

[simterm]

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

[/simterm]

DNS

Создаём домен:

Настройка хоста

Let’s Encrypt

Устанавливаем клиент:

[simterm]

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

[/simterm]

Получаем сертификат через standalone аутентификатор:

[simterm]

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): [email protected]

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

[/simterm]

NGINX

Устанавливаем NGINX:

[simterm]

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

[/simterm]

Генерируем ключ для SSL:

[simterm]

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

[/simterm]

Добавляем файл настроек виртуалхоста – /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";
    }
}

Проверяем синтаксис, перезагружаем конфиги:

[simterm]

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

[/simterm]

Проверяем работу:

[simterm]

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

[/simterm]

Редирект работает, всё хорошо.

Connection timed out – потому что бекенд ещё не запущен.

Let’s Encrypt renew config и crontask

Теперь, когда у нас есть NGINX, который работает на порту 80 – renew сертификата Let’s Encrypt не сработает, т.е. он устанавливался со standalone-аутентификацией.

Редактируем конфиг домена /etc/letsencrypt/renewal/dev.bitwarden.setevoy.org.ua.conf, меняем блок [renewalparams] с:

...
[renewalparams]
authenticator = standalone
account = ee3***3c1
server = https://acme-v02.api.letsencrypt.org/directory

На:

...
[renewalparams]
authenticator = webroot
account = ee3***3c1
server = https://acme-v02.api.letsencrypt.org/directory
[[webroot_map]]
dev.bitwarden.setevoy.org.ua = /var/www/html/
...

Теперь можно добавить cron-задачу для обновления сертификата:

0 0 * * * /opt/letsencrypt/letsencrypt-auto renew --quiet --renew-hook "systemctl reload nginx" &> /var/log/letsencrypt/letsencrypt.log

С этим всё.

Docker и Docker Compose

Для запуска Bitwarden потребуется Docker и Docker Compose – устанавливаем.

Docker:

[simterm]

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

[/simterm]

Проверяем:

[simterm]

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

[/simterm]

Добавляем пользователя admin в группу docker:

[simterm]

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

[/simterm]

Устанавливаем Docker Compose:

[simterm]

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

[/simterm]

Установка Bitwarden

Переходим на страницу bitwarden.com/host, и получаем ключ:

Каждая новая установка Bitwarden должна выполняться со своими ключами.

Загружаем скрипт, который выполнит установку и настройку. Он же используется для управления сервисом:

[simterm]

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

[/simterm]

Скрипт выполняет загрузку файлов с https://github.com/bitwarden/server, а затем вызывает скрипт https://github.com/bitwarden/server/blob/master/scripts/run.sh с опцией install.

Доступные опции для 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.

Запускаем установку:

[simterm]

root@ip-172-31-36-249:/bitwarden# ./bitwarden.sh install
 _     _ _                         _            
| |__ (_) |___      ____ _ _ __ __| | ___ _ __  
| '_ \| | __\ \ /\ / / _` | '__/ _` |/ _ \ '_ \ 
| |_) | | |_ \ V  V / (_| | | | (_| |  __/ | | |
|_.__/|_|\__| \_/\_/ \__,_|_|  \__,_|\___|_| |_|
...
(!) 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`

[/simterm]

Настройка Bitwarden

Скрипт выполняет установку всех файлов в каталог bwdata:

[simterm]

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

[/simterm]

Основной файл настроек – bwdata/config.yml.

В файле ./bwdata/env/global.override.env задаются основные переменные, к ним перейдём позже.

Стек запускается из файла ./bwdata/docker/docker-compose.yml:

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

Обновляем файл config.yml – отключаем SSL, т.к. у нас свой NGINX со своим SSL, и меняем порты HTTP и HTTPS:

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

Обновляем конфиги в приложениях:

[simterm]

./bitwarden.sh rebuild

[/simterm]

Запускаем:

[simterm]

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

[/simterm]

Проверяем в браузере:

Проверяем контейнеры:

[simterm]

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

[/simterm]

В сервисы Bitwarden монтируются каталоги с хоста, в которых хранятся данные, например – mssql:

[simterm]

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

[/simterm]

Поэтому для бекапа достаточно хранить папку bwdata.

Настройка почты

Почта настраивается через переменные из файла bwdata/env/global.override.env.

У нас будет использоваться AWS SES, обновляем переменные:

...
[email protected]
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
...

Перезапускаем Bitwarden (rebuild нужен только при изменениях в config.yml):

[simterm]

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

[/simterm]

В случае проблем с отправкой почты – можно попробовать посмотреть логи API-сервиса в файле bwdata/logs/api/Api/дата.txt, или в контейнере:

[simterm]

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

[/simterm]

Регистрация в Bitwarden

Теперь можно зарегистрироваться.

Кликаем на Создать аккаунт:

Жмём Подтвердить.

Bitwarden Admin и пользователи

В файле bwdata/env/global.override.env в поле adminSettings__admins= добавляем ящик администратора.

При чём это не обязательно может быть зарегистрированный пользователь, см документацию:

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

После логина с этим ящиком на него будет отправлена ссылка для авторизации, которая будет валидна 15 минут:

...
[email protected],[email protected]
...

Перезапускаем сервис:

[simterm]

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

[/simterm]

Переходим на страницу https://dev.bitwarden.setevoy.org.ua/admin:

Логинимся с указанным в adminSettings__admins ящиком, получаем письмо, и переходим по ссылке в нём:

Но вообще особого смысла в админке не понял – пользователей создать нельзя, организации – нельзя… Удалить – можно 🙂

С организациями и ролями надо будет ещё разобраться, когда прикручу триал Enterprise-версии.

Пользовательские настройки

Заходим через обычную форму входа, для пользователей – и попадаем собственно в пространство пользователя:

В Tools можно импортировать данные из, например, KeePass (вообще выбор источников для импорта впечатлил):

Добавление данных вручную:

Получение пароля:

Работа с Bitwarden

Chrome plugin

Устанавливаем со страницы в Chrome webstore:

Слева вверху кликаем Settings:

Указываем URL сервера:

Логинимся:

И получаем доступ к своим секретам:

Плюс при логине на различные страницы он будет предлагать сохранить пароль, как и все стандартные менеджеры паролей:

Linux desktop

Есть, наверно, для всех Linux-систем.

В Arch Linux можно установить из AUR:

[simterm]

$ yaourt -S bitwarden-bin

[/simterm]

И логинимся аналогично тому, как делали это в Chrome:

Импорт из KeePass

Проверим, как работает импорт.

Експортируем базу KeePass в XML:

Переходим в Bitwarden – Tools > Import data:

Готово – даже с сохранением структуры каталогов:

Експорт данных работает аналогично – можно выгрузить данные в JSON и CSV, и потом, например CSV, импортировать в локальный KeePass. Такой себе дополнительный бекап данных.

Учтите, что в файле все пароли будут в незашифрованном виде.

Multi-factor авторизация

Двухфакторную авторизацию можно настроить в My account – Two-step Login, тут всё стандартно:

Бекап и восстановление

Очень-очень-очень не хочется потерять все пароли проекта, поэтому – проверим, как работает бекапирование и восстановление.

Т.к. у нас /bitwarden смонтирован отдельным EBS, то логика простая: каждую ночь через AWS Data Lifecycle Manager будет создаваться снапшот диска, который потом, в случае проблем, можно будет подключить к новому ЕС2-инстансу, и развернуть Bitwarden на нём.

Проверяем, тут уже без скриншотов и прочего:

  1. создаём снапшот вручную
  2. создаём из него новый EBS
  3. запускаем новый ЕС2
  4. монтируем созданый EBS в /bitwarden
  5. получаем Let’s Encrypt сертификат
  6. устанавливаем NGINX, настраиваем виртуалхост
  7. устанавливаем Docker, Docker Compose
  8. если менялся домен – редактируем /bitwarden/bwdata/config.yml, меняем в нём параметр url
  9. выполняем ./bitwarden.sh rebuild
  10. выполняем ./bitwarden.sh start
  11. Profit!

В целом – на этом пока всё.

Когда получим триал – добавлю обзор по работе с пользователями и ролями (если там вообще получится то, чего хочется).