SSD Nodes Learn Hosting plans →
Руководства Matt ConnorАвтор: Matt Connor

Насколько безопасен Vaultwarden: руководство по защите

Vaultwarden шифрует данные на стороне клиента, но хранит метаданные в открытом виде. Узнайте, как защитить ADMIN_TOKEN, файлы резервных копий и настроить доступ к контейнеру.

Безопасен ли Vaultwarden? Краткий ответ

Vaultwarden безопасен в самом важном аспекте: каждый элемент хранилища шифруется на вашем устройстве до того, как попадет на сервер. Сервер хранит зашифрованное содержимое хранилища вместе с метаданными учетной записи в открытом виде. Тот, кто скопирует всю базу данных, по-прежнему будет нуждаться в ключах шифрования хранилища, чтобы прочитать его содержимое, но сразу получит доступ к адресам электронной почты и подсказкам к паролям.

Этот ответ подразумевает многое, и слабые места возникают именно там, где вы настраиваете систему. Панель администратора, защищенная угадываемым токеном. Порт контейнера, открытый для всего интернета. Файл config.json в открытом виде. Резервная копия в формате tarball, лежащая в домашнем каталоге на том же сервере. Ничто из этого не является проблемой криптографии. Все это — причины, по которым самохостируемые хранилища оказываются скомпрометированы.

Все, что описано ниже, предполагает наличие работающей установки. Если у вас ее еще нет, сначала выполните настройку согласно руководству по установке Vaultwarden на VPS, а затем вернитесь и последовательно выполните пункты этого списка.

Что на самом деле хранит сервер

Vaultwarden реализует модель данных Bitwarden. Имя элемента хранилища, имя пользователя, пароль, заметки и URI шифруются на стороне клиента с помощью случайно сгенерированного ключа элемента до отправки любого запроса. Этот ключ защищен симметричным ключом пользователя или организации; ключ, производный от пароля, защищает симметричный ключ пользователя. Содержимое прикрепленных файлов использует отдельный ключ вложения, защищенный ключом элемента. Сервер получает непрозрачные данные с привязанным к ним UUID (универсально уникальным идентификатором).

Некоторые данные не являются зашифрованными, и вы должны точно знать, какие именно:

  • Адрес электронной почты вашей учетной записи и подсказка к мастер-паролю — в открытом виде.
  • Настройки KDF (функции формирования ключа) и соль, так как они нужны клиенту для восстановления ключа при следующем входе в систему.
  • Серверный хеш хеша мастер-пароля, который отправляет клиент; он используется для аутентификации самого входа.
  • Метаданные: членство в организации, имена устройств, время последнего входа.
  • Секрет TOTP для двухфакторной аутентификации на основе приложения-аутентификатора. Он хранится в таблице twofactor в незашифрованном виде, так как сервер должен вычислять ожидаемый код для сравнения с вашим. Это не то же самое, что секрет TOTP (временного одноразового пароля), который вы храните внутри элемента хранилища; он зашифрован, как и любое другое поле.

Папка с данными занимает мало места. При установке через Docker это путь, который вы примонтировали к /data.

sudo ls -l /vw-data/

В db.sqlite3 хранится почти всё состояние системы. В attachments/ хранятся загруженные файлы в директориях с именами UUID, вне таблиц базы данных. sends/ предназначена для вложений Send и считается временной. icon_cache/ — это временные файлы. rsa_key.pem и сопутствующие файлы используются для подписи JWT (JSON web tokens) вошедших в систему пользователей, поэтому копия этого закрытого ключа может быть использована для подделки сессии входа в хранилище. В config.json хранятся настройки, сохраненные через страницу администратора, включая учетные данные SMTP в открытом виде и значение настроенного токена администратора. При следовании приведенным ниже инструкциям по Argon2 в файле будет храниться хеш токена администратора, а не пароль в открытом виде.

Таким образом, практическая модель угроз сводится к доступу к файловой системе, а не к сетевой криптографии. Доступ на чтение к этой директории дает злоумышленнику адреса электронной почты всех пользователей, их секреты 2FA для входа, ключ для подделки сессий и офлайн-копию каждого хранилища для последующего взлома. Каждый шаг, описанный ниже, направлен на то, чтобы ограничить доступ к этой директории.

Сначала настройте токен администратора

/admin — это полноценная панель управления: список пользователей, приглашения, удаление аккаунтов и все настройки среды выполнения. Она защищена только одним общим секретным ключом. Имен пользователей нет. Двухфакторная аутентификация для каждого пользователя не предусмотрена.

