在Debian12上用docker部署Vaultwarden
5月29日更新
大致步骤:
- 在合适的位置创建文件夹保存
docker-compose.yml
文件和数据库数据- 配置
docker-compose.yml
文件,配置好后运行docker compose up -d
运行服务- 配置反向代理
- 配置fail2ban 防止密码管理器帐号被暴力破解
前期准备
- 一个vps服务器
- 一个域名,已经dns解析到服务器的ip地址(下文用
example.com
替代,自行替换成你自己的)
开始部署
设定数据保存位置
我喜欢在/home
文件夹存放docker容器的数据,因此创建并进入/home/docker_apps/vaultwarden
文件夹:
cd /home
mkdir docker_apps docker_apps/vaultwarden
进入刚刚创建的文件夹,创建docker-compose.yml
文件并编辑
cd docker_apps/vaultwarden
vim docker-compose.yml
键入i进入编辑模式(左下角显示--insert--
)
编辑配置docker-compose.yml
文件
我的docker-compose.yml
文件(使用了postgresql数据库):
services:
vaultwarden:
image: vaultwarden/server:latest
container_name: vaultwarden
volumes:
- ./vw-data/:/persistent/
- ./vw-attachments/:/attachments/
# - ./vw-database/:/database/
#启用默认的数据库时启用,并注释掉下文的‘- DATABASE_URL=’,这里启用了postgresql就不启用了
- /icon_cache/ #这样子后每次更新会清除图标,可以可避免保留过时的图标
- ./logs/:/fail2banlogs/
#log日志文件,启用fail2ban时需要
restart: unless-stopped
depends_on:
- db
ports:
- "127.0.0.1:8888:80"
environment:
- DOMAIN=https://example.com #输入你自己的域名
# - SIGNUPS_DOMAINS_WHITELIST=gmail.com,outlook.com,hotmail.com,qq.com
#启用后"SIGNUPS_ALLOWED"将失效,始终可使用下面设置的邮箱域名后缀注册
#如果不启用邮件服务,可设置一个其他人不知道的域名后缀来达到禁止其他人注册
#不过密码管理器这种东西很少有人会去一个不明网站注册一个然后拿来用吧
- WEB_VAULT_ENABLED=true #启用网页页面
- SIGNUPS_ALLOWED=false
#启用后禁止注册,只能登录管理员页面去邀请用户,启用SIGNUPS_ALLOWED后失效
- SIGNUPS_VERIFY=true
#启用注册验证,即往注册帐号的邮箱发送验证
- ADMIN_TOKEN=${VAULTWARDEN_ADMIN_TOKEN}
#启用管理员界面,https://域名/admin 登录,这些在配置文件中设置的都可以在上面再配置
# 数据映射
- DATA_FOLDER=/persistent
# - DATABASE_URL=/database/vaultwarden.sqlite3
#使用默认数据库时启用,使用其他数据库时将此条注释掉
- DATABASE_URL=postgres://${DB_USER}:${DB_SECRET}@db/${DB_NAME}?sslmode=disable
#使用默认数据库时,将此条注释掉
- ATTACHMENTS_FOLDER=/attachments
- ICON_CACHE_FOLDER=/icon_cache
- ROCKET_WORKERS=20
#(可选)启用bitwarden的push,访问https://bitwarden.com/host/ 输入邮箱注册,地区选的美国
#在网页端登录过,然后下次再登录需要你重复输入密码时会多出一个用其他设备登录
#点击那个按钮可用在手机"设置-待处理的登录请求批准登录"
#设置完这个后,会给你手机推送一个消息,iOS亲测可用,其他系统自测
- PUSH_ENABLED=true
- PUSH_INSTALLATION_ID= #将注册的id复制至此
- PUSH_INSTALLATION_KEY= #将注册的key复制至此
#通知邮件的配置
#我这里使用的是自建邮箱,gmail的设置可用去官方wiki查看
- SMTP_HOST=
- SMTP_PORT=587
- SMTP_SECURITY=starttls
- SMTP_FROM=${SMTP_FROM}
- SMTP_USERNAME=${SMTP_USER}
- SMTP_PASSWORD=${SMTP_PASSWD}
- SHOW_PASSWORD_HINT=false #密码提示
- LOG_FILE=/fail2banlogs/vaultwarden.log #日志文件,配合fail2ban使用
- LOG_LEVEL=info
- EXTENDED_LOGGING=true
# - ENABLE_WEBSOCKET=false # 禁用websocket,建议别禁
#使用你喜欢的数据库,postgres的话可用设置16或者17,我这个比较早以前弄得是15,最好固定版本
db:
image: postgres:15
container_name: postgres_vaultwarden
environment:
- POSTGRES_DB=${DB_NAME}
- POSTGRES_USER=${DB_USER}
- POSTGRES_PASSWORD=${DB_SECRET}
#特殊字符要特别设置转义字符,懒得折腾可用仅使用大小写的字母和数字
volumes:
- ./db:/var/lib/postgresql/data
restart: unless-stopped
修改好后键入:wq
按下回车退出
使用默认sqlite
的docker-compose.yml
文件
services:
vaultwarden:
image: vaultwarden/server:latest
container_name: vaultwarden
volumes:
- ./vw-data/:/persistent/
- ./vw-attachments/:/attachments/
- ./vw-database/:/database/
- /icon_cache/ # 升级后会清除图标
- ./vw-logs/:/f2blogs/ # log日志文件位置,如果使用fail2ban需要
restart: unless-stopped
ports:
- "127.0.0.1:8888:80"
environment:
# web以及基本配置
- DOMAIN=https://example.com
- WEB_VAULT_ENABLED=true # 启用网页页面
- SIGNUPS_ALLOWED=false # 启用禁止注册
- SIGNUPS_VERIFY=true # 启用注册验证
- ADMIN_TOKEN=${VAULTWARDEN_ADMIN_TOKEN} # 启用管理员界面
#数据映射
- DATA_FOLDER=/persistent
- ATTACHMENTS_FOLDER=/attachments
- DATABASE_URL=/database/vaultwarden.sqlite3
- ICON_CACHE_FOLDER=/icon_cache
- ROCKET_WORKERS=20
#启用bitwarden的push,前提是你是用bitwarden的官方客户端
#如果使用keyguard(安卓)这种开源第三方客户端,不知道有没有推送
#ID和key访问https://bitwarden.com/host/ 填入邮箱获得,地区随便选我选了美国
#作用是如果你网页端登录时有用其他设备登录会有通知push到你手机
#iOS亲测可用,其他端没有测试过
- PUSH_ENABLED=true
- PUSH_INSTALLATION_ID=
- PUSH_INSTALLATION_KEY=
#通知邮件的配置(可选)
- SMTP_HOST=
- SMTP_PORT=
- SMTP_SECURITY=starttls
- SMTP_FROM=${SMTP_FROM}
- SMTP_USERNAME=${SMTP_USER}
- SMTP_PASSWORD=${SMTP_PASSWD}
#显示密码提示
- SHOW_PASSWORD_HINT=true
#日志文件,用于配合fail2ban
- LOG_FILE=/f2blogs/vaultwarden.log
- LOG_LEVEL=info
- EXTENDED_LOGGING=true
编辑.env
环境变量
同文件夹下键入
vim .env
按 i 进入编辑模式
VAULTWARDEN_ADMIN_TOKEN=
DB_NAME=
DB_USER=
DB_SECRET=
SMTP_FROM=
SMTP_USERNAME=
SMTP_PASSWD=
如果使用默认配置则不需要在.env文件中设置数据库信息"DB_xxx"
的相关变量自行删除
各个值都用小引号‘’
括起来。
如果启用管理员页面.env文件里的VAULTWARDEN_ADMIN_TOKEN
值要避免明文,如何设置参考官方wiki,中文版页面。
配置完成后在此文件夹下运行
docker compose up -d
以启动服务。
可使用命令docker ps
是否正常运行
配置反向代理
需要提前安装好nginx、certbot、python3-certbot-nginx
如果没有安装,执行:
apt update
apt install nginx certbot python3-certbot-nginx
创建配置文件
vim /etc/nginx/conf.d/vaultwarden.conf
按i
进入编辑模式,wiki上有示例配置,或者查看 汉化版说明
用certbot申请ssl证书,以下二选一
- 停止nginx(
systemctl stop nginx
)后运行certbot certonly --standalone -d example.com
然后再去配置文件中指定ssl证书文件位置,再运行systemctl restart nginx
重启nginx - 不停止nginx,将配置文件的server块改成只监听80端口,让certbot自动设置你的ssl证书位置,执行
certbot --nginx -d example.com
我使用第二种,下面是示例配置:
文件路径:/etc/nginx/conf.d/vaultwarden.conf
:
server {
listen 80;
listen [::]:80;
server_name example.com;
client_max_body_size 200M;
location / {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host;
proxy_pass http://localhost:8888/;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header X-Forwarded-Proto $scheme;
}
}
编辑好后,执行certbot --nginx -d example.com
后如果没有报错那就是已经设置上了,这时候再查看这个配置会发现被certbot自动增加上了ssl部分,打开浏览器访问你的网页吧。
或者你可以用cf-tunnel
的方式设置ssl
,适合家里云这种配置起来麻烦的情况,可参考少数派的这篇文章,
优点是相比家里云,没有端口号小尾巴,且配置简单
缺点是可能延迟高,但这个密码库是本地存储的,只有修改密码库时要联网,对延迟要求不高,勉强能接受
使用cf-tunnel
的或者开了cloudflare
小黄云的要去管理页面把客户端IP标头设置为CF-Connecting-IP
否则fail2ban不会起作用
配置fail2ban
即输错密码3
次后会ban掉IP一段时间
fail2ban可以直接照汉化过的wiki来。 假设你按官方的wiki设置了一对filter与jail规则
vaultwarden.local
(按wiki
在对应的文件夹创建对应的文件),执行fail2ban-client status vaultwarden
查看状态
设置网页端的fail2ban
在fail2ban
的filter.d
文件夹创建规则,输入以下内容vim /etc/fail2ban/filter.d/vaultwarden.local
# path_f2b/filter.d/vaultwarden.local
[INCLUDES]
before = common.conf
[Definition]
failregex = ^.*?Username or password is incorrect\. Try again\. IP: <ADDR>\. Username:.*$
ignoreregex =
在fail2ban
的jail.d
文件夹创建规则,输入以下内容vim /etc/fail2ban/jail.d/vaultwarden.local
# path_f2b/jail.d/vaultwarden.local
[vaultwarden]
enabled = true
port = 80,443,8081
filter = vaultwarden
banaction = %(banaction_allports)s
logpath = /path/to/vaultwarden.log #你的log文件的绝对路径
maxretry = 3
bantime = 14400
findtime = 14400
设置网页端admin
管理界面的fail2ban
在fail2ban
的filter.d
文件夹创建规则,输入以下内容vim /etc/fail2ban/filter.d/vaultwarden-admin.local
# path_f2b/filter.d/vaultwarden-admin.local
[INCLUDES]
before = common.conf
[Definition]
failregex = ^.*Invalid admin token\. IP: <ADDR>.*$
ignoreregex =
在fail2ban
的jail.d
文件夹创建规则,输入以下内容vim /etc/fail2ban/jail.d/vaultwarden-admin.local
# path_f2b/jail.d/vaultwarden-admin.local
[vaultwarden-admin]
enabled = true
backend = pyinotify #由于我使用的系统是Debian以及我使用的是apt方式安装的fail2ban,按wiki说法这里得加这个
port = 80,443
filter = vaultwarden-admin
banaction = %(banaction_allports)s
logpath = /path/to/vaultwarden.log #你的log文件的绝对路径
maxretry = 3
bantime = 14400
findtime = 14400
TOTP
的fail2ban
设置,用于vaultwarden
帐号设置了二次验证的
在fail2ban
的filter.d
文件夹创建规则,输入以下内容vim /etc/fail2ban/filter.d/vaultwarden-totp.local
# path_f2b/filter.d/vaultwarden-totp.local
# Fail2Ban filter for Vaultwarden TOTP
[INCLUDES]
before = common.conf
[Definition]
failregex = ^.*\[ERROR\] Invalid TOTP code! Server time: (.*) UTC IP: <ADDR>$
ignoreregex =
在fail2ban
的jail.d
文件夹创建规则,输入以下内容 vim /etc/fail2ban/jail.d/vaultwarden-totp.local
# path_f2b/jail.d/vaultwarden-totp.local
[vaultwarden-totp]
enabled = true
backend = pyinotify #由于我使用的系统是Debian以及我使用的是apt方式安装的fail2ban,按wiki说法这里得加这个
port = 80,443
filter = vaultwarden-totp
banaction = iptables-multiport[name=vaultwarden-totp, port="80,443", protocol=tcp]
logpath = /path/to/vaultwarden.log #你的log文件的绝对路径
maxretry = 3
bantime = 14400
findtime = 14400
重启fail2ban sudo systemctl restart fail2ban
即可生效
查看对应的规则ban了多少IP
#查看web登录失败封禁状况
fail2ban-client status vaultwarden
#如果某个IP访问登录帐号页面并输错密码或者邮箱,3次会banIP(jail文件对应规则maxretry = 3)
#查看管理员页面登录失败封禁状况
fail2ban-client status vaultwarden-admin
#如果某个IP在登录管理员页面输错密码,3次会banIP(jail文件对应规则maxretry = 3)
#查看二次验证输入错误封禁状况
fail2ban-client status vaultwarden-totp
#如果某个IP在登录vaultwarden时,输入二次验证时出错会记录,3次会banIP(jail文件对应规则maxretry = 3)
docker安装的fail2ban可去wiki自己研究
到此为止基本结束了。