自建 bitwarden 服务

白嫖的 1Password 到期,该考虑续费或者换用其他服务了。

PS: 在更新这篇文章时,bitwarden_rs wiki 更新了 docker-compose 相关文档,建议使用 docker-compose。

Using Docker Compose · dani-garcia/bitwarden_rs Wiki

换还是不换

很久前就在 V2EX 看过讨论,一般有三大推荐:1Password、KeePass、bitwarden。

1Password:用了一年,体验没有网友说的那么神,可能是因为我不用苹果设备。

KeePass:复杂度高,全平台解决方案需要一点折腾。

bitwarden:分为两派,一派是掏钱买 bitwarden 服务,还有一派是自建 bitwarden。

这三个综合比较下来果然还是对 bw 印象更好:

  1. 官方的免费方案足够良心
  2. 所有代码都开源,精神可嘉,用得安心
  3. 支持自建服务,自建可获得 All Feature 体验

决定自建 bw,官方 C# 写的服务端要求有点高,可能是想上天:

  • Processor: x64, 2 GHz dual core
  • Memory: 4 GB RAM (system memory)
  • Storage: 25 GB
  • Docker: Engine 19+ and Compose 1.24+

最终选用了社区用 rust 写的 bitwarden_rs。bitwarden_rs 支持 SQLite、MySQL 和 PostgreSQL,如果是自己一人用,SQLite 就好,同时方便备份。

Docker 安装

跟着 bitwarden_rs 文档一路下一步就好。

拉镜像:

1
sudo docker pull bitwardenrs/server:latest

启动:

1
2
3
4
sudo docker run -d --name bitwarden \
-v /bw-data/:/data/ \
-p 10080:80 \
bitwardenrs/server:latest

我还添加了一些必要的参数,主要是邮件服务和管理相关:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
sudo docker run -d --name bitwarden \
-e SMTP_HOST=smtp.office365.com \
-e SMTP_FROM= \
-e SMTP_PORT=587 \
-e SMTP_SSL=true \
-e SMTP_USERNAME= \
-e SMTP_PASSWORD= \
-e SIGNUPS_ALLOWED=false \
-e ADMIN_TOKEN= \
-v /bw-data/:/data/ \
-p 10080:80 \
bitwardenrs/server:latest

Nginx

Nginx 配置

新建 bw 的 nginx 配置:

1
sudo vim /etc/nginx/sites-enabled/bw.conf

内容如下:

server {
  server_name pw.bolitao.xyz;

  client_max_body_size 128M;

  location / {
    proxy_pass http://127.0.0.1:10080;
    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;
  }
}

证书

老规矩 certbot 一把梭:

1
sudo certbot --nginx
Saving debug log to /var/log/letsencrypt/letsencrypt.log
Plugins selected: Authenticator nginx, Installer nginx

Which names would you like to activate HTTPS for?
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1: pw.bolitao.xyz
2: rss.bolitao.xyz
3: ...
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Select the appropriate numbers separated by commas and/or spaces, or leave input
blank to select all options shown (Enter 'c' to cancel):

选中 bw 然后按提示一路下一步就好。

备份

注:以下操作在 root 用户下进行。

创建备份文件夹和脚本:

1
mkdir /bw-data/bw-backup && vim /root/scripts/bw_backup.sh

内容如下:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#!/bin/bash
SCRIPT_DIR="/root"
NOW=$(date +"%Y%m%d")
TMP_PATH='/tmp'
DROPBOX_DIR="/root/dropbox"
SOURCE_SQLITE_DB="/bw-data/db.sqlite3"                   # bw sqlite3 文件
BACKUP_SQLITE_FILE="/bw-data/bw-backup/backup.sqlite3"   # 使用 sqlite3 的 backup 指令导出的文件
BAK_ARCHIVE_FILE_NAME="bw-$NOW.tar.gz"                   # 上传至 Dropbox 的压缩包文件名
BAK_ARCHIVE_FULL_PATH="$TMP_PATH/$BAK_ARCHIVE_FILE_NAME" # 上传至 Dropbox 压缩包文件

sqlite3 $SOURCE_SQLITE_DB ".backup '$BACKUP_SQLITE_FILE'"
echo "数据库备份完成,打包中..."
tar cfzP "$BAK_ARCHIVE_FULL_PATH" "$BACKUP_SQLITE_FILE"
echo "所有数据打包完成,准备上传..."
# 用脚本上传到dropbox
"$SCRIPT_DIR"/dropbox_uploader.sh upload "$BAK_ARCHIVE_FULL_PATH" "$DROPBOX_DIR/$BAK_ARCHIVE_FILE_NAME"
if [ $? -eq 0 ]; then
    echo "上传完成"
else
    echo "上传失败,重新尝试"
fi

# 删除本地的临时文件,sqlite3 backup 命令的导出文件不用删,下次会覆盖
rm -f "$BAK_ARCHIVE_FULL_PATH"

赋可执行权限:

1
chmod +x /root/scripts/bw_backup.sh

编辑 crontab 定时任务:

1
crontab -e

每周三和周日的上午两点进行备份,内容如下:

1
0 2 * * 0,3 /bin/bash /root/scripts/bw_backup.sh > /dev/null

修改后保存退出。

恢复备份

把备份的文件覆盖掉 /bw-data 下的 db.sqlite3 就好。

参考

updatedupdated2021-01-052021-01-05
加载评论