Уже лет как пять я периодически подумывал об обновлении стратегии хранения личных, корпоративных и паролей клиентов, а так же их передачи. До сегодняшнего дня, много-много лет, я использовал классический PasswordSafe на компьютерах и, с 2017, pwSafe на iPhone с синхронизацией криптоконтейнеров через iCloud. Но доступность этого решения оставляет желать… желать и желать, увы!
Сейчас же, существует огромное количество решений, доступность которых находится совершенно на другом уровне! Но с увеличением доступности, падает надежность – особенно меня всегда смущало расположение базы данных неизвестно где и у кого! Еще более в этом месте волнует полнейшее отсутствие гарантий, что завтра этот сервис будет все так же онлайн… причем по самому огромному спектру причин, зачастую даже не зависящих от воли владельцев сервиса!
Но сравнительно недавно у меня посвился Raspberry Pi 4 Model B и тут возможности заиграли новыми красками!
Мук, как таковых, на самом деле и не было – пробежался по интерфейсам Open Source систем, имеющих self-hosted решения, выбрал, что больше нравится и соответствует моим требованиям, погуглил немного отзывы и историю, в итоге остановился на Bitwarden'e. Далее осталось выбрать реализацию сервиса.
Но и тут особых сложностей не возникло – по сути, Vaultwarden ничем не отличается от официального сервера1), кроме того, что он более «легкий» и имеет на борту разблокированные платные, а тут бесплатные, функции. Выбор очевиден2)!
В итоге я получил:
Все манипуляции проводятся на 64-битной Raspberry Pi OS 11 (bullseye):
Для удобства авторизовываемся под суперпользователем
sudo -s
curl -fsSL https://download.docker.com/linux/debian/gpg | sudo gpg --dearmor -o /etc/apt/trusted.gpg.d/docker.gpg
echo "deb [arch="$(dpkg --print-architecture)" signed-by=/etc/apt/trusted.gpg.d/docker.gpg] https://download.docker.com/linux/debian "$(. /etc/os-release && echo "$VERSION_CODENAME")" stable" | tee /etc/apt/sources.list.d/docker.list > /dev/null
apt update && apt upgrade
apt install ca-certificates curl gnupg
apt install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
В моем случае, во время конфигурирования пакета «docker-ce» появилась ошибка запуска службы «invoke-rc.d: initscript docker, action "start" failed. (code=exited, status=1/FAILURE)», а journalctl -xe
ни сказал вообще ничего интересного кроме «Failed to start Docker Application Container Engine».
А вот при попытке запуска демона dockerd
напрямую уже появилось что-то интересное:
ERRO[2023-04-28T20:59:30.882570089+10:00] failed to mount overlay: no such device storage-driver=overlay2 ERRO[2023-04-28T20:59:30.882760347+10:00] exec: "fuse-overlayfs": executable file not found in $PATH storage-driver=fuse-overlayfs WARN[2023-04-28T20:59:30.896634105+10:00] Running modprobe bridge br_netfilter failed with message: modprobe: WARNING: Module bridge not found in directory /lib/modules/6.1.19-v8+ modprobe: WARNING: Module br_netfilter not found in directory /lib/modules/6.1.19-v8+, error: exit status 1
Немного погуглив, выполнил rpi-update
5) и reboot
, что однозначно помогло, но не совсем – служба начала запускаться, но при попытке загрузить контейнер стала появляться ошибка «Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running?»… при том, что docker daemon is running!
Решил попробовать откатиться к стабильным версиям
sudo apt install --reinstall libraspberrypi0 libraspberrypi-{bin,dev,doc} raspberrypi-bootloader raspberrypi-kernel
что помогло уже окончательно!
После всех манипуляций, для окончательной установки пакета, нужно выполнить
sudo apt install docker-ce
docker pull vaultwarden/server:latest
openssl rand -base64 48
docker run -d -e ADMIN_TOKEN='$argon2id$v=XX$m=XXXXX,t=X,p=X$HASH' -e TZ='Asia/Vladivostok' -e WEBSOCKET_ENABLED=true --restart unless-stopped --name vaultwarden -v /opt/vaultwarden/:/data/ -p 127.0.0.1:8080:80 -p 127.0.0.1:3012:3012 vaultwarden/server:latest
Для дальнейшей настройки, необходим «белый» IP-адрес и общедоступный домен. Для примера, ниже будут использоваться следующие условности:
Ну и, соответственно, доступ к маршрутизатору, обладающему этим IP.
Т.к. nginx у меня уже установлен и обслуживает систему мониторинга LibreNMS, мне нужно исправить конфигурацию последней, для возможности использования ее в получении сертификата Let's Encrypt, и добавить отдельную конфигурацию для Vaultwarden.
LibreNMS висит на 80-м порту и должен быть доступен только внутри сети, поэтому:
nano /etc/nginx/sites-enabled/librenms.vhost
allow XXX.XXX.XXX.0/24; deny all;
location /.well-known/acme-challenge { allow all; alias /tmp/vaultwarden/ssl/; }
mkdir -p /tmp/vaultwarden/ssl/
nano /etc/nginx/sites-enabled/vaultwarden.vhost
systemctl reload nginx
Конфигурация маршрутизатора сводится к публикации портов 80/768414) и, если необходимо, настройке NAT Loopback.
# Server Publishing /ip firewall nat add action=netmap chain=dstnat comment="Publishing .well-known and Vaultwarden" dst-address=AAA.AAA.AAA.AAA dst-port=80,7684 protocol=tcp to-addresses=XXX.XXX.XXX.XXX /ip firewall filter add action=accept chain=forward comment="Accept .well-known and Vaultwarden" dst-address=XXX.XXX.XXX.XXX dst-port=80,7684 in-interface=Internet-1 protocol=tcp # NAT Loopback /ip firewall mangle add action=mark-packet chain=prerouting comment="Mark Vaultwarden packets from LAN" connection-state=new dst-address=AAA.AAA.AAA.AAA in-interface-list=LAN new-packet-mark=nat-loopback passthrough=yes /ip firewall nat add action=masquerade chain=srcnat comment="Masquerade Vaultwarden from LAN" packet-mark=nat-loopback
sudo -s
snap install core
snap refresh core
snap install --classic certbot && ln -s /snap/bin/certbot /usr/bin/certbot
certbot -d vw.example.zone --nginx
Что странно, больше ничего не потребовалось… сертификаты без лишних вопросов сохранил сюда «/etc/letsencrypt/live/vw.example.zone/»… и добавил в конфиг «/etc/nginx/sites-enabled/vaultwarden.vhost» нужные строки.
certbot renew --dry-run
Осталось добавить полноценную конфигурацию обратного прокси:
nano /etc/nginx/sites-enabled/vaultwarden.vhost
# The `upstream` directives ensure that you have a http/1.1 connection # This enables the keepalive option and better performance # # Define the server IP and ports here. upstream vaultwarden-default { zone vaultwarden-default 64k; server 127.0.0.1:8080; keepalive 2; } upstream vaultwarden-ws { zone vaultwarden-ws 64k; server 127.0.0.1:3012; keepalive 2; } # Redirect HTTP to HTTPS #1 #server { # listen 80; # listen [::]:80; # server_name vaultwarden.example.tld; # return 301 https://$host$request_uri; #} server { listen 7684 ssl http2; # listen [::]:443 ssl http2; #2 server_name vw.example.zone; # Specify SSL Config when needed #3 ssl_certificate /etc/letsencrypt/live/vw.example.zone/fullchain.pem; # managed by Certbot ssl_certificate_key /etc/letsencrypt/live/vw.example.zone/privkey.pem; # managed by Certbot include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot client_max_body_size 128M; location / { proxy_http_version 1.1; proxy_set_header "Connection" ""; 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; proxy_pass http://vaultwarden-default; } location /notifications/hub/negotiate { proxy_http_version 1.1; proxy_set_header "Connection" ""; 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; proxy_pass http://vaultwarden-default; } location /notifications/hub { proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header Forwarded $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; proxy_pass http://vaultwarden-ws; } # Optionally add extra authentication besides the ADMIN_TOKEN # Remove the comments below `#` and create the htpasswd_file to have it active # #location /admin { # # See: https://docs.nginx.com/nginx/admin-guide/security-controls/configuring-http-basic-authentication/ # auth_basic "Private"; # auth_basic_user_file /path/to/htpasswd_file; # # proxy_http_version 1.1; # proxy_set_header "Connection" ""; # # 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; # # proxy_pass http://vaultwarden-default; #} }
Пояснения к изменениям в конфигурации по умолчанию:
systemctl reload nginx
Админ-панель доступна по адресу «https://vw.example.zone:7684/admin».
Из важного, в ней необходимо установить параметр «General settings» → «Domain URL»18), который должен соответствовать установленным выше параметрам. В данном контексте должно быть так – «https://vw.example.zone:7684».
Остальные параметры сугубо на свое усмотрение.
Разве что, после всех настроек, желательно отключить регистрацию в «General settings» → «Allow new signups» и полностью отключить админ-панель:
nano /opt/vaultwarden/config.json
и удаляем из нее строку «admin_token»
docker run -d -e TZ='Asia/Vladivostok' -e WEBSOCKET_ENABLED=true --restart unless-stopped --name vaultwarden -v /opt/vaultwarden/:/data/ -p 127.0.0.1:8080:80 -p 127.0.0.1:3012:3012 vaultwarden/server:latest
Обновление, в моем случае, с версии 1.28.1 до 1.30.1 простейшее и описано ниже, но!
В этой версии служба web-сокета на отдельном порту оставлена только в режиме совместимости, т.е. она не будет обновляться, и в ближайшем будущем будет вообще удалена! Поэтому обновление на более свежую версию, вероятно, уже потребует изменения конфигурации обратного прокси.
sudo -s
docker pull vaultwarden/server:latest
docker stop vaultwarden & docker rm vaultwarden
docker run -d -e TZ='Asia/Vladivostok' -e WEBSOCKET_ENABLED=true --restart unless-stopped --name vaultwarden -v /opt/vaultwarden/:/data/ -p 127.0.0.1:8080:80 -p 127.0.0.1:3012:3012 vaultwarden/server:latest
На этом, собственно, все.
docker system prune -a
но надо быть осторожным, т.к. не удаляет она только запущенные контейнеры и соответствующие им образы!
sudo docker logs vaultwarden | grep "Version" -m 1
Для резервного копирования можно использовать этот скрипт с такой конфигурацией20):
/etc/nginx/sites-enabled/vaultwarden.vhost /opt/vaultwarden/
/opt/vaultwarden/db.sqlite3
Обсуждение