# 关于

这里介绍[ Bitwarden](https://bitwarden.com/) 和 [Vaultwarden](https://github.com/dani-garcia/vaultwarden) 的本地部署方法、日常使用以及疑难解答。同时列出了 Bitwarden 相关的各种服务的访问入口、名词解释及其他相关资源。

## Vaultwarden 与 Bitwarden 的区别 <a href="#difference-between-vaultwarden-and-bitwarden" id="difference-between-vaultwarden-and-bitwarden"></a>

* Vaultwarden 是一个用于本地搭建 Bitwarden 服务器的第三方 Docker 项目。仅在部署的时候使用 Vaultwarden 镜像，桌面端、移动端、浏览器扩展等客户端均使用官方 Bitwarden 客户端。
* Vaultwarden 除不支持 Bitwarden 官方企业版的部分功能（详情见[这里](https://rs.ppgg.in/home#missing-features)）外，其他大部分功能均**免费**支持。并跟随官方版本保持及时更新。
* Vaultwarden 比 Bitwarden 官方版更轻量。官方版使用 .Net 开发，使用 MSSQL 数据库，要求至少 2GB 内存；Vaultwarden 使用 Rust 编写，改用 SQLite 数据库（现在也支持 MySQL 和 PostgreSQL），运行时只需要 10M 内存，可以说对硬件基本没有要求。


# Bitwarden 部署和使用


# 准备

{% hint style="warning" %}
**注意**：个人账户（免费版和高级版）、家庭版组织和企业版组织支持本地托管，免费版组织和团队版组织不支持本地托管。
{% endhint %}

这里以 CentOS 7 with Firewalld 上部署 Bitwarden 为例。

## 系统要求 <a href="#system-requirements" id="system-requirements"></a>

* 处理器：x64, 1.4GHz 或更高
* 内存：2GB 或更多
* 存储空间：10GB 或以上
* Docker：Engine 19+ 以及 Compose 1.24+
* 必须使用 https 才能正常使用（如注册新账号等）

| 软硬件       | 最低配置                        | 推荐配置                        |
| --------- | --------------------------- | --------------------------- |
| 处理器       | x64, 1.4GHz                 | x64, 2GHz 双核                |
| 内存        | 2GB RAM                     | 4GB RAM                     |
| 存储        | 12GB                        | 25GB                        |
| Docker 版本 | Engine 19+ 以及 Compose 1.24+ | Engine 19+ 以及 Compose 1.24+ |

## 配置域名 <a href="#configure-domain" id="configure-domain"></a>

这里假设使用的域名为：`vault.yourdomain.com`。

### 解析域名 <a href="#resolve-domain" id="resolve-domain"></a>

将域名 `vault.yourdomain.com` 的 A 记录解析到部署 Bitwarden 服务器所在的公网 IP 地址。

### 准备域名证书文件 <a href="#prepare-domain-certificate" id="prepare-domain-certificate"></a>

我们一般使用 Bitwarden 中由 Let's Encrypt 生成和更新的免费 SSL 证书，这样就不需要专门准备域名证书文件了。或者使用自己的证书文件（例如 DNSPod 上申请的 TrustAsia 免费 SSL 证书，证书文件放置于 Bitwarden 实例中）。或者在 Bitwarden 的前面使用反向代理的方式启用 HTTPS。

## 其他 <a href="#others" id="others"></a>

服务器防火墙开启相应的端口（比如 443）。


# 部署

## 安装 Docker 和 Docker Compose <a href="#install-docker-and-docker-compose" id="install-docker-and-docker-compose"></a>

### 准备工作 <a href="#preparation" id="preparation"></a>

#### 1、检查内核版本 <a href="#id-1-check-the-kernel-version" id="id-1-check-the-kernel-version"></a>

```shell
uname -r
# Docker 要求 CentOS 系统的内核版本高于 3.10
```

#### 2、（可选）更新到最新 yum 包 <a href="#id-2-update-to-the-latest-yum-package" id="id-2-update-to-the-latest-yum-package"></a>

```shell
yum update -y
```

#### 3、安装需要的软件包 <a href="#id-3-install-the-required-packages" id="id-3-install-the-required-packages"></a>

```shell
yum install -y yum-utils device-mapper-persistent-data lvm2
# yum-util 提供 yum-config-manager 功能， 另外两个是 devicemapper 驱动依赖
```

#### 4、设置 yum 源 <a href="#id-4-set-up-yum-source" id="id-4-set-up-yum-source"></a>

```shell
yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
```

### 安装 Docker <a href="#install-docker" id="install-docker"></a>

#### 1、安装最新稳定版的 Docker <a href="#id-1-install-the-latest-stable-version-of-docker" id="id-1-install-the-latest-stable-version-of-docker"></a>

```shell
sudo yum install docker-ce docker-ce-cli containerd.io
```

如果上述命令运行出错，可能是系统（如 CentOS 8）上安装有旧版本的 Docker，需要先卸载旧版本：

```shell
yum remove docker docker-common docker-selinux docker-engine docer-io
```

#### 2、启动 Docker <a href="#id-2-start-docker" id="id-2-start-docker"></a>

```shell
sudo systemctl start docker
```

#### 3、加入开机启动 <a href="#id-3-add-to-boot-up" id="id-3-add-to-boot-up"></a>

```shell
sudo systemctl enable docker
```

#### 4、验证安装是否成功 <a href="#id-4-verify-whether-the-installation-is-successful" id="id-4-verify-whether-the-installation-is-successful"></a>

```shell
docker version
# 有 client 和 service 两部分表示 docker 安装并启动成功了（有部分错误不用管）
```

### 安装 Docker Compose <a href="#install-docker-compose" id="install-docker-compose"></a>

访问 <https://github.com/docker/compose/releases/latest> 查看并记下最新的 docker-compose 版本号（例如：`1.27.3`）。

#### 1、下载最新版本的 docker-compose 到 `/usr/local/bin` 目录 <a href="#id-1-download-the-latest-version-of-docker-compose" id="id-1-download-the-latest-version-of-docker-compose"></a>

```shell
sudo curl -L "https://github.com/docker/compose/releases/download/1.27.3/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
```

#### 2、授予可执行权限 <a href="#id-2-grant-executable-privileges" id="id-2-grant-executable-privileges"></a>

```shell
sudo chmod +x /usr/local/bin/docker-compose
```

#### 3、验证安装是否成功（可能需要重启系统） <a href="#id-3-verify-that-the-installation-is-successful" id="id-3-verify-that-the-installation-is-successful"></a>

```shell
docker compose -v
# 或者 'docker-compose -v'，如果使用独立的 Docker Compose 的话
# 安装成功会显示 docker-compose 版本号
```

## 安装 Bitwarden <a href="#install-bitwarden" id="install-bitwarden"></a>

### 下载 Bitwarden 脚本文件 <a href="#download-bitwarden-script-file" id="download-bitwarden-script-file"></a>

将 Bitwarden 脚本下载到当前位置并授予可执行权限：

```shell
curl -Lso bitwarden.sh https://go.btwrdn.co/bw-sh \
    && chmod +x bitwarden.sh
```

### 启动安装程序 <a href="#start-the-installer" id="start-the-installer"></a>

```shell
./bitwarden.sh install
```

{% hint style="info" %}
如果中途由于网络等原因卡住不动，可以随时 `Crl+C` 终止，然后重新运行上述命令。国内服务器建议为 Docker 配置代理，参考[此文](https://ppgg.in/blog/12859.html)。
{% endhint %}

根据提示一步一步操作（这里使用 Let's Encrypt 免费证书）：

1、输入您给 Bitwarden 实例分配的域名，这里以 `vault.yourdomain.com` 为例。

2、询问您是否使用 Let's Encrypt 来生成免费的 SSL 证书，这里选 `y` 。

3、输入您的电子邮件地址。

4、输入用于 Bitwarden 实例的数据库名称。

5、开始自动拉取安装所需的文件，等待完成。

6、分别输入从 <https://bitwarden.com/host> 获取的安装 ID 和安装密钥。

7、等待完成。

{% hint style="info" %}
如果您使用自己的证书文件：

1. 输入您给 Bitwarden 实例分配的域名，这里以 `vault.yourdomain.com` 为例。
2. 询问您是否使用 Let's Encrypt 来生成免费的 SSL 证书，这里选 `n` ，我们使用自己申请的证书。
3. 开始自动拉取安装所需的文件，等待完成。
4. 分别输入从 <https://bitwarden.com/host> 获取的安装 ID 和安装密钥。
5. 询问您是否要使用 SSL 证书。这里选 `y` 。
6. 是可信的 SSL 证书吗？这里选 `y` 。
7. 等待完成。
8. 将主证书文件、私钥文件、任何中间证书文件上传到 `./bwdata/ssl/vault.yourdomain.com` 目录中。
   {% endhint %}

8、根据需要更改安装配置文件 `./bwdata/config.yml` 中的设置（如自定义证书的路径、端口等）。然后运行命令：

```shell
./bitwarden.sh rebuild
```

9、根据需要更改环境配置文件 `./bwdata/env/global.override.env` 中的设置。

### 启动 Bitwarden <a href="#start-bitwarden" id="start-bitwarden"></a>

```shell
./bitwarden.sh start
```

开始自动拉取镜像，等待全部完成。

{% hint style="info" %}
首次启动 Bitwarden 时，可能会花费很长时间（根据您的网速可能需要好几个小时），因为它会从 Docker Hub 下载所有映像，特别是 MSSQL 镜像比较大。
{% endhint %}

## 脚本可用的命令 <a href="#script-commands" id="script-commands"></a>

Bitwarden 主脚本（`bitwarden.sh` 或 `bitwarden.ps1`）具有以下可用的命令：

{% hint style="info" %}
PowerShell 用户需要使用前缀 `-`（开关）运行命令。例如 `.\bitwarden.ps1 -start`。
{% endhint %}

| 命令           | 描述                                                                                                                                                                |
| ------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| install      | 启动安装程序。                                                                                                                                                           |
| start        | 启动所有容器。                                                                                                                                                           |
| restart      | 重新启动所有容器（与 `start` 相同）。                                                                                                                                           |
| stop         | 停止所有容器。                                                                                                                                                           |
| update       | 更新所有容器和数据库。                                                                                                                                                       |
| updatedb     | 更新/初始化数据库。                                                                                                                                                        |
| updaterun    | 更新 `run.sh` 文件。                                                                                                                                                   |
| updateself   | 更新主脚本本身。                                                                                                                                                          |
| updateconf   | 更新所有容器，而无需重新启动正在运行的实例。                                                                                                                                            |
| uninstall    | <p>在执行此命令之前，系统会提示您保存数据库文件。选 <code>y</code> 将创建一个包含最新备份的数据库的 tar 文件。</p><p></p><p>停止容器，删除 <code>bwdata</code> 目录及其所有内容，并删除临时卷。执行后，系统会询问您是否还要清除所有 Bitwarden 镜像。</p> |
| compresslogs | <p>将所有服务器日志或指定日期范围内的服务器日志的压缩包下载到当前目录。</p><p>例如，使用 <code>./bitwarden.sh compresslogs 20240304 20240305</code> 下载 2024 年 03 月 04 日至 2024 年 03 月 05 日的日志。</p>        |
| renewcert    | 续签证书。                                                                                                                                                             |
| rebuild      | 重建从 `config.yml` 生成的安装资产。                                                                                                                                         |
| help         | 列出所有命令。                                                                                                                                                           |


# 安装配置文件

安装配置文件用于生成必要的安装资产（如 Bitwarden 实例的端口、证书文件路径等），以便 Bitwarden 脚本用于安装操作。

安装配置文件位置：`./bwdata/config.yml` 。

`config.yml` 默认内容如下：

{% code title="config.yml" %}

```yaml
# 
# 注意：对该文件进行修改后，你需要运行 'rebuild' 或 'update' 命令，以使其生效。
# 
# 用于从浏览器访问安装的完整 URL。（必填）
url: https://vault.yourdomain.com
# 
# 自动生成的 './docker/docker-compose.yml' 配置文件。
# 警告：禁用已生成的配置文件会破坏未来的更新。需要您自行负责维护这个配置文件。
# 模板：https://github.com/bitwarden/server/blob/master/util/Setup/Templates/DockerCompose.hbs
generate_compose_config: true
# 
# 自动生成的 './nginx/default.conf' 配置文件。
# 警告：禁用已生成的配置文件会破坏未来的更新。需要您自行负责维护这个配置文件。
# 模板：https://github.com/bitwarden/server/blob/master/util/Setup/Templates/NginxConfig.hbs
generate_nginx_config: true
# 
# Docker 编译文件的 HTTP 端口映射。留空以移除端口映射。
# 了解更多：https://docs.docker.com/compose/compose-file/#ports
http_port: 80
# 
# Docker 编译文件的 HTTPS 端口映射。留空以移除端口映射。
# 了解更多：https://docs.docker.com/compose/compose-file/#ports
https_port: 443
# 
# Docker 编译文件的版本。留空以使用默认值。
# 了解更多：https://docs.docker.com/compose/compose-file/compose-versioning/
compose_version: 
# 
# 配置 Nginx 的 SSL。
ssl: true
# 
# Nginx 使用的 SSL 的版本（ssl_protocols）。留空以使用推荐的默认值。
# 了解更多：https://wiki.mozilla.org/Security/Server_Side_TLS
ssl_versions: 
# 
# Nginx 使用的 SSL 密码套件（ssl_ciphers）。留空以使用推荐的默认值。
# 了解更多：https://wiki.mozilla.org/Security/Server_Side_TLS
ssl_ciphersuites: 
# 
# 使用可管理的 Let's Encrypt 证书。
ssl_managed_lets_encrypt: false
# 
# 实际的证书。（如果不使用可管理的 Let's Encrypt 配置 SSL，则必填）
# 注意：路径使用容器的 ssl 目录。'./ssl' 主机目录被映射到容器内的 '/etc/ssl' 目录。
ssl_certificate_path: /etc/ssl/vault.yourdomain.com/certificate.crt
# 
# 证书私钥。（如果不使用可管理的 Let's Encrypt 配置 SSL，则必填）
# 注意：路径使用容器的 ssl 目录。'./ssl' 主机目录被映射到容器内的 '/etc/ssl' 目录。
ssl_key_path: /etc/ssl/vault.yourdomain.com/private.key
# 
# 如果该证书是由 CA 信任的，你需要提供该 CA 的证书。
# 注意：路径使用容器的 ssl 目录。'./ssl' 主机目录被映射到容器内的 '/etc/ssl' 目录。
ssl_ca_path: /etc/ssl/vault.yourdomain.com/ca.crt
# 
# Diffie Hellman ephemeral parameters
# 了解更多：https://security.stackexchange.com/q/94390/79072
# 注意：路径使用容器的 ssl 目录。'./ssl' 主机目录被映射到容器内的 '/etc/ssl' 目录。
ssl_diffie_hellman_path: 
# 
# 与 Bitwarden 推送中继服务（push.bitwarden.com）进行通信，以实现移动应用的实时同步。
push_notifications: true
# 
# 使用 docker 卷（'mssql_data'）而不是主机映射的卷来存放持久化数据库。
# 警告：改变这个值会导致您失去对现有持久化数据库的访问。
# 了解更多：https://docs.docker.com/storage/volumes/
database_docker_volume: false
# 
# 在 nginx.conf 中定义的"真实"的 IP。对于定义转发客户端 IP 地址的代理服务器很有用。
# 了解更多：https://nginx.org/en/docs/http/ngx_http_realip_module.html
real_ips: 
```

{% endcode %}

更改安装配置文件后，需要运行 **`rebuild`**（重建）命令以使更改生效：

```shell
./bitwarden.sh rebuild
```


# 环境配置文件

环境配置文件用于在 Bitwarden 部署完成以后增减某些功能，如配置 SMTP、启用 Yubico、启用系统管理员门户、禁用用户注册等。

环境配置文件位置：`./bwdata/env/global.override.env` 。

`global.override.env` 默认内容如下：

{% code title="global.override.env" %}

```systemd
globalSettings__baseServiceUri__vault=https://vault.yourdomain.com
globalSettings__baseServiceUri__api=https://vault.yourdomain.com/api
globalSettings__baseServiceUri__identity=https://vault.yourdomain.com/identity
globalSettings__baseServiceUri__admin=https://vault.yourdomain.com/admin
globalSettings__baseServiceUri__notifications=https://vault.yourdomain.com/notifications
globalSettings__baseServiceUri__sso=https://vault.yourdomain.com/sso
globalSettings__baseServiceUri__portal=https://vault.yourdomain.com/portal
globalSettings__sqlServer__connectionString="Data Source=tcp:mssql,1433;Initial Catalog=vault;Persist Security Info=False;User ID=sa;Password=xGKRrfeggznz5SEAFKAqYPmMNCujUNdK;MultipleActiveResultSets=False;Connect Timeout=30;Encrypt=True;TrustServerCertificate=True"
globalSettings__identityServer__certificatePassword=UYS4X3urhIikdexM58pNYJ6o535gOxg4
globalSettings__attachment__baseDirectory=/etc/bitwarden/core/attachments
globalSettings__attachment__baseUrl=https://vault.yourdomain.com/attachments
globalSettings__dataProtection__directory=/etc/bitwarden/core/aspnet-dataprotection
globalSettings__logDirectory=/etc/bitwarden/logs
globalSettings__logRollBySizeLimit=
globalSettings__syslog__destination=
globalSettings__licenseDirectory=/etc/bitwarden/core/licenses
globalSettings__internalIdentityKey=jpGTst16CGZL2BTjvzL5erR2XRTqsWrhBysa4tTomf6KtVXr8TF0hcxuACxVUpt5
globalSettings__oidcIdentityClientKey=nZu60QKCaOrpPjF9jxrOHnd07d1RrWXrHp5sxv8C7CL9IBu9w9bhI5s03E8qeyiX
globalSettings__duo__aKey=KeW4TH9jYSfmdWGd0c0nROS3TXJHIMdRzNZrw7bHqw0svhE6ePL9jWBiwRRHNc1w
globalSettings__installation__id=0e39beb9-5efe-4ebb-919d-ac3e00d7b1c1
globalSettings__installation__key=QNruWGv7N0n5UY18f4ay
globalSettings__yubico__clientId=REPLACE
globalSettings__yubico__key=REPLACE
globalSettings__mail__replyToEmail=no-reply@vault.yourdomain.com
globalSettings__mail__smtp__host=REPLACE
globalSettings__mail__smtp__port=587
globalSettings__mail__smtp__ssl=false
globalSettings__mail__smtp__username=REPLACE
globalSettings__mail__smtp__password=REPLACE
globalSettings__disableUserRegistration=false
globalSettings__hibpApiKey=REPLACE
adminSettings__admins=
```

{% endcode %}

由于**环境配置文件只有在 Bitwarden 容器启动时才会被读取**，因此，更改环境配置文件后，需要运行 **`restart`**（重启）命令以使更改生效：

```shell
./bitwarden.sh restart
```

{% hint style="warning" %}
注意环境配置文件中值为 `https://vault.yourdomain.com` 的所有变量，需要全部修改其值为实际的外部访问地址（包括端口），否则当有链接跳转时，会导致错误，例如验证电子邮件的跳转链接、管理员门户的跳转链接。假设外部访问地址为 `https://vault.yourdomain.com:28443`，则环境配置文件中值为 `https://vault.yourdomain.com` 的所有变量的值都要替换为 `https://vault.yourdomain.com:28443`。
{% endhint %}

## 已有变量 <a href="#included-variables" id="included-variables"></a>

以下变量在 `global.override.env` 中已经存在：

| 变量                                               | 描述                                                                                                                                                                           |
| ------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| globalSettings\_\_sqlServer\_\_connectionString= | 使用此字段[连接到外部 MSSQL 数据库](https://help.ppgg.in/on-premises-hosting/connect-to-an-external-mssql-database)。                                                                      |
| globalSettings\_\_oidcIdentityClientKey=         | 随机生成的 OpenID Connect 客户端密钥。有关更多信息，请参阅 [OpenID 文档](https://openid.net/specs/openid-connect-registration-1_0.html#RegistrationResponse)。                                       |
| globalSettings\_\_duo\_\_aKey=                   | 随机生成的 Duo 密钥。有关更多信息，请参阅 [Duo 文档](https://duo.com/docs/duoweb#1.-generate-an-akey)。                                                                                           |
| globalSettings\_\_yubico\_\_clientId=            | YubiCloud 验证服务或自托管的 Yubico 验证服务器的客户端 ID。如果是 YubiCloud，请在[此处](https://upgrade.yubico.com/getapikey/)获取您的客户端 ID 和安全密钥。如果是自托管，请参阅可选变量 `globalSettings__yubico__validationUrls`。 |
| globalSettings\_\_yubico\_\_key=                 | YubiCloud 验证服务或自托管的 Yubico 验证服务器的安全密钥。如果是 YubiCloud，请在[此处](https://upgrade.yubico.com/getapikey/)获取您的客户端 ID 和安全密钥。如果是自托管，请参阅可选变量 `globalSettings__yubico__validationUrls`。   |
| globalSettings\_\_mail\_\_replyToEmail=          | 用于邀请的电子邮件地址，通常为 `no_reply@smpt__host`。                                                                                                                                       |
| globalSettings\_\_mail\_\_smtp\_\_host=          | SMTP 服务器的主机名（建议）或 IP 地址。                                                                                                                                                     |
| globalSettings\_\_mail\_\_smtp\_\_port=          | SMTP 服务器使用的 SMTP 端口。                                                                                                                                                         |
| globalSettings\_\_mail\_\_smtp\_\_ssl=           | <p>（布尔值）SMTP 服务器是否使用加密协议：<br><code>true</code> ：SSL<br><code>false</code> ：TLS</p>                                                                                           |
| globalSettings\_\_mail\_\_smtp\_\_username=      | `smtp__host` 的有效用户名。                                                                                                                                                         |
| globalSettings\_\_mail\_\_smtp\_\_password=      | `smtp__host` 的有效密码。                                                                                                                                                          |
| globalSettings\_\_disableUserRegistration=       | 指定为 `true` 将禁用新用户通过注册页面在此实例上注册账户。                                                                                                                                            |
| globalSettings\_\_hibpApiKey=                    | 您的 HaveIBeenPwned (HIBP) API 密钥，参阅[此处](https://haveibeenpwned.com/API/Key)。                                                                                                  |
| adminSettings\_\_admins=                         | 用于访问系统管理员门户的电子邮件地址。                                                                                                                                                          |

## 可选变量 <a href="#optional-variables" id="optional-variables"></a>

以下变量在 `global.override.env` 中尚不存在，但可以手动添加：

| 变量                                                   | 描述                                                                                                                                                                                                                                                                                                            |
| ---------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| globalSettings\_\_logDirectory=                      | 指定日志文件的保存目录。默认为 `globalSettings__logDirectory=bwdata/logs`。                                                                                                                                                                                                                                                   |
| globalSettings\_\_logRollBySizeLimit=                | 开启滚动日志并指定滚动日志文件的大小限制，以字节为单位（例如开启并设置为 1 GB `globalSettings__logRollBySizeLimit=1073741824` ）。                                                                                                                                                                                                                  |
| globalSettings\_\_syslog\_\_destination=             | 指定要将日志文件发送到的 Syslog 服务器或端点（例如 `globalSettings__syslog__destination=udp://example.com:514`）。                                                                                                                                                                                                                   |
| globalSettings\_\_mail\_\_smtp\_\_trustServer=       | 指定为 `true` 将以显式信任 SMTP 服务器提供的证书（**不建议用于生产中**）。                                                                                                                                                                                                                                                                |
| globalSettings\_\_mail\_\_smtp\_\_sslOverride=       | 指定为 `true` 将在端口 25 上使用 SSL（而不是 TLS）。                                                                                                                                                                                                                                                                          |
| globalSettings\_\_mail\_\_smtp\_\_startTls=          | 指定为 `true` 将强制 STARTTLS（随机 TLS）。                                                                                                                                                                                                                                                                              |
| globalSettings\_\_organizationInviteExpirationHours= | 指定组织邀请到期的小时数。默认为 `120` 小时。                                                                                                                                                                                                                                                                                    |
| globalSettings\_\_yubico\_\_validationUrls\_\_0=     | <p>自托管 Yubico 验证服务器的主要地址。例如：<code>globalSettings\_\_yubico\_\_validationUrls\_\_0=<https://your.url.com/wsapi/2.0/verify></code></p><p></p><p>通过创建递增的环境变量来添加其他验证服务器 URL，例如：  <code>globalSettings\_\_yubico\_\_validationUrls\_\_1=</code>，<code>globalSettings\_\_yubico\_\_validationUrls\_\_2=</code>。</p> |
| adminSettings\_\_deleteTrashDaysAgo=                 | 指定多少天后从回收站永久删除项目。默认为 `30` 天。                                                                                                                                                                                                                                                                                  |


# 使用

## 配置 SMTP <a href="#configure-smtp" id="configure-smtp"></a>

Bitwarden 的很多日常验证场景，比如新账户邮件地址的验证、邀请用户、管理门户的使用等，严重依赖 SMTP 功能。部署好 Bitwarden 后，第一步就应该配置 SMTP。

根据您的电子邮件服务提供商关于 SMTP 的说明，修改环境配置文件 `./bwdata/env/global.override.env` 中的如下变量的值：

```systemd
globalSettings__mail__replyToEmail=no-reply@example.com
globalSettings__mail__smtp__host=smtp.example.com
globalSettings__mail__smtp__port=587
globalSettings__mail__smtp__ssl=false
globalSettings__mail__smtp__username=reply@example.com
globalSettings__mail__smtp__password=YOUR.PASSWORD
```

### Gmail 邮箱示例 <a href="#example-for-gmail" id="example-for-gmail"></a>

```systemd
globalSettings__mail__replyToEmail=yourname@gmail.com # 您的 Gmail 邮箱地址
globalSettings__mail__smtp__host=smtp.gmail.com
globalSettings__mail__smtp__port=465
globalSettings__mail__smtp__ssl=true
globalSettings__mail__smtp__username=yourname@gmail.com # 您的 Gmail 邮箱地址
globalSettings__mail__smtp__password=YOUR.PASSWORD # 如果您的 Google 账户开启了二次验证，这里必须使用应用专用密码
```

### [腾讯企业邮箱](https://exmail.qq.com/)示例 <a href="#example-for-qqmail" id="example-for-qqmail"></a>

```systemd
globalSettings__mail__replyToEmail=you@yourdomain.com # 您的企业邮箱的完整邮件地址
globalSettings__mail__smtp__host=smtp.exmail.qq.com
globalSettings__mail__smtp__port=465
globalSettings__mail__smtp__ssl=true
globalSettings__mail__smtp__username=you@yourdomain.com # 您的企业邮箱的完整邮件地址
globalSettings__mail__smtp__password=YOUR.PASSWORD # 您的企业邮箱密码（如已开启安全登陆则需要使用客户端专用密码)
```

**说明：**

* 将上面的电子邮件地址替换为您自己的腾讯企业邮箱地址
* `globalSettings__mail__smtp__host` 使用 `smtp.exmail.qq.com` 无效的话，尝试更换为 `hwsmtp.exmail.qq.com`

## 更新 Bitwarden <a href="#update-bitwarden" id="update-bitwarden"></a>

按顺序运行以下命令：

```shell
./bitwarden.sh updateself # 更新 bitwarden.sh 文件本身
./bitwarden.sh update # 更新 Bitwarden
```

等待完成。

{% hint style="info" %}
可以创建一个 cronjob 或计划任务以每周甚至每晚运行这些更新命令。这将自动使您的安装保持为最新。
{% endhint %}

## 备份和还原 <a href="#backup-and-restore" id="backup-and-restore"></a>

参考[官方帮助文档](https://help.ppgg.in/on-premises-hosting/backup-your-hosted-data)，或[使用 dropbox\_uploader.sh 脚本自动打包备份到 Dropbox](/vaultwarden/use#auto-backup-data)（推荐）。

## 使用系统管理员门户 <a href="#using-admin-portal" id="using-admin-portal"></a>

修改环境配置文件 `./bwdata/env/global.override.env` 中变量 `adminSettings__admins` 的值为可以访问管理门户的邮件地址（多个地址使用英文逗号分隔），以启用系统管理员门户。例如：

```systemd
adminSettings__admins=john@example.com,bill@gmail.com,tom@example.com
```

这些管理员电子邮件地址在您的 Bitwarden 安装中**不需要**是已注册的帐户。

如果您不想启用系统管理门户，将 `adminSettings__admins` 值保留为默认的空白值即可。

更多详细信息，请参考[此文](https://help.ppgg.in/on-premises-hosting/system-administrator-portal)。

{% hint style="warning" %}
要正常使用管理员门户，需要先配置好 SMTP。
{% endhint %}

{% hint style="info" %}
**如果您使用非默认的 HTTPS 端口，服务器版本为 1.37.1 的 Bitwarden 可能会有问题：**&#x5F53;访问 `https://vault.yourdomain.com:8443/admin` 时，它会自动跳转到 `https://vault.yourdomain.com/admin/login?returnUrl=%2Fadmin`导致无法访问。

解决方法就是在跳转地址中手动加入端口号后再访问。
{% endhint %}

## 删除 Bitwarden 安装 <a href="#remove-bitwarden-installation" id="remove-bitwarden-installation"></a>

删除比较简单。先停止 Bitwarden，然后删除 `bwdata` 文件夹即可。

```shell
./bitwarden.sh stop
```

## 设置 Fail2ban <a href="#setup-fail2ban" id="setup-fail2ban"></a>

设置[ Fail2ban](https://www.fail2ban.org/) 后，可以在您设置的 n 次错误登录后自动阻止登录的 IP 地址，防止攻击者暴力破解您的密码库登录，以增强您的 Bitwarden 的安全性。

{% hint style="danger" %}
为了使 Fail2ban 对 IP 拦截更准确，如果您的域名使用 [Cloudflare](https://www.cloudflare.com/) 解析，需要设置其代理状态为  `DNS only`，而不要设置为 `Proxied`。
{% endhint %}

{% hint style="info" %}
下面的 jail 文件中 的 `action =` 语句根据 CentOS 7 使用的是自带的 [Firewalld](https://firewalld.org/) 防火墙，如果使用 iptables，写法应有所不同。

参考资料：[bitwarden-fail2ban-libressl](https://github.com/yes-youcan/bitwarden-fail2ban-libressl)
{% endhint %}

这里以我的 [Vultr](https://www.vultr.com/?ref=7966491) 上的 CentOS 7 with Firewalld 服务器为例。

### 配置环境变量 <a href="#configure-environment-variables" id="configure-environment-variables"></a>

默认情况下，Bitwarden 日志文件的名称为 `当前日期.txt`，需要在设置 Fail2ban 之前配置 Bitwarden 的环境变量开启滚动日志，以使日志文件名称更改为 `log.txt`。

编辑环境配置文件 `./bwdata/env/global.override.env` ，最下方添加一行环境变量：

```systemd
globalSettings__logRollBySizeLimit=1073741824 # 开启滚动日志并指定滚动日志文件的大小限制。这里我们设置为 1GB
```

重启 Bitwarden 使更改生效：

```shell
./bitwarden.sh restart
```

### 安装 Fail2ban <a href="#install-fail2ban" id="install-fail2ban"></a>

```shell
sudo yum install epel-release # 对于 CentOS 7 需要先安装 EPEL 库
sudo yum install fail2ban # 安装 Fail2Ban
```

将 Fail2ban 加入开机启动：

```shell
sudo systemctl enable fail2ban
```

启动 Fail2ban：

```shell
sudo systemctl start fail2ban
```

### 配置 Fail2ban <a href="#configure-fail2ban" id="configure-fail2ban"></a>

#### 创建 filter 文件 <a href="#create-filter-file" id="create-filter-file"></a>

对于 Bitwarden，我们直接使用 Fail2ban 自带的 `/etc/fail2ban/filter.d/bitwarden.conf` 文件，不需要做任何修改。

{% hint style="info" %}
如果您的 Fail2ban 不带此 bitwarden.conf 文件：

1、先创建文件：

```shell
vi /etc/fail2ban/filter.d/bitwarden.local
```

2、然后复制并粘帖如下内容：

```systemd
[INCLUDEshS]
before = common.conf

[Definition]
_daemon = Bitwarden-Identity
failregex = ^%(__prefix_line)s\s*\[(?:W(?:RN|arning)|Bit\.Core\.[^\]]+)\]\s+Failed login attempt(?:, 2FA invalid)?\. <ADDR>$
```

{% endhint %}

#### 创建 Jail 文件 <a href="#create-jail-file" id="create-jail-file"></a>

创建文件：

```shell
vi /etc/fail2ban/jail.d/bitwarden.local
```

复制并粘帖如下内容：

```systemd
[bitwarden]
enabled = true
filter = bitwarden
port = http,https
logpath = /root/bwdata/logs/identity/Identity/log.txt
action = iptables-allports[actname=bitwarden,name=bitwarden,protocol=all]
        iptables-allports[actname=bitwarden-docker,name=bitwarden-docker,protocol=all,chain=DOCKER-USER]
maxretry = 3
bantime = 43200
findtime = 3600
```

### 测试 Fail2ban <a href="#test-fail2ban" id="test-fail2ban"></a>

先打开文件监控：

```shell
sudo tail -f /var/log/fail2ban.log
```

然后尝试用错误的登录信息登录网页密码库，Fail2Ban 如果生效的话，将在 `fail2ban.log` 文件监控窗口显示相关的警告信息，类似于： `INFO [bitwarden] Found 110.238.14.224 - 2021-08-03 20:15:08`，当一定时间内达到设置的失败次数时：`NOTICE [bitwarden] Ban 110.238.14.224`，如下图：

![](/files/-MjiZK84TWfHuAsJNfr_)

同时查看系统的当前 iptables，在最下面会显示 Fail2Ban 封禁的 IP：

```shell
sudo iptables --list -n
```

如果您的 IP 被 ban，浏览器刷新时将无法再次打开网页密码库。

#### 解除被 ban 的 IP <a href="#unban-ip" id="unban-ip"></a>

```shell
sudo fail2ban-client set bitwarden unbanip xxx.xxx.xxx.xxx
```

#### Fail2ban 不起作用 <a href="#fail2ban-not-working" id="fail2ban-not-working"></a>

参看[故障 - Fail2ban 不起作用](/vaultwarden/troubleshoot#fail2ban-not-work)章节。

### Fail2ban 常用命令及参数解释 <a href="#fail2ban-common-commands" id="fail2ban-common-commands"></a>

Fail2ban 常用命令：

* `sudo systemctl start fail2ban` # 启动 Fail2ban
* `sudo systemctl stop fail2ban` # 停止 Fail2ban
* `sudo systemctl restart fail2ban` # 重启 Fail2ban
* `sudo fail2ban-client ping` # 检查 Fail2ban 是否正常运行（正常将显示 `pong`）

参数解释：

* `failregex = ^.*Invalid admin token\. IP: <ADDR>.*$` # 查找日志记录中错误记录正则表达式
* `ignoreregex =` # 忽略日志记录中错误记录正则表达式
* `filter = bitwarden` # 对应的筛选器名称
* `action = iptables[name=bitwarden, port=443, protocol=tcp]` # 动作参数
* `logpath = /root/bwdata/logs/identity/Identity/log.txt` # 日志文件的路径
* `maxretry = 3` # IP 被 ban 前允许失败的次数
* `bantime = 43200` # IP 被 ban 的时长（秒），`-1` 表示永 ban
* `findtime = 3600` # 此时长（秒）内达到 `maxretry` 次就 ban IP
* `ignoreip = xxx.xxx.xxx.xxxx` # 不受限制的 IP


# 故障

## 部署过程输入安装 ID/密钥确认后提示错误：`Unable to validate installation id. Problem contacting Bitwarden server.` <a href="#unable-to-validate-installation-id" id="unable-to-validate-installation-id"></a>

> 无法验证安装 ID。联系 Bitwarden 服务器时出现问题。

原因为 Docker 无法访问外部网络。对于新的 CentOS 8 系统可能会出现这个故障（我在新的 CentOS 7 系统上测试时未出现此故障）。

添加一条防火墙规则让 Docker 流量通过：

```shell
# 允许防火墙伪装 IP
sudo firewall-cmd --zone=public --add-masquerade --permanent

# 重启防火墙
sudo firewall-cmd --reload
```

参考链接：[Install Bitwarden on CentOS/RHEL 8](https://www.informaticar.net/install-bitwarden-on-centos-rhel-8/)

## 注册新账号时出现错误：`发生错误。An unhandled server error has occurred.` <a href="#an-unhandled-server-error-has-occurred" id="an-unhandled-server-error-has-occurred"></a>

登录 SSH 运行语句：

```shell
docker logs -f bitwarden-mssql
```

您会发现有提示：`sqlservr: This program requires a machine with at least 2000 megabytes of memory.`

说明内存不足，增加内存为至少 2000MB 即可。

{% hint style="info" %}
当您刚部署好 Bitwarden 而未注册任何账号，使用任意账号密码登录，可能也会出现此错误。
{% endhint %}

## 第一次注册新账号时出现错误：`发生错误。Failed to fetch.` <a href="#failed-to-fetch" id="failed-to-fetch"></a>

原因为未配置 SMTP。当您刚部署好 Bitwarden 而未注册任何账号，使用任意账号密码登录，可能也会出现此错误。

## 导入高级会员许可证时出现错误：`发生错误。This license is not valid for this user.` <a href="#this-license-is-not-valid-for-this-user" id="this-license-is-not-valid-for-this-user"></a>

原因为账户电子邮件地址不匹配。自托管服务器上的账户电子邮件地址必须与 Bitwarden 云端购买了高级会员的账户电子邮件地址一致，才能将高级会员许可证文件导入本地。更换电子邮箱地址即可。

导入许可证文件后，可以成功更改自托管服务器上此账户的电子邮件地址，但 Bitwarden 会定期检测导入的许可证文件中的电子邮件地址是否与账户电子邮件地址匹配，从而导致许可证过期。

## 导入许可证文件时出现错误： `发生错误。Valid License.` <a href="#valid-license" id="valid-license"></a>

许可证无效。原因可能为：

* 上传的许可证类型不匹配（比如高级会员许可证文件上传到组织中）
* 许可证文件内容被修改

## 收到标题为 `License Expired` 的电子邮件 <a href="#license-expired-email" id="license-expired-email"></a>

邮件内容如下：

> This email is to notify you that your Bitwarden premium license has expired and must be updated for continued use. See the following article for details about replacing your license file: <https://bitwarden.com/help/article/licensing-on-premise/>

提示许可证过期需要更新许可证。原因可能为：

* 许可证确实过期。登录 Bitwarden 云账户，如果订阅过期，先续费订阅，然后重新下载许可证后在自托管服务器上做更新许可证的操作。
* 更改了自托管账户的电子邮件地址。Bitwarden 会定期自动检测本地账户的电子邮件地址是否和许可证中的电子邮件地址一致，不一致会删除许可证文件，从而导致许可证过期。

## 使用非默认的 HTTPS 端口时，管理门户跳转的网址不正确 <a href="#incorrect-admin-portal-url" id="incorrect-admin-portal-url"></a>

Bitwarden 服务器版本 1.37.1。

网页版密码库地址为 `https://vault.yourdomain.com:28443` ，对应的管理员门户地址应该为 `https://vault.yourdomain.com:28443/admin` ，访问时会自动跳转到 `https://vault.yourdomain.com/admin/login?returnUrl=%2Fadmin` ，导致无法访问。

临时解决办法是在跳转的地址上手动加端口号： `https://vault.yourdomain.com:28443/admin/login?returnUrl=%2Fadmin` 。

暂时无法彻底解决，可能为此版本 Bitwarden 的 bug，等待 Bitwarden 官方的修复。

## 忘记了安装 ID 和安装密钥 <a href="#forgot-the-installation-id-and-key" id="forgot-the-installation-id-and-key"></a>

从 Bitwarden 云账户下载家庭账户和企业账户的许可证文件时，需要输入与您的 Bitwarden 安装相匹配的安装 ID。如果您忘记了安装 ID 和安装密钥，可以从环境变量文件 `./bwdata/env/global.override.env` 中找到。

从 <https://bitwarden.com/host> 获取安装 ID 和安装密钥后，应将其保存在您能够记住且安全的地方。

## Fail2ban 不起作用 <a href="#fail2ban-not-work" id="fail2ban-not-work"></a>

参看[故障 - Fail2ban 不起作用](/vaultwarden/troubleshoot#fail2ban-not-work)章节。


# 总结

## 安装 ID/密钥相关 <a href="#installation-id-and-key" id="installation-id-and-key"></a>

* 从 <https://bitwarden.com/host> 获取安装 ID / 安装密钥时，不需要登录，也不要求是注册用户。
* 即使是同一个电子邮件地址，每次获取到的安装 ID / 安装密钥也不一样。
* 本地自托管安装时，需要提供安装 ID / 安装密钥才能进一步安装。
* 下载组织计划的许可证文件时，需要提供与自托管安装时相同的安装 ID 才能下载。
* 如果多个 Bitwarden 安装实例使用同一个安装 ID / 安装密钥，似乎没有任何问题（通过与官方进行邮件沟通）。

## 许可证相关 <a href="#license" id="license"></a>

* 上传高级会员许可证之前，需要先验证电子邮件地址。
* 自托管个人账户：免费版不需要上传许可证文件；若要解锁高级版会员功能，则需要上传高级版会员许可证文件。
* 自托管组织账户：免费版和团队版不支持自托管，家庭版和企业版均需要上传相应的许可证文件。
* 许可证文件有两种类型：1、高级版会员；2、组织方案（家庭版和企业版）。
* 同一个许可证文件可用于任意数量的 Bitwarden 实例上。
* 是否需要在下次付款后或者更改订阅后，下载并更新本地的许可证文件？是的。
* 自托管服务器导入许可证后，订阅到期日会比 Bitwarden 云端相应延后 7 天。在这 7 天内，需要手动更新自托管服务器的许可证文件。
* 高级版会员许可证与账户的电子邮箱地址相关联。自托管服务器上的账户电子邮箱地址必须与 Bitwarden 云端购买了高级版会员的账户电子邮箱地址一致。

## 关于 HTTPS <a href="#about-https" id="about-https"></a>

启用 HTTPS 有很多种方式，我们这里只讨论使用可信的 SSL 证书的方式，目前也可以很方便地获取到免费的 SSL 证书（如 DNSPod、阿里云提供的有效期 1 年的免费证书）。使用自签名的证书比较不实用就不讨论了。

一般有以下几种比较简单的方式：

* 将自己已经准备好的证书文件放置于 Bitwarden 内
* 使用 Bitwarden 由 Let's Encrypt 生成并自动更新的免费 SSL 证书
* 在 Bitwarden 前面使用带 SSL 证书的反向代理（比如群晖的反向代理服务器）

## 其他 <a href="#others" id="others"></a>

* 自托管后的本地账户并不会与 Bitwarden 云账户同步密码库数据。
* Bitwarden 云账户是管理订阅（如升级高级版会员、添加/删除用户席位、更改付款方式等）的唯一方式。
* 订阅内容（如组织类型、用户席位数、订阅到期日等）通过许可证文件反映到本地托管服务器上。


# Vaultwarden 部署和使用


# 准备

{% hint style="info" %}
2021-04-27：从 [v1.21.0](https://github.com/dani-garcia/vaultwarden/releases/tag/1.21.0) 开始，bitwarden\_rs 项目更名为 Vaultwarden。参阅 [#1642](https://github.com/dani-garcia/vaultwarden/discussions/1642) 了解更多说明。
{% endhint %}

这里以 [Vultr](https://www.vultr.com/?ref=7966491) VPS CentOS 7 with iptables 上部署 Vaultwarden 为例。

## 系统要求 <a href="#system-requirements" id="system-requirements"></a>

Vaultwarden 使用 Rust 编写，支持 SQLite、MySQL 和 PostgreSQL 数据库后端，运行时只需要 10M 内存，可以说对硬件基本没有要求。

## 预设环境 <a href="#predefined-environment" id="predefined-environment"></a>

* OS 为 CentOS 7 with Docker Application
* 以下设置基于 [LNMP](https://lnmp.org/)，并使用 LNMP 的相关命令、配置等
* 已存在其他 Web 服务
* 假设使用域名 `vault.yourdomain.com` 访问 Vaultwarden 实例
* Vaultwarden 容器的 80 端口暴露到宿主机的 8443 端口上
* 使用 LNMP 中由 Let's Encrypt 生成并自动更新的免费证书
* 在 Nginx 上设置反向代理为 Vaultwarden 开启 https

## 添加虚拟主机 <a href="#add-vhost" id="add-vhost"></a>

使用如下命令添加一个 vhost：

```shell
lnmp vhost add
```

说明：

* 使用域名 `vault.yourdomain.com`
* 使用 INMP 自带的 Let's Encrypt 创建 SSL 证书
* 其他如 Rewrite rule、PHP Pathinfo、access log、databse、ftp 等全部选 `no`

虚拟主机 `vault.yourdomain.com` 的 Nginx 配置文件位置：`/usr/local/nginx/conf/vhost/vault.yourdomain.com.conf`

其默认的完整内容如下：

```nginx
server {
  listen 80;
  # listen [::]:80;
  server_name vault.yourdomain.com;
  index index.html index.htm index.php default.html default.htm default.php;
  root /home/wwwroot/vault.yourdomain.com;
  
  include rewrite/none.conf;
  # error_page   404   /404.html;
  
  # Deny access to PHP files in specific directory
  # location ~ /(wp-content|uploads|wp-includes|images)/.*\.php$ { deny all; }
  
  include enable-php.conf;
  
  location ~ .*\.(gif|jpg|jpeg|png|bmp|swf)$ {
    expires 30d;
  }
  
  location ~ .*\.(js|css)?$ {
    expires 12h;
  }
  
  location ~ /.well-known {
    allow all;
  }
  
  location ~ /\. {
    deny all;
  }
  
  access_log off;
}

server {
  listen 443 ssl http2;
  # listen [::]:443 ssl http2;
  server_name vault.yourdomain.com;
  index index.html index.htm index.php default.html default.htm default.php;
  root /home/wwwroot/vault.yourdomain.com;
  
  ssl_certificate /usr/local/nginx/conf/ssl/vault.yourdomain.com/fullchain.cer;
  ssl_certificate_key /usr/local/nginx/conf/ssl/vault.yourdomain.com/vault.bitwarden.in.key;
  ssl_session_timeout 5m;
  ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3;
  ssl_prefer_server_ciphers on;
  ssl_ciphers "TLS13-AES-256-GCM-SHA384:TLS13-CHACHA20-POLY1305-SHA256:TLS13-AES-128-GCM-SHA256:TLS13-AES-128-CCM-8-SHA256:TLS13-AES-128-CCM-SHA256:EECDH+CHACHA20:EECDH+CHACHA20-draft:EECDH+AES128:RSA+AES128:EECDH+AES256:RSA+AES256:EECDH+3DES:RSA+3DES:!MD5";
  ssl_session_cache builtin:1000 shared:SSL:10m;
  # openssl dhparam -out /usr/local/nginx/conf/ssl/dhparam.pem 2048
  ssl_dhparam /usr/local/nginx/conf/ssl/dhparam.pem;
  
  include rewrite/none.conf;
  # error_page   404   /404.html;
  
  # Deny access to PHP files in specific directory
  # location ~ /(wp-content|uploads|wp-includes|images)/.*\.php$ { deny all; }
  
  include enable-php.conf;
  
  location ~ .*\.(gif|jpg|jpeg|png|bmp|swf)$ {
    expires 30d;
  }
  
  location ~ .*\.(js|css)?$ {
    expires 12h;
  }
  
  location ~ /.well-known {
    allow all;
  }
  
  location ~ /\. {
    deny all;
  }
  
  access_log off;
}
```

我们需要修改此文件，以添加如下功能：

## 设置反向代理 <a href="#setup-a-reverse-proxy" id="setup-a-reverse-proxy"></a>

设置反向代理以使用 LNMP 生成并自动更新的免费 Let's Encrypt 证书。参考[代理示例 → Nginx (by blackdex)](https://rs.ppgg.in/deployment/proxy-examples)。

在 `vault.yourdomain.com` 配置文件的 `server { listen 443;` 语句块内的第一个 `location` 块上方添加如下内容：

```nginx
client_max_body_size 128M; # 允许大型附件

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

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

## 设置 http 跳转到 https <a href="#setup-http-to-jump-to-https" id="setup-http-to-jump-to-https"></a>

在 `server { listen 80;` 语句块内的 `root ...` 行下方添加一行：

```nginx
return 301 https://$server_name$request_uri;
```

**另外，还要删除如下两个 location 语句块**。不删除的话会导致无法解析 Vaultwarden 实例内容。

```nginx
location ~ .*\.(gif|jpg|jpeg|png|bmp|swf)$ {
  expires 30d;
}

location ~ .*\.(js|css)?$ {
  expires 12h;
}
```

上面所有设置和修改完成后的 `vault.yourdomain.com.conf` 文件的完整内容如下：

```nginx
server {
  listen 80;
  # listen [::]:80;
  server_name vault.yourdomain.com;
  index index.html index.htm index.php default.html default.htm default.php;
  root /home/wwwroot/vault.yourdomain.com;
  
  return 301 https://$server_name$request_uri; # 设置 http 跳转到 https
  
  include rewrite/none.conf;
  # error_page   404   /404.html;
  
  # Deny access to PHP files in specific directory
  # location ~ /(wp-content|uploads|wp-includes|images)/.*\.php$ { deny all; }
  
  include enable-php.conf;
  
  access_log off;
}

server {
  listen 443 ssl http2;
  # listen [::]:443 ssl http2;
  server_name vault.yourdomain.com;
  index index.html index.htm index.php default.html default.htm default.php;
  root /home/wwwroot/vault.yourdomain.comn;
  
  ssl_certificate /usr/local/nginx/conf/ssl/vault.yourdomain.com/fullchain.cer;
  ssl_certificate_key /usr/local/nginx/conf/ssl/vault.yourdomain.com/vault.bitwarden.in.key;
  ssl_session_timeout 5m;
  ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3;
  ssl_prefer_server_ciphers on;
  ssl_ciphers "TLS13-AES-256-GCM-SHA384:TLS13-CHACHA20-POLY1305-SHA256:TLS13-AES-128-GCM-SHA256:TLS13-AES-128-CCM-8-SHA256:TLS13-AES-128-CCM-SHA256:EECDH+CHACHA20:EECDH+CHACHA20-draft:EECDH+AES128:RSA+AES128:EECDH+AES256:RSA+AES256:EECDH+3DES:RSA+3DES:!MD5";
  ssl_session_cache builtin:1000 shared:SSL:10m;
  # openssl dhparam -out /usr/local/nginx/conf/ssl/dhparam.pem 2048
  ssl_dhparam /usr/local/nginx/conf/ssl/dhparam.pem;
  
  include rewrite/none.conf;
  # error_page   404   /404.html;
  
  # Deny access to PHP files in specific directory
  # location ~ /(wp-content|uploads|wp-includes|images)/.*\.php$ { deny all; }
  
  include enable-php.conf;
  
  # ==设置反向代理开始== #
  client_max_body_size 128M; # 允许大型附件
  
  location / {
    proxy_pass http://127.0.0.1:8443;
    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:8443;
  }
  
  location /admin {
    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;
    proxy_pass http://127.0.0.1:8443;
  }
  # ==设置反向代理结束== #
  
  location ~ /.well-known {
    allow all;
  }
  
  location ~ /\. {
    deny all;
  }
  
  access_log off;
}
```

重启 Nginx 使配置生效：

```shell
/etc/init.d/nginx restart
```

## 其他 <a href="#others" id="others"></a>

### 在 Vultr 实例上开放相应的外部访问端口 <a href="#open-the-external-access-port" id="open-the-external-access-port"></a>

Vultr 实例默认开启了 443 端口，如果你使用非 443 端口，需要在 [Vultr 后台](https://my.vultr.com/firewall/)或在 CentOS 上添加相应的防火墙规则。


# 部署

## 部署 Vaultwarden <a href="#deploy-vaultwarden" id="deploy-vaultwarden"></a>

```shell
docker run -d --restart always --name vaultwarden \
  -e TZ=Asia/Shanghai
  -e LOG_FILE=/data/log/vaultwarden.log \
  -e ADMIN_TOKEN=some_random_token \
  -v /vaultwarden-data/:/data/ \
  -p 8443:80 \
  vaultwarden/server:latest
```

或者：

```shell
docker run -d --restart always --name vaultwarden -e TZ=Asia/Shanghai -e LOG_FILE=/data/log/vaultwarden.log -e ADMIN_TOKEN=some_random_token -v /vaultwarden-data/:/data/ -p 8443:80 vaultwarden/server:latest
```

参数解释：

* `-d`：指定容器运行于前台或者后台（默认为 `false` 表示运行于后台）
* `--restart always`：自动启动（在宿主机重启后或者 Docker 服务重启后）
* `--name vaultwarden`：指定容器名称为 `vaultwarden`
* `-e TZ=Asia/Shanghai`：设置时区为 `Asia/Shanghai`
* `-e LOG_FILE=/data/log/vaultwarden.log`：设置日志文件路径
* `-e ADMIN_TOKEN=some_random_token`：设置 `ADMIN_TOKEN` 环境变量以启用管理页面
* `-v /vaultwarden-data/:/data/`：挂载容器的 `data` 目录到宿主机的 `vaultwarden-data` 目录上
* `-p 8443:80`：指定容器的 `80` 端口暴露在宿主机的 `8443` 端口上

## 其他部署示例 <a href="#other-deployment-examples" id="other-deployment-examples"></a>

群晖上部署 Vaultwarden 请参阅[使用群晖搭建第三方 Bitwarden 密码服务器](https://ppgg.in/blog/10271.html)。更多请参阅 [Vaultwarden Wiki](https://rs.ppgg.in/) — [部署示例](https://rs.ppgg.in/deployment/deployment-examples)部分。


# 配置

## 关于配置 <a href="#about-configuration" id="about-configuration"></a>

有三种配置方式：

1. 通过管理页面 `https://vault.yourdomain.com/admin` 配置
2. 通过直接修改管理配置文件 `config.json` 配置
3. 通过在启动 Vaultwarden 容器时指定环境变量配置

一般通过管理页面来对 Vaultwarden 进行配置，因为比较直观。

**注意：**

* 管理页面的设置会覆盖相应的环境变量值或 `config.json` 文件中的现有值
* 管理页面的只读部分只能通过环境变量来设置
* Vaultwarden 容器只有在启动的时候才会读取 `config.json` 配置文件，所以，直接修改 `config.json` 后，需要重启 Vaultwarden 容器才能使更改生效（重启命令：`docker restart vaultwarden`）

管理页面点击 `Save` 后会自动在 `vaultwarden-data` 下生成/更新 `config.json` 文件。**注意**：只有值不为空的设置项才会出现在 `config.json` 文件中。

{% hint style="info" %}
所有可设置的环境变量的列表：<https://github.com/dani-garcia/vaultwarden/blob/main/.env.template>
{% endhint %}

## 管理页面中各配置项说明 <a href="#configuration-options" id="configuration-options"></a>

{% hint style="warning" %}
**注意**：管理页面的设置会覆盖相应的环境变量值或 `config.json` 文件中的现有值。保存后，建议停止设置环境变量以免造成混淆。这不适用于只读部分，只读部分只能通过环境变量进行设置。
{% endhint %}

### General Settings

* **`Domain URL`**：如果与默认值不同，则需要将其设置为用于访问服务器的 URL，包含「http\[s]://」和端口号。如果没有这个值，某些服务器功能（如附件下载、电子邮件链接和 U2F 等）将无法正常工作。示例：`https://vault.yourdomain.com:28443`
* **`Allow Sends`**：控制是否允许用户创建 Bitwarden Send。此设置全局适用于所有用户。要对单个组织进行控制，请使用「禁用 Send」组织策略。默认值：`true`
* **`HIBP Api Key`**：[HaveIBeenPwned](https://en.wikipedia.org/wiki/Have_I_Been_Pwned%3F) API 密钥。在[此处](https://haveibeenpwned.com/API/Key)申请（收费服务）。无 HIBP 的话，密码库报告中的「数据泄露报告」无法使用
* **`Per-user attachment limit (KB)`**：对每个用户的附件存储空间限制在 xx KB 以内，达到限制后无法上传更多附件
* **`Per-organization attachment limit (KB)`**：对每个组织的附件存储空间限制在 xx KB 以内，达到限制后无法上传更多附件
* **`Per-user send storage limit (KB)`**：对每个用户的 Send 存储空间限制在 xx KB 以内，达到限制后无法上传更多 Send
* **`Trash auto-delete days`**：在自动删除一个废弃项目之前等待的天数。如果不设置，废弃的项目就不会被自动删除。这是一个全局设置，所以请确保将这个设置的任何更改告知所有用户
* **`Incomplete 2FA time limit`**：在启用了 2FA 的登录被认为不完整之前等待的分钟数，从而导致电子邮件通知。不完整的 2FA 登录是指提供了正确的主密码但未完成所需的 2FA 步骤，这可能表明主密码已泄露。设置为 `0` 以禁用此检查。此设置全局适用于所有用户。默认值：`3`
* **`Disable icon downloads`**：设置为 `true` 将禁用图标下载，这将仍然为 `$ICON_CACHE_FOLDER` 提供图标服务，但不会产生任何外部网络请求。需要将 `$ICON_CACHE_TTL` 设置为 `0`，否则最终会删除图标，并且不会被再次下载。默认值：`false`
* **`Allow new signups`**：控制新用户是否可以注册。即使此功能被禁用，用户仍可以被 Vaultwarden 管理员邀请。默认值：`true`
* **`Require email verification on signups. This will prevent logins from succeeding until the address has been verified`**：注册时要求验证电子邮箱。未验证前将无法成功登录。默认值：`false`
* **`If signups require email verification, automatically re-send verification email if it hasn't been sent for a while (in seconds)`**：如果设置了注册时验证电子邮箱，设置自动重新发送验证电子邮件的时间间隔（单位秒）。默认值：`3600`
* **`If signups require email verification, limit how many emails are automatically sent when login is attempted (0 means no limit)`**：如果设置了注册时验证电子邮箱，限制尝试登录时自动发送电子邮件的次数（`0` 表示无限制）。默认值：`6`
* **`Email domain whitelist`**：限制只能某些域名的电子邮箱可以注册，以英文逗号分隔。将忽略 `SIGNUPS_ALLOWED=false`。示例：`example.com,example.net`
* **`Org creation users`**：可以创建新组织的用户电子邮箱列表，以英文逗号分隔。值为空或 `all` 表示所有用户均可以创建组织；`none` 表示所有用户均不可以
* **`Allow invitations`**：控制组织管理员是否可以邀请用户，将忽略 `SIGNUPS_ALLOWED=false`。默认值：`true`
* **`Enable emergency access`**：控制用户是否可以启用对其账户的紧急访问。此设置全局适用于所有用户。默认值：`true`
* **`Allow email change`**：控制用户是否可以更改电子邮箱。此设置适用于所有用户。默认值：`true`
* **`Password iterations`**：服务器端密码散列迭代次数，新用户或当前用户更改密码时才会应用此设置。太高降低性能，太低主密码易被暴力破解，不建议低于 `100000`。默认值：`100000`
* **`Allow password hints`**：控制用户是否可以设置密码提示。此设置全局适用于所有用户。默认值：`true`
* **`Show password hints (Know the risks!)`**：如果未配置 SMTP 服务且允许密码提示，则控制是否在网页中直接显示密码提示。不建议用于可公开访问的实例，因为这会提供对潜在敏感数据的未经身份验证的访问。默认值：`false`
* **`Admin token/Argon2 PHC`**：定义用于登录管理页面的纯文本 Token 或 Argon2 PHC 字符串并启用管理页面。在这里更改它不会取消当前会话授权。这里的值可以被在启动 Vaultwarden 容器时指定的环境变量值覆盖
* **`Invitation organization name`**：定义非来自特定组织的邀请电子邮件中显示的名称。示例：`Vaultwarden`

### Advanced Settings

* **`Client IP header`**：客户端 IP 标头，用于标识客户端的 IP。如果为空，则使用远程 IP，设置为 `none` 将禁用任何标头及仅使用远程 IP。默认值：`X-Client-IP`
* **`Icon redirect code`**：重定向到外部图标服务的 HTTP 状态代码。支持的代码有 `301`（传统永久）、`302`（传统临时）、`307`（临时）和 `308`（永久）。临时重定向在测试不同的图标服务时很有用，但一旦确定了一个服务，就应考虑使用永久重定向以利于缓存。目前 Bitwarden 客户端对传统代码的支持更好。
* **`Positive icon cache expiry`**：已成功缓存的图标重新下载的间隔时间（单位秒），此时间后图标将被重新下载。`0` 表示不重新下载。默认值：`2592000`
* **`Negative icon cache expiry`**：未成功缓存的图标重新下载的间隔时间（单位秒），此间隔后图标将重新尝试下载。`0` 表示不重新下载。默认值：`259200`
* **`Icon download timeout`**：下载图标时的超时时间（单位秒）。默认值：`10`
* **`Block HTTP domains/IPs by Regex`**：任何匹配此正则表达式的域名和 IP 的图标将不会被内部 HTTP 客户端获取。用于隐藏本地网络中的其他服务器。查看 wiki 了解更多详细信息
* **`Block non globle IPs`**：启用后，内部 HTTP 客户端将拒绝连接任何非全局 IP 地址。这对确保内部环境安全非常有用。有关它将阻止的 IP 列表，请参阅 [Wiki](https://zh.wikipedia.org/wiki/%E4%BF%9D%E7%95%99IP%E5%9C%B0%E5%9D%80)。默认值：`true`
* **`Disable Two-Factor remember`**：禁用它将强制用户每次登录时使用二次验证。注意复选框虽存在但会被忽略。默认值：`false`
* **`Disable authenticator time drifted codes to be valid`**：禁用验证器时间漂移。启用此功能后，仅当前 TOTP 码有效，否则当前 TOTP 以及前 30 秒和后 30 秒的 TOTP 均有效。默认值：`false`
* **`Require new device emails`**：用户登录时，需要发送电子邮件。如果发送电子邮件失败，登录也将失败。默认值：`false`
* **`Reload templates (Dev)`**：将此设置为 `true` 时，每个请求都会重新加载模板。这会降低服务器速度，仅在开发过程中使用它。默认值：`false`
* **`Log timestamp format`**：日志的时间戳格式，参考[日期和时间语法格式](https://docs.rs/chrono/latest/chrono/format/strftime)。默认值：`%Y-%m-%d %H:%M:%S.%3f`
* *（已改为放入* [*Read-Only Config*](#read-only-config) *中）*~~**`Bypass admin page security (Know the risks!)`**：禁用管理页面的管理令牌，以便您可以在前端使用自己的认证方式。默认值：`false`~~
* **`Allowed iframe ancestors (Know the risks!)`**：允许将网页密码库嵌入到 iframe 中的域名列表，这对于嵌入到安全的内部网络中时有用
* **`Allowed connect-src (Know the risks!)`**：允许使用脚本界面（如转发电子邮箱别名功能）加载其他域名的 URL
* **`Admin session lifetime`**：设置管理员会话的生命周期值（单位分钟）
* **`Increase note size limit (Know the risks!)`**：将安全备注大小限制设置为 100\_000，而不是默认的 10\_000。警告：这可能会导致客户端出现问题。此外，导出将无法在 Bitwarden 服务器上运行！默认值：`false`

### Yubikey Settings

* **`Enabled`**：启用 Yubikey。默认值：`true`
* **`Client ID`**：在[此处](https://upgrade.yubico.com/getapikey/)申请的您的 `YUBICO_CLIENT_ID`
* **`Secret Key`**：在[此处](https://upgrade.yubico.com/getapikey/)申请的您的 `YUBICO_SECRET_KEY`
* **`Server`**：自定义 OTP 服务器地址。值为空表示使用默认的 YubiCloud 服务器地址

### Global Duo Settings

{% hint style="warning" %}
注意：用户可以覆盖这部分的设置
{% endhint %}

* **`Enabled`**：启用 Duo。默认值：`false`
* **`Client Id`**：[Duo 管理面板](https://admin.duosecurity.com/login)生成的 `Integration Key`
* **`Client Secret`**：[Duo 管理面板](https://admin.duosecurity.com/login)生成的 `Secret Key`
* **`Host`**：[Duo 管理面板](https://admin.duosecurity.com/login)生成的 `API hostname`

### SMTP Email Seiings

{% hint style="info" %}
**注意**：v1.25.0 版本之前的 Vaultwarden 有一个关于 SSL 和 TLS 的漏洞/错误标记的配置设置项。这已在后续测试版和新发布的版本中得到修复。

旧配置项是 `SMTP_SSL` 和 `SMTP_EXPLICIT_TLS`。

新配置项是 `SMTP_SECURITY`，它具有以下选项：`starttls`、`force_tls` 和 `off`。

* `SMTP_SECURITY=starttls` 等同于 `SMTP_SSL=true`

* `SMTP_SECURITY=force_tls` 等同于 `SMTP_EXPLICIT_TLS=true`
  {% endhint %}

* **`Enabled`**：启用 SMTP。默认值：`true`

* **`Use Sendmail`**：是否通过 sendmail 命令发送邮件。默认值：`false`

* **`Sendmail Command`**：使用哪个 sendmail 命令。如果未指定，则使用在 $PATH 中找到的那个

* **`Host`**：SMTP 服务器地址

* *（v1.25.0 及之后版本已移除）*~~**`Enable Secure SMTP`**：（显式）启用此功能后，将默认使用 STARTTLS（一般为 587 或 25 端口）。默认值：`true`~~

* *（v1.25.0 及之后版本已移除）*~~**`Force TLS`**：（隐式）启用此功能将强制使用 SSL/TLS 连接（一般为 465 端口），而不是使用 STARTTLS 升级的不安全的连接。`Enable Secure SMTP` 必须设置为 `true`，此设置才能起作用。默认值：`false`~~

* **`Secure SMTP`**：启用安全连接。可用的值：`starttls`（显式 - 端口 587 或 25）、`force_tls`（隐式 - 端口 465）、`off` 不加密。默认值： `starttls`

* **`Port`**：SMTP 服务器端口。默认值：`587`

* **`From Address`**：发件人地址

* **`From Name`**：发件人名称。默认值：`Vaultwarden`

* **`Username`**：用户名

* **`Password`**：密码

* **`SMTP Auth mechanism`**：对于 SSL，默认值应为 `Plain` 或 `Login`；对于非 SSL，默认值应为空。可用的值：`Plain`、`Login`、`Xoauth2`。使用多个选项时需要用英文逗号「`,`」分隔

* **`SMTP connection timeout`**：SMTP 连接超时时间（单位秒）。默认值：`15`

* **`Server name sent during HELO`**：默认情况下，此值是机器的主机名，但可能需要更改以防触发某些反垃圾邮件过滤器

* *（已改为放入* [*Read-Only Config*](#read-only-config) *中）*~~**`Enable SMTP debugging (Know the risks!)`**：危险：启用此功能会输出非常详细的 SMTP 信息。这可能包含敏感信息，如密码和用户名！仅在排除故障时才启用此功能。默认值：`false`~~

* **`Embed images as email attachments`**：默认值：`true`

* **`Accept Invalid Certs (Know the risks!)`**：危险：允许无效证书。这个选项会带来严重的漏洞，导致中间人攻击！仅当您无法使用有效证书时才将此作为最后的手段。如果证书有效但主机名不匹配，请改用 `SMTP_ACCEPT_INVALID_HOSTNAMES`（即下面的 `Accept Invalid Hostnames (Know the risks!)`）。默认值：`false`

* **`Accept Invalid Hostnames (Know the risks!)`**：危险：允许无效的主机名。这个选项会带来严重的漏洞，导致中间人攻击！仅当您无法使用有效证书时才将此作为最后的手段。默认值：`false`

* **`Test SMTP`**：根据以上的设置，发送测试邮件到指定的电子邮件地址，测试 SMTP 功能

### Email 2FA Settings

* **`Enabled`**：禁用将阻止用户设置新的电子邮件 2FA 以及使用已配置的电子邮件 2FA。默认值：`false`
* **`Email token size`**：电子邮件 Token 的位数（最小 `6`，最大 `19`）。请注意，无论这里设置为多少，Bitwarden 客户端都将其硬编码为 6 位数。默认值：`6`
* **`Token expiration time`**：Token 的最大有效时间（单位秒）。用户必须在此时间内打开电子邮件客户端并复制 Token。默认值：`600`
* **`Maximum attempts`**：重置电子邮件 Token 并发送新邮件之前的最大尝试次数。默认值：`3`
* **`Setup email 2FA at signup`**：设置为电子邮件 2FA 提供程序，而不考虑任何组织策略。默认值：`false`
* **`Auto-enable 2FA (Know the risks!)`**：在需要时自动将电子邮件 2FA 设置为备用提供程序。默认值：`false`

### Read-Only Config

{% hint style="warning" %}
注意：这些选项无法在编辑器（以及管理页面）中修改，因为它们需要重新启动服务器。要修改它们，需要在启动服务器时设置正确的环境变量。您可以在每个选项的工具提示中检查变量名称。
{% endhint %}

* **`Data folder`**：主数据文件夹。默认值：`data`
* **`Database URL`**：数据库 URL。默认值：`data/db.sqlite3`
* **`Icon cache folder`**：图标缓存文件夹。默认值：`data/icon_cache`
* **`Attachments folder`**：附件文件夹。默认值：`data/attachments`
* **`Sends folder`**：Send 文件夹。默认值：`data/sends`
* **`Temp folder`**：用于存储临时上传的文件。默认值：`data/tmp`
* **`Templates folder`**：模板数据文件夹，默认情况下使用嵌入式模板。默认值：`data/templates`
* **`Session JWT key`**：会话 [JWT](https://juejin.im/post/6844904034181070861#heading-10) 密钥。默认值：`data/rsa_key`
* **`Web vault folder`**：网页密码库文件夹。默认值：`web-vault/`
* **`Enable websocket notifications`**：启用 Websocket 通知。默认值：`false`
* *（v1.31.0 版本已移除）*~~**`Websocket address`**：Websocket 服务器地址。默认值：`0.0.0.0`~~
* *（v1.31.0 版本已移除）*~~**`Websocket port`**：Websocket 服务器端口。默认值：`3012`~~
* **`Enable push notifications`**：启用推送通知。默认值：`false`
* **`Push relay uri`**：推送中继的 URI。默认值：`https://push.bitwarden.com`
* **`Push identity uri`**：推送身份验证的 URI。默认值：`https://identity.bitwarden.com`
* **`Installation id`**：来自 <https://bitwarden.com/host> 的安装 ID
* **`Installation key`**：来自 <https://bitwarden.com/host> 的安装密钥
* **`Job scheduler poll interval`**：作业调度线程检查运行的频率。如果设置为 `0`，则全局禁止调度作业。默认值：`30000`
* **`Send purge schedule`**：检查是否有 Send 超过其删除日期的作业的 Cron 时间表。默认为每小时（第 5 分钟）。设置为空则禁用此作业。默认值：`0 5 * * * *`
* **`Trash purge schedule`**：检查要永久删除的废弃项目的作业的 Cron 时间表。默认为每天（午夜后的第 5 分钟）。设置为空则禁用此作业。默认值：`0 5 0 * * *`
* **`Incomplete 2FA login schedule`**：检查未完成 2FA 登录的作业的 Cron 时间表。默认为每分钟（第 30 秒）。设置为空则禁用此作业。默认值：`30 * * * *`
* **`Emergency notification reminder schedule`**：向紧急访问的授予人发送过期提醒作业的 Cron 时间表。默认为每小时（第 5 分钟）。设置为空则禁用此作业。默认值：`0 5 * * * *`
* **`Emergency request timeout schedule`**：授予已达到规定等待时间的紧急访问请求作业的 Cron 时间表。默认为每小时（第 5 分钟）。设置为空则禁用此作业。默认值：`0 5 * * * *`
* **`Event cleanup schedule`**：从事件表中清除旧事件的作业的 Cron 时间表。默认为每天（午夜后的第 10 分钟）。设置为空则禁用此作业。默认值：`0 10 0 * * *`
* **`Auth Request cleanup schedule`**：从验证请求中清除旧的验证请求的作业的 Cron 时间表。默认为每分钟（第 30 秒）。设置为空则禁用此作业。默认值：`30 * * * * *`
* **`Duo Auth context cleanup schedule`**：从数据库中清除过期 Duo 上下文的作业的 Cron 时间表。如果禁用了 Duo MFA 或将其设置为使用传统的 iframe 提示，则不会执行任何操作。默认为每分钟（第 30 秒）。设置为空则禁用此作业。默认值：`30 * * * * *`
* **`Domain Set`**：表示域名是否由管理员设置，否则将使用默认值。默认值：`false`
* **`Domain origin`**：域名 URL 源。例如 `https://vault.yourdomain.com:8443/admin`，其 Domian origin 是 `https://vault.yourdomain.com:8443`
* **`Domain path`**：域名 URL 路径。例如 `https://vault.yourdomain.com:8443/admin`，其 Domian path 是 `/admin`
* **`Enable web vault`**：启用网页密码库。默认值：`true`
* **`Enable event logging`**：为组织启用事件日志。默认值：`false`
* **`Invitation token expiration time (in hours)`**：组织邀请令牌、紧急访问邀请令牌、电子邮件验证令牌和删除请求令牌的失效小时数（必须至少为 `1`。单位小时）。默认值：`120`
* **`Events days retain`**：保存在数据库中的事件的天数。如果不设置，事件将无限期保留
* **`Internal IP header property, used to avoid recomputing each time`**：内部 IP 标头属性，用于避免每次重新计算。默认值：`true`
* **`Icon service`**：预定义的图标服务，选项包括：`internal`、`bitwarden`、`duckduckgo`、`google`。要指定自定义图标服务，请设置一个带有 `{}` 实例的 URL 模板，使用域名替换。例如：`https://icon.example.com/domain/{}`。 `internal` 指的是 Vaultwarden 的内置图标获取实现。如果设置了一个外部服务，则对 Vaultwarden 的图标请求将返回 HTTP 重定向到外部服务上的相应图标。默认值：`internal`
* **`_icon_service_url`**：图标服务 URL
* **`_icon_service_csp`**：图标服务 CSP
* **`[Deprecated] Icon blacklist Regex`**：改为使用 `http_request_block_regex`
* **`[Deprecated] Icon blacklist non global IPs`**：改为使用 `http_request_block_non_global_ips`
* **`Customize the enabled feature flags on the clients`**：这是一个要启用的以英文逗号分隔的功能标志列表。默认值：`fido2-vault-credentials`
* **`Enable extended logging`**：启用扩展日志记录，这将在日志中显示时间戳和目标。默认值：`true`
* **`Enable the log to output to Syslog`**：启用记录到 [Syslog](https://zh.wikipedia.org/wiki/Syslog)。默认值：`false`
* **`Log file path`**：日志记录文件的路径。默认值：`/data/vaultwarden.log`
* **`Log level`**：日志记录的级别。可用的值：`trace`、`tebug`、`info`、`warn`、`error` 以及 `off`。为了减少日志数量，可以将级别设置为 `warn` 或 `error`。默认值：`info`。
* **`Enable DB WAL`**：启用数据库 WAL。关闭这个设置可能会导致性能变差，但如果在一些不支持 WAL 的外来文件系统上使用 Vaultwarden，可能会有帮助。在改变这个设置之前，请参阅[项目 Wiki](https://rs.ppgg.in/configuration/database/running-without-wal-enabled)。默认值：`true`
* **`Max database connection retries`**：在启动过程中重试数据库连接的次数，每次重试的间隔时间为 1 秒，设置为 `0` 表示无限制重试。默认值：`15`
* **`Timeout when aquiring database connection`**：获取数据库连接时超时时间。默认值：`30`
* **`Database connection pool size`**：用于连接数据库的连接池的大小。默认值：`10`
* **`Database connection init`**：创建新数据库连接时运行的 SQL 语句，主要对连接范围内的 pragmas 有用。如果为空，则使用数据库指定的默认值。默认值：空
* **`Bypass admin page security (Know the risks!)`**：禁用管理页面的管理令牌，以便您可以在前端使用自己的验证方式。默认值：`false`
* **`Seconds between login requests`**：在启动速率限制之前，来自同一 IP 地址的登录和 2FA 请求之间的平均秒数。默认值：`60`
* **`Max burst size for login requests`**：在保持 `login_ratelimit_seconds` 指示的平均值的情况下，允许最多此大小的突发请求。注意，这同时适用于登录和 2FA，所以建议至少允许 2 个突发请求。默认值：`10`
* **`Seconds between admin requests`**：在启动速率限制之前，来自同一 IP 地址的管理请求之间的平均秒数。默认值：`300`
* **`Max burst size for admin requests`**：在保持 `admin_ratelimit_seconds` 指示的平均值的情况下，允许最多此大小的突发请求。默认值：`3`
* **`Enable groups (BETA!) (Know the risks!)`**：为组织启用群组支持（目前存在已知问题！）。默认值：`false`
* **`Generated max_note_size value to prevent if..else matching during every check`**：生成的最大备注大小值，以防止每次检查时都出现 if...else 匹配问题。默认值：`10000`
* **`Enforce Single Org with Reset Password Policy`**：在设置重置密码策略（Bitwarden 默认执行此策略）之前强制启用单一组织策略。我们鼓励使用多个组织，因为在 Vaultwarden 中群组不可用。将此设置为 `true` 将在启用重置密码策略之前强制启用单一组织策略。默认值：`false`
* **`Attempt to use deprecated iframe-based Traditional Prompt (Duo WebSDK 2)`**：尝试使用过时的基于 iframe 的传统提示（Duo WebSDK 2）**。**&#x9ED8;认值：`false`
* **`Application Key (generated automatically)`**：Duo 相关的密钥，（启用 Duo 后）由系统自动生成
* **`Sendmail Command`**：要使用的 Sendmail 命令。如果未指定，则使用在 $PATH 中找到的
* **`DEPRECATED smtp_ssl`**：请使用 `SMTP_SECURITY`
* **`DEPRECATED smtp_explicit_tls`**：请使用 `SMTP_SECURITY`
* **`_smtp_img_src`**：默认值：`cid:`
* **`Enable SMTP debugging (Know the risks!)`**：启用该选项将输出非常详细的 SMTP 信息。其可能包含敏感信息，如密码和用户名！仅在需要排除故障时才启用此功能！默认值：`false`

### Backup Database

{% hint style="warning" %}
**警告：**&#x6B64;功能仅创建 SQLite 数据库的备份副本。这不包括完全恢复 Vaultwarden 实例可能需要的任何配置或文件附件数据。有关如何执行完整备份的详细信息，请参阅[备份](https://rs.ppgg.in/other-information/backing-up-your-vault) wiki 页面。
{% endhint %}

## 管理页面可读写配置项与环境变量名称的对应 <a href="#configuration-options-corresponding-to-variable" id="configuration-options-corresponding-to-variable"></a>

<table><thead><tr><th width="203.80980706304">管理页面可读写配置项</th><th width="204.07124226928534">对应的环境变量（或 config.json 中字段）</th><th>默认值</th></tr></thead><tbody><tr><td><strong>General Settings</strong></td><td></td><td></td></tr><tr><td>Domain URL</td><td>[domain]</td><td></td></tr><tr><td>Allow Sends</td><td>[sends_allowed]</td><td>true</td></tr><tr><td>HIBP Api Key</td><td>[hibp_api_key]</td><td></td></tr><tr><td>Per-user attachment limit (KB)</td><td>[user_attachment_limit]</td><td></td></tr><tr><td>Per-organization attachment limit (KB)</td><td>[org_attachment_limit]</td><td></td></tr><tr><td>Per-user send storage limit (KB)</td><td>[user_send_limit]</td><td></td></tr><tr><td>Trash auto-delete days</td><td>[trash_auto_delete_days]</td><td></td></tr><tr><td>Incomplete 2FA time limit</td><td>[incomplete_2fa_time_limit]</td><td>3</td></tr><tr><td>Disable icon downloads</td><td>[disable_icon_download]</td><td>false</td></tr><tr><td>Allow new signups</td><td>[signups_allowed]</td><td>true</td></tr><tr><td>Require email verification on signups. This will prevent logins from succeeding until the address has been verified</td><td>[signups_verify]</td><td>false</td></tr><tr><td>If signups require email verification, automatically re-send verification email if it hasn't been sent for a while (in seconds)</td><td>[signups_verify_resend_time]</td><td>3600</td></tr><tr><td>If signups require email verification, limit how many emails are automatically sent when login is attempted (0 means no limit)</td><td>[signups_verify_resend_limit]</td><td>6</td></tr><tr><td>Email domain whitelist</td><td>[signups_domains_whitelist]</td><td></td></tr><tr><td>Org creation users</td><td>[org_creation_users]</td><td></td></tr><tr><td>Allow invitations</td><td>[invitations_allowed]</td><td>true</td></tr><tr><td>Eable emergency access</td><td>[emergency_access_allowed]</td><td>true</td></tr><tr><td>Allow email change</td><td>[email_change_allowed]</td><td>true</td></tr><tr><td>Password iterations</td><td>[password_iterations]</td><td>100000</td></tr><tr><td>Allow password hints</td><td>[password_hints_allowed]</td><td>true</td></tr><tr><td>Show password hint (Know the risks!)</td><td>[show_password_hint]</td><td>false</td></tr><tr><td>Admin token/Argon2 PHC</td><td>[admin_token]</td><td></td></tr><tr><td>Invitation organization name</td><td>[invitation_org_name]</td><td>Vaultwarden</td></tr><tr><td><strong>Advanced Setings</strong></td><td></td><td></td></tr><tr><td>Client IP header</td><td>[ip_header]</td><td>X-Real-IP</td></tr><tr><td>Icon redirect code</td><td>[icon_redirect_code]</td><td>302</td></tr><tr><td>Positive icon cache expiry</td><td>[icon_cache_ttl]</td><td>2592000</td></tr><tr><td>Negative icon cache expiry</td><td>[icon_cache_negttl]</td><td>259200</td></tr><tr><td>Icon download timeout</td><td>[icon_download_timeout]</td><td>10</td></tr><tr><td>Block HTTP domains/IPs by Regex</td><td>[http_request_block_regex]</td><td></td></tr><tr><td>Block non global IPs</td><td>[http_request_block_non_global_ips]</td><td>true</td></tr><tr><td>Disable Two-Factor remember</td><td>[disable_2fa_remember]</td><td>false</td></tr><tr><td>Disable authenticator time drifted codes to be valid</td><td>[authenticator_disable_time_drift]</td><td>false</td></tr><tr><td>Require new device emails</td><td>[require_device_email]</td><td>false</td></tr><tr><td>Reload templates (Dev)</td><td>[reload_templates]</td><td>false</td></tr><tr><td>Log timestamp format</td><td>[log_timestamp_format]</td><td>%Y-%m-%d %H:%M:%S.%3f</td></tr><tr><td><del>Bypass admin page security (Know the risks!)</del></td><td><del>[disable_admin_token]</del></td><td><del>false</del></td></tr><tr><td>Allowed iframe ancestors (Know the risks!)</td><td>[allowed_iframe_ancestors]</td><td></td></tr><tr><td>Allowed connect-src (Know the risks!)</td><td>[allowed_connect_src ]</td><td></td></tr><tr><td>Admin session lifetime</td><td>[admin_session_lifetime]</td><td></td></tr><tr><td>Increase note size limit (Know the risks!)</td><td>[increase_note_size_limit]</td><td>false</td></tr><tr><td><strong>Yubikey Seetings</strong></td><td></td><td></td></tr><tr><td>Enabled</td><td>[_enable_yubico]</td><td>true</td></tr><tr><td>Client ID</td><td>[yubico_client_id]</td><td></td></tr><tr><td>Secret Key</td><td>[yubico_secret_key]</td><td></td></tr><tr><td>Server</td><td>[yubico_server]</td><td></td></tr><tr><td><strong>Global Duo Settings</strong></td><td></td><td></td></tr><tr><td>Enabled</td><td>[_enable_duo]</td><td>false</td></tr><tr><td>Client Id</td><td>[duo_ikey]</td><td></td></tr><tr><td>Client Secret</td><td>[duo_skey]</td><td></td></tr><tr><td>Host</td><td>[duo_host]</td><td></td></tr><tr><td><strong>SMTP Email Settings</strong></td><td></td><td></td></tr><tr><td>Enabled</td><td>[_enable_smtp]</td><td>true</td></tr><tr><td>Use Sendmail</td><td>[use_sendmail]</td><td>false</td></tr><tr><td>Sendmail Command</td><td>[sendmail_command]</td><td></td></tr><tr><td>Host</td><td>[smtp_host]</td><td></td></tr><tr><td><del>Enable Secure SMTP</del></td><td><del>[smtp_ssl]</del></td><td><del>true</del></td></tr><tr><td><del>Force TL</del>S</td><td><del>[smtp_explicit_tls]</del></td><td><del>false</del></td></tr><tr><td>Secure SMTP</td><td>[smtp_security]</td><td>starttls</td></tr><tr><td>Port</td><td>[smtp_port]</td><td>587</td></tr><tr><td>From Address</td><td>[smtp_from]</td><td></td></tr><tr><td>From Name</td><td>[smtp_from_name]</td><td>Vaultwarden</td></tr><tr><td>Username</td><td>[smtp_username]</td><td></td></tr><tr><td>Password</td><td>[smtp_password]</td><td></td></tr><tr><td>SMTP Auth mechanism</td><td>[smtp_auth_mechanism]</td><td></td></tr><tr><td>SMTP connection timeout</td><td>[smtp_timeout]</td><td>15</td></tr><tr><td>Server name sent during HELO</td><td>[helo_name]</td><td></td></tr><tr><td><del>Enable SMTP debugging (Know the risks!)</del></td><td><del>[smtp_d</del>e<del>bug]</del></td><td><del>false</del></td></tr><tr><td>Embed images as email attachments</td><td>[smtp_embed_images]</td><td>ture</td></tr><tr><td>Accept Invalid Certs (Know the risks!)</td><td>[smtp_accept_invalid_certs]</td><td>false</td></tr><tr><td>Accept Invalid Hostnames (Know the risks!)</td><td>[smtp_accept_invalid_hostnames]</td><td>false</td></tr><tr><td>Test SMTP</td><td>-</td><td></td></tr><tr><td><strong>Email 2FA Settings</strong></td><td></td><td></td></tr><tr><td>Enabled</td><td>[_enable_email_2fa]</td><td>false</td></tr><tr><td>Email token size</td><td>[email_token_size]</td><td>6</td></tr><tr><td>Token expiration time</td><td>[email_expiration_time]</td><td>600</td></tr><tr><td>Maximum attempts</td><td>[email_attempts_limit]</td><td>3</td></tr><tr><td>Setup email 2FA at signup</td><td>[email_2fa_enforce_on_verified_invite]</td><td>false</td></tr><tr><td>Auto-enable 2FA (Know the risks!)</td><td>[email_2fa_auto_fallback]</td><td>false</td></tr></tbody></table>

## 管理页面只读配置项与环境变量名称的对应 <a href="#read-only-configuration-options-corresponding-to-variable" id="read-only-configuration-options-corresponding-to-variable"></a>

\[**备注**]：管理页面的只读部分配置项只能通过环境变量进行设置。

| 管理页面只读配置项                                                                       | 对应的环境变量（或 config.json 中字段）                       | 默认值                              |
| ------------------------------------------------------------------------------- | ------------------------------------------------ | -------------------------------- |
| Data folder                                                                     | \[data\_folder]                                  | data                             |
| Database URL                                                                    | \[database\_url]                                 | data/db.sqlite3                  |
| Icon cache folder                                                               | \[icon\_cache\_folder]                           | data/icon\_cache                 |
| Attachments folder                                                              | \[attachments\_folder]                           | data/attachments                 |
| Sends folder                                                                    | \[sends\_folder]                                 | data/sends                       |
| Temp folder                                                                     | \[tmp\_folder]                                   | data/tmp                         |
| Templates folder                                                                | \[templates\_folder]                             | data/templates                   |
| Session JWT key                                                                 | \[rsa\_key\_filename]                            | data/rsa\_key                    |
| Web vault folder                                                                | \[web\_vault\_folder]                            | web-vault/                       |
| Enable websocket notifications                                                  | \[enable\_websocket]                             | false                            |
| ~~Websocket address~~                                                           | ~~\[websocket\_address]~~                        | ~~0.0.0.0~~                      |
| ~~Websocket port~~                                                              | ~~\[websocket\_port]~~                           | ~~3012~~                         |
| Enable push notifications                                                       | \[push\_enabled]                                 |                                  |
| Push relay uri                                                                  | \[push\_relay\_uri]                              | <https://push.bitwarden.com>     |
| Push identity uri                                                               | \[push\_identity\_uri]                           | <https://identity.bitwarden.com> |
| Installation id                                                                 | \[push\_installation\_id]                        |                                  |
| Installation key                                                                | \[push\_installation\_key]                       |                                  |
| Job scheduler poll interval                                                     | \[job\_poll\_interval\_ms]                       | 30000                            |
| Send purge schedule                                                             | \[send\_purge\_schedule]                         | 0 5 \* \* \* \*                  |
| Trash purge schedule                                                            | \[trash\_purge\_schedule]                        | 0 5 0 \* \* \*                   |
| Incomplete 2FA login schedule                                                   | \[incomplete\_2fa\_schedule]                     | 30 \* \* \* \* \*                |
| Emergency notification reminder schedule                                        | \[emergency\_notification\_reminder\_schedule]   | 0 5 \* \* \* \*                  |
| Emergency request timeout schedule                                              | \[emergency\_request\_timeout\_schedule]         | 0 5 \* \* \* \*                  |
| Event cleanup schedule                                                          | \[event\_cleanup\_schedule]                      | 0 10 0 \* \* \*                  |
| Auth Request cleanup schedule                                                   | \[auth\_request\_purge\_schedule]                | 30 \* \* \* \* \*                |
| Duo Auth context cleanup schedule                                               | \[duo\_context\_purge\_schedule]                 | 30 \* \* \* \* \*                |
| Domain Set                                                                      | \[domain\_set]                                   | false                            |
| Domain origin                                                                   | \[domain\_origin]                                |                                  |
| Domain path                                                                     | \[domain\_path]                                  |                                  |
| Enable web vault                                                                | \[web\_vault\_enabled]                           | true                             |
| Enable event logging                                                            | \[org\_events\_enabled]                          | false                            |
| Invitation token expiration time (in hours)                                     | \[invitation\_expiration\_hours]                 | 120                              |
| Events days retain                                                              | \[events\_days\_retain]                          |                                  |
| Internal IP header property, used to avoid recomputing each time                | \[\_ip\_header\_enabled]                         | true                             |
| Icon service                                                                    | \[icon\_service]                                 | internal                         |
| \_icon\_service\_url                                                            | \[\_icon\_service\_url]                          |                                  |
| \_icon\_service\_csp                                                            | \[\_icon\_service\_csp]                          |                                  |
| \[Deprecated] Icon blacklist Regex                                              | \[icon\_blacklist\_egex]                         |                                  |
| \[Deprecated] Icon blacklist non global IPs                                     | \[icon\_blacklist\_non\_global\_ips]             | true                             |
| Customize the enabled feature flags on the clients                              | \[experimental\_client\_feature\_flags]          | fido2-vault-credentials          |
| Enable extended logging                                                         | \[extended\_logging]                             | true                             |
| Enable the log to output to Syslog                                              | \[use\_syslog]                                   | false                            |
| Log file path                                                                   | \[log\_file]                                     | /data/log/vaultwarden.log        |
| Log level                                                                       | \[log\_level]                                    | Info                             |
| Enable DB WAL                                                                   | \[enable\_db\_wal]                               | true                             |
| Max database connection retries                                                 | \[db\_connection\_retries]                       | 15                               |
| Timeout when aquiring database connection                                       | \[database\_timeout]                             | 30                               |
| Database connection pool size                                                   | \[database\_max\_conns]                          | 10                               |
| Database connection init                                                        | \[database\_conn\_init]                          |                                  |
| Bypass admin page security (Know the risks!)                                    | \[disable\_admin\_token]                         | false                            |
| Seconds between login requests                                                  | \[login\_ratelimit\_seconds]                     | 60                               |
| Max burst size for login requests                                               | \[login\_ratelimit\_max\_burst]                  | 10                               |
| Seconds between admin requests                                                  | \[admin\_ratelimit\_seconds]                     | 300                              |
| Max burst size for admin requests                                               | \[admin\_ratelimit\_max\_burst]                  | 3                                |
| Enable groups (BETA!) (Know the risks!)                                         | \[org\_groups\_enabled]                          | false                            |
| Generated max\_note\_size value to prevent if..else matching during every check | \[\_max\_note\_size]                             | 10000                            |
| Enforce Single Org with Reset Password Policy                                   | \[enforce\_single\_org\_with\_reset\_pw\_policy] | false                            |
| Attempt to use deprecated iframe-based Traditional Prompt (Duo WebSDK 2)        | \[duo\_use\_iframe]                              | false                            |
| Application Key (generated automatically)                                       | \[\_duo\_akey]                                   |                                  |
| Sendmail Command                                                                | \[sendmail\_command]                             |                                  |
| DEPRECATED smtp\_ssl                                                            | \[smtp\_ssl]                                     |                                  |
| DEPRECATED smtp\_explicit\_tls                                                  | \[smtp\_explicit\_tls]                           |                                  |
| \_smtp\_img\_src                                                                | \[\_smtp\_img\_src]                              | cid:                             |
| Enable SMTP debugging (Know the risks!)                                         | \[smtp\_debug]                                   | false                            |


# 使用

## 配置 SMTP <a href="#config-smtp" id="config-smtp"></a>

### Gmail 示例 <a href="#example-for-gmail" id="example-for-gmail"></a>

```yaml
  "_enable_smtp": true,
  "smtp_host": "smtp.gmail.com",
  "smtp_security": "force_tls", # 对于v1.25.0 之前的版本，改为如下俩行：
  # "smtp_ssl": true, 
  # "smtp_explicit_tls": true,
  "smtp_port": 465,
  "smtp_from": "you@gmail.com",
  "smtp_from_name": "vaultwarden",
  "smtp_username": "you@gmail.com",
  "smtp_password": "Application-specific password", # 如果您的 Google 账户开启了二次验证，这里必须使用应用专用密码
  "smtp_auth_mechanism": "Login", # 注意此配置
  "smtp_timeout": 15,
```

{% hint style="warning" %}
“*为帮助确保您的帐号安全，从 **2022 年 5 月 30 日**起，Google 不再支持那些会要求您仅使用用户名和密码登录 Google 帐号的第三方应用或设备*”，参阅[此处](https://support.google.com/accounts/answer/6010255?hl=zh-Hans)。
{% endhint %}

对于 Gmail SMTP，建议使用 Google 的应用专用密码。参阅[使用应用专用密码登录](https://support.google.com/accounts/answer/185833?hl=zh-Hans)。

### Outlook 示例 <a href="#example-for-outlook" id="example-for-outlook"></a>

使用 Outlook 始终无法配置成功，但我部署的官方 Bitwarden 使用 Outlook 配置  SMTP 完全正常。此故障可能和这个有关：[# 851](https://github.com/dani-garcia/vaultwarden/issues/851)

## 更新 Vaultwarden <a href="#update-vaultwarden" id="update-vaultwarden"></a>

1、拉取最新版本的稳定版镜像

```shell
docker pull vaultwarden/server:latest
```

2、停止旧版本容器

```shell
docker stop vaultwarden
```

3、移除旧版本容器

```shell
docker rm vaultwarden
```

4、使用已挂载的数据创建新的容器

```shellscript
docker run -d --restart always --name vaultwarden -e TZ=Asia/Shanghai -e LOG_FILE=/data/log/vaultwarden.log -v /vaultwarden-data/:/data/ -p 8443:80 vaultwarden/server:latest
```

## 修改域名 <a href="#change-domain" id="change-domain"></a>

1. 为新域名添加相应的 DNS A 记录
2. 按照[准备](/vaultwarden/preparation)步骤中的说明添加新的虚拟主机
3. 按照[准备](/vaultwarden/preparation)步骤中的说明修改新主机的 Nginx 配置文件（位置：`/usr/local/nginx/conf/vhost/your-new-domain.com.conf`）
4. 重启 Nginx
5. 修改 Vaultwarden 配置文件（位置：`/vaultwarden-data/config.json`），将 `"domain"` 的值修改为新的域名
6. 重启 Vaultwarden（命令：`docker restart vaultwarden`）

## 自动备份数据 <a href="#auto-backup-data" id="auto-backup-data"></a>

这里我们使用 [dropbox\_uploader.sh](https://github.com/andreafabrizi/Dropbox-Uploader) 脚本自动打包并备份整个 `vaultwarden-data` 文件夹到 Dropbox。

### 1、创建 Dropbox 应用 <a href="#id-1-create-dropbox-application" id="id-1-create-dropbox-application"></a>

1. 登录 Dropbox 后，打开 [App Console](https://www.dropbox.com/developers/apps) 页面，点击 **Create app** 按钮创建一个 App
2. **Choose an API** → 勾选 **Scoped access**（以前可选 **Dropbox Legacy API**，目前已移除）
3. **Choose the type of access you need** → 选择 **App folder**
4. **Name your app** → 输入 **App 名称**（必须是不存在的名称，已存在会有提示已被占用），此名称会作为 Dropbox 上此 App 可读写的文件夹名称
5. 创建成功后，进入应用
6. 在 **Setting** 选项卡下的 **OAuth 2** 部分，**Access token expiration** 选择 **No expiration**，然后点击 **Generated access token** 下方的 **Generate** 按钮生成 `access token`，记录下此 `access token` 值（刷新页面后将不会再次显示）

### 2、上传并配置脚本 <a href="#id-2-upload-and-config-script" id="id-2-upload-and-config-script"></a>

SSH 定位到 VPS 的 `root` 目录，下载 [`dropbox_uploader.sh`](https://github.com/andreafabrizi/Dropbox-Uploader) 脚本文件，然后赋予可执行权限，然后运行脚本：

```bash
# 下载 dropbox_uploader.sh 脚本文件
wget https://raw.github.com/andreafabrizi/Dropbox-Uploader/master/dropbox_uploader.sh

# 赋予可执行权限
chmod +x dropbox_uploader.sh

# 运行此脚本配置 access token
./dropbox_uploader.sh
```

根据提示输入刚才的 Dropbox 应用的 `access token` 值，以配置 `dropbox_uploader.sh`。

\[**备注**]：删除 `.dropbox_uploader` 文件后再次运行 `./dropbox_uploader.sh` 命令可以重新配置 `access token`（或直接编辑 `.dropbox_uploader` 文件）。

### 3、创建自己的备份脚本 <a href="#id-3-create-your-own-script" id="id-3-create-your-own-script"></a>

```shell
vi /root/vaultwarden-data_backup.sh
```

复制并粘帖如下内容：

```bash
#!/bin/bash

# 这个改成你存放已下载的 dropbox_uploader.sh 的文件夹位置
SCRIPT_DIR="/root"
# 这个改成你的备份文件想要放在 Dropbox 上的文件夹名称。如果不存在，脚本会自动创建
BACK_DIR="/vaultwarden-data"
# 这个是你想要备份的本地 VPS 上的文件夹，不同的目录用空格分开
BACKUP_SRC="/vaultwarden-data"
# 这个是你临时存放备份压缩文件的地方，这里我们放在 /tmp/vaultwarden-data-backup 下
BACKUP_DST="/tmp/vaultwarden-data-backup"

# 定义备份文件的名称
## 定义当前日期的备份文件
BACKUP_FILE=vaultwarden-data_$(date +"%Y-%m-%d").tar.gz
## 定义 6 天前的备份文件
OLD_BACKUP_FILE_6=vaultwarden-data_$(date -d -6day +"%Y-%m-%d").tar.gz
## 定义 15 天前的备份文件
OLD_BACKUP_FILE_15=vaultwarden-data_$(date -d -15day +"%Y-%m-%d").tar.gz

# 删除 VPS 上 6 天前的备份文件
rm -rf "$BACKUP_DST/$OLD_BACKUP_FILE_6"

# 对备份文件夹进行压缩打包
tar zcf "$BACKUP_DST/$BACKUP_FILE" $BACKUP_SRC

# 上传备份文件到 Dropbox
$SCRIPT_DIR/dropbox_uploader.sh upload "$BACKUP_DST/$BACKUP_FILE" "$BACK_DIR/$BACKUP_FILE"

# 删除 Dropbox 上 15 天前的备份文件
$SCRIPT_DIR/dropbox_uploader.sh delete "$BACK_DIR/$OLD_BACKUP_FILE_15"
```

赋予可执行权限：

```shell
chmod +x /root/vaultwarden-data_backup.sh
```

输入 `./vaultwarden-data_backup.sh` 手动执行脚本，以测试能否成功备份。

{% hint style="info" %}
运行 `./vaultwarden-data_backup.sh` 手动执行脚本时可能会出现 error，只要能成功备份，不用理会这些错误。
{% endhint %}

### 4、创建自动执行任务 <a href="#id-4-create-autorun-task" id="id-4-create-autorun-task"></a>

```shellscript
# 打开定时任务
crontab -e

# 添加一行新任务：每天凌晨 4 点自动执行此脚本
0 4 * * * /root/vaultwarden-data_backup.sh

# 重启定时任务
service crond restart
```

## 日志转储 <a href="#logging-logrotation" id="logging-logrotation"></a>

如果你想保留日志记录，又不希望日志记录文件变得越来越大，可以设置定期转储日志记录。

创建日志转储规则文件：

```shell
vi /etc/logrotate.d/vaultwarden
```

复制并粘帖如下内容：

```yaml
# 其他配置项使用 logrotate 配置文件 /etc/logrotate.conf 中的默认值
/vaultwarden-data/log/vaultwarden.log
{
  daily
  rotate 30
  missingok
  copytruncate
  noolddir
  dateext
  postrotate
  find /vaultwarden-data/log/ -name vaultwarden.log"-`(date +%Y%m%d)`" -exec mv {} /vaultwarden-data/log/vaultwarden"-`(date +%Y%m%d)`".log \;
  endscript
}
```

这里设置为每天转储一次（如果日志记录比较少也可以设置为每周或每月），并保留 30 个转储的日志记录文件。

配置解释：

* `daily`：`daily` 指定转储周期为每天。也可以为 `weekly` / `monthly` 。默认为 `weekly`。
* `rotate 30`：表示转储备份的数量。这里为 30 个。
* `missingok`：在日志转储期间，任何错误将被忽略。
* `copytruncate`：用于还在打开中的日志文件。把当前日志截断并备份，然后再清空。由于备份和清空之间有一个时间差，可能会丢失部分日志数据。
* `noolddir`：转储后的日志文件和当前日志文件放在同一个目录下。
* `dateext`：指定转储后的日志文件以当前日期格式结尾。如 `vaultwarden.log-20201020`。
* `postrotate/endscript`：在转储之后需要执行的命令可以放入这个语句对中，这两个关键字必须单独成行。同样，`prerotate/endscript` 表示在转储之前需要执行的命令。

详细配置参阅 [logrotate 日志管理工具](https://www.cnblogs.com/wushuaishuai/p/9330952.html)。

## 定期清空日志 <a href="#clear-the-log-regularly" id="clear-the-log-regularly"></a>

如果你不想保留日志记录，也可以设置定期将其清空。

创建脚本文件：

```shellscript
vi /root/del_vaultwarden_log.sh
```

复制并粘帖如下内容：

```shellscript
#! /bin/bash
cat /dev/null > /vaultwarden-data/log/vaultwarden.log # 清空 Vaultwarden 的日志记录
```

赋予可执行权限：

```shell
chmod +x /root/del_vaultwarden_log.sh
```

创建自动执行任务：

```shellscript
# 打开定时任务
crontab -e

# 添加一行新任务：每月 1 号的凌晨 1 点自动执行此脚本
0 1 1 * * /root/del_vaultwarden_log.sh

# 重启定时任务
service crond restart
```

## 设置 Fail2ban <a href="#setup-fail2ban" id="setup-fail2ban"></a>

设置[ Fail2ban](https://www.fail2ban.org/) 后，可以在您设置的 n 次错误登录后自动阻止登录的 IP 地址，防止攻击者暴力破解您的密码库登录，以增强您的 Vaultwarden 的安全性。

{% hint style="danger" %}
如果您的域名使用 [Cloudflare](https://www.cloudflare.com/) 解析，为了使 Fail2ban 对 IP 拦截更准确，需要设置其代理状态为  `DNS only`（仅限 DNS），而不要设置为 `Proxied`（已代理）。
{% endhint %}

{% hint style="info" %}
下面的 jail 文件中 的 `action =` 语句根据 CentOS 7 使用的是 iptables 防火墙，如果使用 [Firewalld](https://firewalld.org/)，写法应有所不同。
{% endhint %}

这里以我的 [Vultr](https://www.vultr.com/?ref=7966491) 上的 CentOS 7 with iptables 防火墙为例。

### 安装 Fail2ban <a href="#install-fail2ban" id="install-fail2ban"></a>

```shell
sudo yum install epel-release # 对于 CentOS 7 需要先安装 EPEL 库
sudo yum install fail2ban # 安装 Fail2Ban
```

将 Fail2ban 加入开机启动：

```shell
sudo systemctl enable fail2ban
```

启动 Fail2ban：

```shell
sudo systemctl start fail2ban
```

### 为网页密码库配置 Fail2ban <a href="#config-fail2ban-for-web-vault" id="config-fail2ban-for-web-vault"></a>

#### 创建 filter 文件 <a href="#create-filter-file" id="create-filter-file"></a>

创建文件：

```shell
vi /etc/fail2ban/filter.d/vaultwarden.local
```

复制并粘帖如下内容：

```systemd
[INCLUDES]
before = common.conf

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

#### 创建 Jail 文件 <a href="#create-jail-file" id="create-jail-file"></a>

创建文件：

```shell
vi /etc/fail2ban/jail.d/vaultwarden.local
```

复制并粘帖如下内容：

```systemd
[vaultwarden]
enabled = true
filter = vaultwarden
action = iptables[name=vaultwarden, port=443, protocol=tcp]
logpath = /vaultwarden-data/log/vaultwarden.log
maxretry = 10
bantime = 43200
findtime = 3600
```

### 为管理页面配置 Fail2ban <a href="#config-fail2ban-for-admin-portal" id="config-fail2ban-for-admin-portal"></a>

#### 创建 filter 文件 <a href="#create-filter-file" id="create-filter-file"></a>

创建文件：

```shell
vi /etc/fail2ban/filter.d/vaultwarden-admin.local
```

复制并粘帖如下内容：

```systemd
[INCLUDES]
before = common.conf

[Definition]
failregex = ^.*Invalid admin token\. IP: <ADDR>.*$
ignoreregex =
```

#### 创建 Jail 文件 <a href="#create-jail-file" id="create-jail-file"></a>

创建文件：

```shell
vi /etc/fail2ban/jail.d/vaultwarden-admin.local
```

复制并粘帖如下内容：

```systemd
[vaultwarden-admin]
enabled = true
filter = vaultwarden-admin
action = iptables[name=vaultwarden, port=443, protocol=tcp]
logpath = /vaultwarden-data/log/vaultwarden.log
maxretry = 10
bantime = 43200
findtime = 3600
```

### 测试 Fail2ban <a href="#test-fail2ban" id="test-fail2ban"></a>

先打开文件监控：

```shell
sudo tail -f /var/log/fail2ban.log
```

然后尝试用错误的登录信息登录网页密码库或管理页面，Fail2ban 如果生效的话，将在 `fail2ban.log` 文件监控窗口显示相关的警告信息，类似于： `INFO [vaultwarden] Found 172.68.142.89 - 2020-11-03 20:15:08`，当一定时间内达到设置的失败次数时：`NOTICE [vaultwarden] Ban 172.68.142.89`，如下图：

![](/files/-MQl-5nlr-NwqXZUFvJK)

同时查看系统的当前 iptables，在最下面会显示 f2b-vaultwarden 封禁的 IP：

```shell
sudo iptables --list -n
```

如果您的 IP 被 ban，浏览器刷新时将无法再次打开网页密码库或管理页面。

#### 解除被 ban 的 IP <a href="#unban-ip" id="unban-ip"></a>

```shell
sudo fail2ban-client set vaultwarden unbanip xxx.xxx.xxx.xxx
```

#### Fail2ban 不起作用 <a href="#fail2ban-not-working" id="fail2ban-not-working"></a>

参看[故障 - Fail2ban 不起作用](/vaultwarden/troubleshoot#fail2ban-not-work)章节。

### Fail2ban 常用命令及参数解释 <a href="#fail2ban-common-commands" id="fail2ban-common-commands"></a>

Fail2ban 常用命令：

* `sudo systemctl start fail2ban` # 启动 Fail2ban
* `sudo systemctl stop fail2ban` # 停止 Fail2ban
* `sudo systemctl restart fail2ban` # 重启 Fail2ban
* `sudo fail2ban-client ping` # 检查 Fail2ban 是否正常运行（正常将显示 `pong`）

参数解释：

* `failregex = ^.*Invalid admin token\. IP: <ADDR>.*$` # 查找日志记录中错误记录正则表达式
* `ignoreregex =` # 忽略日志记录中错误记录正则表达式
* `filter = vaultwarden` # 对应的筛选器名称
* `action = iptables[name=vaultwarden, port=443, protocol=tcp]` # 动作参数
* `logpath = /vaultwarden-data/log/vaultwarden.log` # 日志文件的路径
* `maxretry = 10` # IP 被 ban 前允许失败的次数
* `bantime = 43200` # IP 被 ban 的时长（秒），`-1` 表示永 ban
* `findtime = 3600` # 此时长（秒）内达到 `maxretry` 次就 ban IP
* `ignoreip = xxx.xxx.xxx.xxxx` # 不受限制的 IP

### 参考链接 <a href="#reference-links" id="reference-links"></a>

* [如何使用 fail2ban 防御 SSH 服务器的暴力破解攻击](https://linux.cn/article-5067-1.html)
* [CentOS7 下安装和使用 Fail2ban](https://www.jianshu.com/p/4fdec5794d08)

## 电子邮件模板和管理面板本地化 <a href="#localization" id="localization"></a>

{% hint style="info" %}
注意模板文件对应的 Vaultwarden 版本。不同版本的 Vaultwarden 的模板文件会有一定的差别（差别应该不大）。
{% endhint %}

### 电子邮件模板 <a href="#email-templates" id="email-templates"></a>

1. 将 [Vaultwarden 存储库](https://github.com/dani-garcia/vaultwarden)电子邮件模板文件（位置：`src/static/templates/email`）里的相应文字翻译成您需要的语言，注意确保文件里的 `{{variables}}` 以及 HTML 标签的完整
2. 保持文件结构，将翻译好的模板文件放置于您安装的 Vaultwarden 对应的文件夹下（这里为 `/vaultwarden-data/templates/email`，其中 `vaultwarden-data` 是部署的时候使用 `-v` 参数指定的宿主机文件夹 ）
3. 重启 Vaultwarden（命令：`docker restart vaultwarden`）

### 管理面板模板 <a href="#admin-panel-templates" id="admin-panel-templates"></a>

1. 将 [Vaultwarden 存储库](https://github.com/dani-garcia/vaultwarden)管理面板模板文件（位置：`src/static/templates/admin`）里的相应文字翻译成您需要的语言，注意确保文件里的 `{{variables}}` 以及 HTML 标签的完整
2. 保持文件结构，将翻译好的模板文件放置于您的安装的 Vaultwarden 对应的文件夹下（这里为 `/vaultwarden-data/templates/admin`，其中 `vaultwarden-data` 是部署的时候使用 `-v` 参数指定的宿主机文件夹 ）
3. 重启 Vaultwarden（命令：`docker restart vaultwarden`）


# 故障

## 使用 Outlook 配置 SMTP 不成功 <a href="#configuring-smtp-with-outlook-does-not-work" id="configuring-smtp-with-outlook-does-not-work"></a>

使用 Outlook 始终无法在 Vaultwarden 上配置成功，但我部署的官方 Bitwarden 使用 Outlook 配置  SMTP 完全正常。此故障可能和这个有关：[# 851](https://github.com/dani-garcia/vaultwarden/issues/851)

## 直接修改 `config.json` 文件不生效 <a href="#modifying-the-config-json-file-directly-does-not-work" id="modifying-the-config-json-file-directly-does-not-work"></a>

通过管理页面修改配置并保存后，会将配置参数写入 `config.json` 文件，但当通过直接编辑 `config.json` 文件配置参数后，管理页面无法读取修改后的配置参数。

**原因为只有在 Vaultwarden 容器启动时才会读取 `config.json` 文件**。修改 `config.json` 文件后要使功能生效，需要在修改 `config.json` 文件后重启 Vaultwarden 容器：

```shell
docker restart vaultwarden
```

## 日志记录的时间和系统时间不一致 <a href="#the-time-of-logging-and-the-system-time-do-not-match" id="the-time-of-logging-and-the-system-time-do-not-match"></a>

日志记录使用 UTC（全球标准时间），而中国使用时间为 UTC+8，比 UTC 推后 8小时。

在创建 Vaultwarden 容器时加上时区环境变量：

```systemd
-e TZ=Asia/Shanghai
```

## Fail2ban 不起作用 <a href="#fail2ban-not-work" id="fail2ban-not-work"></a>

先查看 Fail2ban 是否正常运行。如果正常运行，运行下面的命令后将显示 `Server replied: pong`：

```shell
sudo fail2ban-client ping
```

如果 Fail2ban 正常运行，可能的原因：

### 创建 Jail 文件时 Vaultwarden 日志记录文件的路径设置不正确 <a href="#incorrect-path-setting-when-creating-jail-file" id="incorrect-path-setting-when-creating-jail-file"></a>

### Vaultwarden 日志记录文件中记录项的时间和系统时间不一致 <a href="#the-time-of-the-log-entry-and-the-system-time-do-not-match" id="the-time-of-the-log-entry-and-the-system-time-do-not-match"></a>

**原因**：Vaultwarden 容器的时区与主机的时区不一致

**现象**：无论怎么测试，fail2ban.log 中看不到 ban IP 的记录

**解决**：在创建 Vaultwarden 容器时加上时区环境变量：`-e TZ = Asia/Shanghai`

### Fail2ban 的 iptables 封禁策略不正确 <a href="#fail2bans-iptables-blocking-policy-is-incorrect" id="fail2bans-iptables-blocking-policy-is-incorrect"></a>

**原因**：Fail2ban 默认的 iptables 封禁策略为 `REJECT--reject-with icmp-port-unreachable`，需要变更为 `DROP`

**现象**：`sudo iptables --list -n` 命令能看到被 ban 的 IP 记录，但封禁策略为 `REJECT`

**解决**：编辑 `/etc/fail2ban/action.d/iptables-common.conf` 文件，将封禁策略变更为 `DROP`

```bash
# 打开 iptables-common.conf 文件
sudo vi /etc/fail2ban/action.d/iptables-common.conf

# 注释掉这一行
blocktype = REJECT --reject-with icmp-port-unreachable

# 添加一行
blocktype = DROP

# 重启 Fail2ban
sudo systemctl restart fail2ban
```

## Let's Encrypt 证书未自动续期 <a href="#lets-encrypt-certificate-does-not-auto-renew" id="lets-encrypt-certificate-does-not-auto-renew"></a>

正常情况下，使用 LNMP 自带的 Let's Encrypt 生成的相应的证书（这里为 `vault.yourdomain.com`）会自动续期。

### Let's Encrypt 未自动续期的原因 <a href="#reasons-why-lets-encrypt-does-not-auto-renew" id="reasons-why-lets-encrypt-does-not-auto-renew"></a>

查看 Let's Encrypt 日志文件 `/usr/local/acme.sh/acme.sh.log`，发现如下错误记录：

> Verify error:Invalid response from <https://vault.yourdomain.com/.well-known/acme-challenge/QK1Gw-lJbi78GO5smcU1-Akkkm13UQbtLmVR073J2iI>

原因为我之前将 `vault.yourdomain.com.conf` 配置文件中的如下语句移除了，添加上即可：

<pre class="language-nginx"><code class="lang-nginx">  location ~ /.well-known {
<strong>    allow all;
</strong>  }
</code></pre>

### 手动续期方法 <a href="#manual-renewal-methods" id="manual-renewal-methods"></a>

```shell
# 定位到 /usr/local/acme.sh/ 目录
cd /usr/local/acme.sh/

# 手动续期 vault.yourdomain.com 的 Let’s Encrypt 证书
acme.sh --renew -d vault.yourdomain.com
```

如果由于某些原因无法手动续期，则可以通过 lnmp 命令删除虚拟主机然后重新添加虚拟主机的方式重新获取证书（此操作不会丢失 Vaultwarden 的数据，并且不需要对 Vaultwarden 做任何操作）：

1、备份 `vault.yourdomain.com` 虚拟主机的配置文件：`/usr/local/nginx/conf/vhost/vault.yourdomain.com.conf`

2、删除并重新创建 `vault.yourdomain.com` 虚拟主机：

```shell
# 删除虚拟主机
lnmp vhost del # 根据提示输入 vault.yourdomain.com 以删除此虚拟主机

# 删除网站文件
chattr -i /home/wwwroot/vault.yourdomain.com/.user.ini # 需要先执行此命令才能删除 .user.ini 文件
rm -rf /home/wwwroot/vault.yourdomain.com/ # 执行删除操作

# 新建虚拟主机
lnmp vhost add
# 根据提示输入使用的域名（这里为 vault.yourdomain.com）
# 选择使用 Let's Encrypt
# 其他如 Rewrite rule、PHP Pathinfo、access log、databse、ftp 等全部选 no
```

3、恢复 `vault.yourdomain.com` 虚拟主机的配置文件：`/usr/local/nginx/conf/vhost/vault.yourdomain.com.conf`

4、重启 nginx 使配置生效：

```shell
lnmp nginx restart

# 或者
/etc/init.d/nginx restart
```

## 在网页密码库后台进入 YubiKey OTP 安全钥匙的两步登录配置时出错 <a href="#two-step-login-for-yubikey-otp-error" id="two-step-login-for-yubikey-otp-error"></a>

### 错误内容 1 <a href="#error-1" id="error-1"></a>

> 发生错误。 `YUBICO_CLIENT_ID` or `YUBICO_SECRET_KEY` environment variable is not set. Yubikey OTP Disabled

原因为未设置配置文件 `config.json` 中 Yubico 的 `Client ID` 和 `Secret key` 环境变量的值。通过 [Yubico API key signup](https://upgrade.yubico.com/getapikey/) 页面注册您的 Yubico 的 `Client ID` 和 `Secret key`，然后将其通过管理页面或直接配置到 `config.json` 中即可。

### 错误内容 2 <a href="#error-2" id="error-2"></a>

> 发生错误。 Yubico support is disabled

原因为未启用 YubiKey，在管理员门户中启用即可。


# 日常使用（通用）

## 更改客户端应用程序环境 <a href="#change-the-client-app-environment" id="change-the-client-app-environment"></a>

默认情况下，客户端（浏览器扩展、桌面端及移动端）与 Bitwarden 云服务器通信。如果您有自己托管的 Bitwarden 或 Vaultwarden 安装，则需要更改客户端的托管环境，以与您的实例而不是与 Bitwarden 云服务器进行通信。

1. 在登录或注册界面的**登录到:** 选择**自托管**
2. 在**自托管环境**的**服务器 URL**下输入您自己托管的 Bitwarden 或 Vaultwarden 安装的基础 URL（包含端口）
3. 点击**保存**

## 配置 Duo 中使用 Yubico OTP <a href="#config-yubico-otp-in-duo" id="config-yubico-otp-in-duo"></a>

参阅[配置 Duo 中使用 Yubico OTP](https://ppgg.in/blog/13289.html)。

## 重复项目的移除 <a href="#remove-duplicate-items" id="remove-duplicate-items"></a>

如果您导入 Bitwarden 的数据中有大量的重复项目，想找一种方法可以显示这些重复的项目并选择一个来保留，而不想手动去一个一个查找，[这里](https://community.bitwarden.com/t/duplicate-removal-tool-report/648)有一些提示和参考。

## iOS App URI

Bitwarden 客户端使用 URI 自动识别网站和 App，以方便自动填充（参阅[用于自动填充的 URI](https://help.ppgg.in/password-manager/autofill/troubleshoot-autofill/forming-uris-for-autofill)）。

* 对于 Bitwarden 浏览器扩展，使用网站的 URL 地址，格式如 `https://www.ppgg.in`
* 对于 Bitwarden for Android，使用 Android App 的包 ID / 包名称，格式如 `androidapp://com.instagram.android`

而对于 Bitwarden for iOS，开发者通常没有在他们的 iOS App 中正确设置 URI，所以大部分 iOS App 无法被 Bitwarden 识别。参阅[这里](https://www.reddit.com/r/Bitwarden/comments/run3ie/is_it_possible_to_get_bitwarden_to_recognize_an/)和[这里](https://community.bitwarden.com/t/how-to-get-uri-for-ios-app)。

[获取移动 App URI 的方法](https://help.ppgg.in/password-manager/autofill/troubleshoot-autofill/forming-uris-for-autofill#obtaining-uris-for-mobile-apps)。


# 各种访问地址

## Bitwarden Public API

{% embed url="<https://bitwarden.com/help/api/>" %}

关于 Bitwarden Public API 请参阅 [Bitwarden 公共 API 帮助文档](https://help.ppgg.in/admin-console/bitwarden-public-api)。

## Bitwarden Status Page <a href="#bitwarden-status-page" id="bitwarden-status-page"></a>

{% embed url="<https://status.bitwarden.com/>" %}

在 Bitwarden 的公共状态页面中可以查看所有服务（包括公共 API）的运行状况和事件信息。

## 删除账户 <a href="#delete-account" id="delete-account"></a>

* 对于 Bitwarden 云托管实例：<https://vault.bitwarden.com/#/recover-delete>
* 对于自托管实例：<https://vault.yourdomain.com/#/recover-delete>

## 恢复账户 <a href="#recover-account" id="recover-account"></a>

如果您无法访问用于两步登录 (2FA) 的设备或方法，则可以使用**恢复代码**来恢复对您的账户的访问权限。

* 对于 Bitwarden 云托管实例：<https://vault.bitwarden.com/#/recover-2fa>
* 对于自托管实例：<https://vault.yourdomain.com/#/recover-2fa>

## 管理员门户 <a href="#admin-portal" id="admin-portal"></a>

* <https://vault.yourdomain.com/admin>

只有自托管实例才拥有管理员门户。

## YubiKey OTP <a href="#yubikey-otp" id="yubikey-otp"></a>

对于自托管实例，要启用 YubiKey OTP 方式的两步登录，需要事先配置并上传 Yubico OTP 密钥到您的 YubiKey 中，然后注册 Yubico API 密钥。

YubiKey 5 系列、4 系列、FIPS 系列以及 NEO、Edge 支持 OTP。[YubiKey 产品比较](https://www.yubico.com/store/compare/)或 [YubiKey 产品对比](https://ppgg.in/blog/13176.html)。

### 上传 Yubico OTP 密钥 <a href="#upload-yubico-otp-key" id="upload-yubico-otp-key"></a>

{% embed url="<https://upload.yubico.com/>" %}

{% hint style="success" %}
处于出厂状态的 YubiKey，第一个 OTP 插槽已经配置好，无需配置和上传，直接使用即可。
{% endhint %}

通过 [YubiKey Manager](https://www.yubico.com/products/services-software/download/yubikey-manager/)（或 [YubiKey Personalization Tools](https://www.yubico.com/products/services-software/download/yubikey-personalization-tools/)）配置好您的 Yubico OTP 密钥，然后通过上面的 Yubico OTP key upload 将配置的 `Public ID`、`Private ID` 以及 `Secret key` 上传到 YubiCloud，才能在 Bitwarden（或其他第三方服务）中使用您的 Yubico OTP。

{% hint style="danger" %}
**注意**：无任何方式取回已写入到 YubiKey 中的 `Public ID`、`Private ID` 以及 `Secret key`，因此，如果后期要将其用作他用的话（比如用在 Duo 中），则需要在生成的时候手动将其记录下来。
{% endhint %}

### 注册 Yubico API 密钥 <a href="#signup-yubico-api-key" id="signup-yubico-api-key"></a>

{% embed url="<https://upgrade.yubico.com/getapikey/>" %}

注册 Yubico API 密钥以获取 `Client ID` 和 `Secret key`，然后将获取到的 `Client ID` 和 `Secret key` 的值通过管理页面或直接配置到配置文件中。


# 密码管理软件

## NodeWarden

[NodeWarden](https://github.com/shuaiplus/nodewarden) 是另一个与 Vaultwarden 类似的 Bitwarden 兼容的服务端。它运行在 Cloudflare Workers 上，原创 Web Vault 界面，比 Vaultwarden 更轻量。

* [NodeWarden Github 仓库](https://github.com/shuaiplus/nodewarden)
* [NodeWarden Wiki](https://nodewarden.app/zh/)
* [NodeWarden 在线 Demo](https://demo.nodewarden.app/login)

## Warden

Warden 是运行在 Cloudflare Workers 上的 [Vaultwarden](https://github.com/dani-garcia/vaultwarden)。

* [Warden Github 仓库](https://github.com/qaz741wsd856/warden-worker)
* [Warden 在线 Demo](http://warden.qqnt.de/)

## 开源密码管理软件 <a href="#open-source-password-manager" id="open-source-password-manager"></a>

* [KeePass](https://keepass.info/) - [SourceForge](https://sourceforge.net/projects/keepass/)
* [Clipperz](https://clipperz.is/) - [Github](https://github.com/clipperz/password-manager)（已停更）
* [Encryptr](https://spideroak.com/encryptr/) - [Github](https://github.com/SpiderOak/Encryptr)（已停更）
* [Padlock](https://padloc.app/) - [Github](https://github.com/padloc/padloc)
* [Passopolis](https://passopolis.com/) - [Github](https://github.com/WeAreWizards/passopolis-server)（已停更）
* [Password Safe](https://pwsafe.org/) - [Github](https://github.com/pwsafe/pwsafe)
* RatticDB - [Github](https://github.com/tildaslash/RatticD)（已停更）
* [Passman](https://passman.cc/) - [Github](https://github.com/nextcloud/passman)
* [Passbolt](https://www.passbolt.com/) - [Github](https://github.com/passbolt)

## 专有密码管理软件 <a href="#proprietary-password-manager" id="proprietary-password-manager"></a>

* [1Password](https://1password.com)
* [LastPass](https://www.lastpass.com/)
* [Keeper](https://www.keepersecurity.com/zh_CN/)
* [Enpass](https://www.enpass.io/)
* [Dashlane](https://www.dashlane.com/)
* [SplashID](https://splashid.com/)
* [RememBear](https://www.remembear.com/)
* [RoboForm](https://www.roboform.com/)
* [SafeInCloud](https://safe-in-cloud.com/)
* [NordPass](https://nordpass.com/)
* [Passpack](https://www.passpack.com/)
* [Myki](https://myki.com/)
* [PassCamp](https://www.passcamp.com/)
* [Zoho Vault](https://www.zoho.com/vault/)

## 其他 <a href="#others" id="others"></a>

* [Password Manager Pro](https://www.manageengine.com/products/passwordmanagerpro/)，一个面向企业的密码安全管理软件。[中文文档资源](https://www.manageengine.cn/products/passwordmanagerpro/help.html)
* [Pleasant Password Server](https://pleasantsolutions.com/passwordserver)，一个专有的，与 KeePass 兼容，为企业用户设计的多用户企业密码服务器
* [Password Safe by MATESO](https://www.passwordsafe.com/)
* [CommonKey](https://www.commonkey.com/)
* [ManageEngine Password Manager Pro](https://www.manageengine.com/products/passwordmanagerpro/)
* [Team Password Manager](https://teampasswordmanager.com/)
* [Zoho Vault](https://www.zoho.com/vault/)
* [Bravura Pass](https://www.bravurasecurity.com/products/bravura-pass)
* [SailPoint Password Management](https://www.sailpoint.com/products/identity-security-cloud/atlas/add-ons/password-management)
* [Sticky Password](https://www.stickypassword.com/)
* [Intuitive Password](https://www.intuitivepassword.com/)
* [Password Boss](https://www.passwordboss.com/)
* [Passwork](https://passwork.pro/)
* [Passportal](https://www.n-able.com/products/passportal)
* [Psono](https://psono.com/zh/)

## 参考链接 <a href="#reference-links" id="reference-links"></a>

* [密码管理服务列表](https://zh.wikipedia.org/wiki/%E5%AF%86%E7%A2%BC%E7%AE%A1%E7%90%86%E6%9C%8D%E5%8B%99%E6%B8%85%E5%96%AE) by Wikipedia
* [七款值得推荐的开源密码管理工具](https://yq.aliyun.com/articles/196675)（[英文原文](https://venturebeat.com/2015/10/13/7-open-source-password-managers-to-try-now-that-logmein-owns-lastpass/), by VentureBeat）
* [The Best Password Managers for 2020](https://www.pcmag.com/picks/the-best-password-managers). by PC Magazine
* [10 Best Password Managers for Business](https://www.smbguide.com/best-password-managers/). by SMB Guide


# 免费公共实例

这里收集使用 Vaultwarden 搭建的免费公共实例。更多实例请自行使用关键词「Vaultwarden Web Vault」进行网页搜索。

{% hint style="danger" %}
注意：请自行确定这些公共实例的稳定性，以及使用这些公共实例所存在的安全风险。
{% endhint %}

* [https://vault.ppgg.in](https://vault.ppgg.in/)：本人搭建的 Vaultwarden 服务，不保证稳定和持久
* <https://passwd.nite07.com>：[Nite](https://www.nite07.com/) 搭建的 Vaultwarden 服务，使用 SSO 登录
* <https://bitwarden.garudalinux.org>
* <https://vault.tedomum.net>
* <https://passwd.hostux.net>
* [https://bitwarden.scutech.com](https://bitwarden.scutech.com/)


# 术语以及其他

## 名词术语 <a href="#terms" id="terms"></a>

* [**2FA**](https://zh.wikipedia.org/wiki/%E9%9B%99%E9%87%8D%E8%AA%8D%E8%AD%89)：Two-factor authentication，**双重验证**、**二次验证**。比如某些网站，使用用户名和密码验证后还需要短信验证码才能登录。双重验证 (2FA) 是多重验证 (MFA) 的一个特例。
* [**MFA**](https://zh.wikipedia.org/wiki/%E5%A4%9A%E9%87%8D%E8%A6%81%E7%B4%A0%E9%A9%97%E8%AD%89)：除了双重验证 (2FA) ，还有三重验证、四重验证等，这些统一叫做**多重验证**。
* [**U2F**](https://zh.wikipedia.org/wiki/%E9%80%9A%E7%94%A8%E7%AC%AC%E4%BA%8C%E5%9B%A0%E7%B4%A0)：Universal 2nd Factor，**通用第二因素**。是一个开放认证标准，它使用专门的 USB 或 NFC 设备来加强并简化双重验证 (2FA) 。最初由 Google 和 YubiKey 开发，目前由 [FIDO 联盟](https://zh.wikipedia.org/wiki/FIDO%E8%81%94%E7%9B%9F)运作和管理。
* [**FIDO**](https://zh.wikipedia.org/wiki/FIDO%E8%81%94%E7%9B%9F)：Fast IDentity Online，**在线快速身份认证**。FIDO 是一套身份认证框架协议，由 [FIDO 联盟](https://fidoalliance.org/)维护并制定相应的技术规范和标准。
* [**FIDO 联盟**](https://fidoalliance.org/)：是一个成立于 2012 年 7 月的行业协会，旨在为众多网站和移动服务提供更简单、更安全的用户身份认证体验的开放性可扩展标准。
* **FIDO U2F**：是一个由 FIDO 联盟制定的 U2F 身份认证标准。
* [**OTP**](https://zh.wikipedia.org/wiki/%E4%B8%80%E6%AC%A1%E6%80%A7%E5%AF%86%E7%A2%BC)：One-Time Password，**一次性密码**，也叫**动态密码**。
* [**TOTP**](https://zh.wikipedia.org/wiki/%E5%9F%BA%E4%BA%8E%E6%97%B6%E9%97%B4%E7%9A%84%E4%B8%80%E6%AC%A1%E6%80%A7%E5%AF%86%E7%A0%81%E7%AE%97%E6%B3%95)：Time-based One-time Password，**基于时间的一次性密码**。

## 两步登录支持的客户端 App <a href="#client-app-supported-by-two-step-login" id="client-app-supported-by-two-step-login"></a>

<table><thead><tr><th width="204.79998779296875">两步登录方式</th><th width="107.20001220703125">桌面 App</th><th width="105.5999755859375">移动 App</th><th width="96.7999267578125">CLI</th><th width="106.4000244140625">网页 App</th><th>浏览器扩展</th></tr></thead><tbody><tr><td>验证器 App</td><td>✔︎</td><td>✔︎</td><td>✔︎</td><td>✔︎</td><td>✔︎</td></tr><tr><td>电子邮件</td><td>✔︎</td><td>✔︎</td><td>✔︎</td><td>✔︎</td><td>✔︎</td></tr><tr><td>YubiKey OTP</td><td>✔︎</td><td>✔︎</td><td>✔︎</td><td>✔︎</td><td>✔︎</td></tr><tr><td>FIDO2 WebAuthn</td><td>⚊</td><td>⚊</td><td>⚊</td><td>✔︎</td><td>✔︎</td></tr><tr><td><strong>Duo Security</strong></td><td></td><td></td><td></td><td></td><td></td></tr><tr><td>— Duo Push</td><td>✔︎</td><td>✔︎</td><td>⚊</td><td>✔︎</td><td>✔︎</td></tr><tr><td>— Duo 短信</td><td>✔︎</td><td>✔︎</td><td>⚊</td><td>✔︎</td><td>✔︎</td></tr><tr><td>— Duo 电话</td><td>✔︎</td><td>✔︎</td><td>⚊</td><td>✔︎</td><td>✔︎</td></tr><tr><td>— Duo U2F 安全钥匙</td><td>⚊</td><td>⚊</td><td>⚊</td><td>✔︎</td><td>✔︎</td></tr><tr><td>— Duo Token</td><td>✔︎</td><td>✔︎</td><td>⚊</td><td>✔︎</td><td>✔︎</td></tr><tr><td>— Duo Bypass Code</td><td>✔︎</td><td>✔︎</td><td>⚊</td><td>✔︎</td><td>✔︎</td></tr></tbody></table>

## YubiKey OTP 和 FIDO2 WebAuthn 比较 <a href="#yubikey-otp-and-fido-u2f-comparison" id="yubikey-otp-and-fido-u2f-comparison"></a>

<table data-full-width="false"><thead><tr><th></th><th>连接验证服务器</th><th>支持的 Bitwarden App</th></tr></thead><tbody><tr><td>YubiKey OTP</td><td>需要（每次）</td><td>所有</td></tr><tr><td>FIDO2 WebAuthn</td><td>不需要</td><td>仅网页密码库和浏览器扩展</td></tr></tbody></table>

## 支持 FIDO U2F 的安全钥匙 <a href="#fido-u2f-enabled-security-keys" id="fido-u2f-enabled-security-keys"></a>

* [YubiKey](https://www.yubico.com/products/)：由瑞典 [Yubico](https://www.yubico.com/) 公司开发的安全钥匙。YubiKey 5 系列、4 系列、YubiKey FIPS 系列、Security Key 系列、YubiKey NEO、YubiKey Edge 支持 FIDO U2F。[维基百科条目](https://zh.wikipedia.org/wiki/YubiKey)。
* [SoloKeys](https://solokeys.com/collections/all)：由美国 [SoloKeys](https://solokeys.com/) 公司开发的安全钥匙。
* [Google Titan](https://cloud.google.com/titan-security-key)：由美国 [Google](https://www.google.com/) 公司开发的安全钥匙。
* [Nitrokey FIDO U2F](https://www.nitrokey.com/#comparison)：由德国 [Nitrokey](https://www.nitrokey.com/) 公司开发的安全钥匙。
* [FEITIAN Security Key](https://www.ftsafe.com/Products/FIDO)：由中国[飞天](https://www.ftsafe.com/)公司开发的安全钥匙。

## 支持 OTP 的 YubiKey <a href="#otp-enabled-yubikeys" id="otp-enabled-yubikeys"></a>

* YubiKey 5 系列
* YubiKey FIPS 系列
* YubiKey 4 系列
* YubiKey NEO
* YubiKey Edge

{% hint style="info" %}
YubiKey 4 系列、YubiKey NEO、YubiKey Edge 已经停产。
{% endhint %}

## 验证器 App 推荐 <a href="#authenticator-app-recommendations" id="authenticator-app-recommendations"></a>

这里的验证器 App 指的是用于[两步登录 Bitwarden 账户](https://help.ppgg.in/my-account/two-step-login/two-step-login-methods)所使用的 App。一定要有自动备份功能，以防您在丢失了安装了此验证器 App 的设备时，可以恢复备份以正常登录 Bitwarden。

[Authy](https://authy.com/) 是 Bitwarden 推荐的验证器 App，因为它拥有任一设备的备份功能。即使您丢失了安装 Authy 的设备，备份功能也能防止您失去对两步登录令牌的访问。在 Authy App 的 **Accounts** 界面打开 **Authenticator Backups** 开关，即可使用该功能。

不推荐 [Google Authenticator](https://support.google.com/accounts/answer/1066447?hl=en)，虽然「从 2020 年 5 月 7 日起，Google Authenticator 包含了验证码在跨 Android 设备上的可移植性功能」。

| 验证器 App                                                                                      | 支持的平台                           | 开发者                                                    |
| -------------------------------------------------------------------------------------------- | ------------------------------- | ------------------------------------------------------ |
| [Authy](https://authy.com/)                                                                  | iOS、Android、macOS、Windows、Linux | [Twilio](https://www.twilio.com/en-us)                 |
| [FreeOTP](https://freeotp.github.io/)                                                        | iOS、Android                     | [Red Hat](https://www.redhat.com/)                     |
| [Raivo OTP](https://raivo-otp.com/)                                                          | iOS、macOS                       | [Mobime](https://mobime.org/)                          |
| [2FAS](https://2fas.com/)                                                                    | iOS、Android、浏览器扩展               | [2FAS](https://github.com/twofas)                      |
| [Aegis](https://getaegis.app/)                                                               | Android                         | [Beem Development](https://github.com/beemdevelopment) |
| [Google Authenticator](https://support.google.com/accounts/answer/1066447?hl=en)             | iOS、Android                     | [Google](https://www.google.com/)                      |
| [Microsoft Authenticator](https://www.microsoft.com/en-us/security/mobile-authenticator-app) | iOS、Android                     | [Microsoft](https://www.microsoft.com/)                |

### 验证器 App 比较 <a href="#authenticator-app-comparisons" id="authenticator-app-comparisons"></a>

* [Google Authenticator vs. 2FAS](https://2fas.com/vs/google-authenticator/)
* [Microsoft Authenticator vs. 2FAS](https://2fas.com/vs/microsoft-authenticator/)
* [10 Most Popular Two-Factor Authentication Apps Compared](https://www.protectimus.com/blog/10-most-popular-2fa-apps-on-google-play/)
* [The 10 best authenticator apps for Android, iOS, Windows, and macOS](https://www.kaspersky.com/blog/best-authenticator-apps-2022/43261/)

## Bitwarden 李鬼 <a href="#bitwarden-counterfeiter" id="bitwarden-counterfeiter"></a>

* [https://www.bitwarden.pro](https://www.bitwarden.pro/)

Bitwarden 公司很看重 bitwarden 域名的所有权。我注册过几次 bitwarden 的顶级域名，最后都被 Bitwarden 仲裁收回。所以，李鬼很难长期存在，也反映了 Bitwarden 对安全的重视。

## 第三方客户端 <a href="#third-party-clients" id="third-party-clients"></a>

[Keyguard](https://github.com/AChep/keyguard-app) 是一款面向 Bitwarden® 平台和 KeePass (KDBX) 的多客户端 App。KeyGuard 通过兼容 Bitwarden 的 API 来实现密码管理功能，支持 Android、Windows、Mac、Linux。


