# 使用

## 配置 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.md)步骤中的说明添加新的虚拟主机
3. 按照[准备](/vaultwarden/preparation.md)步骤中的说明修改新主机的 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.md#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`）


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://host.ppgg.in/vaultwarden/use.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
