banner
huqingye

huqingye

使用非 Docker 方案在騰訊雲輕量應用伺服器上搭建密碼管理軟體 Vaultwarden (Bitwarden_rs)(轉)

前言#

Bitwarden 是一款自由且開源的密碼管理服務,使用者可在加密的保管庫中存儲敏感資訊(例如網站登入憑據)。Bitwarden 平台提供有多種客戶端應用程式,包括網頁用戶介面、桌面應用、瀏覽器擴展、移動應用以及命令行介面。Bitwarden 作為一款商業自由軟體,其開發公司提供雲端托管服務 (bitwarden.com),同時為廣大開源社區提供自行部署的解決方案。

Vaultwarden 原名 Bitwarden_rs,自 v2.21.0 開始更名為 Vaultwarden。Bitwarden 原始服務端使用 C# 編寫,部署困難,且要求 MSSQL 等商業軟體,運行需要 2GB 以上的內存;而 Vaultwarden 是一個使用 Rust 編寫的非官方 Bitwarden 伺服器實現,它與官方 Bitwarden 客戶端兼容,運行 Vaultwarden 時只需要 10M 內存,可以說對硬體基本沒有要求,對於不希望使用官方的佔用大量資源的自托管部署而言,它是理想的選擇。

Vaultwarden 除不支持官方企業版的部分功能(如事件日誌、目錄同步以及 SSO 登入)外,其他大部分功能均免費支持。並跟隨官方版本保持及時更新。

Vaultwarden 實現了 Bitwarden API 所需的大部分功能,因此桌面端、移動端、瀏覽器擴展等客戶端均可直接使用 Bitwarden 官方的客戶端應用程式。

Vaultwarden 倉庫推薦的安裝方式均為直接使用 Docker 部署,本文將介紹一種使用非 Docker 方式、直接在系統上部署 Vaultwarden 的方法。16MB 左右的內存佔用,再配合 MySQL 替代默認的 SQLite 作為數據存儲形式可以將其 “功耗” 降到最低。

一、準備工作#

1.1 伺服器和系統選用#

由於 Vaultwarden 運行時幾乎不消耗系統資源,因此可以選用任意型號的輕量應用伺服器;伺服器系統建議選擇 Ubuntu 18.04 或更新版本以及 Debian 10 或更新版本的 Linux 發行版,使用 CentOS 似乎會因依賴軟體包版本問題而出現未知的錯誤。

此外,由於部署 Vaultwarden 不會對現有系統環境造成破壞性影響,在已經有網站業務的伺服器上部署 Vaultwarden 也是一個不錯的選擇。

1.2 環境配置#

1.2.1 軟體包及依賴配置#

依次執行以下命令以更新軟體包資訊、安裝必要的軟體包及開發工具包:

<div class="vditor-copy"><textarea></textarea><span aria-label="複製" onmouseover="this.setAttribute('aria-label', '複製')" class="vditor-tooltipped vditor-tooltipped__w" onclick="this.previousElementSibling.select();document.execCommand('copy');this.setAttribute('aria-label', '已複製')"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-clipboard"><path d="M16 4h2a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2h2"></path><rect x="8" y="2" width="8" height="4" rx="1" ry="1"></rect></svg></span></div><code class="lang-bash hljs vditor-linenumber small-scroll-bar overflow-y-auto" style="max-height: 1359px;">apt update -y
apt install git nano curl wget htop pkg-config openssl libssl1.1 libssl-dev -y
apt install build-essential -y<div class="vditor-linenumber__temp" style="display: none;"></div><span class="vditor-linenumber__rows"><span></span><span></span><span></span></span></code>

be-install

be-install

1.2.2 Rust 環境配置#

執行 curl https://sh.rustup.rs -sSf | sh 以配置 Rust 環境。(國內可能較慢)

rust-install

rust-install

出現 Rust is installed now. Great! 即代表安裝完成。

