# 准备

{% 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 上添加相应的防火墙规则。
