Post

Password Manager Self-Hosted con Bitwarden

Self hosting di un moderno gestore di password con MFA, backup, DDNS, certificato ssl e sicurezza avanzata.

Perché farlo?

I gestori di password rappresentano strumenti estremamente utili. Da diversi anni faccio affidamento su di essi, tuttavia, è importante sottolineare che non tutti sono equivalenti. Inizialmente, ho optato per gestori di password integrati nel browser, ma successivamente ho effettuato una rapida transizione a KeePass. Tra le alternative considerate, Bitwarden ha attirato la mia attenzione, soprattutto quando ho scoperto la possibilità di gestirlo autonomamente. Bitwarden offre molte delle stesse funzionalità di LastPass, ma grazie all’self-hosting ho potuto ampliarne ulteriormente le capacità, in particolare con il supporto a YubiKey.

Riconosciuto come uno dei migliori gestori di password open-source attualmente disponibili. Inoltre, Bitwarden si distingue per il supporto a YubiKey, fornendo un ulteriore livello di sicurezza. Al contrario di KeePass, Bitwarden fornisce anche report sulle password compromesse, deboli e riutilizzate, rendendolo una scelta ancora più completa e affidabile.

Neanche a farlo apposta, pochi giorni fa hanno bucato dei sistemi a quanto pare di LastPass1. Un ulteriore motivo in più per passare a delle soluzioni self-hosted per la gestione delle proprie credenziali.

Cosa vi occorre

È possibile eseguire tutto il necessario su un singolo Raspberry Pi 3B+. Bitwarden ha un consumo di risorse relativamente molto basso, ma esiste un’implementazione alternativa scritta in Rust che funziona molto bene anche su un Raspberry Pi.

  • Raspberry Pi (Questa sarebbe normalmente una costruzione economica, ma i problemi della catena di approvvigionamento hanno gonfiato i prezzi dei Raspberry Pi ultimamente, controlla diversi siti per il prezzo migliore.)
  • Custodia
  • Scheda Micro SD (16 GB dovrebbero essere sufficienti.)
  • Cavo Ethernet
  • Alimentazione
  • Connessione Internet

Iniziamo

Consiglio di seguire i passaggi iniziali suggeriti Qui fino alla parte “Installate e configurate Pi-Hole”. Cercate anche di saltare, per il momento, l’installazione del firewall ufw e attendere fino alla fine dell’installazione per configurarlo in modo da essere prima a conoscenza di tutte le porte che si intendono utilizzare con i servizi.

Il prossimo passo è installare Docker.

1
curl -sSL https://get.docker.com | sh

Next, aggiungere l’user al docker group.

1
sudo usermod -aG docker pi

Per il tutorial userò come esempio l’utenza pi, come già accennato in altri articoli, comporta un rischio di sicurezza. Cercate di cambiarlo con qualche altro nome utente.

Per testare docker:

1
docker run hello-world

Andate sulla pagina GitHub vaultwardene e leggete la documentazione.

Ora Docker pull:

1
docker pull vaultwarden/server:latest

Ora abbiamo opzioni e variabili di ambiente da configurare. Per prima cosa abbiamo bisogno di una directory per i dati.

1
mkdir ~/bw-data

Abbiamo bisogno anche di un token admin. usiamo openssl per generare una stringa casuale di caratteri:

1
openssl rand -base64 48

il comando genererà una stringa da 48 caratteri. se vuoi 64, cambia il 48 a 64. Copia poi l’output in un posto sicuro.

Se vuoi utilizzare YubiKey, cosa che consiglio, dobbiamo prima configurare un paio di cose. Prima cosa, necessitiamo del software YubiKey Manager. Ti permette di configurare 5 serie di OTP e registrarle nel YubiCloud. Avrai bisogno anche di una chiave API Yubico necessaria per il tuo server in modo da permettere l’autenticazione con le challenges OTP. Registrane una qui. Riceverai un client ID e una secret, salvale anche questo in un posto sicuro. Raccomando anche di configurare un servizio SMTP. E Una feature in più è quella di ricevere una email per ogni nuovo login. Verifica le tue opzioni e variabili per la configurazione SMTP qui.

Ora dovresti avere tutte le variabili necessarie per eseguire l’immagine docker di vaultwarden, ma devi comunque essere in grado di accederci. Il metodo più semplice è quello di usare un reverse proxy per esporlo su Internet, richiederà alcune configurazioni aggiuntive.

Per prima cosa eseguiamo l’immagine docker.

1
docker run -d --name bitwarden -e YUBICO_CLIENT_ID=12345 -e YUBICO_SECRET_KEY=<KEY> -e ADMIN_TOKEN=<TOKEN> --restart=always -v /home/PI/bw-data/:/data/ -p 8080:80 -p 3012:3012 vaultwarden/server:latest

Aggiungi ulteriormente le tue configurazione SMTP alle variabili.