依次執行以下命令以配置 cargo 命令的環境變數:

<div class="vditor-copy"><textarea></textarea><span aria-label="複製" onmouseover="this.setAttribute('aria-label', '複製')" class="vditor-tooltipped vditor-tooltipped__w" onclick="this.previousElementSibling.select();document.execCommand('copy');this.setAttribute('aria-label', '已複製')"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-clipboard"><path d="M16 4h2a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2h2"></path><rect x="8" y="2" width="8" height="4" rx="1" ry="1"></rect></svg></span></div><code class="lang-bash hljs vditor-linenumber small-scroll-bar overflow-y-auto" style="max-height: 1359px;"><span class="hljs-built_in">echo</span> <span class="hljs-string">'export PATH=~/.cargo/bin:$PATH'</span> &gt;&gt; ~/.bashrc
<span class="hljs-built_in">export</span> PATH=~/.cargo/bin:<span class="hljs-variable">$PATH</span> 
<span class="hljs-built_in">which</span> rustc<div class="vditor-linenumber__temp" style="display: none;"></div><span class="vditor-linenumber__rows"><span></span><span></span><span></span></span></code>

rustc-install

rustc-install

若返回 /root/.cargo/bin/rustc 則代表完成 Rust 環境的配置。

二、編譯 Vaultwarden#

執行 git clone https://github.com/dani-garcia/vaultwarden && cd vaultwarden 以拉取 Vaultwarden 儲存庫(國內可能較慢):

vw-pull

vw-pull

執行 cargo clean && cargo build --features mysql --release 以啟動 Vaultwarden 的編譯。

其中,mysql 可以為與 sqlitepostgresql 三者的任意組合,選擇編譯 mysqlpostgresql 時,系統必須安裝了 MySQL 或 PostgreSQL,否則將提示:

<div class="vditor-copy"><textarea></textarea><span aria-label="複製" onmouseover="this.setAttribute('aria-label', '複製')" class="vditor-tooltipped vditor-tooltipped__w" onclick="this.previousElementSibling.select();document.execCommand('copy');this.setAttribute('aria-label', '已複製')"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-clipboard"><path d="M16 4h2a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2h2"></path><rect x="8" y="2" width="8" height="4" rx="1" ry="1"></rect></svg></span></div><code class="lang-bash hljs vditor-linenumber small-scroll-bar overflow-y-auto" style="max-height: 1359px;">linking with `cc` failed: <span class="hljs-built_in">exit</span> status: 1
...
= note: /usr/bin/ld: cannot find -lmysqlclient
          collect2: error: ld returned 1 <span class="hljs-built_in">exit</span> status<div class="vditor-linenumber__temp" style="display: none;"></div><span class="vditor-linenumber__rows"><span></span><span></span><span></span></span></code>

不想安裝 MySQL 的可以僅安裝其適用於 Rust 語言的 Client 庫(限 Ubuntu 或 Debian):

<div class="vditor-copy"><textarea></textarea><span aria-label="複製" onmouseover="this.setAttribute('aria-label', '複製')" class="vditor-tooltipped vditor-tooltipped__w" onclick="this.previousElementSibling.select();document.execCommand('copy');this.setAttribute('aria-label', '已複製')"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-clipboard"><path d="M16 4h2a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2h2"></path><rect x="8" y="2" width="8" height="4" rx="1" ry="1"></rect></svg></span></div><code class="lang-bash hljs vditor-linenumber small-scroll-bar overflow-y-auto" style="max-height: 1359px;">apt install librust-mysqlclient-sys-dev -y<div class="vditor-linenumber__temp" style="display: none;"></div><span class="vditor-linenumber__rows"><span></span></span></code>

編譯需要 3GB 左右的內存,內存不足的可以調整虛擬內存,虛擬內存建議空閒 2GB 左右;編譯耗時較久,LemonBench 跑分在 800 左右的單核伺服器編譯耗時 28 分 54 秒。