В старых руководствах рекомендуется генерировать ADMIN_TOKEN с помощью openssl rand -base64 48. Это работает, но оставляет секрет в открытом виде в любом месте, где вы его настраиваете. Vaultwarden также принимает строку Argon2 PHC (password hashing competition), поэтому сохраненное значение будет хешем. Сгенерируйте его с помощью работающего контейнера:

docker exec -it vaultwarden /vaultwarden hash

Или не затрагивая работающий контейнер:

docker run --rm -it vaultwarden/server /vaultwarden hash

Система дважды запросит пароль, а затем выведет строку, начинающуюся с $argon2id$. При установке на «голое железо» (bare-metal) выполните ./vaultwarden hash. Если вы предпочитаете использовать CLI argon2 напрямую, проект документирует минимальные параметры согласно OWASP:

echo -n 'MySecretPassword' | argon2 "$(openssl rand -base64 32)" -e -id -k 19456 -t 2 -p 1

Теперь ловушка, на которой многие теряют час времени. Строка PHC содержит множество символов $, а Docker Compose воспринимает $ как интерполяцию переменных. Если вставить её без экранирования в блок environment:, значение, которое попадет в контейнер, будет искажено, и /admin отклонит токен, который вы считаете верным. Есть два безопасных способа. В docker-compose.yml удвойте каждый символ $:

environment:
  ADMIN_TOKEN: $$argon2id$$v=19$$m=19456,t=2,p=1$$UUZxK1FZMkZoRHFQRlVrTXZvS0E3bHpNQW55c2dBN2NORzdsa0Nxd1JhND0$$cUoId+JBUsJutlG4rfDZayExfjq4TCt48aBc9qsc3UI

В файле .env экранирование не требуется, но используйте одинарные кавычки:

ADMIN_TOKEN='$argon2id$v=19$m=65540,t=3,p=4$MmeKRnGK5RW5mJS7h3TOL89GrpLPXJPAtTK8FTqj9HM$DqsstvoSAETl9YhnsXbf43WeaUwJC6JhViIvuPoig78'

Затем ограничьте частоту запросов к панели и сократите время сессии:

ADMIN_RATELIMIT_SECONDS=300
ADMIN_RATELIMIT_MAX_BURST=3
ADMIN_SESSION_LIFETIME=20

Это позволяет совершить серию из трех попыток входа администратора с одного IP-адреса, после чего лимит восстанавливается со скоростью один запрос каждые пять минут. Учитываются как правильные, так и неправильные пароли, поскольку ограничитель срабатывает до проверки пароля. Запросы сверх лимита получают ответ HTTP 429 с Too many requests, try again later.. Сессия администратора истекает через 20 минут после входа, независимо от того, продолжаете ли вы пользоваться панелью, так как активность не продлевает её действие.

Лучшее решение: отключите эту страницу. Большинству инстансов она нужна один раз — для настройки SMTP и приглашения первых пользователей, а затем больше не требуется. Чтобы отключить её, не задавайте ни ADMIN_TOKEN, ни DISABLE_ADMIN_TOKEN, удалите любой ключ "admin_token" из config.json, а затем пересоздайте контейнер. Удаление ключа из файла важно, так как страница администратора записывает настройки именно туда, и то, что находится в config.json, имеет приоритет над переменными окружения. Удаление только переменной оставит страницу доступной.

Закройте регистрацию до того, как кто-либо обнаружит домен

SIGNUPS_ALLOWED=false
SIGNUPS_VERIFY=true
SHOW_PASSWORD_HINT=false

SIGNUPS_ALLOWED по умолчанию имеет значение true. Оставьте его таким, и любой, кто зайдет на ваш домен, получит учетную запись, а его данные будут храниться в той же db.sqlite3, что и ваши. Установите значение false и добавляйте пользователей через приглашения со страницы администратора; SMTP доставит письмо с приглашением, а если SMTP не настроен, сервер сохранит приглашение для этого адреса. INVITATIONS_ALLOWED также по умолчанию имеет значение true, что позволяет администраторам организации приглашать других пользователей. Это допустимо, если вы доверяете своим пользователям, и должно быть false на инстансе с одним пользователем. Если регистрация должна быть разрешена только для определенных доменов, SIGNUPS_DOMAINS_WHITELIST=example.com является более ограниченным вариантом, чем открытая регистрация, но значительно менее безопасным, чем приглашения.

