Безопасная среда ч.2. Хранение паролей
Как показывает практика, придумать один пароль и использовать его для всех сайтов довольно плохая затея т.к. компрометация одного сервиса ведет к компрометации остальных использующих этот пароль. Например, утечка данных из службы доставки может привести к потере почтового ящика. Потому, сейчас, в современные браузеры внедряется плагин который проверяет сохранённые пароли не только на наличие в слитых базах, но и на уникальность. Однако, с растущим количеством онлайн-сервисов хранить все уникальные пароли в голове попросту невозможно (не в ущерб уникальности), потому имеет смысл использовать специальные приложения для хранения. Хранилище паролей должно отвечать следующим критериям:
- шифрование пользовательских данных
- обязательный запрос второго фактора при восстановлении доступа
- отсутствие компрометаций (по этому пункту не проходит LastPass, например)
Локальное хранение⌗
Если нет необходимости синхронизировать пароли между несколькими машинами, то хорошим вариантом будет KeePassX.
Работает на всех десктопных платформах: Windows, MacOS, Linux
Умеет:
- Шифрование БД с паролям
- Детерминированное хранение (несколько баз для разных задач)
- Хранение документов
- Автогенерация стойких паролей
- Поиск
Еще на базе KeePassX можно реализовать максимально параноидальное решение:
- Взять usb-флешку и удалить все разделы
- Создать зашифрованный раздел с помощью VeraCrypt
- Хранить файлы-БД в зашифрованном разделе
- ???
- Proffit!
Но не стоит забывать, что даже такое решение можно “взломать” как в комиксе xkcd.
Облачное хранение⌗
Если же стоит задача получить сервис а-ля “зарегистрировался -> заплатил -> работает”, то лучшим решением будет 1Password.
Умеет:
- Удобное хранение всего и вся
- Максимальная интеграция в MacOS/iOS. Windows/Linux/Android так же поддерживаются, но нет ощущения от “UX на кончиках пальцев” как в яблочных продуктах.
- Устойчивая архитектура безопасности (не было известных утечек и ребята проводят всякие испытания своих систем с помощью “белых хакеров”)
Но, к сожалению, вся эта прелесть разбивается о необходимость оплаты картами: Visa, Mastercard, American Express, Discover, Diners Club, and UnionPay. Еще можно платить через AppleID/GooglePlay, но на такое тоже не стоит полагаться. К счастью есть еще одно решение…
Self-hosted хранение⌗
Есть такой open-source продукт Bitwarden. Если вкратце, то это попытка сделать 1password с шифром и длинными ключами + возможность размещения на своих серверах.
Умеет практически все тоже самое, что 1password, только бесплатно… ну… почти. За возможность хранить OneTimePassword хотят денег и можно было бы с этим смириться если бы не существование неофициальной реализации сервера - Vaultwarden.
Из-за того, что Vaultwarden написан на Rust, то потребляет ОЗУ на несколько порядков меньше чем официальная версия сервера.
Фичи
- Объединение пользователей в организации
- Вложения
- API
- Поддержка токенов U2F, YubiKey, Duo
- Расширения в браузер и отдельное ПО для всех платформ
На этом решении я и остановился, а запустить сервер оказалось проще простого.
Vaultwarden на своей VPS⌗
Подготавливаем Nginx⌗
Чтобы кроме Vaultwarden на VPS можно было запустить какой-нибудь еще сайт, то лучше порты контейнера не выставлять “в Мир”, а проксировать через Nginx. Подробнее про базовую конфигурацию Nginx можно прочесть в другой заметке
ВАЖНО! После запуска контейнера появляется интерфейс настройки/установки, потому добавить запись DNS лучше ПОСЛЕ всех манипуляций
Пример конфигурации с https
server {
server_name vault.domain;
listen 80;
listen [::]:80;
return 301 https://vault.domain$request_uri;
}
server {
server_name vault.domain;
listen [::]:443 ssl http2;
listen 443 ssl http2;
ssl_certificate ; # managed by Certbot
ssl_certificate_key ; # managed by Certbot
ssl_trusted_certificate ;
location / {
if ($allowed_country = no) {
return 403;
}
proxy_pass http://localhost:8181/;
proxy_set_header Host $host;
proxy_http_version 1.1;
proxy_set_header Connection "";
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";
access_log /var/log/nginx/vault.access.log;
error_log /var/log/nginx/vault.error.log;
}
}
Где allowed_country - специальная переменная в которой хранится страна из которой пришел пользователь. Сделано для того, чтобы отсечь китайские/оракловые ботнеты. Логику работы можно задать глобально, в /etc/nginx/nginx.conf
geoip_country /usr/share/GeoIP/GeoIP.dat;
map $geoip_country_code $allowed_country {
default no;
RU yes;
}
localhost:8181 - соответствует настройкам докера - -p 127.0.0.1:8181:80
- что означает открытие порта 8181 на localhost, который смотрит в порт 80 внутри контейнера.
Поднимаем docker⌗
Самый простой способ поднять Vaultwarden - это развернуть docker-контейнер по инструкции с GitHub.
Пример команды запуска контейнера
docker run -dit --restart always --name vaultwarden -e SMTP_HOST="smtp.domain" -e SMTP_FROM="noreply-vault@domain" -e SMTP_PORT=465 -e SMTP_SSL=false -e SMTP_EXPLICIT_TLS=true -e SMTP_USERNAME="noreply-vault@domain" -e SMTP_PASSWORD=<secret> -e ADMIN_TOKEN=<secret> -v /opt/vault-data/:/data/ -p 127.0.0.1:8181:80 vaultwarden/server:latest
Для получения ADMIN_TOKEN надо выполнить openssl rand -base64 48
. Так же имеет смысл указать настройки SMTP для поддержки второго фактора через почту.
После удачного запуска в /etc/hosts прописываем соответствие будущему доменному имени (vault.domain) и IP адресу VPSки. Заходим браузером по адресу vault.domain, выполняем первичную настройку и все! И напоследок не забыть удалить строчку из /etc/hosts и прописать новый домен в DNS записи.
Подпишись на мой канал в Телеграм!