Vaultwarden est-il sécurisé ? Les points à durcir
Vaultwarden chiffre le coffre côté client, mais conserve les métadonnées en clair. Le vrai risque vient du token admin et de votre fichier de sauvegarde.
Vaultwarden est-il sécurisé ? La réponse courte
Vaultwarden est sécurisé à l’endroit le plus important : chaque élément du coffre est chiffré sur votre appareil avant d’être transmis au serveur. Le serveur stocke le contenu chiffré du coffre avec les métadonnées de compte en clair. Une personne qui copie l’intégralité de la base de données doit encore disposer des clés de chiffrement du coffre pour en lire le contenu, mais elle obtient immédiatement les adresses e-mail des comptes et les indices de mot de passe.
Cette réponse recouvre plusieurs aspects, et les points faibles sont ceux que vous configurez. Un panneau d’administration protégé par un token facile à deviner. Un port de conteneur publié sur l’ensemble d’Internet. Un config.json en clair. Une archive tar de sauvegarde stockée dans le répertoire personnel sur le même serveur. Aucun de ces problèmes ne relève de la cryptographie. Tous expliquent pourquoi des coffres auto-hébergés sont vidés.
Tout ce qui suit suppose que l’installation fonctionne. Si ce n’est pas encore le cas, commencez par l’installer en suivant le guide d’installation de Vaultwarden sur un VPS, puis revenez parcourir cette liste dans l’ordre.
Ce que le serveur stocke réellement
Vaultwarden implémente le modèle de données de Bitwarden. Le nom, le nom d’utilisateur, le mot de passe, les notes et les URI d’un élément de coffre sont chiffrés côté client avec une clé d’élément générée aléatoirement avant l’envoi de toute requête. Cette clé est protégée par la clé symétrique de l’utilisateur ou de l’organisation ; la clé dérivée du mot de passe protège la clé symétrique de l’utilisateur. Le contenu des pièces jointes utilise une clé de pièce jointe distincte, protégée par la clé de l’élément. Le serveur reçoit des données opaques auxquelles est associé un UUID (identifiant universellement unique).
Certaines données ne sont pas chiffrées. Vous devez savoir exactement lesquelles :
- L’adresse e-mail de votre compte et l’indication de mot de passe principal, en clair.
- Les paramètres de votre KDF (fonction de dérivation de clé) et le sel, car le client en a besoin pour reconstruire la clé lors de la prochaine connexion.
- Un hash côté serveur du hash du mot de passe principal envoyé par le client, utilisé pour authentifier la connexion elle-même.
- Les métadonnées : appartenance à une organisation, noms des appareils, heures de dernière connexion.
- Le secret TOTP utilisé pour la connexion à deux facteurs avec une application d’authentification. Il se trouve en clair dans la table
twofactor, car le serveur doit calculer le code attendu pour le comparer au vôtre. Il ne s’agit pas du même secret TOTP (mot de passe à usage unique basé sur le temps) que celui que vous stockez dans un élément de coffre : celui-ci est chiffré comme n’importe quel autre champ.
Le dossier de données est peu volumineux. Avec une installation Docker, il s’agit du chemin que vous avez monté sur /data.
sudo ls -l /vw-data/db.sqlite3 contient presque tout l’état de l’application. attachments/ contient les fichiers téléversés dans des répertoires nommés selon leur UUID, en dehors des tables de la base de données. sends/ contient les pièces jointes de Send et est censé être temporaire. icon_cache/ peut être supprimé sans conséquence. rsa_key.pem et les fichiers associés signent les JWT (JSON Web Tokens) des utilisateurs connectés. Une copie de cette clé privée permet donc de falsifier une session de connexion au coffre. config.json stocke les paramètres enregistrés depuis la page d’administration, notamment les identifiants SMTP en clair et la valeur configurée du token d’administration. En suivant les instructions relatives à Argon2 ci-dessous, vous stockez le hash du token d’administration plutôt que le mot de passe en clair.
Le modèle de menace pratique concerne donc l’accès au système de fichiers, et non la cryptographie réseau. Un accès en lecture à ce seul répertoire donne accès à l’adresse e-mail de chaque utilisateur, à ses secrets de 2FA de connexion, à une clé permettant de falsifier des sessions et à une copie hors ligne de chaque coffre, qui peut être attaquée à loisir. Toutes les étapes ci-dessous visent à empêcher tout accès à ce répertoire.
Corriger d’abord le token d’administration
/admin est un panneau de contrôle complet : liste des utilisateurs, invitations, suppression et réglages d’exécution. Il est protégé par un seul secret partagé, sans autre protection. Il n’y a pas de nom d’utilisateur ni de double authentification par utilisateur.
Les anciens guides vous indiquent de générer ADMIN_TOKEN avec openssl rand -base64 48. Cela fonctionne, mais le secret reste en clair partout où vous le configurez. Vaultwarden accepte également une chaîne PHC Argon2 (Password Hashing Competition), ce qui permet de stocker un hash à la place. Générez-en une avec un conteneur en cours d’exécution :
docker exec -it vaultwarden /vaultwarden hashOu sans modifier le conteneur en cours d’exécution :
docker run --rm -it vaultwarden/server /vaultwarden hashLa commande demande deux fois le mot de passe, puis affiche une ligne qui commence par $argon2id$. Avec une installation bare metal, exécutez ./vaultwarden hash. Si vous préférez utiliser directement la CLI argon2, le projet documente les paramètres minimaux de l’OWASP :
echo -n 'MySecretPassword' | argon2 "$(openssl rand -base64 32)" -e -id -k 19456 -t 2 -p 1Voici maintenant le piège qui peut vous faire perdre une heure. Une chaîne PHC contient beaucoup de caractères $, et Docker Compose interprète $ comme une interpolation de variable. Si vous la collez sans échappement dans un bloc environment:, la valeur transmise au conteneur est altérée. /admin rejette alors un token pourtant correct. Deux méthodes sûres existent. Dans docker-compose.yml, doublez chaque $ :
environment:
ADMIN_TOKEN: $$argon2id$$v=19$$m=19456,t=2,p=1$$UUZxK1FZMkZoRHFQRlVrTXZvS0E3bHpNQW55c2dBN2NORzdsa0Nxd1JhND0$$cUoId+JBUsJutlG4rfDZayExfjq4TCt48aBc9qsc3UIDans un fichier .env, aucun échappement n’est nécessaire, mais utilisez des guillemets simples :
ADMIN_TOKEN='$argon2id$v=19$m=65540,t=3,p=4$MmeKRnGK5RW5mJS7h3TOL89GrpLPXJPAtTK8FTqj9HM$DqsstvoSAETl9YhnsXbf43WeaUwJC6JhViIvuPoig78'Limitez ensuite le débit du panneau et réduisez la durée de sa session :
ADMIN_RATELIMIT_SECONDS=300
ADMIN_RATELIMIT_MAX_BURST=3
ADMIN_SESSION_LIFETIME=20Cela autorise un burst de trois requêtes de connexion d’administration par adresse IP cliente, puis rétablit le quota à raison d’une requête toutes les cinq minutes. Les mots de passe corrects et incorrects sont comptabilisés, car le limiteur s’exécute avant la vérification du mot de passe. Les requêtes qui dépassent la limite reçoivent le code HTTP 429 avec Too many requests, try again later.. La session d’administration expire 20 minutes après la connexion, que vous utilisiez encore le panneau ou non, car l’activité ne prolonge pas sa durée.
Mieux encore : désactivez la page. La plupart des instances en ont besoin une seule fois, pour configurer SMTP et inviter les premiers utilisateurs, puis plus jamais. Pour la désactiver, ne définissez ni ADMIN_TOKEN ni DISABLE_ADMIN_TOKEN, supprimez toute clé "admin_token" de config.json, puis recréez le conteneur. La suppression de la clé dans le fichier est importante, car la page d’administration y écrit ses réglages, et les valeurs présentes dans config.json sont prioritaires sur celles de l’environnement. Supprimer uniquement la variable laisse la page accessible.
Fermez les inscriptions avant que quelqu’un ne trouve le domaine
SIGNUPS_ALLOWED=false
SIGNUPS_VERIFY=true
SHOW_PASSWORD_HINT=falseSIGNUPS_ALLOWED vaut true par défaut. Laissez cette valeur et toute personne qui accède à votre domaine peut créer un compte. Ses données sont alors stockées dans le même db.sqlite3 que les vôtres. Définissez cette option sur false et ajoutez les utilisateurs par invitation depuis la page d’administration. SMTP envoie l’e-mail d’invitation. Sans SMTP, le serveur enregistre une invitation pour cette adresse. INVITATIONS_ALLOWED vaut également true par défaut et permet aux administrateurs d’organisation d’inviter d’autres personnes. Cela convient si vous faites confiance à vos utilisateurs. Sur une instance utilisée par une seule personne, cette option doit rester sur false. Si seules certaines adresses de domaine doivent pouvoir s’inscrire, SIGNUPS_DOMAINS_WHITELIST=example.com est plus restrictif que les inscriptions ouvertes, mais nettement moins sûr que les invitations.
SHOW_PASSWORD_HINT vaut false par défaut et doit le rester. Lorsque cette option est activée et qu’aucun SMTP n’est configuré, la saisie d’une adresse e-mail valide dans le formulaire de connexion renvoie l’indice du mot de passe maître du compte. Cela divulgue l’indice et confirme que l’adresse existe.
Si votre instance a autorisé les inscriptions ouvertes, même pendant une courte période, ouvrez la page d’administration et consultez la liste des utilisateurs avant de supposer que vous êtes le seul compte présent.
Le port que vous ne vouliez pas publier
L’image Docker écoute sur le port 80 à l’intérieur du conteneur. Une installation bare metal utilise par défaut ROCKET_PORT=8000. La commande d’exécution documentée le publie ainsi :
--publish 127.0.0.1:8000:80Le préfixe 127.0.0.1: est essentiel. Si vous écrivez plutôt -p 8000:80, Docker se lie à 0.0.0.0 et ajoute pour cela des règles DNAT (destination network address translation) dans la table nat. Ces règles sont évaluées avant les chaînes filter gérées par ufw. Ainsi, ufw status indique que le port est refusé alors que celui-ci répond bien aux connexions venant d’Internet. Le mécanisme complet est expliqué dans le guide sur les ports Docker qui contournent ufw.
Vérifiez ce qui écoute réellement :
sudo ss -tlnp | grep 8000Un résultat correct contient une seule ligne liée à 127.0.0.1:8000. Une ligne liée à 0.0.0.0:8000 signifie que le coffre est exposé directement. Corrigez le mapping, puis recréez le conteneur, car une liaison de port est définie lors de la création du conteneur et docker compose restart ne la modifiera pas :
docker compose up -d --force-recreateUn autre port figure encore dans d’anciens guides : 3012, le port WebSocket séparé. Sa prise en charge a été supprimée dans Vaultwarden 1.31.0, car le trafic de notification est passé sur le port HTTP principal. WEBSOCKET_ENABLED et WEBSOCKET_PORT sont obsolètes depuis la version 1.29.0 et sont ignorés. Le paramètre actuel est ENABLE_WEBSOCKET, dont la valeur par défaut est true. Si votre pare-feu ou votre fichier compose ouvre encore le port 3012, fermez-le.
Terminez TLS sur un reverse proxy, pas dans Rocket
Vaultwarden peut gérer lui-même TLS (transport layer security) via Rocket, son framework web, mais le projet déconseille cette configuration en production. La prise en charge TLS intégrée de Rocket ne fournit pas un support strict de SNI (server name indication). C’est également pourquoi les recommandations de hardening préconisent d’accéder à votre instance par son nom d’hôte, et jamais par une adresse IP seule. Les plages d’adresses IP publiques sont analysées en permanence. Un coffre-fort qui répond sur une adresse IP finit donc par être découvert.
Les éléments importants d’un server block nginx sont les suivants :
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;
}Par défaut, nginx règle client_max_body_size sur 1m. Sans surcharge, seuls les corps de requête qui dépassent cette limite échouent. nginx renvoie HTTP 413 au client et journalise client intended to send too large body: ... bytes ; le fichier rejeté n’atteint pas Vaultwarden. Les en-têtes Upgrade et Connection transmettent la négociation WebSocket à /notifications/hub. Si vous les supprimez, le coffre-fort continue de fonctionner, mais les notifications WebSocket ne parviennent plus aux clients web et desktop. Les clients mobiles utilisent des notifications push configurées séparément.
Caddy utilise une configuration plus courte et obtient lui-même le certificat :
vw.example.com {
reverse_proxy 127.0.0.1:8000 {
header_up X-Real-IP {remote_host}
}
}Indiquez ensuite cette configuration à Vaultwarden :
DOMAIN=https://vw.example.com
IP_HEADER=X-Real-IPIP_HEADER utilise déjà X-Real-IP par défaut. Il faut donc vérifier que le proxy définit effectivement cet en-tête. Vaultwarden n’accepte également cet en-tête que depuis les adresses répertoriées dans IP_HEADER_TRUSTED_PROXIES, qui vaut local par défaut : toute adresse qui n’est pas globale, ce qui couvre un proxy exécuté sur le même hôte ou sur le même réseau de conteneurs. Un proxy qui se connecte depuis une adresse publique doit être ajouté à cette liste. Si l’en-tête est absent ou provient d’une adresse non approuvée, chaque ligne de journal et chaque limite de débit de connexion utilise l’adresse du proxy lui-même. Les échecs d’un seul attaquant sont alors comptabilisés pour tous les utilisateurs de l’instance. Si vous utilisez IP_HEADER=X-Forwarded-For à la place, la version 1.37.4 utilise l’adresse la plus à droite qui ne correspond pas à un proxy approuvé. Répertoriez donc tous les proxies de la chaîne, y compris un CDN placé devant nginx. Définissez également DOMAIN sur l’URL https réelle. Vaultwarden construit les liens d’invitation et de récupération de compte à partir de cette valeur, et les clés de sécurité WebAuthn sont liées à cette origine.
Un détail est souvent oublié : la connexion WebSocket transmet le jeton de session dans la chaîne de requête, sous la forme /notifications/hub?access_token=[JWT]. Ce jeton apparaît donc en clair dans le journal d’accès de votre proxy. Masquez le paramètre access_token dans le format du journal, ou vérifiez que ces journaux ne sont envoyés nulle part où vous n’exercez pas de contrôle.
Bannir le brute force sur le point de connexion
Les limites de débit sont activées par défaut (LOGIN_RATELIMIT_SECONDS=60, LOGIN_RATELIMIT_MAX_BURST=10). Elles ralentissent un attaquant, mais ne l’arrêtent pas. fail2ban le fait, mais il doit pouvoir lire quelque part les échecs de connexion de Vaultwarden. Avec Docker, la solution la plus simple consiste à utiliser un fichier journal, car Vaultwarden n’en écrit pas par défaut :
LOG_FILE=/data/vaultwarden.log
LOG_LEVEL=info
EXTENDED_LOGGING=trueUn échec de connexion par mot de passe produit une ligne de cette forme. C’est cette chaîne que votre filtre doit rechercher :
[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.Écrivez le filtre dans /etc/fail2ban/filter.d/vaultwarden.local :
[INCLUDES]
before = common.conf
[Definition]
failregex = ^.*?Username or password is incorrect\. Try again\. IP: <ADDR>\. Username:.*$
ignoreregex =Puis la jail dans /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 = 14400Si Vaultwarden s’exécute comme un service systemd plutôt que dans un conteneur, vous pouvez ignorer LOG_FILE : le wiki fail2ban du projet lit le journal avec backend = systemd et utilise un journalmatch sur l’unité Vaultwarden à la place de logpath.
Si vous avez conservé la page d’administration, ajoutez une seconde jail dont le failregex est ^.*Invalid admin token\. IP: <ADDR>.*$, car les échecs d’administration sont consignés avec un message différent et le filtre de connexion ne les détectera jamais. Vérifiez ensuite votre configuration :
sudo systemctl restart fail2ban
sudo fail2ban-client status vaultwardenUne jail fonctionnelle liste votre fichier journal dans File list et indique Currently failed: 0. Saisissez trois fois un mot de passe incorrect depuis un autre réseau : ce compteur augmente, puis l’adresse apparaît dans Banned IP list. Si le compteur ne bouge jamais, la cause habituelle est logpath : il doit s’agir du chemin du fichier sur l’hôte, et non du chemin /data/... à l’intérieur du conteneur. L’autre cause fréquente est un X-Real-IP manquant ou non fiable, ce qui fait que chaque bannissement cible votre propre proxy. Le reste de la configuration, notamment la jail SSH que vous devriez déjà exécuter, figure dans le guide fail2ban pour Ubuntu 24.04.
Le mot de passe principal reste l’ensemble du système
Le chiffrement côté client signifie que le mot de passe principal protège la clé symétrique de l’utilisateur. Un mot de passe principal court sur une instance dont la base de données a été copiée par un attaquant n’est protégé par aucun élément de cet article, car l’attaquant effectue ses essais hors ligne sur cette copie, à la vitesse permise par son matériel. Aucun paramètre du serveur ne s’applique à la machine de l’attaquant.
PASSWORD_ITERATIONS=600000 est facile à mal interpréter. Il définit le nombre d’itérations du hash côté serveur appliqué au hash de connexion envoyé par le client, et le modèle de configuration du projet indique qu’une valeur modifiée est appliquée aux utilisateurs existants lors de leur prochaine connexion. Ce paramètre ne modifie pas le KDF côté client, qui détermine le coût d’une attaque hors ligne contre le coffre. Ce réglage appartient à chaque compte. Il se modifie dans Settings, Security, Keys du coffre web, ce qui rechiffre la clé. La documentation de Bitwarden indique que ses clients depuis 2026.2.1 augmentent automatiquement un réglage PBKDF2 inférieur à 600,000 itérations lorsque l’utilisateur se connecte ou déverrouille le coffre avec le mot de passe principal. Au 10 octobre 2026, ce comportement n’est pas confirmé avec un serveur Vaultwarden et il ne modifie jamais les réglages Argon2id. Une personne inscrite il y a plusieurs années peut donc encore utiliser un réglage KDF plus ancien et moins élevé. Vérifiez ce réglage et informez les utilisateurs concernés, car le serveur ne peut pas le faire à leur place.
Activez ensuite l’authentification à deux facteurs pour chaque compte. Elle ne protège pas le texte chiffré, car elle n’intervient pas dans le chiffrement du coffre. Elle empêche toutefois un mot de passe volé de suffire pour se connecter et synchroniser une copie. Lorsque l’e-mail est configuré, REQUIRE_DEVICE_EMAIL=true rend obligatoire l’e-mail de connexion depuis un nouvel appareil : si l’envoi échoue, la connexion échoue. Si le service de messagerie est entièrement désactivé, ce réglage ne bloque pas les connexions depuis de nouveaux appareils.
Les sauvegardes sont le point faible des coffres auto-hébergés
Un tar czf du dossier de données, laissé dans un répertoire personnel sur le même VPS, annule toutes les étapes précédentes. Cette archive contient db.sqlite3 avec le texte chiffré de chaque utilisateur, rsa_key.pem qui permet de falsifier les sessions de connexion, et config.json avec la valeur configurée du token d’administration et le mot de passe SMTP. Suivre les instructions Argon2 stocke un hash du mot de passe administrateur ; le mot de passe SMTP reste en clair. Un accès en lecture à ce seul fichier expose les métadonnées des comptes, les secrets du serveur et les données chiffrées du coffre.
Deux règles suffisent. Sortez l’archive du serveur. Chiffrez-la avant de la transférer.
Il y a aussi un problème d’intégrité. Copier db.sqlite3 avec cp pendant que le service fonctionne peut produire un fichier en cours d’écriture qui ne s’ouvrira pas. Vous ne le découvrirez qu’au moment de la restauration. Utilisez plutôt le snapshot intégré à SQLite :
sqlite3 /vw-data/db.sqlite3 ".backup '/tmp/vw-db-backup.sqlite3'"La restauration, que presque personne ne teste, est couverte dans le guide de sauvegarde et de restauration de Vaultwarden.
Ce que vous abandonnez par rapport à Bitwarden hébergé
Bilan honnête. Le service hébergé de Bitwarden est exploité par des personnes dont le métier à temps plein consiste à l’administrer, avec des audits tiers publiés. L’auto-hébergement remplace cela par votre propre cadence d’application des correctifs.
Vaultwarden publie les correctifs de sécurité dans des releases ordinaires, et celles-ci paraissent souvent. Vérifiée le 2 novembre 2026 dans le flux des releases du projet, la release actuelle est la 1.37.5, publiée le 1 novembre 2026. Ses notes couvrent deux avis de sécurité de niveau Medium et recommandent vivement de mettre à jour dès que possible. Cette version est également requise à partir du web vault 2026.7.1 pour activer ou désactiver les méthodes de connexion en deux étapes, et à partir de 2026.9.0 pour prendre le contrôle d’un compte via l’accès d’urgence. La release précédente, 1.37.4, publiée le 5 octobre 2026, couvrait sept avis de sécurité, dont le plus grave était classé High. Il s’agissait de la quatrième release depuis la 1.37.0 du 24 juillet 2026 : la 1.37.1 a suivi le 29 juillet, la 1.37.2 le 22 août (requise pour les clients en version 2026.8.0 et ultérieure), et la 1.37.3 le 13 septembre, qui révoque les jetons de mémorisation de la 2FA lorsque les identifiants ou la 2FA changent, et applique une limitation de débit aux endpoints de préconnexion et d’authentification. Si vous exploitez des organisations dont vous ne faites pas entièrement confiance aux administrateurs, les notes de la 1.37.4 recommandent également de renouveler la clé API de chaque organisation après la mise à jour. La 1.37.4 modifie aussi l’adresse lue depuis X-Forwarded-For, comme indiqué dans la section précédente sur le reverse proxy. Une instance que vous avez configurée il y a un an et oubliée exécute un code vieux d’un an. La balise latest ne suffit pas à elle seule : un conteneur en cours d’exécution conserve l’image avec laquelle il a démarré jusqu’à ce que vous exécutiez docker compose pull et le recréiez. Mettez en place les mises à niveau automatiques sur Ubuntu pour les paquets de l’hôte, et ajoutez la mise à jour du conteneur à un rappel de calendrier que vous consulterez réellement.
La conclusion à tirer pour un lecteur honnête est la suivante : la cryptographie repose ici sur la conception de Bitwarden et elle tient la route, tandis que le risque opérationnel vous incombe entièrement. Si vous appliquez les correctifs et sauvegardez les données ailleurs, une instance Vaultwarden sur un VPS que vous contrôlez est un emplacement raisonnable pour conserver vos mots de passe. Si ces deux habitudes ne seront pas mises en place, payez le service hébergé et consacrez votre attention à autre chose. La comparaison fonctionnalité par fonctionnalité se trouve dans Vaultwarden comparé à Bitwarden auto-hébergé.
Renforcez l’hôte sous-jacent au conteneur
Vaultwarden est un processus sur une machine Linux. Le compte root de cette machine peut lire /vw-data, quelle que soit la configuration de l’application. Exécutez le conteneur avec un utilisateur non privilégié en utilisant user: "1000:1000" dans votre fichier compose, et attribuez les bons propriétaires au dossier de données. Montez ensuite en lecture seule tout ce que le conteneur ne doit pas modifier avec :ro. Fermez enfin la porte d’entrée : Renforcer SSH sur un VPS explique comment autoriser uniquement l’authentification par clé et désactiver l’authentification par mot de passe. C’est ce qui bloque l’attaque classique qui contourne toutes les mesures précédentes.
FAQ
Quelqu’un peut-il lire mes mots de passe s’il vole la base de données Vaultwarden ?
Pas directement. Chaque élément du coffre est chiffré côté client avec une clé générée aléatoirement, protégée par la clé symétrique de l’utilisateur ou de l’organisation ; la clé dérivée du mot de passe protège la clé symétrique de l’utilisateur. db.sqlite3 contient le contenu chiffré du coffre ainsi que les métadonnées de compte en clair. L’attaquant obtient immédiatement l’adresse e-mail et l’indication de mot de passe de chaque compte, les paramètres du KDF, les métadonnées de connexion et d’appareil, ainsi que les secrets TOTP de connexion dans la table twofactor. Ces derniers sont stockés sans chiffrement, car le serveur doit calculer le code attendu. L’attaquant peut aussi tenter de casser hors ligne le texte chiffré du coffre aussi longtemps qu’il le souhaite. C’est pourquoi la longueur du mot de passe principal détermine le résultat.
Dois-je utiliser ADMIN_TOKEN ou désactiver complètement la page d’administration ?
Désactivez-la si possible, car la plupart des instances n’en ont besoin qu’une fois pour configurer SMTP et inviter des utilisateurs. Pour la désactiver, ne définissez ni ADMIN_TOKEN ni DISABLE_ADMIN_TOKEN, supprimez toute clé "admin_token" de config.json, puis recréez le conteneur. Supprimer uniquement la variable d’environnement ne suffit pas, car les paramètres écrits par la page d’administration sont stockés dans config.json et sont prioritaires. Si vous conservez la page, stockez le token sous forme de hash Argon2 produit par vaultwarden hash plutôt que sous forme de chaîne aléatoire en clair, puis définissez ADMIN_RATELIMIT_MAX_BURST=3.
Mon ADMIN_TOKEN est correct, mais /admin le refuse. Quel est le problème ?
Il s’agit presque toujours d’une interpolation $. Une chaîne PHC Argon2 contient plusieurs caractères $, et Docker Compose les interprète comme des variables dans un bloc docker-compose.yml environment:. Le conteneur reçoit donc une valeur modifiée, même si le fichier semble correct. Doublez chaque $ en $$ dans le fichier Compose, ou placez la valeur dans un fichier .env entouré de guillemets simples, où aucun échappement n’est nécessaire. Recréez ensuite le conteneur, car un redémarrage ne recharge pas les changements d’environnement.
Dois-je encore ouvrir le port 3012 pour les notifications ?
Non. La prise en charge du trafic WebSocket sur le port 3012 a été supprimée dans Vaultwarden 1.31.0, car les notifications utilisent désormais le port HTTP principal. WEBSOCKET_ENABLED et WEBSOCKET_PORT sont obsolètes depuis 1.29.0 et sont ignorés. Le paramètre actuel est ENABLE_WEBSOCKET, dont la valeur par défaut est true. Fermez le port 3012 dans le firewall et supprimez-le de votre fichier Compose. Vérifiez ensuite que votre reverse proxy transmet les en-têtes Upgrade et Connection, car les notifications WebSocket des navigateurs et des clients desktop en dépendent. Les clients mobiles utilisent des notifications push configurées séparément.