オフィシャル: http://pefs.io
ports: https://www.freshports.org/sysutils/pefs-kmod/
コンパクトなチュートリアルあり: https://wiki.freebsd.org/PEFS
スライド: http://pefs.io/static/pefs-devsummit-2011-oct.pdf

2011とあるのでどうだろうと思ったのですが FreeBSD 12.0-RELEASE で普通に使えました。
普通のチュートリアルは上を参照ください。下はもう一つのチュートリアルです。
下で private ディレクトリまで準備できます。

# pkg install pefs-kmod
# kldload pefs
# mkdir private.enc private
# pefs mount private.enc private

まだ鍵を準備していませんが、private 以下に書いていくと、private.enc 以下に暗号化された実体が記録されていきます。

Key chains というのを作っていくのですが スライド ページ10DAG があります。
模して次を作っていくことにします。

+-----------------------+
| T  (9e39b8c21dea1d93) |
+-----------------------+
            |
            v
+-----------------------+  +-----------------------+  
| S1 (87ee2f60bd8eaf5a) |  | S2 (84551ece0649113e) |
+-----------------------+  +-----------------------+
            |                          |
            v                          v
+--------------------------------------------------+
| C  (5c1894bd1c4f6366)                            |
+--------------------------------------------------+

箱の中は パスフレーズ(パスフレーズ文字列のハッシュ値) とします。
Tの子はS1で、S1の子はCです。

まだ鍵を準備していませんので、書けません。

# echo str > private/file_C
zsh: read-only file system: private/file_C

pefs addchain で鍵を登録するのですが、このコマンドは親と子のペアを登録するのが標準です。
最初の鍵(子のいない鍵)を登録するため -Z オプションをします。
さらにマウント元のディレクトリ private.enc を対象とするために -f を指定します。

# pefs addchain -f -Z private.enc
Enter parent key passphrase: C
Reenter parent key passphrase: C
# find -s ./ -type f
./private/.pefs.db
./private.enc/.pefs.db
# pefs showchains private
Enter passphrase: C
Key chain:
        1    5c1894bd1c4f6366 aes128-xts
# echo str > private/file        _C
zsh: read-only file system: private/file_C

パスフレーズのからのハッシュ値が名前となります。
この時点ではマウント直後と同様に書けません。
使用する鍵を指定します。

# pefs addkey -c private
Enter passphrase: C
# echo str > private/file_C
# find -s ./ -type f
./private/.pefs.db
./private/file_C
./private.enc/.+2+jSBPun89VBA4xC5mgqMcwe8pGHPmt
./private.enc/.pefs.db

書けました。
ファイル名と実体が暗号化されています。(暗号化には tweak を用いるとあり、同じパスフレーズであっても同じになると限りません)
使用する鍵を除いてみましょう。

# pefs flushkeys private
# find -s ./ -type f
./private/.+2+jSBPun89VBA4xC5mgqMcwe8pGHPmt
./private/.pefs.db
./private.enc/.+2+jSBPun89VBA4xC5mgqMcwe8pGHPmt
./private.enc/.pefs.db

file_C が確認できなくなりました。
ここまでで通常の使用が開始できると思います。

次は上の Key chains を構成してみましょう。

# pefs addkey -c private
Enter passphrase: C
# pefs addchain private
Enter parent key passphrase: S1
Reenter parent key passphrase: S1
Enter chained key passphrase: C
Reenter chained key passphrase: C
# pefs addchain private
Enter parent key passphrase: S2
Reenter parent key passphrase: S2
Enter chained key passphrase: C
Reenter chained key passphrase: C
# pefs addchain private
Enter parent key passphrase: T
Reenter parent key passphrase: T
Enter chained key passphrase: S1
Reenter chained key passphrase: S1

pefs showchains では入力したパスフレーズの鍵とその子が表示されます。

# pefs showchains private
Enter passphrase: T
Key chain:
        1    9e39b8c21dea1d93 aes128-xts
        2    87ee2f60bd8eaf5a aes128-xts
        3    5c1894bd1c4f6366 aes128-xts
