前言#
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>
1.2.2 Rust 環境配置#
執行 curl https://sh.rustup.rs -sSf | sh
以配置 Rust 環境。(國內可能較慢)
出現 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> >> ~/.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>
若返回 /root/.cargo/bin/rustc
則代表完成 Rust 環境的配置。
二、編譯 Vaultwarden#
執行 git clone https://github.com/dani-garcia/vaultwarden && cd vaultwarden
以拉取 Vaultwarden 儲存庫(國內可能較慢):
執行 cargo clean && cargo build --features mysql --release
以啟動 Vaultwarden 的編譯。
其中,mysql
可以為與 sqlite
和 postgresql
三者的任意組合,選擇編譯 mysql
或 postgresql
時,系統必須安裝了 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 秒。
三、安裝 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://
。
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>
刪去被註解的行,最終配置如圖:
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>
若正常啟動,則如下圖提示:
四、使用 Nginx 反向代理 Vaultwarden#
本文以寶塔面板為例,其他環境與此操作相同。
4.1 新建站點#
新建一個站點,域名填寫步驟 3.4 中的域名,配置好 SSL 證書。
4.2 配置反向代理#
名稱隨意,目標 URL 為 http://127.0.0.1:8000
,其他默認。
供非寶塔用戶的 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 開始密碼管理的第一步。
六、Vaultwarden 後續更新#
重做步驟二、步驟 3.1, 3.3 並執行 systemctl restart vaultwarden.service
即可。
參考文獻#
https://nickhuber.ca/blog/bitwarden-rs-without-docker
https://gist.github.com/tavinus/59c314f4ccd70879db7f11074eacb6cc****