cpmdone

cpmdone

三、安裝 Vaultwarden#

3.1 移動 Vaultwarden 二進制文件#

依次執行以下命令:

<div class="vditor-copy"><textarea></textarea><span aria-label="複製" onmouseover="this.setAttribute('aria-label', '複製')" class="vditor-tooltipped vditor-tooltipped__w" onclick="this.previousElementSibling.select();document.execCommand('copy');this.setAttribute('aria-label', '已複製')"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-clipboard"><path d="M16 4h2a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2h2"></path><rect x="8" y="2" width="8" height="4" rx="1" ry="1"></rect></svg></span></div><code class="lang-bash hljs vditor-linenumber small-scroll-bar overflow-y-auto" style="max-height: 1359px;">cp target/release/vaultwarden /usr/bin/vaultwarden
chmod +x /usr/bin/vaultwarden<div class="vditor-linenumber__temp" style="display: none;"></div><span class="vditor-linenumber__rows"><span></span><span></span></span></code>

以將 Vaultwarden 二進制文件置入系統可執行目錄並賦予執行權限。

3.2 配置 Vaultwarden 專用用戶#

依次執行以下命令:

<div class="vditor-copy"><textarea></textarea><span aria-label="複製" onmouseover="this.setAttribute('aria-label', '複製')" class="vditor-tooltipped vditor-tooltipped__w" onclick="this.previousElementSibling.select();document.execCommand('copy');this.setAttribute('aria-label', '已複製')"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-clipboard"><path d="M16 4h2a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2h2"></path><rect x="8" y="2" width="8" height="4" rx="1" ry="1"></rect></svg></span></div><code class="lang-bash hljs vditor-linenumber small-scroll-bar overflow-y-auto" style="max-height: 1359px;">useradd -s /sbin/nologin -M vaultwarden
mkdir -p /var/lib/vaultwarden/data
chown -R vaultwarden:vaultwarden /var/lib/vaultwarden/<div class="vditor-linenumber__temp" style="display: none;"></div><span class="vditor-linenumber__rows"><span></span><span></span><span></span></span></code>

3.3 部署 Vaultwarden Web UI#

依次執行以下命令:

<div class="vditor-copy"><textarea></textarea><span aria-label="複製" onmouseover="this.setAttribute('aria-label', '複製')" class="vditor-tooltipped vditor-tooltipped__w" onclick="this.previousElementSibling.select();document.execCommand('copy');this.setAttribute('aria-label', '已複製')"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-clipboard"><path d="M16 4h2a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2h2"></path><rect x="8" y="2" width="8" height="4" rx="1" ry="1"></rect></svg></span></div><code class="lang-bash hljs vditor-linenumber small-scroll-bar overflow-y-auto" style="max-height: 1359px;">wget https://github.com/dani-garcia/bw_web_builds/releases/download/v2.28.0/bw_web_v2.28.0.tar.gz
tar -xf bw_web_v2.28.0.tar.gz -C /var/lib/vaultwarden/<div class="vditor-linenumber__temp" style="display: none;"></div><span class="vditor-linenumber__rows"><span></span><span></span></span></code>

其中 v2.28.0 為寫作時的版本號,獲取地址為 https://github.com/dani-garcia/bw_web_builds/releases/latest ,請保持最新。

3.4 編寫 Vaultwarden 配置文件#

執行 touch /etc/vaultwarden.env 並寫入以下內容:

