Clevis 是一個用於自動解密的可插入框架。它可用於提供資料的自動解密,甚至 LUKS 卷的自動解鎖。
這看起來像什麼?好吧,第一步是加密一些資料。我們用一個簡單的命令來做到這一點:
$ clevis encrypt PIN CONFIG < PLAINTEXT > CIPHERTEXT.jwe
此命令在標準輸入上取得純文本,並在標準輸出上產生加密的 JWE 物件。除了明文之外,我們還需要指定兩個額外的輸入參數。
首先是引腳。在U形夾術語中,引腳是實現自動解密的插件。我們在這裡簡單地傳遞一個引腳的名稱。
其次,是配置。配置是一個 JSON 對象,將直接傳遞到 pin。它包含執行加密和設定自動解密所需的所有配置。
要解密我們的 JWE,我們只需執行以下操作:
$ clevis decrypt < CIPHERTEXT.jwe > PLAINTEXT
請注意,解密命令不需要額外的輸入或互動。讓我們來看一些更具體的例子。
Tang 是一種伺服器實現,無需託管即可提供加密綁定服務。克萊維斯全力支持唐。以下是如何將 U 型夾與 Tang 一起使用的範例:
$ echo hi | clevis encrypt tang ' {"url": "http://tang.local"} ' > hi.jwe
The advertisement is signed with the following keys:
kWwirxc5PhkFIH0yE28nc-EvjDY
Do you wish to trust the advertisement ? [yN] y
在此範例中,我們使用 Tang pin 加密訊息“hi”。在這種情況下,唯一需要的參數是 Tang 伺服器的 URL。在加密過程中,Tang pin 會向伺服器請求金鑰通告,並要求您信任金鑰。這與 SSH 的工作原理類似。
或者,您可以使用adv
參數手動載入廣告。此參數採用引用儲存廣告的檔案的字串,或廣告本身的 JSON 內容。當像這樣手動指定廣告時,Clevis 假定該廣告是可信的。
Clevis 支援將可信任平台模組 2.0 (TPM2) 晶片中的金鑰進行加密。用於加密的加密強度高的隨機金鑰使用 TPM2 晶片進行加密,並在解密時使用 TPM2 進行解密,以允許 U 形夾解密儲存在 JWE 中的秘密。
例如:
$ echo hi | clevis encrypt tpm2 ' {} ' > hi.jwe
Clevis 將加密金鑰的公鑰和私鑰儲存在 JWE 物件中,因此可以在解密時取得這些金鑰以解封使用 TPM2 加密的金鑰。
U 型夾可以執行 PKCS#11 應用程式的角色,如 RFC 7512:PKCS#11 URI 方案所述。
PKCS#11 協定確定必須將 PIN(個人識別號碼)配置到硬體設備中,以便解鎖過程成功。 U形夾將允許用戶解鎖特定的加密磁碟,並將提供一種獲取PIN碼的方法。會有兩種可能:
1 - 在啟動時提供 PIN:在第一種情況下,Clevis 將偵測 PKCS#11 裝置並提示輸入其 PIN。如果 PIN 碼錯誤,Clevis 將再次提示輸入 PIN 碼。使用者有責任了解在 PIN 未知的情況下設備可能被鎖定/變磚的情況。
2 - 在 U 型夾配置時提供 PIN:在第二種情況下,U 型夾將使用 PIN 值進行配置。
最初,RFC7512 定義了一種機制來指定一種特殊類型的 URI( pkcs11
URI),該機制允許識別設備以及解鎖設備所需的資訊。值得特別注意的是參數pin-value
,它允許分別指定 PIN 的值或 PIN 的位置。 U形夾最初會理解「引腳值」參數。您可以在下面找到使用先前參數的 PKCS#11 URI 的範例:
pin-value
的 PKCS#11 URI: pkcs11:token=Software%20PKCS%2311%20softtoken;manufacturer=Snake%20Oil,%20Inc.?pin-value=the-pin
下一節將提供 U 形夾配置範例,以便闡明將 PKCS#11 裝置綁定到加密磁碟的不同選項。
U 型夾將為使用者提供將特定 PKCS#11 裝置綁定到加密裝置的機制。 U形夾的新接腳名稱為pkcs11
,配置方式與目前使用的方式相同:
$ clevis luks bind -h
Usage: clevis luks bind [-y] [-f] [-s SLT] [-k KEY] [-t TOKEN_ID] [-e EXISTING_TOKEN_ID] -d DEV PIN CFG
作為第一個範例,使用者可以透過向 Clevis 指定設備的 URI 來提供設備的資訊:
$ clevis luks bind -d /dev/sda1 pkcs11 '{"uri": "pkcs11:model=PKCS%2315%20emulated;manufacturer=piv_II;
serial=0a35ba26b062b9c5;token=clevis;id=%02;object=Encryption%20Key"}'
另一個選項是為 Clevis 提供配置,以便綁定 Clevis 找到的第一個 PKCS#11 設備。為此,可以提供一個空 URI,如下所示:
$ clevis luks bind -d /dev/sda1 pkcs11 '{"uri": "pkcs11:"}'
與前一個相同的更短的配置命令如下所示:
$ clevis luks bind -d /dev/sda1 pkcs11 '{}'
在這種情況下,Clevis將負責檢測設備,如果沒有找到設備,則負責轉儲相應的錯誤。
必須澄清的是,提供空 URI 將使 Clevis 提示選擇與令牌相符的可用金鑰之一,以避免意外使用不必要的金鑰進行加密。
可以向 Clevis 提供模組路徑,以便它使用該模組來存取設備。只有當該卡不受底層 Clevis 軟體 (OpenSC) 支援時才需要這樣做。因此,模組路徑字段是完全可選的。若要提供模組位置,使用者可以向“uri”U 形夾配置提供“模組路徑”:
$ clevis-luks-bind -d /dev/sda1 pkcs11 '{"uri": "pkcs11:model=PKCS%2315%20emulated;manufacturer=piv_II;
serial=0a35ba26b062b9c5;token=clevis;id=%02;object=Encryption%20Key?
module-path=/usr/local/lib64/libmypkcs11.so"}'
與其他裝置一樣,可以使用clevis luks list
指令檢查已綁定到 PKCS#11 裝置的加密磁碟:
$ clevis luks list -d /dev/sda1
1: pkcs11 '{"uri": "pkcs11:model=PKCS%2315%20emulated;manufacturer=piv_II;
serial=0a35ba26b062b9c5;token=clevis;id=%02;object=Encryption%20Key?
module-path=/usr/local/lib64/libmypkcs11.so"}'
在開發的第一階段,Clevis 將在 OpenSC 之上使用以提供 PKCS#11 功能。 OpenSC,特別是pkcs11-tool
,提供了一個選項來指示用於解密的機制。出於測試目的,某些程式庫(例如 SoftHSM)不支援預設的pkcs11-tool
機制,因此需要提供特定的機制來使用。因此,可以為 Clevis 提供一個使用機制,以防預設機制RSA-PKCS-OAEP
無效:
$ clevis luks bind -d /dev/sda1 pkcs11 '{"uri": "pkcs11:", "mechanism":"RSA-PKCS"}'
為了檢查特定令牌的可用機制,可以使用指令pkcs11-tool -M
:
$ pkcs11-tool -M
Using slot 0 with a present token (0x0)
Supported mechanisms:
SHA-1, digest
...
SHA512, digest
MD5, digest
...
RSA-PKCS-KEY-PAIR-GEN, keySize={2048,4096}, generate_key_pair
目前,Clevis 僅支援 RSA 機制。由於其餘演算法的限制,沒有其他非對稱密碼演算法可以輕鬆地進行加密。 ECC 僅支援簽章和金鑰派生,但不支援加密。加密操作可以透過金鑰派生以某種方式構建,但這不是一個簡單的操作。
必須強調的是,RSA-PKCS 機制(PKCS#1.5 加密填充)被認為是不安全的,它主要是為了相容性而提供的,但不建議在生產中使用它。
U 型夾將允許透過提供給 URI 的參數來指定 PKCS#11 設備所在的插槽:
$ clevis luks bind -d /dev/sda1 pkcs11 '{"uri": "pkcs11:slot-id=0"}'
必須澄清的是,僅提供槽資訊將使 Clevis 猜測與所選槽中的令牌匹配的可用密鑰之一,這可能會導致意外地使用不需要的密鑰進行加密。不建議使用 slot 作為設備選擇器,因為 slot id 是一個不能保證在 PKCS#11 模組初始化過程中保持穩定的數字。但是,某些庫和模組提供穩定的插槽標識符,因此它可以用於這些特殊情況。
有兩個更好的選項可以區分不同的 PKCS#11 設備:
1 - 使用公鑰物件的多設備配置(建議):
從OpenSC
的最新版本(從 OpenSC 0.26.0 版本開始)開始,Clevis 使用pkcs11-tool
來處理大多數 PKCS#11 命令,PKCS#11 URI 會針對令牌和物件進行轉儲。
$ pkcs11-tool -L | grep uri
uri : pkcs11:model=PKCS%2315%20emulated;manufacturer=piv_II;serial=42facd1f749ece7f;token=clevis
uri : pkcs11:model=PKCS%2315%20emulated;manufacturer=OpenPGP%20project;serial=000f06080f4f;token=OpenPGP%20card%20%28User%20PIN%29
$ pkcs11-tool -O --slot-index 1 --type pubkey | grep uri
ising slot 0 with a present token (0x0)
uri: pkcs11:model=PKCS%2315%20emulated;manufacturer=OpenPGP%20project;serial=000f06080f4f;token=OpenPGP%20card%20%28User%20PIN%29;id=%03;object=Authentication%20key;type=public
在這種特殊情況下,當存在多個 PKCS#11 裝置時,選擇特定裝置的公鑰並將其綁定到 U 型夾:
$ clevis luks bind -d /dev/sda pkcs11 '{"uri":"pkcs11:model=PKCS%2315%20emulated;manufacturer=OpenPGP%20project;serial=000f06080f4f;token=OpenPGP%20card%20%28User%20PIN%29;id=%03;object=Authentication%20key;type=public"}'
如果您使用模組路徑,則必須使用提供 --module 選項時返回的路徑:
$ pkcs11-tool --module /usr/lib64/libykcs11.so -O --type pubkey | grep uri
/usr/local/bin/pkcs11-tool.manual --module /usr/lib64/libykcs11.so -O --type pubkey | grep uri
Using slot 0 with a present token (0x0)
uri: pkcs11:model=YubiKey%20YK5;manufacturer=Yubico%20%28www.yubico.com%29;serial=28083311;token=YubiKey%20PIV%20%2328083311;id=%03;object=Public%20key%20for%20Key%20Management;type=public
uri: pkcs11:model=YubiKey%20YK5;manufacturer=Yubico%20%28www.yubico.com%29;serial=28083311;token=YubiKey%20PIV%20%2328083311;id=%19;object=Public%20key%20for%20PIV%20Attestation;type=public
$ clevis luks bind -d /dev/sda pkcs11 '{"uri":"pkcs11:model=YubiKey%20YK5;manufacturer=Yubico%20%28www.yubico.com%29;serial=28083311;token=YubiKey%20PIV%20%2328083311;id=%03;object=Public%20key%20for%20Key%20Management;type=public;module-path=/usr/lib64/libykcs11.so"}'
2 - 具有串列+令牌規範的多設備配置:
對於pkcs11-tool
不轉儲令牌/物件的 URI 的版本,U 形夾將使用裝置serial
+ token label
對「嘗試」特定標識。在這種類型的場景中,可以使用這兩個參數執行識別,但也應提供model
以便在詢問 PIN 時方便 U 形夾告知設備:
# pkcs11-tool -L | grep "token label|serial"
token label : OpenPGP card (User PIN)
serial num : 42facd1f749ece7f
$ clevis luks bind -d /dev/sda pkcs11 '{"uri":"pkcs11:model=PKCS%2315%20emulated;serial=000f06080f4f;token=OpenPGP%20card%20%28User%20PIN%29"}'
請記住,特殊字元必須以百分比模式定義,如 RFC 7512:PKCS#11 URI 方案中所定義。
若要安裝和設定 U 型夾 PKCS#11 功能,必須遵循下列步驟:
1 - 安裝 Clevis 所需的依賴項,包括 PKCS#11 依賴項:
$ sudo dnf install -y opensc pcsc-lite openssl socat
2 - PKCS11 設備必須可透過「pkcs11-tool」存取:
$ pkcs11-tool -L
pkcs11-tool -L
Available slots:
Slot 0 (0x0): Yubico YubiKey OTP+CCID 00 00
token label : clevis
...
uri : pkcs11:model=PKCS%2315%20emulated;manufacturer=piv_II;serial=42facd1f749ece7f;token=clevis
3 - 配置設備以與 U 型夾綁定:
$ sudo clevis luks bind -d /dev/sda5 pkcs11 '{"uri":"pkcs11:"}'
如果需要提供要使用的模組,可以透過module-path
URI 參數來完成:
$ sudo clevis luks bind -d /dev/sda5 pkcs11 '{"uri":"pkcs11:module-path=/usr/lib64/libykcs11.so.2"}'
4 - 啟用 clevis-luks-pkcs11-askpass.socket 單元:
$ sudo systemctl enable --now clevis-luks-pkcs11-askpass.socket
5 - /etc/crypttab 設定:
為了使 PKCS#11 功能正常工作,必須配置/etc/crypttab
文件,以便 systemd 使用 AF_UNIX 套接字等待解鎖磁碟的關鍵短語,而不是透過控制台提示它。
Clevis PKCS#11 單元檔案會在路徑/run/systemd/clevis-pkcs11.sock
中設定一個套接字來傳送和接收磁碟解鎖的資訊。對於將透過 PKCS#11 U 形銷解鎖的磁碟,必須將該套接字檔案配置為金鑰檔案。因此,必須在/etc/crypttab
中引入下一個變更才能進行解鎖:
$ sudo diff -Nuar /etc/crypttab.ori /etc/crypttab
--- /etc/crypttab.ori 2024-07-04 10:46:16.295073739 +0200
+++ /etc/crypttab 2024-07-03 17:14:27.764743860 +0200
@@ -1 +1,2 @@
-luks-6e38d5e1-7f83-43cc-819a-7416bcbf9f84 UUID=6e38d5e1-7f83-43cc-819a-7416bcbf9f84 - -
+luks-6e38d5e1-7f83-43cc-819a-7416bcbf9f84 UUID=6e38d5e1-7f83-43cc-819a-7416bcbf9f84 /run/systemd/clevis-pkcs11.sock keyfile-timeout=30s
強烈建議設定keyfile-timeout
選項來配置失敗機制,以防發生某些解鎖錯誤並且需要透過控制台手動輸入密碼。
6 - 重新啟動並測試:
系統應啟動並詢問 PKCS#11 設備 PIN,只有在 PIN 正確的情況下才解密對應配置的加密磁碟。
7 - 如果不需要測試啟動過程,請使用下一個命令進行加密和解密(請注意,必須提供 PIN 值才能正常工作),並檢查是否可以使用此單行程式碼執行字串的加密/解密,並且不會發生錯誤:
$ echo "top secret" | clevis encrypt pkcs11 '{"uri":"pkcs11:module-path=/usr/lib64/libykcs11.so.2?pin-value=123456"}' | clevis decrypt
應傳回top secret
字串
U 型夾提供了一種將引腳混合在一起以提供複雜的解鎖策略的方法。這是透過使用稱為 Shamir 秘密共享 (SSS) 的演算法來完成的。
SSS 是一種閾值方案。它創建一個密鑰並將其分成多個部分。每個部分都使用另一個密碼進行加密(甚至可能遞歸地使用 SSS)。此外,您也定義閾值t
。如果至少可以解密t
區塊,則可以恢復加密金鑰並且解密可以成功。
以下是我們將 SSS 引腳與 Tang 和 TPM2 引腳一起使用的範例:
$ echo hi | clevis encrypt sss
' {"t": 2, "pins": {"tpm2": {"pcr_ids": "0"}, "tang": {"url": "http://tang.local"}}} '
> hi.jwe
在上面的範例中,我們定義了兩個子引腳,閾值為 2。
這是我們僅使用唐針的另一個範例:
$ echo hi | clevis encrypt sss
' {"t": 1, "pins": {"tang": [{"url": "http://server1.local/key"}, {"url": "http://server2.local/key"}]}} '
> hi.jwe
在此範例中,我們定義了 Tang 引腳的兩個子實例 - 每個實例都有自己的配置。由於我們的閾值為 1,因此如果任何一個Tang pin 實例在解密過程中成功,SSS 就會成功。
U 型夾可用於使用引腳綁定 LUKS 卷,以便它可以自動解鎖。
它的工作原理相當簡單。我們產生一個新的、加密強度高的金鑰。此密鑰會作為附加密碼新增至 LUKS。然後,我們使用 U 形夾加密該金鑰,並使用 LUKSMeta 將輸出 JWE 儲存在 LUKS 標頭內。
以下是我們使用 Tang 引腳綁定/dev/sda1
的範例:
$ sudo clevis luks bind -d /dev/sda1 tang ' {"url": "http://tang.local"} '
The advertisement is signed with the following keys:
kWwirxc5PhkFIH0yE28nc-EvjDY
Do you wish to trust the advertisement ? [yN] y
Enter existing LUKS password:
成功完成此綁定程序後,可以使用提供的解鎖器之一解鎖磁碟。
如果您想使用基於網路的解鎖,則需要指定rd.neednet=1
作為核心參數,或在使用 dracut 建立時使用--hostonly-cmdline
。
如果您使用帶有 TLS 的Tang (例如: '{"url": "https://tang.remote"}'
),資料夾/etc/ssl
應包含在 initramfs 映像中, --include /etc/ssl /etc/ssl --force
使用 dracut 建立時強制。
Dracut 解鎖程式嘗試在早期啟動期間自動解鎖磁碟區。這允許自動根卷加密。啟用 Dracut 解鎖器非常簡單。安裝 Clevis 後只需重建 initramfs:
$ sudo dracut -f
重新啟動後,系統將提示您使用密碼解鎖磁碟區。在後台,U 形夾將嘗試自動解鎖該磁碟區。如果成功,密碼提示將被取消,引導將繼續。
當將 Clevis 與 initramfs-tools 一起使用時,為了重建 initramfs,您需要執行:
sudo update-initramfs -u -k ' all '
重新啟動後,它的行為就像使用 Dracut 一樣。
我們的 UDisks2 解鎖器在您的桌面工作階段中運作。您不需要手動啟用它;只需安裝 Clevis UDisks2 解鎖器並重新啟動桌面工作階段即可。解鎖器應該會自動啟動。
這款解鎖器的工作原理與 Dracut 解鎖器幾乎完全相同。如果您插入已與 U 型夾綁定的可移動存儲設備,我們將在桌面密碼提示的同時嘗試自動解鎖它。如果自動解鎖成功,密碼提示將消失,無需用戶幹預。
綁定到 U 型夾策略的 LUKS 裝置也可以使用 clevis luks 解鎖指令解鎖。
$ sudo clevis luks unlock -d /dev/sda1
可以使用 clevis luks unbind 指令取消綁定 LUKS 磁碟區。例如:
$ sudo clevis luks unbind -d /dev/sda1 -s 1
可以使用 clevis luks list 指令列出綁定到給定 LUKS 磁碟區的引腳。例如:
$ sudo clevis luks list -d /dev/sda1
請不要直接安裝U形夾。相反,請使用您首選發行版的軟體包。
此指令分別安裝核心 U 型夾指令、Dracut 解鎖器和 UDisks2 解鎖器。
$ sudo dnf install clevis clevis-dracut clevis-udisks2
如上一節所述,建議不要直接安裝U形夾。但是,如果您的 Linux 發行版不存在 Clevis 軟體包,則手動編譯和安裝 Clevis 的步驟如下:
$ wget https://github.com/latchset/clevis/releases/download/v21/clevis-21.tar.xz
$ tar Jxvf clevis-21.tar.xz
$ cd clevis-21
$ mkdir build
$ cd build
meson
來設定編譯: $ meson setup ..
ninja
指令編譯: $ ninja
ninja install
指令安裝(您需要 root 權限): $ sudo ninja install