SHOW_PASSWORD_HINT по умолчанию имеет значение false, и его следует оставить таким. Если эта настройка включена, а SMTP не сконфигурирован, ввод корректного адреса электронной почты в форму входа вернет подсказку к мастер-паролю этой учетной записи. Это приведет к утечке подсказки и подтвердит существование адреса в системе.

Если ваш инстанс работал с открытой регистрацией в течение любого времени, откройте страницу администратора и изучите список пользователей, прежде чем делать вывод, что вы являетесь единственным владельцем учетной записи.

Порт, который вы не собирались публиковать

Docker-образ ожидает соединения на порту 80 внутри контейнера. При установке на «голое железо» по умолчанию используется ROCKET_PORT=8000. В документации команда запуска публикует его следующим образом:

--publish 127.0.0.1:8000:80

Префикс 127.0.0.1: — это ключевой момент. Если указать -p 8000:80, Docker привяжет порт к 0.0.0.0, записывая правила DNAT (destination network address translation) в таблицу nat. Эти правила обрабатываются раньше цепочек filter, которыми управляет ufw, поэтому ufw status сообщает, что порт закрыт, хотя он успешно отвечает на запросы из интернета. Подробности механизма описаны в руководстве по обходу ufw портами Docker.

Проверьте, что именно прослушивает порт:

sudo ss -tlnp | grep 8000

Корректный результат — одна строка, привязанная к 127.0.0.1:8000. Строка, привязанная к 0.0.0.0:8000, означает, что хранилище доступно напрямую. Исправьте маппинг и пересоздайте контейнер, так как привязка порта фиксируется при создании контейнера, и docker compose restart её не изменит:

docker compose up -d --force-recreate

В старых руководствах встречается ещё один порт: 3012, отдельный порт для WebSocket. Поддержка этого порта была удалена в Vaultwarden 1.31.0, так как трафик уведомлений был перенесён на основной HTTP-порт. Параметры WEBSOCKET_ENABLED и WEBSOCKET_PORT считаются устаревшими начиная с версии 1.29.0 и игнорируются. Текущий переключатель — ENABLE_WEBSOCKET, значение по умолчанию для которого true. Если ваш межсетевой экран или compose-файл всё ещё открывают порт 3012, закройте его.

Завершение TLS на обратном прокси, а не в Rocket

Vaultwarden может самостоятельно обеспечивать TLS (transport layer security) через Rocket, свой веб-фреймворк, однако разработчики проекта не рекомендуют делать это в production. Встроенная реализация TLS в Rocket не поддерживает строгий SNI (server name indication), поэтому рекомендации по безопасности предписывают обращаться к экземпляру приложения по имени хоста, а не по IP-адресу. Диапазоны публичных IP-адресов постоянно сканируются, и хранилище, отвечающее на прямой IP-адрес, будет обнаружено.

Важные части блока сервера nginx:

client_max_body_size 525M;

location / {
  proxy_pass http://127.0.0.1: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;
  proxy_set_header Upgrade $http_upgrade;
  proxy_set_header Connection $connection_upgrade;
}

По умолчанию в nginx параметр client_max_body_size равен 1m, поэтому без переопределения запросы с телом больше этого лимита будут завершаться ошибкой. nginx возвращает клиенту HTTP 413 и записывает в лог client intended to send too large body: ... bytes; отклоненный файл не доходит до Vaultwarden. Заголовки Upgrade и Connection обеспечивают передачу рукопожатия WebSocket в /notifications/hub. Если их убрать, хранилище продолжит работать, но уведомления через WebSocket перестанут приходить в браузерные и десктопные клиенты; мобильные клиенты используют отдельно настроенные push-уведомления.

Конфигурация Caddy короче, и он самостоятельно получает сертификат:

vw.example.com {
  reverse_proxy 127.0.0.1:8000 {
    header_up X-Real-IP {remote_host}
  }
}

Затем укажите это в настройках Vaultwarden:

DOMAIN=https://vw.example.com
IP_HEADER=X-Real-IP

