概述
在我们的生活和工作当中,会接触到 N 多的 APP 或网页,因为并不是每个服务都能用类似 QQ 一键登录的方式来绑定账号,所以也就有了 N 多的账号密码,记密码成为了让我们非常头疼的事情。太简单或者过于单一的密码容易被撞库或“脱裤”,而太复杂的密码又难以记忆。
因此,市面上就有了多款帮助我们记录密码的软件服务,比如 1password、Lastpass 等。这些软件能够自动抓取我们提交的账号密码保存到云端,实现多终端同步、自动填充密码等功能。虽说这类服务一般还是比较靠谱的,而且还有一些付费套餐。但是密码存在别人的服务器上你总是会有些不放心,谁知道哪天会不会出现数据泄露之类的问题?
鉴于此,本文分享一个基于腾讯云服务,低成本打造个人专属密码管理服务的方案。
Ps:本文首发于腾讯云云+社区,参与了【玩转腾讯云】征文比赛,阅读后有所收获的小伙伴们记得帮忙去原文地址点赞、评论和转发哦!
一、准备工作
本文完整的方案会用到 DNSPod、腾讯云 CDN、CVM 以及 COS 4 个云服务,因此我们先登录腾讯云控制台购买或激活服务:
- 个人域名一个,下文以 mm.zhangge.net 代替(必须,最好是备案过的域名,如果没有可以新注册一个)
- SSL 证书一个(必须,可以申请腾讯云免费证书)
- 域名解析平台账号(必须,推荐使用 DNSPod)
- 腾讯云 CVM 一台(必须,安装 Centos7.2 以上版本系统,如果没有备案域名请购买香港或海外区域)
- 腾讯云 CDN 服务(可选/推荐 )
- 腾讯云 COS 服务(可选/推荐)
对于新手,推荐使用【新人免费产品专区】的免费体验产品来落地方案,等决定正式启用也可以付费转为正式服务;
对于已经有博客的老鸟,就可以直接复用已有服务器啦,且不仅限于腾讯云 CVM;
对于有 NAS 或树莓派的朋友,同样也可以参考部署,不过一定要注意数据备份哦!
这里简单说下腾讯云免费证书的申请步骤:
1、首先打开腾讯云的免费证书申请页面,如图填写信息:
2、然后,在 DNSPod 管理的域名直接选自动验证即可,其他根据实际情况选择:
3、最后,等待自动颁发即可:
二、部署服务
注:以下步骤在全新的腾讯云 CVM完成。
1、环境初始化
这里采用 Docker 部署方案,因此需要先安装 Dcoker,安装步骤如下(已经有 Docker 环境的请跳过):
# 1、登录 root,获取在线安装脚本(这里直接使用 root 账号,简化流程)
curl -fsSL https://get.docker.com -o get-docker.sh
# 2、执行安装脚本
sh get-docker.sh --mirror AzureChinaCloud
# 3、修改 Docker 持久化目录(可选/推荐)
test -d /var/lib/docker && \
mv /var/lib/docker /var/lib/docker_backup && \
mkdir -p /data/docker && \
ln -sf /data/docker /var/lib/docker
# 4、开启镜像加速(可选/推荐)
cat >/etc/docker/daemon.json<<EOF
{
"registry-mirrors": [
"https://dockerhub.azk8s.cn",
"https://hub-mirror.c.163.com"
]
}
EOF
# 5、启动 Docker 并加入开机启动项
systemctl daemon-reload
systemctl enable docker
systemctl start docker
# 6、验证是否安装成功(有 Docker 信息输出即为成功):
docker info
2、部署 Bitwarden
没错!本次私有密码管理方案正是基于 Bitwarden,张戈已经使用半年有余,非常满意!这里使用 Docker 一键部署方式,命令如下:
docker run -d \
--name bitwarden \
-p 8080:80 \
-p 3012:3012 \
--restart=always \
-e SIGNUPS_ALLOWED=true \
-e WEB_VAULT_ENABLED=true \
-e DOMAIN=https://mm.zhangge.net \
-v /data/bitwarden/data:/data \
bitwardenrs/server:latest
3、部署反向代理
Bitwarden 必须启用 HTTPS 访问管理界面才能正常注册,所以如果不打算套一层腾讯云 CDN 来做安全加固的话,还需要在本地部署一个 Nginx 来代理 Bitwarden,以便开启 HTTPS。
Ps:如果用腾讯云 CDN 的话,腾讯云 CDN 支持自定义源站端口,直接启用 HTTPS,所以这步可以跳过。
Nginx 代理配置步骤如下:
①、上传证书文件
上文我们已经提交了腾讯云免费证书申请,等成功颁发后,可以下载到证书文件包:然后将解压后 Nginx 目录下的 crt 和 key 文件上传到服务器,放到/data/bitwarden/cert 目录即可:
②、Nginx 配置
编写 Nginx 配置文件,保存为 /data/bitwarden/nginx/vhost.conf:
server {
listen 443 ssl http2;
server_name mm.zhangge.net; # 根据实际情况修改!!!
ssl_certificate /data/bitwarden/cert/1_mm.zhangge.net_bundle.crt; # 根据实际情况修改!!!
ssl_certificate_key /data/bitwarden/cert/2_mm.zhangge.net.key>;# 根据实际情况修改!!!
ssl_session_cache shared:le_nginx_SSL:1m;
ssl_session_timeout 1440m;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
ssl_ciphers "ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES256-SHA:ECDHE-ECDSA-DES-CBC3-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:DES-CBC3-SHA:!DSS";
# Allow large attachments
client_max_body_size 128M;
location / {
proxy_pass http://127.0.0.1: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://127.0.0.1:3012;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
location /notifications/hub/negotiate {
proxy_pass http://127.0.0.1:8080;
}
}
③、启动 Nginx 容器
docker run -d \
--name nginx \
--restart=always \
--net=host \
-v /data/bitwarden/cert:/data/bitwarden/cert \
-v /data/bitwarden/nginx/vhost.conf:/etc/nginx/conf.d/default.conf \
nginx:latest
若无意外,我们只需要在 DNSPod 将 mm.zhangge.net 这个域名解析到 CVM 服务器的公网 IP 就能正常打开 Bitwarden 的管理后台了 :Ps:其他反向代理配置可以参考:https://github.com/dani-garcia/bitwarden_rs/wiki/Proxy-examples
4、启用 CDN
这里用到 CDN 主要起到 3 个作用:
- 启用 HTTPS:上文提到了 Bitwarden 必须要用 HTTPS 访问,这里借助腾讯云 CDN 可以快速开启 HTTPS 访问;
- 安全加固:启用 CDN 可以有效的隐藏我们的服务器真实 IP,而且 CDN 自带很多安全防护,比如 WAF【相关文章】;
- 访问加速:启用 CDN 之后,静态文件就能缓存到 CDN 节点实现访问加速【相关文章】。
Ps:因为腾讯云 CDN 支持自定义端口的源站,所以上一步反向代理在使用腾讯云 CDN 的方案下是可以忽略不做的。
CDN 配置步骤如下:
①、打开腾讯云 CDN 管理界面,确认已经激活服务:https://console.cloud.tencent.com/cdn/access
②、点击添加域名:mm.zhangge.net,如图:
- 源站地址填写 CVM 公网 IP+上文 bitwarden 容器的暴露端口 8080(即可以跳过第 5 步,不需要本地再部署一份反向代理);
- 回源协议选择 HTTP。
③、缓存配置
- 将全部类型-所有文件的刷新时间改为 0 天,即不缓存
- 新增一个文件类型,内容为:.jpg;.png;.css;.woff;.woff2;.svg,刷新时间设置为 30 天或更长,即静态文件缓存到 CDN(文件类型是从 Bitwarden 分析得出);
- 然后如图调整下优先级,确保需要缓存的规则放到最前,全部-所有文件这个兜底类型放到最后。

④、域名解析
在基本配置界面找到 CDN 给分配的 CNAME 地址:
复制这个地址,前往 DNS 解析面板,如图新增一个 CNAME 解析:
⑤、开启 HTTPS
在等 DNS 解析生效期间,我们回到腾讯云 CDN 配置面板,找到【高级配置】,启用 HTTPS 和 HTTP2.0:
在证书选择界面,选择腾讯云托管证书即可自动加载到我们在上文申请到的免费证书了:
提交后,我们回到域名配置,开启强制 HTTPS 和 HTTP2.0:
5、配置 Bitwarden
做完以上配置,我们就可以正常访问 Bitwarden 的后台管理了:https://mm.zhangge.net/,刚部署的服务还没有账号,此时我们点击【Create Account】创建我们自己的账号:
如图填写信息并提交:
提交后返回了登录界面,此时我们就可以用刚刚创建的账号来登录后台了:
Ps:如果还需要给家人或朋友提供这个服务,也可以邀请他们自己来注册账号,这样就能让我们部署的服务实现更大的价值了!说不定几十块的投入就能让你成功脱单哦!
另外,喜欢中文界面的朋友可以在设置里面改为中文简体:
保存后重新登录就变成中文界面了:
最后,因为我们部署 Bitwarden 是私人使用场景,因此需要修改下 Bitwarden 的容器启动脚本,将前面的 SIGNUPS_ALLOWED=true 改为 SIGNUPS_ALLOWED=false,也就是禁止用户注册。具体步骤如下:
# 删除之前启动的 bitwarden 容器
docker rm -f bitwarden
# 修改为禁止注册然后重新拉起容器
docker run -d \
--name bitwarden \
-p 8080:80 \
-p 3012:3012 \
--restart=always \
-e SIGNUPS_ALLOWED=false \
-e WEB_VAULT_ENABLED=true \
-e DOMAIN=https://mm.zhangge.net \
-v /data/bitwarden/data:/data \
bitwardenrs/server:latest
这样一来,我们部署的 Bitwarden 就无法再新增注册用户了,当需要注册新用户时,只需要修改这个参数重建下容器即可 。
三、使用介绍
完成上述步骤后,我们已经部署了一套私有 Bitwarden 密码管理服务。下面简单介绍下常见使用场景。
1、数据导入
很多朋友肯定用过一些市面上的密码管理,比如 Lastpas、1Password 等 ,如果在这些第三方密码管理平台上已经存在历史密码数据,我们可以通过导出导入的方式将密码数据迁移到我们自己部署的 Bitwarden 上来 。由于文章篇幅有限就不赘述了,网上已经有很多前人分享的文章,比如:https://www.cnblogs.com/woniu666/p/11922580.html。
2、客户端使用
Bitwarden 支持 Web、Chrome,Firefox、Opera 以及 Edge 浏览器插件,拥有 iOS、Android 客户端,因此我们可以根据需要选择安装 Bitwarden 的客户端即可。下面我主要介绍下 Bitwarden 的谷歌浏览器插件的使用。
①、安装插件
- 在线安装:打开谷歌浏览器扩展商店,搜索 Bitwarden 就可以安装;
- 离线安装:如果网络上不方便打开谷歌浏览器扩展商店的朋友,可以使用离线下载方式。
②、插件配置
安装后点击浏览器上的 Bitwarden 小盾牌图标,弹出如图界面,然后点击弹出层左上角的选项按钮,进入插件设置:
在设置界面,我们只需要填写【服务器 URL】为上文自己部署的 Bitwarden 服务地址然后保存,这里也就是 https://mm.zhangge.net/:
保存后,我们就可以登录上文创建的账号了:
登录后,我们切换到右下角设置-->选项:
勾选自动填充选项,开启网页密码账号自动填充功能:
③、插件使用
现在我们随便找个需要登录的网页,填写账号密码点击登录后,Bitwarden 插件就会弹出是否要保存的提示了:
只要我们点击保存,下次再打开这个页面 Bitwarden 就能自动填充账号密码信息,如果是有多个账号,则需要点击小盾牌图标从列表里面选择一个账号来填充:
④、密码生成
Bitwarden 插件同样还支持密码生成,我们在注册新的账号时,强烈推荐使用 Bitwarden 来生成随机密码,而不要使用我们经常好记的密码,这样安全性就能得到极大的提升。反正是这个随机密码由 Bitwarden 来记忆即可。
四、安全加固
自己的密码有多重要这事肯定不需要张戈来强调了,大家肯定都会谨慎对待。因此我们还需要对 Bitwarden 进行一些必要的安全加固。
1、使用 CDN 加固
这个前文已经介绍过了,就不赘述了。
2、两步登录
Bitwarden 支持开启两步登陆,也就是在我们设定的静态主密码的基础上进一步开启了动态验证码二次验证登录。支持如下渠道:
这里推荐使用谷歌的 Authenticator 动态验证码 APP,启动速度超快,IOS 上直接搜索 Authenticator 就可以下载安装了。如图只需要 3 步就能完成动态验证器的关联:
完成操作后,我们再登录 Bitwarden 就需要在手机上打开动态验证码来进行两步验证了:
如此一来,我们登录 Bitwarden,就需要使用动态验证码了,麻是麻烦点,但是更安全了!
3、数据备份
数据备份本身就是一个老生常谈、不能忽视的关键节点,更别提是我们的密码数据了!因此,对于 Bitwarden 我们还需要设置下定时的数据备份。这里依然使用张戈博客经常提到的 7 天循环数据备份方案,并保存一份副本到腾讯云的 COS。
教程地址:https://zhang.ge/5117.html,先参考教程开通、设置下 COS。
文章中的备份脚本在这里同样适用,这里再次贴一下脚本内容:
#!/bin/sh
###################################################################
# Web Backup version 1.0.0 Author: Jager <im@zhang.ge> #
# For more information please visit https://zhang.ge/5117.html #
#-----------------------------------------------------------------#
# Copyright ©2016 zhang.ge. All rights reserved. #
###################################################################
isDel=n
args=$#
isDel=${!args}
# 设置压缩包解压密码
mypassword=123456
test -f /etc/profile && . /etc/profile >/dev/null 2>&1
baseDir=$(cd $(dirname $0) && pwd)
zip --version >/dev/null || yum install -y zip
ZIP=$(which zip)
TODAY=`date +%u`
PYTHON=$(which python)
MYSQLDUMP=$(which mysqldump)
# coscmd 工具上传函数
uploadToCOS()
{
file=$2
domain=$1
file_name=$(basename $2)
coscmd upload $file $domain/$file_name
if [[ $? -eq 0 ]] && [[ "$isDel" == "y" ]]
then
test -f $2 && rm -f $2
fi
}
printHelp()
{
clear
printf '
=====================================Help infomation=========================================
1. Use For Backup database:
The $1 must be [db]
$2: [domain]
$3: [dbname]
$4: [mysqluser]
$5: [mysqlpassword]
$6: [back_path]
$7: [isDel]
For example:./backup.sh db zhang.ge zhangge_db zhangge 123456 /home/wwwbackup/zhang.ge
2. Use For Backup webfile:
The $1 must be {file}:
$2: [domain]
$3: [site_path]
$4: [back_path]
$5: [isDel]
For example:./backup.sh file zhang.ge /home/wwwroot/zhang.ge /home/wwwbackup/zhang.ge
=====================================End of Hlep==============================================
'
exit 0
}
backupDB()
{
domain=$1
dbname=$2
mysqluser=$3
mysqlpd=$4
back_path=$5
test -d $back_path || (mkdir -p $back_path || echo "$back_path not found! Please CheckOut Or feedback to zhang.ge..." && exit 2)
cd $back_path
#如果是要备份远程 MySQL,则修改如下语句中 localhost 为远程 MySQL 地址
$MYSQLDUMP -hlocalhost -u$mysqluser -p$mysqlpd $dbname --skip-lock-tables --default-character-set=utf8 >$back_path/$domain\_db_$TODAY\.sql
test -f $back_path/$domain\_db_$TODAY\.sql || (echo "MysqlDump failed! Please CheckOut Or feedback to zhang.ge..." && exit 2)
$ZIP -P$mypassword -m $back_path/$domain\_db_$TODAY\.zip $domain\_db_$TODAY\.sql && \
uploadToCOS $domain $back_path/$domain\_db_$TODAY\.zip
}
backupFile()
{
domain=$1
site_path=$2
back_path=$3
test -d $site_path || (echo "$site_path not found! Please CheckOut Or feedback to zhang.ge..." && exit 2)
test -d $back_path || (mkdir -p $back_path || echo "$back_path not found! Please CheckOut Or feedback to zhang.ge..." && exit 2)
test -f $back_path/$domain\_$TODAY\.zip && rm -f $back_path/$domain\_$TODAY\.zip
$ZIP -P$mypassword -9r $back_path/$domain\_$TODAY\.zip $site_path && \
uploadToCOS $domain $back_path/$domain\_$TODAY\.zip
}
while [ $1 ]; do
case $1 in
'--db' | 'db' )
backupDB $2 $3 $4 $5 $6
exit
;;
'--file' | 'file' )
backupFile $2 $3 $4
exit
;;
* )
printHelp
exit
;;
esac
done
printHelp
将代码保存到 /data/bitwarden/opt/backup.sh,然后手工执行一次数据备份看看效果:
bash /data/bitwarden/opt/backup.sh file mm.zhangge.net /data/bitwarden/data /data/bitwarden/backup
若备份成功,我们在 crontab 新增一个定时任务,实现定期备份数据:
# 编辑 crontab
crontab -e
# 插入一条定时任务:
0 3 * * * bash /data/bitwarden/opt/backup.sh file mm.zhangge.net /data/bitwarden/data /data/bitwarden/backup >/dev/null 2>&1
五、总结
本文结合腾讯云 CDN、CVM、COS、DNSPod 及免费 SSL 证书等服务,基于 Bitwarden 开源密码管理软件打造了个人私有密码管理服务。并在常见使用场景及安全加固方面做了较为详细的介绍。想自己部署私有密码管理服务的朋友可以参考完成。如果觉得阅读本文后任何疑问都可以在本文后面留言说明,张戈会定期回复。
另外,本文参加了【玩转腾讯云】的征文活动,欢迎大家转发、点赞==>原文地址。
最后,附上本文部署的 Bitwarden Demo(非长期提供,请勿正式使用),方便大家尝鲜、对比:
- Demo 地址:https://mm.zhangge.net/
- Demo 账号:demo@demo.com
- Demo 密码:vFnP9QJFoTB5N6
因属于公开服务,请大家千万不要记录真实密码,避免带来不必要的损失!!
靠谱,准备在NAS上搞搞,原理一下,数据放本地,再做个备份到腾讯云,确实不错,合计我现在还在用最传统的客户端记录
嗯,我就是部署在群晖NAS上的,毕竟要压榨下利用价值嘛~这文章主要是为了参加腾讯云的征文比赛来的,老铁记得去那边点赞评论下哦。
群晖备份到COS直接用cloud sync服务即可。
最近张哥憋坏了,太高产了哈哈,点赞去了
Docker环境如果没有并且不方便安装那怎么办呢?
如果没有服务器,那只能用第三方了。
请问这个密码管理器安全吗?我一直用得1P,不想续费了,像换一个平台。
首先数据掌握在你自己手里,这点比第三方的安全,其次主要自己做好安全防护,比如套CDN,服务器做好安全加固等等,一般来说安全性还是有保障的
安不安全还是一个未知数
只要联网,就没有绝对安全的服务,除非你记到心里,而且还不能说梦话,不能被灌药....
近一年来一直使用QQ浏览器,在今年的4月2号突然保存的密码全无,这种情况已经出现第二次了,上次丢失是上一年9月22号,就想着找其他插件(心中闪过自建,瞬间打消),换到了lastpass,目前用的一切正常,正巧昨天看到您的文章,每次需要某些东西的时候正巧遇到你,按照教程搭建,基本完成。唯一遇到的一个问题:单独删除某一个保存的密码表单后台会意外退出,不知道这是什么情况导致的。
不错,学习了,多谢分享!
学习了,家里的群晖部署了ARK游戏服务,图床,准备再根据教程按部就班操作。睡意顿时没有了!
可以的,这个不错
建议选择bitwarden_rs,可免费解锁Bitwarden高级功能,比如附件支持、TOTP等功能。https://www.xiaoz.me/archives/14085
文章写的和你分享的是一个镜像了:bitwardenrs/server
过几天nas到了试一下;还是不搞服务器了;就本地化,要是数据泄露,老婆会打死我的...
相当靠谱
这个早已经用上了,官方一年10刀其实也行!
不错的尝试,可以买回来试试啦
不错的尝试
学习了 感谢
感谢分享
This is a good blog, happy every day
记得第1次看你的文章还是在2016年左右,现在像这种技术含量比较高的文章都是挑着看的。
刚好有腾讯的服务器,回头试试效果
写的很详细,准备去学一下。
自行部署的bitwarden的官方镜像(我知道bitwarden_rs是全功能的 官方版docker服务器不知道)是全功能的吗?支持totp吗?
先收藏起来再说,哈哈,宝藏
先膜拜下!!
先膜拜了!!牛气??
确实需要一个密码管理器,楼主这个感觉有点太麻烦了。
学习了
步骤太详细了,赞
文章不错非常喜欢
这技术真心高大上
BWD免费功能支持我好多年了。。
好像挺久没更新了啊
部署完,使用谷歌插件登录不上,报:cannot read property of null reading iteration ,应该是少什么没有部署吧