前言

很久以前就在少数派等网站中发现有一类密码存储的第三方软件.迫于懒惰一直也没有安装使用.但是最近发现,在连公司的一些vpn或网站时老是密码记不住.今天抽出了点时间去安装

安装bitwarden_rs

bitwarden_rs并不是 bitwarden 的官方项目,而是从官方项目中衍生的第三方实现。bitwarden 的 server 项目使用 .NET 语言和 MSSQL 数据库,生成的 docker 镜像体积较大,第三方作者于是用 rust重写,并使用 sqlite 数据库,并实现了官方的一些付费功能,该 docker 镜像体积较小,方便部署。

拉取docker镜像

docker pull vaultwarden/server:latest

新建数据目录:

mkdir bitwarden-data

新建环境变量配置文件 bitwarden.env。

DOMAIN=your_domain
SIGNUPS_ALLOWED=false 
WEB_VAULT_ENABLED=true
INVITATIONS_ALLOWED=false
WEBSOCKET_ENABLED=true
ROCKET_WORKERS=20
SHOW_PASSWORD_HINT=false
LOG_FILE=/mydata/bitwarden.log
IP_HEADER=X-Real-IP
TZ=Asia/Shanghai

注意第一次运行时,先把 SIGNUPS_ALLOWED 设置为 true,并修改 DOMAIN,以方便创建用户和导入密码库。

启动 docker 容器

export BITWARDEN_DATA=/mydata/bitwarden-data/

docker run -d \
-v $BITWARDEN_DATA:/data/ \
-p 127.0.0.1:10001:80 \
-p 127.0.0.1:10002:3012 \
--env-file=$BITWARDEN_DATA/bitwarden.env \
--name=bitwarden \
--restart=always \
bitwardenrs/server

配置Nginx

作为一个密码管理器服务,为了安全必须开启 HTTPS。关于 HTTPS 的配置请参考项目 secure-nginx

这里只展示为 Bitwarden 设置的请求转发规则

	# reverse proxy
	location / {
		proxy_pass http://127.0.0.1:10001;
		include nginxconfig.io/proxy.conf;
	}

	# notification
	location /notifications/hub {
		proxy_pass http://127.0.0.1:10002;
		proxy_set_header Upgrade $http_upgrade;
		proxy_set_header Connection "upgrade";
	}

	# notification
	location /notifications/hub/negotiate {
		proxy_pass http://127.0.0.1:10001;
		include nginxconfig.io/proxy.conf;
	}

配置 fail2ban

fail2ban 是一个通过监视应用日志并进行正则表达式匹配,将多次登录失败的 IP 通过设置 iptables 进行封禁的工具。给 Bitwarden 设置 fail2ban 可以一定程度上防止主密码遭受暴力破解。

安装

apt install fail2ban

在设置前,检查 docker 容器的 TZ 环境变量和 IP_HEADER 环境变量设置正确。前者影响日志的时间,后者影响日志中记录的真实访问 IP。

首先创建一个过滤器,在 /etc/fail2ban/filter.d 目录新增文件 bitwarden.local,写入以下内容

[INCLUDES]
before = common.conf

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

然后创建一个 jail,在 /etc/fail2ban/jail.d 目录新增文件 bitwarden.local,写入以下内容

[bitwarden]
enabled = true
port = 80,443
name = bitwarden
filter = bitwarden
banaction = iptables-multiport
logpath = /root/bitwarden-data/bitwarden.log
maxretry = 3
bantime = 14400
findtime = 14400

假如你对外监听的端口不是 80 和 443,那么要修改成实际使用的端口,否则 fail2ban 会设置成错误的 iptables,无法禁止 IP 对实际端口的访问。

修改完成后,重启 fail2ban
systemctl restart fail2ban
此时即可故意输入错误的密码,查看 jail 状态中的记录数是否增加
fail2ban-client status bitwarden
输错达到 3 次后,当前 IP 应该就不能再访问服务器的 80 和 443 端口。解封 IP

fail2ban-client set bitwarden unbanip XX.XX.XX.XX

备份

Bitwarden 的模式决定了服务器端的数据永远是最新的,虽然 iOS 和 Android 的客户端支持导出数据,但客户端不会在后台自动同步密码库。若长时间未打开,密码库将不会是最新版本。

此时对服务器数据进行备份就显得尤为重要。服务器端数据是加密的,没有主密码很难解开(话不能说的太绝对)。我们可以定时将将容器挂载目录打包,上传到网络存储。

这里以通过 webdav 上传到坚果云为例。

/etc/cron.daily 目录下新建文件 bitwarden-backup,写入以下内容

#!/bin/sh

set -e

filename="bitwarden-`date +%F`.tar.gz"
cd /root
tar czf "${filename}" bitwarden-data/
curl -u "USERNAME:APP_PASSWD" -T "${filename}" "https://dav.jianguoyun.com/dav/bitwarden/"

rm "${filename}"

增加可执行权限

chmod a+x bitwarden-backup

原文链接