Параметр IP_HEADER по умолчанию уже установлен в X-Real-IP, поэтому задача сводится к тому, чтобы прокси действительно передавал этот заголовок. Vaultwarden принимает заголовок только от адресов, указанных в IP_HEADER_TRUSTED_PROXIES, значение по умолчанию — local: любой неглобальный адрес, что охватывает прокси на том же хосте или в той же сети контейнеров. Прокси, подключающийся с публичного адреса, должен быть добавлен в этот список. Если заголовок отсутствует или поступает с недоверенного адреса, каждая запись в логе и каждый лимит попыток входа будут привязаны к адресу прокси. Это означает, что неудачные попытки одного злоумышленника будут засчитаны как ошибки для всех пользователей экземпляра. Если вы используете IP_HEADER=X-Forwarded-For, версия 1.37.4 берет самый правый адрес, который не является доверенным прокси, поэтому перечислите все прокси в цепочке, включая CDN перед nginx. Установите DOMAIN на реальный https URL, так как Vaultwarden использует его для формирования ссылок на приглашения и восстановление аккаунта, а ключи безопасности WebAuthn привязаны к этому источнику.

Деталь, которую часто упускают: WebSocket-соединение передает токен сессии в строке запроса как /notifications/hub?access_token=[JWT]. Он попадает в access log вашего прокси в открытом виде. Исключите параметр access_token из формата логов или убедитесь, что эти логи не передаются в системы, которые вы не контролируете.

Блокировка перебора паролей на эндпоинте входа

Ограничения частоты запросов (rate limits) включены по умолчанию (LOGIN_RATELIMIT_SECONDS=60, LOGIN_RATELIMIT_MAX_BURST=10). Они замедляют атакующего, но не останавливают его. fail2ban справляется с этой задачей, но ему необходимо получать информацию о неудачных попытках входа в Vaultwarden. В Docker самый простой способ — использовать файл журнала, однако Vaultwarden не записывает его по умолчанию:

LOG_FILE=/data/vaultwarden.log
LOG_LEVEL=info
EXTENDED_LOGGING=true

Неудачная попытка входа с паролем создает строку следующего вида, и именно по ней ваш фильтр должен выполнять сопоставление:

[2026-08-07 09:14:22.000][vaultwarden::api::identity][ERROR] Username or password is incorrect. Try again. IP: 203.0.113.10. Username: user@example.com.

Создайте фильтр в /etc/fail2ban/filter.d/vaultwarden.local:

[INCLUDES]
before = common.conf

[Definition]
failregex = ^.*?Username or password is incorrect\. Try again\. IP: <ADDR>\. Username:.*$
ignoreregex =

И добавьте jail в /etc/fail2ban/jail.d/vaultwarden.local:

[vaultwarden]
enabled = true
backend = pyinotify
port = 80,443
filter = vaultwarden
banaction = %(banaction_allports)s
logpath = /vw-data/vaultwarden.log
maxretry = 3
bantime = 14400
findtime = 14400

Если Vaultwarden работает как systemd-сервис, а не в контейнере, вы можете пропустить LOG_FILE: в вики проекта fail2ban предлагается читать журнал с помощью backend = systemd и использовать journalmatch для юнита Vaultwarden вместо logpath.

Если вы оставили доступ к странице администратора, добавьте второй jail, чей failregex будет ^.*Invalid admin token\. IP: <ADDR>.*$, так как ошибки входа администратора записываются с другим сообщением, и фильтр входа их не увидит. Затем проверьте работу:

sudo systemctl restart fail2ban
sudo fail2ban-client status vaultwarden

Рабочий jail отображает ваш файл журнала в поле File list и сообщает Currently failed: 0. Введите неверный пароль три раза из другой сети: счетчик должен увеличиться, а затем адрес появится в Banned IP list. Если счетчик не меняется, наиболее вероятная причина — logpath: это должен быть путь к файлу на хосте, а не путь /data/... внутри контейнера. Вторая частая причина — отсутствие или недоверие к X-Real-IP, из-за чего все блокировки применяются к вашему прокси. Остальная часть настройки, включая jail для SSH, который у вас уже должен быть запущен, описана в руководстве по fail2ban для Ubuntu 24.04.

Мастер-пароль по-прежнему защищает всю систему

Шифрование на стороне клиента означает, что мастер-пароль защищает симметричный ключ пользователя. Короткий мастер-пароль на экземпляре, базу данных которого скопировал злоумышленник, ничем не защищен в рамках данного поста, так как атакующий будет атаковать эту копию офлайн с любой скоростью, которую позволяет его оборудование. Никакие серверные настройки не влияют на машину злоумышленника.

