自架服務 Rust Kanidm 身分驗證 Passkey

Kanidm 1.11 用自家資料庫繞開 PostgreSQL、把 OpenSSL 也拆了:Rust 原生 IdP 對 Authentik 與 Keycloak 的差異化路線

Kanidm 走的是 Rust 原生 IdP 路線。1.11 版把最後一塊 Python 遺產 rlm_kanidm 換成 Rust,1.10 版整個捨棄 OpenSSL。本文拆解它自建資料庫、passkey-first 的架構賭注,以及對比 Authentik、Keycloak、Zitadel 的實務取捨。

自架 SSO 這幾年已經打成群雄割據——Authentik 用 Python 撐起彈性最強的 flow engine、Keycloak 靠 Red Hat 支持吃下最完整的企業協定、Zitadel 用 Go 與事件溯源打進多租戶 SaaS 領域。Kanidm 在這場戰局裡挑了很不一樣的一條路:全用 Rust 從第一行寫起、不接外部 PostgreSQL、不引入 OpenSSL、passkey 是預設而不是加值選項。

2026 年 8 月釋出的 Kanidm 1.11 把最後一塊 Python 遺產——RADIUS 整合模組 rlm_kanidm 全數換成 Rust,也順手把 schema 從資料庫搬到記憶體、把密碼上限鎖在 128 UTF-8 字元以防 slow-hash DoS。這件事值得討論的點不在 Rust 本身,而在這條路線帶來的架構取捨會直接反映在部署成本、故障面積跟長期升級節奏上——尤其是想用一臺 VPS 就把身分服務打包完的中小組織。

自建資料庫這一步為什麼賭得下去

大多數自架 IdP 走的都是「App 靠外部資料庫」的路線:Authentik 要 PostgreSQL + Redis、Zitadel v4 收斂成僅支援 PostgreSQL(v3 之後不再支援 CockroachDB)、Keycloak 要 PostgreSQL 或 MariaDB。Kanidm 反過來,把資料層直接內建在 server binary 裡,底層是自己在 SQLite 上包出來的儲存引擎,複製協定也是自己寫的。

這個決策在 IdP 這個場景其實比乍看合理。身分資料的存取模式跟一般業務資料庫不一樣:讀多寫少、entry 有嚴謹 schema、cardinality 可預測、需要的 index 種類有限。當存取模式這麼收斂,跑一個通用 RDBMS 反而多養一組維護面。專案作者 William Brown 過去在 SUSE 維護 389 Directory Server 與 FreeIPA 多年,Kanidm 的資料層設計基本上是把 LDAP 的實務經驗重新用 Rust 寫一次,避開 LDAP 那些難以現代化的部分。

實測數字看得出這個賭注拿到了東西。官方文件公布的 benchmark 顯示,在 3000 使用者、1500 群組的資料集下,Kanidm 搜尋比 FreeIPA 快約 3 倍、修改與新增快約 5 倍。資源規劃上,官方指南建議以每筆 entry 約 64 KB RAM 快取、最多 8 KB 磁碟估算,實際占用會依 schema 與索引設定變動;同規模跟 Authentik + PostgreSQL 堆疊相比通常小上一截。

代價則寫在複製這件事上。Kanidm 的複製模型是多節點 eventually consistent——所有節點都能接受寫入,不跑 quorum 也沒選主,靠事件在背景收斂。這帶來兩個實務約束:官方指南建議前端搭 sticky session 讓同一使用者黏在同一節點,避免看到自己剛寫入的資料還沒收斂;或直接把拓撲當 active-passive 用、故障時手動 failover。想要跨區真正主動-主動並容忍寫入衝突的組織要自己補這一層 UX;只需要單機加離線備份的中小站則剛好落在甜蜜點上。

把 OpenSSL 從相依樹裡整片拿掉

1.10 版本(2026 年 5 月)最有份量的動作是把 OpenSSL 整個從相依樹裡砍掉,改採 RustCrypto 加 Rustls。這在自架服務圈幾乎沒別人做到。

意義有幾層。一是供應鏈攻擊面:OpenSSL 過去十年出過幾次高 CVSS 的核心 CVE(Heartbleed、Punycode 溢位、X.509 名字約束繞過),每次都是全球一起半夜排 patch。以 Rust 為主體的密碼學堆疊仍會出漏洞,但屬於 memory-safety 類別的漏洞——buffer overflow、use-after-free、double-free——會被編譯期直接擋掉,Kanidm 這條路線能實際削減的正是這一類的攻擊面。要注意的是 Rustls 底層 provider 仍可能選用 C 實作(例如預設支援的 aws-lc-rs),完全純 Rust 建置需要另外指定 provider。

