Bitwarden_rs
Comment compiler et installer proprement le clone de Bitwarden en Rust. Les bases de données disponibles à ce jour sont MySQL et SQLite.
Compilation
On va avoir besoin des backports Debian pour installer npm
(pour compiler l’interface web) :
echo "deb http://ftp.debian.org/debian stretch-backports main" | sudo tee /etc/apt/sources.list.d/backports.list
sudo apt update
Installation des dépendances :
sudo apt install pkg-config libssl-dev build-essential
sudo apt install npm
Si vous voulez utiliser MySQL comme base de données :
sudo apt install libmysqlclient-dev
Installation de Rust
Installation de rustup, qui nous fournira le compilateur Rust :
curl https://sh.rustup.rs -sSf > rustup.sh
On n’exécute pas direct un script tiré du web ! On regarde d’abord s’il ne va pas faire de saloperies :
vi rustup.sh
On le rend exécutable :
chmod +x rustup.sh
On installe le compilateur Rust (il sera dans notre $HOME
) :
./rustup.sh --default-host x86_64-unknown-linux-gnu --default-toolchain nightly
On source un fichier qui nous permet de l’appeler
source $HOME/.cargo/env
Mise à jour de Rust (si vous l’avez déjà installé via rustup)
rustup update
Compilations
Gagnons du temps en clonant le projet bitwarden_rs et l’interface web (qu’il faut compiler aussi) en même temps .
git clone https://github.com/dani-garcia/bitwarden_rs
git clone https://github.com/bitwarden/web.git web-vault
Compilation de Bitwarden_rs :
cd bitwarden_rs
cargo build --release --features sqlite # ou mysql, selon la bdd que vous souhaitez utiliser
Le résultat de la compilation est dans bitwarden_rs/target/release/
.
Compilation de l’interface web :
cd ../web-vault
# On se positionne sur le dernier tag en date
git checkout -b "$(git tag --sort=v:refname | tail -n1)" "$(git tag --sort=v:refname | tail -n1)"
# Un petit patch pour que ça fonctionne avec notre installation
# Attention, regardez https://github.com/dani-garcia/bw_web_builds/tree/master/patches
# et ce que donne `git tag --sort=v:refname | tail -n1` pour choisir la version de patch la plus proche de votre version de web-vault
wget https://raw.githubusercontent.com/dani-garcia/bw_web_builds/master/patches/v2.12.0.patch
# On vérifie le patch
cat v2.12.0.patch
git apply v2.12.0.patch
npm run sub:init
npm install
npm run dist
ATTENTION : on m’a dit que la compilation de l’interface web prenait 1,5Gio de RAM, assurez-vous que vous en avez assez de libre.
Et on copie l’interface web dans le dossier où attend le résultat de la compilation de bitwarden_rs :
cp -a build/ ../bitwarden_rs/target/release/web-vault/
Installation
On va installer Bitwarden_rs dans /opt/bitwarden
et on le fera tourner avec l’utilisateur www-data
:
cd ..
sudo rsync -a --info=progress2 bitwarden_rs/target/release/ /opt/bitwarden/
sudo chown -R www-data: /opt/bitwarden
Puis on va créer un service systemd
, /etc/systemd/system/bitwarden.service
:
[Unit]
Description=Bitwarden Server (Rust Edition)
Documentation=https://github.com/dani-garcia/bitwarden_rs
After=network.target
[Service]
# The user/group bitwarden_rs is run under. the working directory (see below) should allow write and read access to this user/group
User=www-data
Group=www-data
# The location of the .env file for configuration
EnvironmentFile=/etc/bitwarden_rs.env
# The location of the compiled binary
ExecStart=/opt/bitwarden/bitwarden_rs
# Set reasonable connection and process limits
LimitNOFILE=1048576
LimitNPROC=64
# Isolate bitwarden_rs from the rest of the system
PrivateTmp=true
PrivateDevices=true
ProtectHome=true
ProtectSystem=strict
# Only allow writes to the following directory and set it to the working directory (user and password data are stored here)
WorkingDirectory=/opt/bitwarden/
ReadWriteDirectories=/opt/bitwarden/
[Install]
WantedBy=multi-user.target
Pour l’interface d’administration, on va créer un token avec :
openssl rand -base64 48
La configuration se fait via des variables d’environnement qu’on va mettre dans /etc/bitwarden_rs.env
:
SIGNUPS_ALLOWED=false
WEBSOCKET_ENABLED=true
ADMIN_TOKEN=Un token généré avec `openssl rand -base64 48`
ROCKET_ADDRESS=127.0.0.1
WEBSOCKET_ADDRESS=127.0.0.1
SMTP_HOST=127.0.0.1
SMTP_FROM=bitwarden@example.org
SMTP_PORT=25
SMTP_SSL=false
Vous remarquerez que je dis à Bitwarden d’envoyer les mails via le serveur SMTP local. À vous de faire en sorte qu'il fonctionne. Allez voir le wiki du projet ou le modèle de fichier d’environnement pour voir quelles variables vous pourriez ajouter, enlever, modifier…
Puis :
sudo systemctl daemon-reload
sudo systemctl enable bitwarden
sudo systemctl start bitwarden
sudo systemctl status bitwarden
Nginx
On installe Nginx s’il n’est pas déjà installé :
sudo apt install nginx
Configuration du virtualhost :
server {
listen 80;
listen [::]:80;
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name bitwarden.example.org;
access_log /var/log/nginx/bitwarden.access.log;
error_log /var/log/nginx/bitwarden.error.log;
ssl_certificate /etc/letsencrypt/live/bitwarden.example.org/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/bitwarden.example.org/privkey.pem;
ssl_session_timeout 5m;
ssl_session_cache shared:SSL:5m;
ssl_prefer_server_ciphers On;
ssl_protocols TLSv1.2;
ssl_ciphers 'EECDH+aRSA+AESGCM:EECDH+aRSA+SHA384:EECDH+aRSA+SHA256:EECDH:+CAMELLIA256:+AES256:+CAMELLIA128:+AES128:+SSLv3:!aNULL:!eNULL:!LOW:!3DES:!MD5:!EXP:!PSK:!DSS:!RC4:!SEED:!ECDSA';
ssl_dhparam /etc/ssl/private/dhparam4096.pem;
add_header Strict-Transport-Security max-age=15768000; # six months
gzip off;
if ($https != 'on') {
rewrite ^/(.*)$ https://bitwarden.example.org/$1 permanent;
}
root /var/www/html;
# Allow large attachments
client_max_body_size 128M;
location ^~ '/.well-known/acme-challenge' {
default_type "text/plain";
root /var/www/certbot;
}
location / {
include /etc/nginx/proxy_params;
## /etc/nginx/proxy_params contient normalement ceci :
#proxy_set_header Host $http_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://127.0.0.1:8000;
}
location /notifications/hub {
include /etc/nginx/proxy_params;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_pass http://127.0.0.1:3012;
}
location /notifications/hub/negotiate {
include /etc/nginx/proxy_params;
proxy_pass http://127.0.0.1:8000;
}
}
Pour créer /etc/ssl/private/dhparam4096.pem
:
sudo openssl dhparam -out /etc/ssl/private/dhparam4096.pem 4096
Pour le certificat Let’s Encrypt, on commente le brol relatif à ssl
puis :
sudo nginx -t && sudo nginx -s reload
sudo apt install certbot
sudo mkdir /var/www/certbot/
certbot certonly --rsa-key-size 4096 --webroot -w /var/www/certbot/ --agree-tos --text --renew-hook "/usr/sbin/nginx -s reload" -d bitwarden.example.org
Une fois qu’on a le certificat, on décommente le brol ssl
puis :
sudo nginx -t && sudo nginx -s reload
Sauvegarde
Créer le script de sauvegarde /opt/backup_bitwarden.sh
:
#!/bin/bash
function bwbackup {
DATE=$(date '+%a%H')
# Database
if [[ ! -d /opt/backup_bitwarden/sqlite-backup/ ]]
then
mkdir -p /opt/backup_bitwarden/sqlite-backup/
fi
echo ".backup /opt/backup_bitwarden/sqlite-backup/db.${DATE}.sqlite3" | sqlite3 /opt/bitwarden/data/db.sqlite3 2>> /opt/backup_bitwarden/backup.log
if [[ "$?" -ne "0" ]]
then
echo "Something went wrong with bitwarden database backup, please see /opt/backup_bitwarden/backup.log on verity" | mail -s "Bitwarden database backup" youraddress@mail.example.org
bwbackup
fi
# Files
if [[ ! -d /opt/backup_bitwarden/files-backup/ ]]
then
mkdir -p /opt/backup_bitwarden/files-backup/
fi
rsync -a --delete --exclude db.sqlite3 /opt/bitwarden/data/ /opt/backup_bitwarden/files-backup/$DATE/ 2>> /opt/backup_bitwarden/backup.log
if [[ "$?" -ne "0" ]]
then
echo "Something went wrong with bitwarden files backup, please see /opt/backup_bitwarden/backup.log on verity" | mail -s "Bitwarden files backup" youraddress@mail.example.org
bwbackup
fi
}
bwbackup
Puis :
sudo chmod +x /opt/backup_bitwarden.sh
sudo mkdir /opt/backup_bitwarden
sudo chown www-data: /opt/backup_bitwarden
sudo apt install sqlite3
Puis, dans le cron de l’utilisateur www-data
:
42 4 * * * /opt/backup_bitwarden.sh
Logs
J’aime bien avoir mes logs dans un dossier dédié pour ce genre de service.
Dans /etc/rsyslog.d/bitwarden.conf
:
if $programname == 'bitwarden_rs' then /var/log/bitwarden/bitwarden.log
if $programname == 'bitwarden_rs' then ~
Dans /etc/logrotate.d/bitwarden
:
/var/log/bitwarden/bitwarden.log
{
rotate 52
dateext
weekly
missingok
notifempty
compress
sharedscripts
postrotate
invoke-rc.d rsyslog rotate > /dev/null
endscript
}
Puis :
sudo mkdir /var/log/bitwarden
sudo chown root:adm /var/log/bitwarden
sudo service rsyslog restart
Fail2ban
Un fail2ban qui surveille les logs, ça permet de bloquer les petits malins qui font du bruteforce
sudo apt install fail2ban
Dans /etc/fail2ban/filter.d/bitwarden.conf
:
[INCLUDES]
before = common.conf
[Definition]
failregex = ^.*Username or password is incorrect\. Try again\. IP: <HOST>\. Username:.*$
ignoreregex =
Dans /etc/fail2ban/jail.d/bitwarden.local
:
[bitwarden]
enabled = true
port = 80,443
filter = bitwarden
action = iptables-allports[name=bitwarden]
logpath = /var/log/bitwarden/bitwarden.log
maxretry = 3
bantime = 14400
findtime = 14400
Pour la page d’admin, dans /etc/fail2ban/filter.d/bitwarden-admin.conf
:
[INCLUDES]
before = common.conf
[Definition]
failregex = ^.*Unauthorized Error: Invalid admin token\. IP: <HOST>.*$
ignoreregex =
Dans /etc/fail2ban/jail.d/bitwarden-admin.local
:
[bitwarden-admin]
enabled = true
port = 80,443
filter = bitwarden-admin
action = iptables-allports[name=bitwarden]
logpath = /var/log/bitwarden/bitwarden.log
maxretry = 3
bantime = 14400
findtime = 14400
Finalement :
sudo service fail2ban restart
Conclusion
Voilà, vous devriez avoir un serveur Bitwarden_rs fonctionnel. Plus qu’à aller sur l’interface web que vous venez de mettre en place ou télécharger les clients et à les utiliser !
Pour importer vos mots de passe de Firefox, il faut passer par une application pour les exporter, puis aller dans les outils de votre client (ou de l’interface web).