PASSWORD_ITERATIONS=600000 легко истолковать неверно. Этот параметр задает количество итераций для серверного хеша от хеша авторизации, который отправляет клиент, а шаблон конфигурации проекта гласит, что измененное значение применяется к существующим пользователям при их следующем входе в систему. Он не затрагивает KDF на стороне клиента — именно эта настройка определяет сложность офлайн-атаки на хранилище. Она относится к каждой учетной записи и изменяется в разделе Settings, Security, Keys веб-хранилища, что приводит к повторному шифрованию ключа. Документация Bitwarden гласит, что клиенты начиная с версии 2026.2.1 автоматически повышают настройки PBKDF2 ниже 600,000 итераций при входе пользователя в систему или разблокировке с помощью мастер-пароля. По состоянию на 10 октября 2026 года это поведение не подтверждено для сервера Vaultwarden, и оно никогда не меняет настройки Argon2id. Поэтому пользователь, зарегистрировавшийся много лет назад, может по-прежнему использовать старые, более низкие настройки KDF. Проверьте это и сообщите им, так как сервер не может сделать это за них.

Затем включите двухфакторную аутентификацию для каждой учетной записи. Она не защищает зашифрованные данные, так как не участвует в шифровании хранилища. Однако она предотвращает ситуацию, когда украденного пароля достаточно для входа и синхронизации копии. При настроенной электронной почте параметр REQUIRE_DEVICE_EMAIL=true делает обязательным отправку письма при входе с нового устройства: если отправка не удалась, вход блокируется. Если почтовый сервис полностью отключен, эта настройка не блокирует входы с новых устройств.

Резервные копии — слабое место self-hosted хранилищ

tar czf папки с данными, оставленная в домашнем каталоге на том же VPS, обесценивает все предыдущие шаги. Этот архив содержит db.sqlite3 с зашифрованными данными всех пользователей, rsa_key.pem, позволяющий подделывать сессии входа, и config.json с настроенным значением токена администратора и паролем SMTP. Согласно инструкциям Argon2, сохраняется хеш пароля администратора; пароль SMTP остается в открытом виде. Доступ на чтение к этому единственному файлу раскрывает метаданные учетных записей, секреты сервера и зашифрованные данные хранилища.

Существуют два правила. Переносите архив за пределы сервера. Шифруйте его перед отправкой.

Также существует проблема целостности данных. Копирование db.sqlite3 с помощью cp во время работы сервиса может привести к созданию поврежденного файла, который невозможно будет открыть, и вы узнаете об этом только при попытке восстановления. Используйте встроенную функцию создания снимков SQLite:

sqlite3 /vw-data/db.sqlite3 ".backup '/tmp/vw-db-backup.sqlite3'"

Процесс восстановления, который почти никто не тестирует, описан в руководстве по резервному копированию и восстановлению Vaultwarden.

От чего вы отказываетесь при использовании облачного Bitwarden

Честный подход. Облачный сервис Bitwarden обслуживают специалисты, для которых это основная работа, а результаты сторонних аудитов публикуются в открытом доступе. При самостоятельном хостинге вы берете на себя ответственность за график установки обновлений.

Vaultwarden выпускает исправления безопасности как обычные релизы, и они выходят часто. По состоянию на 2 ноября 2026 года, согласно ленте релизов проекта, актуальной версией является 1.37.5, опубликованная 1 ноября 2026 года. В описании релиза упоминаются два уведомления о безопасности уровня Medium, и настоятельно рекомендуется выполнить обновление как можно скорее. Также это обновление требуется для веб-хранилища версии 2026.7.1 и новее, чтобы включать или выключать методы двухэтапной аутентификации, а для версий 2026.9.0 и новее — для получения доступа к учетной записи через экстренный доступ. Предыдущий релиз, 1.37.4, опубликованный 5 октября 2026 года, содержал семь уведомлений о безопасности, наиболее серьезное из которых имело рейтинг High. Это был четвертый релиз после 1.37.0, вышедшего 24 июля 2026 года: 1.37.1 последовал 29 июля, 1.37.2 — 22 августа (требуется для клиентов версии 2026.8.0 и новее), а 1.37.3 — 13 сентября, который отзывает токены запоминания 2FA при смене учетных данных или настроек 2FA, а также ограничивает частоту запросов к конечным точкам prelogin и auth. Если вы управляете организациями с администраторами, которым не доверяете полностью, в примечаниях к 1.37.4 также рекомендуется сменить API-ключ каждой организации после обновления. Версия 1.37.4 также меняет адрес, считываемый из X-Forwarded-For, что описано в разделе о reverse proxy выше. Экземпляр, который вы настроили год назад и забыли, работает на коде годовой давности. Тег latest сам по себе не помогает: запущенный контейнер продолжает использовать образ, с которого он был запущен, пока вы не выполните docker compose pull и не пересоздадите его. Настройте автоматическую установку обновлений в Ubuntu для пакетов хоста, а обновление контейнера добавьте в календарь с напоминанием, которое вы действительно будете просматривать.