<div class="vditor-copy"><textarea></textarea><span aria-label="複製" onmouseover="this.setAttribute('aria-label', '複製')" class="vditor-tooltipped vditor-tooltipped__w" onclick="this.previousElementSibling.select();document.execCommand('copy');this.setAttribute('aria-label', '已複製')"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-clipboard"><path d="M16 4h2a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2h2"></path><rect x="8" y="2" width="8" height="4" rx="1" ry="1"></rect></svg></span></div><code class="lang-ini hljs vditor-linenumber small-scroll-bar overflow-y-auto" style="max-height: 1359px;"><span class="hljs-attr">DATA_FOLDER</span>=/var/lib/vaultwarden/data/
<span class="hljs-attr">DATABASE_URL</span>=mysql://[資料庫用戶名]:[資料庫密碼]@<span class="hljs-number">127.0</span>.<span class="hljs-number">0.1</span>:<span class="hljs-number">3306</span>/[資料庫名]
<span class="hljs-attr">IP_HEADER</span>=X-Real-IP
<span class="hljs-attr">WEB_VAULT_FOLDER</span>=/var/lib/vaultwarden/web-vault/
<span class="hljs-attr">WEB_VAULT_ENABLED</span>=<span class="hljs-literal">true</span>
<span class="hljs-attr">ADMIN_TOKEN</span>=[base64碼]
<span class="hljs-attr">DOMAIN</span>=https://vaultwarden.iks.moe<div class="vditor-linenumber__temp" style="display: none;"></div><span class="vditor-linenumber__rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code>

其中,[資料庫用戶名] 為 MySQL 資料庫用戶名,[資料庫密碼] 為 MySQL 資料庫用戶的密碼,[資料庫名] 為 MySQL 資料名,此三者均須提前創建;127.0.0.1 不得填寫為 localhost[base64碼] 執行 openssl rand -base64 48 以得到,https://vaultwarden.iks.moe 為你的域名,協議頭必須為 https://

b64

b64

simple-env

simple-env

3.5 編寫 Vaultwarden SystemD 文件#

執行 touch /etc/systemd/system/vaultwarden.service 並寫入以下內容:

<div class="vditor-copy"><textarea></textarea><span aria-label="複製" onmouseover="this.setAttribute('aria-label', '複製')" class="vditor-tooltipped vditor-tooltipped__w" onclick="this.previousElementSibling.select();document.execCommand('copy');this.setAttribute('aria-label', '已複製')"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-clipboard"><path d="M16 4h2a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2h2"></path><rect x="8" y="2" width="8" height="4" rx="1" ry="1"></rect></svg></span></div><code class="lang-ini hljs vditor-linenumber small-scroll-bar overflow-y-auto" style="max-height: 1359px;"><span class="hljs-section">[Unit]</span>
<span class="hljs-attr">Description</span>=Vaultwarden Server
<span class="hljs-attr">Documentation</span>=https://github.com/dani-garcia/vaultwarden

<span class="hljs-comment"># 當你使用 SQLite 時,請取消下一行的註解</span>
<span class="hljs-comment"># After=network.target</span>

<span class="hljs-comment"># 當你使用 MariaDB 時,請取消下兩行的註解</span>
<span class="hljs-comment"># After=network.target mariadb.service</span>
<span class="hljs-comment"># Requires=mariadb.service</span>

<span class="hljs-comment"># 當你使用 MySQL 時,請取消下兩行的註解</span>
<span class="hljs-comment"># After=network.target mysqld.service</span>
<span class="hljs-comment"># Requires=mysqld.service</span>

<span class="hljs-comment"># 當你使用 PostgreSQL 時,請取消下兩行的註解</span>
<span class="hljs-comment"># After=network.target postgresql.service</span>
<span class="hljs-comment"># Requires=postgresql.service</span>

