Мы рассматриваем 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:
Получаем Availability Zone:
Создание EBS
Создаём EBS (по-умолчанию создаётся standart, т.е. HDD, если требуется SSD — то указываем --volume-type gp2
):
Тут указываем тот же регион (--region eu-west-1
) и ту же Availability Zone (--availability-zone eu-west-1a
), в которой создался ЕС2, и размер — 5 ГБ.
Получаем ID этого EBS:
И ID созданного EC2:
Подключаем этот EBS к EC2:
Security Group
Создаём Security Group — тут уже через WebUI, что бы быстрее.
При создании обратите внимание на VPC ID — должна быть та же, в которой и ЕС2:
Порт 80 разрешаем отовсюду, что бы прошла авторизация Let’s Encrypt.
443 и 22 — только из офиса.
Подключаем SG к EC2 — Networking > Change Security Group:
Монтирование EBS
Логинимся на сервер:
Проверяем диски:
nvme1n1
— наш EBS.
Создаём каталог /bitwarden
:
Создаём раздел на /dev/nvme1n1
:
Создаём файловую систему:
Проверяем разделы ещё раз:
Монтируем его в /bitwarden
:
Получаем ID раздела:
Используя UUID — добавляем новую точку монтирования в /etc/fstab
с опцией --nofail
:
Отмонтируем смонтированный вручную раздел:
И монтируем через fstab
:
Проверяем:
Можно перезагрузить машину для полной проверки, заодно — накатить все апдейты:
DNS
Создаём домен:
Настройка хоста
Let’s Encrypt
Устанавливаем клиент:
Получаем сертификат через standalone аутентификатор:
NGINX
Устанавливаем NGINX:
Генерируем ключ для SSL:
Добавляем файл настроек виртуалхоста — /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"; } }
Проверяем синтаксис, перезагружаем конфиги:
Проверяем работу:
Редирект работает, всё хорошо.
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:
Проверяем:
Добавляем пользователя admin
в группу docker
:
Устанавливаем Docker Compose:
Установка Bitwarden
Переходим на страницу bitwarden.com/host, и получаем ключ:
Каждая новая установка Bitwarden должна выполняться со своими ключами.
Загружаем скрипт, который выполнит установку и настройку. Он же используется для управления сервисом:
Скрипт выполняет загрузку файлов с 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 . |
Запускаем установку:
Настройка Bitwarden
Скрипт выполняет установку всех файлов в каталог bwdata
:
Основной файл настроек — 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 ...
Обновляем конфиги в приложениях:
Запускаем:
Проверяем в браузере:
Проверяем контейнеры:
В сервисы Bitwarden монтируются каталоги с хоста, в которых хранятся данные, например — mssql
:
Поэтому для бекапа достаточно хранить папку bwdata
.
Настройка почты
Почта настраивается через переменные из файла bwdata/env/global.override.env
.
У нас будет использоваться AWS SES, обновляем переменные:
... 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 ...
Перезапускаем Bitwarden (rebuild
нужен только при изменениях в config.yml
):
В случае проблем с отправкой почты — можно попробовать посмотреть логи API-сервиса в файле bwdata/logs/api/Api/дата.txt
, или в контейнере:
Регистрация в 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 минут:
... adminSettings__admins=admin@example.com,anotheradmin@example.com ...
Перезапускаем сервис:
Переходим на страницу 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:
И логинимся аналогично тому, как делали это в 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 на нём.
Проверяем, тут уже без скриншотов и прочего:
- создаём снапшот вручную
- создаём из него новый EBS
- запускаем новый ЕС2
- монтируем созданый EBS в
/bitwarden
- получаем Let’s Encrypt сертификат
- устанавливаем NGINX, настраиваем виртуалхост
- устанавливаем Docker, Docker Compose
- если менялся домен — редактируем
/bitwarden/bwdata/config.yml
, меняем в нём параметрurl
- выполняем
./bitwarden.sh rebuild
- выполняем
./bitwarden.sh start
- …
- Profit!
В целом — на этом пока всё.
Когда получим триал — добавлю обзор по работе с пользователями и ролями (если там вообще получится то, чего хочется).