Вывод, который должен сделать честный читатель: криптография здесь основана на архитектуре Bitwarden и она надежна, но операционные риски полностью переходят на вас. Если вы устанавливаете обновления и делаете резервные копии в другом месте, экземпляр Vaultwarden на VPS под вашим контролем — это приемлемое место для хранения паролей. Если эти две привычки не для вас, оплатите облачный сервис и уделите внимание другим задачам. Сравнение функций доступно в сравнении Vaultwarden с самостоятельно развернутым Bitwarden.

Укрепление безопасности хоста под контейнером

Vaultwarden — это один процесс на сервере Linux, и пользователь root на этом сервере может прочитать /vw-data независимо от настроек самого приложения. Запускайте контейнер от имени непривилегированного пользователя с помощью user: "1000:1000" в файле compose, установив соответствующие права владения на папку с данными, и монтируйте всё, во что контейнер не должен записывать данные, в режиме только для чтения с помощью :ro. Затем закройте доступ извне: в укреплении безопасности SSH на VPS описаны вход только по ключам и отключение аутентификации по паролю, что позволяет остановить типичные атаки, которые обходят все вышеперечисленные меры.

FAQ

Может ли кто-то прочитать мои пароли, если украдет базу данных Vaultwarden?

Не напрямую. Каждый элемент хранилища шифруется на стороне клиента с помощью случайно сгенерированного ключа, который защищен симметричным ключом пользователя или организации; ключ, производный от пароля, защищает симметричный ключ пользователя. db.sqlite3 содержит зашифрованное содержимое хранилища вместе с метаданными учетной записи в открытом виде. Злоумышленник сразу получает адрес электронной почты и подсказку к паролю для каждой учетной записи, настройки KDF, метаданные входа и устройств, а также секреты TOTP для входа в таблице twofactor, которые хранятся в незашифрованном виде, так как сервер должен вычислять ожидаемый код. Также злоумышленник может неограниченное время атаковать зашифрованные данные хранилища в офлайн-режиме, поэтому длина мастер-пароля является решающим фактором безопасности.

Стоит ли использовать ADMIN_TOKEN или лучше полностью отключить страницу администратора?

Отключите её, если есть возможность, так как большинству инстансов она нужна один раз для настройки SMTP и приглашения пользователей, а затем больше не требуется. Чтобы отключить её, не задавайте ни ADMIN_TOKEN, ни DISABLE_ADMIN_TOKEN, удалите любой ключ "admin_token" из config.json, а затем пересоздайте контейнер. Удаления только переменной окружения недостаточно, так как настройки, записанные через страницу администратора, хранятся в config.json и имеют приоритет. Если вы все же оставляете страницу, сохраните токен в виде хеша Argon2, созданного с помощью vaultwarden hash, вместо случайной строки в открытом виде, и установите ADMIN_RATELIMIT_MAX_BURST=3.

Мой ADMIN_TOKEN верный, но /admin его отклоняет. В чем проблема?

Почти всегда дело в интерполяции $. Строка Argon2 PHC содержит несколько символов $, и Docker Compose раскрывает их как переменные внутри блока docker-compose.yml environment:, поэтому контейнер получает искаженное значение, хотя в вашем файле оно выглядит правильно. Удвойте каждый $ до $$ в файле compose или перенесите значение в файл .env, заключив его в одинарные кавычки, где экранирование не требуется. После этого пересоздайте контейнер, так как изменения переменных окружения не применяются при простом перезапуске.

Нужно ли мне по-прежнему открывать порт 3012 для уведомлений?

Нет. Поддержка WebSocket-трафика на порту 3012 была удалена в Vaultwarden 1.31.0, так как уведомления были перенесены на основной HTTP-порт, а WEBSOCKET_ENABLED и WEBSOCKET_PORT считаются устаревшими с версии 1.29.0 и игнорируются. Текущая настройка — ENABLE_WEBSOCKET, которая по умолчанию имеет значение true. Закройте порт 3012 в брандмауэре и удалите его из файла compose, затем убедитесь, что ваш reverse proxy передает заголовки Upgrade и Connection, так как браузерные и десктопные WebSocket-уведомления зависят от них. Мобильные клиенты используют отдельно настраиваемые push-уведомления.

Была ли эта статья полезной?