1.强化指南
对应的官方页面地址
应用程序配置
下面的小节涵盖了 Vaultwarden 本身相关的强化。
禁用注册和(可选)邀请
默认情况下,Vaultwarden 允许任何匿名用户在未被邀请的情况下在服务器上注册新账户。如果您可以访问管理页面,则这不是必需的,如果您是服务器上的第一个用户,则这很有用。建议您在管理面板中(如果启用了管理面板的话)或使用环境变量将其禁用,以防止攻击者在您的 Vaultwarden 服务器上创建账户。
Vaultwarden 还允许注册用户邀请其他新用户在服务器上创建账户并加入其组织。只要您信任您的用户,这不会带来直接风险,但是可以在管理面板或使用环境变量将其禁用。
禁用显示密码提示
Vaultwarden 在登录页面上显示密码提示,以适应没有配置 SMTP 的小型/本地部署,这可能被攻击者滥用,以方便对服务器上的用户进行密码猜测攻击。可以在管理面板中通过取消勾选 Show password hints
选项或使用环境变量来禁用它。
HTTPS / TLS 配置
下面的小节涵盖了 HTTPS/TLS 相关的强化。
严格 SNI
SNI 是网络浏览器请求 HTTPS 服务器为特定网站(如 vaultwarden.example.com
)提供 SSL/TLS 证书的方式。假设vaultwarden.example.com
的 IP 地址是 1.2.3.4
。理想情况下,您希望您的实例只能通过 https://vaultwarden.example.com 访问,并且不能通过 https://1.2.3.4 进行访问。这是因为 IP 地址会因为各种原因被不断扫描,如果能通过这种方式检测到您的 Vaultwarden 实例,就会成为一个更明显的目标。例如,一个简单的 Shodan 搜索就会发现一些通过 IP 地址访问的 Bitwarden 实例。
反向代理
一般来说,您应该避免通过 Vaultwarden 内置的 Rocket TLS 支持启用 HTTPS,特别是当您的实例是公开访问的时候。Rocket 本身列出了如下警告:
Rocket's built-in TLS is not considered ready for production use. It is intended for development use only.(Rocket 内置的 TLS 还不能用于生产。它只用于开发用途。)
比如,Rocket TLS 不支持严格 SNI 或 ECC 证书(仅 RSA)。
请参看代理示例,以了解反向代理配置的示例。
访问日志包含 access_token
参数
access_token
参数通过调用具有 JWT 密钥的 GET 请求来建立用于通知的 WSS 连接。
GET 请求示例:
如果您的反向代理配置为保存访问日志,或者访问日志被发送到外部服务(例如 Prometheus + Promtail),建议在外部日志存储上编辑 access_token
参数的值,或者选择直接在您的反向代理上编辑,如果支持的话。
任何其他数据都不会通过 GET 请求发送,无论是加密的还是未加密的。
请注意,内部 Vaultwarden 日志将查询截断为 30 个字符,因此 access_token 会被截断。这意味着默认情况下如果没有使用反向代理,您也应该是安全的。
Docker 配置
下面的小节涵盖了 Docker 相关的强化。
以非 root 用户运行
Vaultwarden Docker 镜像被配置为默认以 root 用户的身份运行容器进程。这允许 Vaultwarden 读取/写入 bind-mounted 到容器中的任何数据,而无需权限问题,即使这些数据是由另一个用户(例如,你在 Docker 主机上的用户账户)拥有的。
默认配置在安全性和可用性之间取得了很好的平衡--在一个非特权 Docker 容器中以 root 身份运行,本身就提供了合理的隔离级别,同时也让那些不是非常精通如何在 Linux 上管理所有权/权限的用户更容易进行设置。然而,作为通用策略,从安全的角度来说,以所需的最低权限运行进程是更好的;对于用 Rust 等内存安全语言编写的程序来说,这一点就不那么重要了,但请注意,Vaultwarden 也使用了一些用 C 语言编写的库代码(例如 SQLite、OpenSSL、MySQL、PostgreSQL 等)。
要在 Docker 中以非 root 用户 (uid/gid 1000) 的身份运行容器进程 (vaultwarden):
在 docker-compose
中类似操作:
在许多 Linux 发行版中,默认用户的 uid/gid 为 1000(运行 id
命令进行验证),所以如果您想在不换成其他用户的情况下轻松地访问您的 Vaultwarden 数据,这是一个很好的值,但你可以根据需要调整 uid/gid。请注意,您很可能需要指定一个数字 uid/gid,因为 Vaultwarden 容器不共享用户/组名到 uid/gid 的相同映射(例如,将容器中的 /etc/passwd
和 /etc/group
文件与 Docker 主机上的文件对比)。
Vaultwarden Docker 镜像的设置使得 vaultwarden
可执行文件绑定到端口 80,这工作正常,因为它默认以 root 身份运行。但是,非 root 进程通常无法绑定到特权端口(即低于 1024 的端口)。从版本 20.10.0 开始(参见 moby/moby#41030),Docker 专门配置其容器,以便默认情况下允许非 root 进程绑定到特权端口。对于早期版本的 Docker 或其他没有这种特殊行为的容器运行时,Vaultwarden Docker 镜像还在 vaultwarden
可执行文件上设置 cap_net_bind_service
功能,这是另一种允许可执行文件在以非 root 用户身份运行时绑定到特权端口的方法。
挂载数据到容器中
一般来说,只有 Vaultwarden 正常运行所需要的数据才应该被挂载到 Vaultwarden 容器中(通常情况下,这只是您的数据目录,也许还有一个包含 SSL/TLS 证书和私钥的目录)。不要挂载您的整个主目录,例如,/var/run/docker.sock
等,除非您有特定的原因,并且知道您在做什么。
另外,如果您不希望 Vaultwarden 修改您挂载的数据(例如,certs),可以通过在卷规范中添加 :ro
来只读挂载它(例如,docker run -v /home/username/vaultwarden-ssl:/ssl:ro
)。
杂项
暴力破解
当不使用双重身份验证时,(理论上)有可能对用户的密码进行暴力破解,从而获得对其账户的访问权限。缓解此问题的一种相对简单的方法是设置 fail2ban,设置后,在过多的失败登录尝试后将阻止访问者的 IP 地址。但是在许多反向代理(例如 cloudflare)后面使用此功能时,应格外注意。参阅:Fail2Ban 设置。
隐藏在子目录下
通常,Bitwarden 实例驻留在子域的根目录下(即 bitwarden.example.com
,而不是 bitwarden.example.com/some/path
)。上游的 Bitwarden 服务器目前只支持子域根目录,而 Vaultwarden 则增加了对备用基本目录的支持。对于某些用户来说,这很有用,因为他们只能访问一个子域,并希望在不同的目录下运行多个服务。在这种情况下,他们通常可以做一些显而易见的选择,比如使用 mysubdomain.example.com/bitwarden
。然而,您也可以通过把 Vaultwarden 放在类似 mysubdomain.example.com/vaultwarden/<mysecretstring>
这样的目录下来提供额外的保护,其中 <mysecretstring>
有效地充当一个密码。也许有人会说这是通过隐藏实现安全,但实际上这是深度防御 -- 子目录的隐蔽性只是额外的一层安全保护,而不是为了成为主要的安全手段(用户主密码的强度仍然是主要的安全手段)。
有关安全性子路径托管的一般性讨论,请参阅:https://github.com/debops/debops/issues/1233
如果你想让 Caddy 断开除 vaultwarden 之外的所有连接:
最后更新于