Cercate di valorizzare le variabili più sensibili (es. api key, token e password etc.) del container tramite delle secrets. Da Docker Compose 1.11 (PR #4368 qui, puoi specificare le secrets nel tuo file docker compose senza usare i container in modalità swarm.

Un Esempio:

abbiamo il nostro proggetto strutturato in questa maniera.

1
2
3
4
5
6
7
8
docker/
  app/
    Dockerfile
  secrets/
    DB_USERNAME
    DB_PASSWORD
    DB_NAME
src/

il nostro file docker-compose.yml sarà di conseguenza strutturato così:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
version: "3.1"

services:
  app:
    build: ./docker/app
    volumes:
      - ./src:/app
    secrets:
      - db-username
      - db-password
      - db-name
secrets:
  db-username:
    file: ./docker/secrets/DB_USERNAME
  db-password:
    file: ./docker/secrets/DB_PASSWORD
  db-name:
    file: ./docker/secrets/DB_NAME
  • Pro:
    • non cè bisogno di farlo partire in swarm
    • puoi usare con familiarità il docker-compose up (e altri strumenti Compose) per velocizzare il processo di sviluppo
    • puoi usare direttive di build e mount source code nel container
    • anche se le secrets non sono consegnate via swarm, l’applicazione non lo sa e non gli importa
    • il file compose sarà uguale allo stack file che può essere usato in produzione
    • tutti i secrets saranno esplicitamente dichiarati, rendendo facile la conoscenza di quelli usati/configurati
  • Contro:
    • Avete bisogno di un file con all’interno il valore per ogni secret. Più secrets = più files
    • Verificare all’interno dei file sul filesystem per vedere i valori

Ora dobbiamo pubblicare il nostro Bitwarden su internet. Cominciamo cercando un nome DNS. Se come la maggiorparte delle persone, non possedi un IP dedicato dal nostro ISP, dobbiamo avvalerci di un servizio DNS dinamico. Per il tutorial raccomando Dynu. Ce ne sono comunque diversi di servizi in questione, la maggiorparte gratuiti. Per avere un account su quest’ultimo clicca qui Dopo aver registrato un nome DDNS puoi automatizzare l’update via DDClient.

1
sudo apt install ddclient

Configura DDClient per il tuo dominio modificando il seguente file /etc/ddclient.conf.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# ddclient configuration for Dynu
#
# /etc/ddclient.conf

daemon=60                                                # Fa un check ogni 60 secondi.
syslog=yes                                               # Aggiorna i log msgs al syslog.
mail=root                                                # Mail tutti msgs a root.
mail-failure=root                                        # Mail fallite update msgs a root.
pid=/var/run/ddclient.pid                                # Registra il PID sel servizio in un file.
use=web, web=checkip.dynu.com/, web-skip='IP Address'    # Prende l'ip dal server.
server=api.dynu.com                                      # Aggiorna l'ip del server.
protocol=dyndns2
login=myusername                                         # Username.
password=YOURPASSWORD                                    # Password o MD5/SHA256 password.
MYDOMAIN.DYNU.COM                                        # Lista di uno o più hostname elencati in ogni riga.
#MYDOMAIN.COM

Dopo aver aggiornato il file di confiurazione con i vostri parametri, eseguite il servizio come demone:

1
/usr/sbin/ddclient -daemon 300 -syslog

Il tuo raspberry aggiornerà Dynu del cambio del tuo tuo ip publico e il dominio si aggiornerà per risolvere il nuovo ip.

Ora dobbiamo procurarci un certificato per il traffico sulla 443. Installiamo Git.

1
sudo apt install git

Dobbiamo clonare questo repo github. contiene uno script utile a Dynu per fargli ottenere un certificato Let’s Encrypt.

Dopo aver clonato, andiamo sul pannello di controllo di Dynu e configuriamo la API key.

Desktop View

Modifichiamo il primo script:

1
nano ~/certbot-domainvalidation-dynu/scripts/script-pre.sh

inserendo l’api key

1
2
#!/bin/bash
api_key='<LA_TUA_API_KEY>'

modifichiamo ora l’altro script

1
nano ~/certbot-domainvalidation-dynu/scripts/script-post.sh

inserendo sempre l’api key:

1
2
#!/bin/bash
api_key='<LA_TUA_API_KEY>'

installiamo i seguenti pacchetti che occorrono:

1
sudo apt install certbot, jq, curl

ed eseguiamo lo script:

1
certbot certonly --manual-public-ip-logging-ok --non-interactive --agree-tos --email <LA_TUA_EMAIL> --manual --preferred-challenges=dns --manual-auth-hook ~/certbot-domainvalidation-dynu/scripts/script-pre.sh --manual-cleanup-hook ~/certbot-domainvalidation-dynu/scripts/script-post.sh -d TUODOMINIO.TLD -d *.TUODOMINIO.TLD

Questa esecuzione vi metterà a disposizione i certificati nel seguente path /etc/letsencypt/live/<TUODOMINIO>/. Puoi trasformarlo anche in uno script bash e farlo eseguire tramite crontab. Usate in caso una buona email per le notifiche di scadenza certificato.

Ora dobbiamo pubblicare ed esporre Bitwarden, usiamo quindi nginx.

1
sudo apt install nginx

configuriamo nginx come reverse proxy:

1
sudo rm /etc/nginx/sites-enabled/default
1
sudo nano /etc/nginx/sites-enabled/bitwarden.conf

copia l’attuale configurazione in bitwarden.conf e apporta le dovute modifiche indicate:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
server {
    listen 80;
    listen [::]:80;
    server_name <YOURFQDN>; #Cambia con il tuo dominio
    return 301 https://$host$request_uri;
}

server {
  listen 443 ssl http2;
  server_name <YOURFQDN>; #Cambia con il tuo dominio
  
  ssl_certificate      /etc/letsencrypt/live/<TUODOMINIO>/fullchain.pem;   
  ssl_certificate_key  /etc/letsencrypt/live/<TUODOMINIO>/privkey.pem;# Allow large attachments
  client_max_body_size 128M;
  
  location / {
    proxy_pass http://0.0.0.0:8080;
    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;
  }
  
  location /notifications/hub {
    proxy_pass http://0.0.0.0:3012;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
  }
  
  location /notifications/hub/negotiate {
    proxy_pass http://0.0.0.0:8080;
  }
}

una volta configurato restartiamo il servizio:

1
sudo systemctl restart nginx

Adesso che abbiamo il nostro reverse proxy configurato, incoraggio a seguire la seguente guida di vaultwarden per la configurazione di Fail2Ban.

per la configurazione si necessita essere a conoscenza della posizione dei log di nginx (in questo path /var/log/nginx/).

Dovreste essere pronti ora per aprire sul vostro router le porte 80 e 443 verso il vostro Pi. Raggiungete tramite il vostro browser il vostro dns name scelto, dovrebbe comparirvi se configurato in modo corretto l’interfaccia web di Bitwarden abilitata con un certificato sicuro in https. Potete ora cominciare a creare un account e ad installare il vostro Bitwarden self-hosted.

Sicurezza

Creato l’account e messo in sicurezza con l’MFA via YubiKey, eseguite i seguenti passaggi per mettere ulteriormente in sicurezza Bitwarden. Navigate sulla pagina web admin, https://TUODOMINIO/admin e inserite il vostro admin token.

Desktop View)

