Clevis は、自動復号化のためのプラグイン可能なフレームワークです。これを使用して、データの自動復号化や、LUKS ボリュームの自動ロック解除を行うこともできます。
これはどのように見えますか?最初のステップは、一部のデータを暗号化することです。これを簡単なコマンドで実行します。
$ clevis encrypt PIN CONFIG < PLAINTEXT > CIPHERTEXT.jwe
このコマンドは、標準入力でプレーンテキストを受け取り、標準出力で暗号化された JWE オブジェクトを生成します。プレーンテキストの他に、2 つの追加の入力パラメータを指定する必要があります。
まずはピンです。クレビスの用語では、ピンは自動復号化を実装するプラグインです。ここではピンの名前を渡すだけです。
2番目は構成です。設定は JSON オブジェクトであり、ピンに直接渡されます。これには、暗号化を実行し、自動復号化をセットアップするために必要なすべての構成が含まれています。
JWE を復号化するには、次の操作を実行するだけです。
$ clevis decrypt < CIPHERTEXT.jwe > PLAINTEXT
復号化コマンドには追加の入力や対話は必要ないことに注意してください。もう少し具体的な例を見てみましょう。
Tang は、エスクローを必要とせずに暗号バインディング サービスを提供するサーバー実装です。クレビスはタンを全面的にサポートしています。以下は、Tang で Clevis を使用する方法の例です。
$ 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 ピンを使用してメッセージ「hi」を暗号化します。この場合に必要なパラメータは、Tang サーバーの URL だけです。暗号化プロセス中に、Tang ピンはサーバーにキーのアドバタイズメントを要求し、キーを信頼するように求めます。これは SSH と同様に機能します。
あるいは、 adv
パラメータを使用してアドバタイズメントを手動でロードすることもできます。このパラメータは、広告が保存されているファイルを参照する文字列、または広告自体の JSON コンテンツのいずれかを受け取ります。このようにアドバタイズメントが手動で指定されると、Clevis はそのアドバタイズメントが信頼できるものであると推定します。
Clevis は、Trusted Platform Module 2.0 (TPM2) チップ内のキーの暗号化のサポートを提供します。暗号化に使用される暗号的に強力なランダム キーは、TPM2 チップを使用して暗号化され、復号化時に TPM2 を使用して復号化されるため、clevis は JWE に保存されている秘密を復号化できます。
例えば:
$ echo hi | clevis encrypt tpm2 ' {} ' > hi.jwe
Clevis は、暗号化されたキーの公開キーと秘密キーを JWE オブジェクトに保存するため、復号化時にこれらをフェッチして、TPM2 を使用して暗号化されたキーの封印を解除できます。
Clevis は、RFC 7512: PKCS#11 URI スキームで説明されているように、PKCS#11 アプリケーションの役割を実行できます。
PKCS#11 プロトコルは、ロック解除プロセスを成功させるために PIN (個人識別番号) をハードウェア デバイスに構成する必要があると判断します。 Clevis を使用すると、ユーザーは特定の暗号化されたディスクのロックを解除でき、PIN を取得する方法が提供されます。次の 2 つの可能性があります。
1 - 起動時に PIN を入力する: この最初のケースでは、Clevis は PKCS#11 デバイスを検出し、その PIN の入力を求めます。 PIN が間違っている場合、Clevis は再度 PIN の入力を求めます。 PIN が不明な場合にデバイスがロック/ブリックされる可能性があることに注意するのはユーザーの責任です。
2 - Clevis 構成時に PIN を指定します。この 2 番目のケースでは、Clevis は PIN 値で構成されます。
最初に、RFC7512 は特別な種類の URI ( pkcs11
URI) を指定するメカニズムを定義します。これにより、デバイスとそのロックを解除するために必要な情報の両方を識別できるようになります。 PIN の値または PIN の場所をそれぞれ指定できるパラメータpin-value
には特に注意が必要です。 Clevis は、最初は「pin-value」パラメータを理解します。以下に、前のパラメータを使用した PKCS#11 URI の例を示します。
pin-value
が定義された PKCS#11 URI: pkcs11:token=Software%20PKCS%2311%20softtoken;manufacturer=Snake%20Oil,%20Inc.?pin-value=the-pin
次のセクションでは、暗号化されたディスクにバインドされる PKCS#11 デバイスのさまざまなオプションを明確にするために、Clevis 構成例を示します。
Clevis は、ユーザーが特定の PKCS#11 デバイスを暗号化されたデバイスにバインドするメカニズムを提供します。 Clevis の新しいピンの名前は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
最初の例として、ユーザーは URI を Clevis に指定することでデバイスの情報を提供できます。
$ 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 によって検出された最初の PKCS#11 デバイスがバインドされるように、Clevis に構成を提供することです。これを行うには、以下に示すように空の URI を指定します。
$ clevis luks bind -d /dev/sda1 pkcs11 '{"uri": "pkcs11:"}'
前のものと同等のさらに短い設定コマンドを以下に示します。
$ clevis luks bind -d /dev/sda1 pkcs11 '{}'
この場合、Clevis はデバイスの検出を担当し、デバイスが見つからない場合は、対応するエラーをダンプする責任を負います。
空の URI を指定すると、不要なキーによる誤った暗号化を避けるために、Clevis がトークンに一致する利用可能なキーの 1 つを選択するように要求されることを明確にする必要があります。
モジュール パスを Clevis に提供すると、そのモジュールを使用してデバイスにアクセスできます。これは、カードが基盤となる Clevis ソフトウェア (OpenSC) でサポートされていない場合にのみ必要です。このため、モジュール パス フィールドは完全にオプションです。モジュールの場所を指定するには、ユーザーは「uri」Clevis 構成に「module-path」を指定します。
$ 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"}'
残りのデバイスと同様に、PKCS#11 デバイスにバインドされている暗号化ディスクは、 clevis luks list
コマンドで確認できます。
$ 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"}'
開発の最初のフェーズでは、PKCS#11 機能を提供するために OpenSC の最上位で Clevis が使用されます。 OpenSC、特にpkcs11-tool
、復号化に使用するメカニズムを示すオプションを提供します。テスト目的では、SoftHSM などの一部のライブラリはデフォルトのpkcs11-tool
メカニズムでは動作しないため、使用する特定のメカニズムを提供する必要があります。このため、デフォルトのRSA-PKCS-OAEP
が無効な場合に備えて、Clevis に使用するメカニズムを提供できます。
$ 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 パディング) は安全ではないと考えられており、主に互換性のために提供されていますが、運用環境での使用は推奨されないことに注意してください。
Clevis では、URI に提供されるパラメータを通じて、PKCS#11 デバイスが配置されているスロットを指定できます。
$ clevis luks bind -d /dev/sda1 pkcs11 '{"uri": "pkcs11:slot-id=0"}'
スロット情報のみを提供すると、Clevis は選択したスロットのトークンに一致する利用可能なキーの 1 つを推測することになり、不要なキーで誤って暗号化される可能性があることを明確にする必要があります。スロット ID は PKCS#11 モジュールの初期化全体で安定していることが保証されていない数値であるため、スロットをデバイス セレクターとして使用することはお勧めできません。ただし、安定したスロット識別子を提供する特定のライブラリとモジュールがあるため、これらの特定の場合に使用できます。
異なる PKCS#11 デバイスを区別するには、2 つのより良いオプションがあります。
1 - 公開キー オブジェクトを使用したマルチデバイス構成 (推奨):
OpenSC
の最新バージョン (OpenSC 0.26.0 リリース以降) 以降、PKCS#11 コマンドのほとんどを処理するために Clevis によって使用されるpkcs11-tool
、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 デバイスが存在するときに、特定のデバイスの公開キーを選択し、それを Clevis にバインドします。
$ 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-path を使用している場合は、--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 をダンプしないバージョンの場合、デバイスのserial
+ token label
ペアを使用して、Clevis によって特定の識別が「試行」されます。このタイプのシナリオでは、これら 2 つのパラメータを使用して識別を実行できますが、PIN を要求するときに Clevis がデバイスについて簡単に通知できるようにするためのmodel
も提供する必要があります。
# 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: The PKCS#11 URI Scheme で定義されているように、特殊文字はパーセント モードで定義する必要があることに注意してください。
クレビス PKCS#11 フィーチャーのインストールと設定を行うには、次の手順に従う必要があります。
1 - PKCS#11 依存関係を含む、Clevis に必要な依存関係をインストールします。
$ 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 - クレビスでバインドするようにデバイスを構成します。
$ 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 機能が適切に動作するには、systemd が AF_UNIX ソケットを使用してディスクのロックを解除するキーフレーズを待機し、コンソールからキーフレーズを要求しないように/etc/crypttab
ファイルを構成する必要があります。
Clevis PKCS#11 ユニット ファイルは、パス/run/systemd/clevis-pkcs11.sock
にソケットを設定して、ディスクのロック解除に関する情報を送受信します。 PKCS#11 クレビス ピンを通じてロックを解除するディスクの場合、そのソケット ファイルをキー ファイルとして設定する必要があります。したがって、ロックを解除するには、次の変更を/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
文字列が返される必要があります
Clevis は、ピンを組み合わせて高度なロック解除ポリシーを提供する方法を提供します。これは、Shamir Secret Sharing (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 つの子ピンを定義し、しきい値は 2 です。これは、SSS 自体が成功するためには、復号化中に両方の子ピンが成功する必要があることを意味します。
以下はタング ピンのみを使用する別の例です。
$ echo hi | clevis encrypt sss
' {"t": 1, "pins": {"tang": [{"url": "http://server1.local/key"}, {"url": "http://server2.local/key"}]}} '
> hi.jwe
この例では、Tang ピンの 2 つの子インスタンスをそれぞれ独自の構成で定義します。しきい値が 1 であるため、Tang ピン インスタンスのいずれかが復号化に成功すると、SSS は成功します。
Clevis を使用すると、ピンを使用して LUKS ボリュームをバインドし、自動的にロックを解除できるようになります。
これがどのように機能するかは非常に簡単です。新しい、暗号的に強力なキーを生成します。このキーは追加のパスフレーズとして LUKS に追加されます。次に、Clevis を使用してこのキーを暗号化し、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:
このバインド プロセスが正常に完了すると、提供されているロック解除機能の 1 つを使用してディスクのロックを解除できます。
ネットワークベースのロック解除を使用したい場合は、カーネル引数として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
再起動すると、パスワードを使用してボリュームのロックを解除するように求められます。バックグラウンドで、Clevis はボリュームのロックを自動的に解除しようとします。成功すると、パスワード プロンプトがキャンセルされ、ブートが続行されます。
Clevis を initramfs-tools で使用する場合、initramfs を再構築するには以下を実行する必要があります。
sudo update-initramfs -u -k ' all '
再起動すると、Dracut を使用しているかのように動作します。
UDisks2 アンロックツールはデスクトップ セッションで実行されます。手動で有効にする必要はありません。 Clevis UDisks2 アンロックツールをインストールし、デスクトップ セッションを再起動するだけです。ロック解除ツールは自動的に開始されるはずです。
このロック解除ツールは、Dracut ロック解除ツールとほぼ同じように機能します。 Clevis にバインドされているリムーバブル ストレージ デバイスを挿入すると、デスクトップのパスワード プロンプトと並行して自動的にロックが解除されます。自動ロック解除が成功すると、ユーザーの介入なしにパスワード プロンプトが閉じられます。
Clevis ポリシーにバインドされた LUKS デバイスは、clevis luksunlock コマンドを使用してロックを解除することもできます。
$ sudo clevis luks unlock -d /dev/sda1
LUKS ボリュームは、clevis luks unbind コマンドを使用してバインドを解除できます。例えば:
$ sudo clevis luks unbind -d /dev/sda1 -s 1
特定の LUKS ボリュームにバインドされているピンは、clevis luks list コマンドを使用してリストできます。例えば:
$ sudo clevis luks list -d /dev/sda1
Clevis を直接取り付けないでください。代わりに、好みのディストリビューションのパッケージを使用してください。
このコマンドは、コアの Clevis コマンド、Dracut アンロック機能と UDisks2 アンロック機能をそれぞれインストールします。
$ sudo dnf install clevis clevis-dracut clevis-udisks2
前のセクションで述べたように、 Clevis を直接インストールしないことをお勧めします。ただし、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