# pefs showchains private
Enter passphrase: S1
Key chain:
        1    87ee2f60bd8eaf5a aes128-xts
        2    5c1894bd1c4f6366 aes128-xts

# pefs showchains private
Enter passphrase: S2
Key chain:
        1    84551ece0649113e aes128-xts
        2    5c1894bd1c4f6366 aes128-xts

複数の鍵が使用できると、どのように振る舞うのでしょうか。
まずは暗号化に用いられた鍵を確認します。

# pefs getkey private/file_C
Key(private/file_C): 5c1894bd1c4f6366 aes128-xts

次は S1 を使ってみましょう。

# pefs showkeys private
Keys:
        0    5c1894bd1c4f6366 aes128-xts
# pefs flushkeys private
# pefs showkeys private
No keys specified
# pefs addkey private
Enter passphrase: S1
# pefs showkeys private
Keys:
        0    87ee2f60bd8eaf5a aes128-xts
        1    5c1894bd1c4f6366 aes128-xts

指定したパスフレーズの鍵とその子が全て使えるようになります。
暗号化してみます。

# pefs getkey private/file_S1
Key(private/file_S1): 87ee2f60bd8eaf5a aes128-xts

file_C と file_S1 では用いられた鍵が異なるようです。
では使える鍵が無いときはどうなるのでしょうか。

# pefs flushkeys private
# pefs showkeys private
No keys specified
# find -s ./ -type f
./private/.+2+jSBPun89VBA4xC5mgqMcwe8pGHPmt
./private/.pefs.db
./private/.uwLFhItsCXV2+kA004wv15VtCBXlY2wp
./private.enc/.+2+jSBPun89VBA4xC5mgqMcwe8pGHPmt
./private.enc/.pefs.db
./private.enc/.uwLFhItsCXV2+kA004wv15VtCBXlY2wp
# pefs addkey private
Enter passphrase: C
# find -s ./ -type f
./private/.pefs.db
./private/.uwLFhItsCXV2+kA004wv15VtCBXlY2wp
./private/file_C
./private.enc/.+2+jSBPun89VBA4xC5mgqMcwe8pGHPmt
./private.enc/.pefs.db
./private.enc/.uwLFhItsCXV2+kA004wv15VtCBXlY2wp
# pefs addkey private
Enter passphrase: S1
pefs: cannot add key: File exists <- このメッセージは子の C を登録しようとしたものに対してだと思われます。S1は登録されています。
# pefs showkeys private
Keys:
        0    5c1894bd1c4f6366 aes128-xts
        1    87ee2f60bd8eaf5a aes128-xts
# find -s ./ -type f
./private/.pefs.db
./private/file_C
./private/file_S1
./private.enc/.+2+jSBPun89VBA4xC5mgqMcwe8pGHPmt
./private.enc/.pefs.db
./private.enc/.uwLFhItsCXV2+kA004wv15VtCBXlY2wp

使える鍵に応じて部分的に復号化されているのが確認できます。

他、補足です。

* pefs setkey <directory> とすることで、そのディレクトリ以下で用いる鍵を指定できます。
* リネームでは用いる鍵は引き継がます。
* 存在するファイル名に対して新たな内容を書いても、用いる鍵は引き継がれます。
* 存在しないファイル名に対して書いた場合は、getkey の 0 が用いられます。
* pam_pefs(8) があります。
* ファイルレイアウトの階層や更新日時やパーミッションまで暗号化するのは意図していません。(geliなどとは異なります)
* この文章で 鍵を登録 とか書いてますが、鍵の実体が .pefs.db に書かれる訳ではありません。既知のパスフレーズかの確認や親子関係の保持に用いられるようです。
* 所謂パスワード変更を行うには、新たな親キーの登録と、そのキーを使った暗号化を意図した新たなinodeに書き写していくような処理が必要になるでしょう。
* Key chains として、最も下の子が複数存在することも可能です。(ここでは C 一つですが) 構造を表示するコマンドは無いようです。

コメントする

perl adv
perl adv