<span class="hljs-section">[Service]</span>
<span class="hljs-attr">User</span>=vaultwarden
<span class="hljs-attr">Group</span>=vaultwarden
<span class="hljs-attr">EnvironmentFile</span>=/etc/vaultwarden.env
<span class="hljs-attr">ExecStart</span>=/usr/bin/vaultwarden
<span class="hljs-attr">LimitNOFILE</span>=<span class="hljs-number">1048576</span>
<span class="hljs-attr">LimitNPROC</span>=<span class="hljs-number">64</span>
<span class="hljs-attr">PrivateTmp</span>=<span class="hljs-literal">true</span>
<span class="hljs-attr">PrivateDevices</span>=<span class="hljs-literal">true</span>
<span class="hljs-attr">ProtectHome</span>=<span class="hljs-literal">true</span>
<span class="hljs-attr">ProtectSystem</span>=strict
<span class="hljs-attr">WorkingDirectory</span>=/var/lib/vaultwarden
<span class="hljs-attr">ReadWriteDirectories</span>=/var/lib/vaultwarden
<span class="hljs-attr">AmbientCapabilities</span>=CAP_NET_BIND_SERVICE

<span class="hljs-section">[Install]</span>
<span class="hljs-attr">WantedBy</span>=multi-user.target<div class="vditor-linenumber__temp" style="display: none;"></div><span class="vditor-linenumber__rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code>

刪去被註解的行,最終配置如圖:

sdc

sdc

3.6 啟動 Vaultwarden#

依次執行以下命令:

<div class="vditor-copy"><textarea></textarea><span aria-label="複製" onmouseover="this.setAttribute('aria-label', '複製')" class="vditor-tooltipped vditor-tooltipped__w" onclick="this.previousElementSibling.select();document.execCommand('copy');this.setAttribute('aria-label', '已複製')"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-clipboard"><path d="M16 4h2a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2h2"></path><rect x="8" y="2" width="8" height="4" rx="1" ry="1"></rect></svg></span></div><code class="lang-bash hljs vditor-linenumber small-scroll-bar overflow-y-auto" style="max-height: 1359px;">systemctl <span class="hljs-built_in">enable</span> --now vaultwarden.service
systemctl start vaultwarden.service
systemctl status vaultwarden.service<div class="vditor-linenumber__temp" style="display: none;"></div><span class="vditor-linenumber__rows"><span></span><span></span><span></span></span></code>

若正常啟動,則如下圖提示:

st-img

st-img

四、使用 Nginx 反向代理 Vaultwarden#

本文以寶塔面板為例,其他環境與此操作相同。

4.1 新建站點#

新建一個站點,域名填寫步驟 3.4 中的域名,配置好 SSL 證書。

bt-newsite

bt-newsite

4.2 配置反向代理#

名稱隨意,目標 URL 為 http://127.0.0.1:8000,其他默認。

image-20220503012246612

image-20220503012246612

供非寶塔用戶的 nginx 反向代理配置:

<div class="vditor-copy"><textarea></textarea><span aria-label="複製" onmouseover="this.setAttribute('aria-label', '複製')" class="vditor-tooltipped vditor-tooltipped__w" onclick="this.previousElementSibling.select();document.execCommand('copy');this.setAttribute('aria-label', '已複製')"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-clipboard"><path d="M16 4h2a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2h2"></path><rect x="8" y="2" width="8" height="4" rx="1" ry="1"></rect></svg></span></div><code class="c++ hljs cpp vditor-linenumber small-scroll-bar overflow-y-auto" style="max-height: 1359px;">location /
{
    proxy_pass http:<span class="hljs-comment">//127.0.0.1:8000;</span>
    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 REMOTE-HOST $remote_addr;
    add_header Cache-Control no-cache;
}<div class="vditor-linenumber__temp" style="display: none;"></div><span class="vditor-linenumber__rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code>

五、使用#

訪問域名,單擊 Create Account 開始密碼管理的第一步。

mainpage

mainpage

六、Vaultwarden 後續更新#

重做步驟二、步驟 3.1, 3.3 並執行 systemctl restart vaultwarden.service 即可。

參考文獻#

https://nickhuber.ca/blog/bitwarden-rs-without-docker

https://gist.github.com/tavinus/59c314f4ccd70879db7f11074eacb6cc****

載入中......
此文章數據所有權由區塊鏈加密技術和智能合約保障僅歸創作者所有。