二是打包難度。過去在 Alpine、musl-based 容器裡編 Kanidm 遇到的問題有九成跟 OpenSSL 有關——動態連結對不上系統版本、跨版本 ABI 崩壞、FIPS 模式切換踩雷。拿掉 OpenSSL 之後 ldd 出來的相依明顯縮短,跨 distro 移植的痛點大幅降低(官方 container 仍是動態連結、非全靜態鏡像)。

三是 FIPS 這條路。Kanidm 官方目前並未針對其密碼學建置走 FIPS 140-3 驗證流程,需要符合政府或金融合規的組織仍需選擇具備 FIPS 驗證路徑的方案。Kanidm 在文件裡直接說明這點,並建議這類場景考慮 Keycloak,因為它可以搭配過 FIPS 認證的 Java crypto provider。這種明確表態比很多同類專案含糊帶過的態度好得多。

Passkey 當預設而不是加值選項

Authentik 與 Keycloak 的 WebAuthn 是「打開之後可以用」,Kanidm 是「passkey 是主流路徑,密碼是備援」。這個差異看似字面遊戲,反映到管理面差很多。

在 Kanidm 建立新使用者時,預設流程就是登入者用管理員給的一次性連結,在瀏覽器上直接註冊 passkey;沒有預設密碼、沒有臨時密碼寄信、也沒有第一次登入強制改密碼那套流程。Kanidm 也支援 WebAuthn Attestation——企業可以透過 policy 只允許特定廠牌的硬體金鑰(例如白名單 YubiKey、綠芯、Feitian)註冊,這是很多合規場景會強制要求的。Authentik 與 Zitadel 目前都沒把 attestation 政策做到這個顆粒度。

1.11 版新增的 128 UTF-8 字元密碼上限值得單獨拉出來講。這不是不信任使用者,而是為了防 slow-hash DoS:Argon2id 這類慢雜湊在 512 位元組以上的輸入下,單次驗證會吃掉伺服器數十毫秒 CPU,攻擊者若對登入 API 塞 4 KB 的假密碼連打,一臺 4 vCPU 的 VPS 幾秒內就會被拖垮。128 字元的門檻對真人使用者夠寬鬆,對自動化打點是硬止血。

值得一提的細節:Kanidm 1.11 起密碼欄位會在瀏覽器端做即時強度提示,但不會把密碼送去外部服務比對,對資安敏感的使用者是加分項。

Unix/PAM/SSH 這條被大多數 IdP 冷落的線

自架 SSO 的資料主要跑在瀏覽器,但真正在用一群 Linux 主機的團隊要的其實不只 web SSO,還包含 SSH 登入、sudo、nsswitch、home directory 掛載、shell 環境。這一大塊過去只有 FreeIPA 加 SSSD 認真做,門檻高到很多小團隊乾脆放棄 IdP 直接自己維護 authorized_keys

Kanidm 從第一天就把這條線放進核心:kanidm-unixd 是常駐在每臺 Linux 主機上的 client daemon,直接接 NSS 與 PAM,本地帳號、群組、SSH 公鑰、憑證都從 Kanidm 拉過來,並支援本地快取讓網路中斷或離線時仍能登入。sudo 授權則仍由主機端的 /etc/sudoerssudoers.d 管理,並非由 Kanidm server 集中下發,這點與 FreeIPA 的 SUDO rule 分發差別要放心裡。1.10 版加入的 bind mount home directory 支援解決了 symlink 在某些 filesystem 或 SELinux 情境下出問題的老 bug——現在可以把 /home/user 直接 bind 到實體資料夾,不再靠可能被 policy 擋掉的 symlink。

對於管理一群 VPS 的團隊,這代表新機開通只要裝 unixd、指向 Kanidm、把使用者與群組加上 POSIX 擴充屬性,該人就能用 passkey 登 web 介面、用 SSH key 登主機、用主機端 sudoers 授予的權限執行指令。要注意撤銷不是即時的:unixd 有本地快取與離線登入設計,實際失效時間取決於 cache_timeout 與離線登入允許期間;對安全敏感的環境建議把 timeout 調短、並在停用帳號時另外強制清 cache。

拿這功能對照 Authentik 或 Zitadel 分工不同:Authentik 本身提供 LDAP outpost 可以讓 Linux 主機透過 SSSD 對接,但整套 Unix 側依舊靠 SSSD 處理;Zitadel 則沒有內建的 Unix client。Kanidm 把 client daemon 一併寫進專案,堆疊統一在同一套工具鏈上,維護面小上一截。

部署面:一顆 binary 加一份 config