Una volta inserito, andare su General setting e disabilitata la spunta su “Allow new signups.”

Desktop View)

questo impedisce a chiunque visiti la tua page di bitwarden di avere la possibilità di registrarsi a meno che non invitato da voi.

Backup

Dato che non fa mai male avere un backup dei tuoi dati password e per di più è una soluzione self-hosted, il Raspberry Pi gira su Micro SD Card, c’è la possibilità usando rclone di farlo.

Per configurare rclone, eseguire:

1
2
3
4
docker run --rm -it \
  --mount type=volume,source=vaultwarden-rclone-data,target=/config/ \
  ttionya/vaultwarden-backup:latest \
  rclone config

Ti guiderà verso la configurazione di rclone in modo da avere una sincronizzazione dei tuoi backup in una destinazione da te scelta, per verificare eseguire:

1
2
3
4
docker run --rm -it \
--mount type=volume,source=vaultwarden-rclone-data,target=/config/ \
ttionya/vaultwarden-backup:latest \
rclone config show

Ricorda il remote name di rclone, per configurare i tuoi backup quanto configurerai il container di backup. Per configurarlo dovrai avere una configurazione simile a questa:

1
2
3
4
5
6
7
8
9
10
docker run -d \
--restart=always \
--name vaultwarden_backup \
--volumes-from=bitwarden \
--mount type=volume,source=vaultwarden-rclone-data,target=/config/ \
-e RCLONE_REMOTE_NAME="TUO-REMOTO" \
-e DATA_DIR="/data" \
-e BACKUP_KEEP_DAYS="NUMERI" \
-e ZIP_PASSWORD="TUAPASSWORD" \
ttionya/vaultwarden-backup:latest

Configurato il backup container, c’era una problema con il seguente pacchetto libseccomp faceva non prendere correttamente al container la timezone. Per fixarlo, aggiornalo in questo modo:

1
2
3
curl http://ftp.us.debian.org/debian/pool/main/libs/libseccomp/libseccomp2_2.5.1-1_armhf.deb --output libseccomp2_2.5.1-1_armhf.deb

sudo dpkg -i libseccomp2_2.5.1-1_armhf.deb

Vi ritroverete ora un password manager, con backups protetti. Raccomando di non fare affidamento solo su questo, ma anche di effettuare periodicamente quando capita dei backup manuali del vault (esportate Bitwarden JSON o con un JSON criptato) in una chiavetta USB a sua volta criptata.


Questo post è sotto licenza CC BY 4.0 a nome dell'autore.

DISCLAIMER: Questo blog non rappresenta una testata giornalistica in quanto viene aggiornato senza alcuna periodicità. Non può pertanto considerarsi un prodotto editoriale ai sensi della legge N°62 del 07/03/2001. Leggi di più

© Cybertome. Alcuni diritti riservati.

Servizio offerto da Jekyll con tema Chirpy