實務部署最簡單的樣子就是拉官方 container image、掛一個 volume 存 SQLite、給一份 TLS 憑證(Kanidm 堅持強制 HTTPS,沒有 plaintext HTTP 模式):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
services:
kanidm:
image: kanidm/server:1.11.1
hostname: idm.example.tw
ports:
- "443:8443"
- "636:3636"
volumes:
- ./data:/data
- ./tls:/tls:ro
environment:
KANIDM_DOMAIN: "idm.example.tw"
KANIDM_ORIGIN: "https://idm.example.tw"
KANIDM_TLS_CHAIN: "/tls/fullchain.pem"
KANIDM_TLS_KEY: "/tls/privkey.pem"
KANIDM_BINDADDRESS: "0.0.0.0:8443"
KANIDM_LDAPBINDADDRESS: "0.0.0.0:3636"

KANIDM_DOMAINKANIDM_ORIGIN 兩項是必要的——origin 是 WebAuthn 綁定的 URL,上線後改 domain 需執行 kanidmd domain rename 且會使既有 WebAuthn 與 OAuth token 全部失效,開頭就要規劃好。一臺 2 vCPU、2 GB RAM 的 VPS 就能跑 5000 使用者規模的正式環境,開啟 LDAPS 後讓 Grafana、Vaultwarden、Immich、Nextcloud 這些自架服務走 OIDC 對接沒有問題。

備份是 offline 操作:停止容器後執行 kanidmd database backup -c /data/server.toml /backup/kanidm.backup.json,產出的 JSON 檔交給 restic 或 borg 做加密異地保存。想要不停機,server.toml 可以開 online_backup 讓服務定時產出 snapshot;還原命令為 kanidmd database restore,官方要求使用與備份相同版本的 server binary。

kanidmd configtest 子指令能在啟動前驗證 config,抓出憑證錯誤、DNS 對不到、時區跑掉這類部署常見的坑,這比要看 log 才發現的體驗好上一截。

三個 IdP 的選型建議

一個大原則:組織規模與整合需求,決定 Kanidm 是否合適。

值得選 Kanidm 的組合有:使用者數在 5 千以內、需要把 Linux SSH/PAM/sudo 一起管、想要 passkey 為預設、希望砍掉外部 DB 相依、對供應鏈安全(無 OpenSSL)在意。臺灣中小型 SaaS、學術實驗室、Web3 團隊、少數 sysadmin 撐起來的內部工具站,多半落在這個範圍。

不建議選 Kanidm 的場景包括:需要 SAML 為主的舊系統對接(Kanidm 1.11 尚未提供 SAML IdP,只支援 OAuth2/OIDC;仍要 SAML 就得選 Keycloak 或 Authentik)、需要企業級 IdP-brokering(把多家外部 IdP 統合起來,Keycloak 是首選)、需要 SaaS 樣板的多租戶隔離(Zitadel 為此而生)、需要極度自訂的登入 flow(Authentik 的 flow engine 沒有對手)、需要 FIPS 認證的合規場景。

至於已經跑 Authentik 或 Keycloak 且運作良好的組織,沒有非搬不可的理由。Kanidm 的價值在新專案或想把身分基礎設施做小、做穩的重構場景,不在替換一個運作中的系統。

把身分服務放在自己控制的機器上

Kanidm 1.11 這一版把 Rust 原生路線走完最後一哩路。對於選型階段還在 Authentik、Zitadel、Keycloak 三個選項裡糾結的組織,多加一個 Kanidm 進來會發現它把「小而完整」這條軸線拉到目前的最高點——SSO、Unix/PAM、SSH、WebAuthn、RADIUS 都在同一套專案的堆疊裡(kanidmd 為 server、kanidm-unixd 為 Unix client、rlm_kanidm 為 RADIUS 模組),無 PostgreSQL、無 Redis、無 OpenSSL。

實際上線之前建議先在測試 VPS 上跑滿一週,把 passkey 註冊、OIDC 對接自架服務、SSH 登入、備份還原、憑證輪替這五件事各走過一遍,就能確認組織的流程能不能承接這種「passkey 為預設」的心態切換——這才是 Kanidm 最需要適應的部分,不是技術。

NCSE Network 提供臺灣本地的高效能 VPS 主機(Intel Gold CPU、NVMe SSD、是方電訊機房),適合部署 Kanidm、Authentik 這類需要低延遲、穩定電力與可控網路環境的自架身分服務。想把 SSO 從第三方 SaaS 搬回自己機房、或是評估 Rust 原生 IdP 的部署架構時,可以直接聯絡 NCSE Network 討論規劃。

需要穩定的雲端主機?

NCSE Network 提供企業級 VPS,7 天免費試用,臺灣是方電訊機房,99% SLA 保證。

查看 VPS 方案 →