データベースなどのアプリケーションは、サードパーティ製の製品として提供される専用のサーバの形態で提供されることがあります。そのような環境を使用する場合、メーカー側のスタッフと連携してデータセンターのメンテナンスタスクを実行する必要があります。また、プライバシーの要件を満たすためにディスクの暗号化を行う必要があるかもしれません。
cryptctl
は LUKS を利用して機密情報を含むディレクトリを暗号化するほか、下記のような追加機能も提供します:
暗号鍵を中央のサーバに配置することができます。通常は中央のサーバは顧客側の施設に設置します。
不用意な再起動が発生したような場合でも、暗号化されたパーティションを自動的に再マウントすることができます。
cryptctl
は下記の 2 つのコンポーネントから構成されています:
1 つもしくは複数の暗号化されたパーティションをマウントするクライアントマシン。この場合、パーティションの暗号を解読するのに必要な鍵を恒久的な場所 (別のディスクなど) に保存しません。クライアントは、クラウドなどのホスティング環境が該当します。
クライアント側からの要求に応じて、パーティションを解読するための暗号鍵を提供するサーバ。
cryptctl
サーバを設定することで、 KMIP (Key Management Interoperability Protocol; 鍵管理相互運用プロトコル) 1.3 互換のサーバを構築することもできます。この場合、 cryptctl
サーバにはクライアント向けの暗号鍵は保存されず、その代わり KMIP 互換のサーバ内に保存することになります。
cryptctl
サーバのメンテナンスについてcryptctl
サーバは暗号化されたディスクに対するタイムアウトを管理するほか、必要であれば暗号鍵そのものを保持することもできます。暗号鍵そのものを保持させる場合は、不正にアクセスされることがなく、信頼できるユーザからのみアクセスできるように設定する必要があります。
これに加えて、サーバのバックアップは定期的に採取する必要があります。サーバのデータが失われてしまうと、クライアントがマウントする暗号化パーティションにもアクセスができなくなってしまうためです。
暗号化を処理するため、 cryptctl
は aes-xts-256 と 512 ビット鍵による LUKS を使用しています。暗号鍵は証明書の検証機能のある TLS を利用して転送されます。
cryptctl
による鍵の取得 (KMIP サーバへの接続を行わない場合の例) #cryptctl
のインストール下記の手順を実行する前に、まずはサーバやクライアントとして動作させる全てのマシン内に cryptctl パッケージがインストールされていることをご確認ください。
cryptctl
サーバの設定 #Edit sourcecryptctl
のクライアントを構築するよりも前に、 cryptctl
サーバを設定する必要があります。
まずはサーバとクライアントとの間で機密を保持するために使用する証明書を作成します。自己署名型の証明書であれば、一般的な手順で証明書を作成してください。公的な証明書を使用する場合は、サーバ向けの証明書を作成して証明機関に提出し、署名を受けてください。
クライアント側の証明書も同様に、公的な証明機関で署名してもらうことができます。このような追加のセキュリティ機能を使用する場合は、あらかじめ証明機関の証明書を手元に用意してください。
root
で下記を実行します:
#
cryptctl init-server
それぞれ表示された質問に対して回答を入力し、 Enter を押していきます。このとき、既定値は質問の末尾に角括弧で括られて表示されます。
まずは強力なパスワードを生成し、そのパスワードが漏洩することの無いよう十分な保護を設定してください。このパスワードはサーバ内に登録されている全てのパーティションの解読を行うためのパスワードになります。
次に PEM エンコードされた TLS 証明書、もしくは TLS 証明書のチェインのパスを指定します。自己署名型の証明書を使用する場合は、何も指定しないでください。また、パスを指定する場合は、絶対パスで指定してください。
既定で表示されるホスト名以外の名前を使用したい場合は、ここでホスト名を指定してください。 cryptctl
では、指定したホスト名を含む証明書を生成します。
クライアント側からの解読要求を受け付けるネットワークインターフェイスの IP アドレスを指定し、続けてポート番号を指定します (既定のポートは 3737 です) 。
IP アドレスの既定値である 0.0.0.0
を使用すると、 cryptctl
は IPv4 を利用する全てのネットワークインターフェイスを介して、クライアントからの要求を受け付けるようになります。
クライアントに対する暗号鍵を保存するための、サーバ内のディレクトリを指定します。
次にクライアントとの通信を行う際、クライアントに対して認証を要求するかどうかを指定します。ここで
(いいえ) を選択すると、クライアント側からはディスクの UUID のみを認証として使用します (なお、いずれを選択した場合でも、サーバの証明書を利用して通信が暗号化されます) 。(はい) を選択した場合は、クライアントの証明書に署名する証明機関を PEM 形式で指定してください。
次に KMIP 1.3 互換のサーバ (1 つまたは複数) を使用するかどうかを選択します。 KMIP 1.3 互換のサーバを使用すると、クライアントの暗号鍵をそこに保存することができるようになります。こちらを選択した場合は、 1 つまたは複数の KMIP 互換サーバのホスト名およびポートを指定してください。
このほか、 KMIP サーバに対して使用するユーザ名やパスワード、証明機関の証明書などを設定します。また、 cryptctl
のサーバで使用するクライアントの識別証明書を設定することもできます。
KMIP サーバを使用する場合、後からの再設定は簡単ではありません。この設定を変更するには、 cryptctl
サーバだけでなく、クライアントについても設定を修正する必要があるためです。
最後に電子メールによる暗号化/解読要求の通知を行うため、 SMTP サーバを設定します。電子メールによる通知機能は、設定しなくてもかまいません。
cryptctl
では、パスワードによる認証が必要な SMTP サーバを指定して、電子メールを送信することはできません。認証が必要な場合は、ローカルの SMTP プロキシを設定してください。
cryptctl
サーバの起動を行うかどうかを尋ねられた場合は、 y
(はい) と入力してください。
設定が終わったら、 cryptctl-server
サービスの状態を確認します:
#
systemctl status cryptctl-server
サーバを後から再設定する場合は、下記のいずれかを行ってください:
cryptctl init-server
を再度実行します。 cryptctl
は既存の設定値を既定値として表示しますので、必要な箇所のみを変更することになります。
設定ファイルである /etc/sysconfig/cryptctl-server
ファイルを直接編集してもかまいません。
ただし直接編集する場合は、 AUTH_PASSWORD_HASH
と AUTH_PASSWORD_SALT
の値を変更してはなりません。これらのオプションは、適切な手段で計算する必要があるためです。
cryptctl
クライアントの設定 #Edit source下記に示す cryptctl
の対話型の設定が、唯一の設定手段となります。
まずは下記の要件を全て満たしていることを確認します:
ネットワーク内に cryptctl
サーバが既に存在していること。
暗号化の対象となるディレクトリが存在すること。
暗号化対象のディレクトリを保持するのに十分なサイズのある、未使用のパーティションがクライアントマシン内に存在すること。
自己署名型の証明書を使用する場合、サーバ側で生成された証明書 ( *.crt
ファイル) をクライアント側にも配置する必要があります。クライアント側で信頼している証明機関で署名された証明書であれば、この必要はありません。
サーバ側でクライアントを認証する際、証明書を利用して行うように設定した場合は、サーバ側で選択した証明機関の署名が付いた TLS 証明書を用意してください。
root
で下記を実行します:
#
cryptctl encrypt
それぞれ表示された質問に対して回答を入力し、 Enter を押していきます。このとき、既定値は質問の末尾に角括弧で括られて表示されます。
接続先となる cryptctl
サーバのホスト名とポートを指定します。
サーバ側で TLS 証明書を利用してクライアントの認証を行うように設定している場合は、対応する証明書とその鍵を指定します。証明書はサーバ側で選択した証明機関による署名が必要となります。
次にサーバの証明書 (*.crt
ファイル) の絶対パスを指定します。
サーバを設定する際に指定した暗号化パスワードを入力します。
暗号化の対象となるディレクトリを指定し、その後にそのディレクトリを暗号化したあとのデータを保存するための空きパーティションのパスを指定します。
パーティションを同時に解読することのできるマシンの台数を指定します。
続いてクライアントからの通信が途絶えた際、追加でパーティションの解読を許可するようにするまでの時間を、秒単位で指定します。
マシンが何らかの理由で停止して再起動した場合には、パーティションを再度解読できるようにする必要があります。そのため一般には、クライアント側の再起動にかかる時間よりも少し短めの値を、タイムアウトとして設定する必要があります。
タイムアウトとして設定する時間が長すぎると、初回の試行では暗号化されたパーティションの解読が失敗するようになります。 cryptctl
では定期的に暗号鍵の取得を試すようになっていますが、次の試行までには時間が空きますので、遅延を発生させることになってしまいます。
逆にタイムアウトが短すぎると、暗号化されたパーティションをそのままコピーするだけで、不正なマシンが暗号を解読できることになってしまいます。
暗号化を開始するには、 yes
(はい) と入力します。
すると、 cryptctl
は指定したディレクトリの暗号化を行い、結果を空きパーティション内に保存するようになります。保存が完了すると、暗号化されたパーティションのマウントが行われます。ファイルシステムの種類は、暗号化前のファイルシステムと同じ種類になります。
暗号化されたパーティションを作成する前に、 cryptctl
は暗号化前のディレクトリ内にある内容を、 cryptctl-moved-
という接頭辞の付いたディレクトリ内に移動します。
ディレクトリが正しく暗号化されたことを確認するには、下記のように入力して実行します:
>
lsblk -o NAME,MOUNTPOINT,UUID
NAME MOUNTPOINT UUID [...] sdc └─sdc1 パーティションの_UUID └─cryptctl-unlocked-sdc1 /secret-partition 解読後の_UUID
cryptctl
では、暗号化されたパーティションを UUID で識別します。上記の例では、 sdc1
の UUID がそれにあたります。
サーバ側でディレクトリが解読されているかどうかを確認するには、 cryptctl
コマンドを使用します:
#
cryptctl list-keys
正しく解読されていれば、下記のような出力が現れるはずです:
2019/06/06 15:50:00 ReloadDB: successfully loaded database of 1 records Total: 1 records (date and time are in zone EDT) Used By When UUID Max.Users Num.Users Mount Point IP_ADDRESS 2019-06-06 15:00:50 UUID 1 1 /secret-partition
解読できていないパーティションの場合は、下記のような出力になります:
2019/06/06 15:50:00 ReloadDB: successfully loaded database of 1 records Total: 1 records (date and time are in zone EDT) Used By When UUID Max.Users Num.Users Mount Point 2019-06-06 15:00:50 UUID 1 1 /secret-partition
Used by
列の違いに着目してください。
表示された UUID が暗号化されたパーティションのものであることを確認してください。
パーティションの暗号化が正しく動作していることを確認したら、あとはクライアント側にある元のディレクトリ (暗号化されていないディレクトリ) を削除してください。たとえば rm
などを使用して削除します。より安全に削除したい場合は、削除を行う前にファイルに対して shred -u
などを使用して、ファイルの内容を上書きしてもかまいません。
shred
コマンドはデータが完全に消すことを保証するわけではない問題についてストレージメディアの種類によっては、 shred
コマンドを使用してもデータが完全には消えない場合があります。特に SSD などではウエアレベリングの仕組みが存在することから、 shred
を実行しても同じ場所には書き込んでくれないことがあります。
クライアントからサーバに対する接続は、 /etc/sysconfig/cryptctl-client
ファイルで設定します。このファイルは手作業で編集してもかまいません。
クライアントのパーティションに対する暗号鍵は、サーバ内の /var/lib/cryptctl/keydb/パーティションの_UUID
内に保存されています。
LUKS で暗号化した新しいファイルシステムに対してマウントポイントを設定する場合、 YaST では既定で /etc/fstab
内に暗号化デバイスの名称を設定します (たとえば /dev/mapper/cr_sda1
のようなデバイス名を使用します) 。 UUID やボリュームラベルではなくデバイス名を使用するのは、 systemd やその他の関連ツールでの取り扱いにあたって都合がよいためです。
このような既定の動作を変更することもできます。具体的には熟練者向けパーティション設定か AutoYaST を使用します。
なお、設定を変更した場合でも、既に設定されている /etc/fstab
には影響がありません。新しくシステムにインストールする場合や、動作中のシステムに新しいパーティションを作成する場合など、新しくマウントするファイルシステムにのみ影響があります。
cryptctl
のクライアントが動作している場合、クライアント側からは 10 秒間隔で cryptctl
のサーバに 「生存通知」 (ハートビート) を送信します。クライアント側で設定した時間以上にクライアント側からの生存通知がサーバに届かない場合、サーバはクライアントがオフラインになったものと判断します。これにより、別のクライアント (もしくは再起動後の同じクライアント) から接続ができるようになります。
全ての鍵に対する使用状況を確認するには、下記のコマンドを入力して実行します:
#
cryptctl list-keys
Num. Users
以下に、どの鍵が使用されているのかが表示されます。それぞれの鍵に対する詳細を表示したい場合は、下記のようなコマンドを入力して実行します:
#
cryptctl show-key UUID
このコマンドを実行すると、マウントポイントやマウントオプション、使用時のオプションや鍵の最終取得時刻、そしてクライアントからの直近 3 回分の生存通知が表示されます。
これに加えて、 journalctl
コマンドを使用することで、鍵をいつ取得したのかのログを確認することができます。
パーティションを手作業で解読するにあたっては、 2 種類の方法が存在しています。いずれもクライアント側で実行します:
オンライン解錠: オンライン解錠を利用すると、タイムアウトの問題を回避したりユーザ制限を行ったりすることができます。この方式は、クライアントとサーバとの間がネットワークで繋がっているものの、クライアント側で自動マウントができないような場合に使用することができます。また、この方式を使用することで、全ての暗号化されたパーティションを解読することができます。
オンライン解錠を実行するには、 cryptctl online-unlock
コマンドを実行します。サーバ側で設定したパスワードを入力する必要があることに注意してください。
オフライン解錠: この方式は、クライアント側からサーバに接続できない状態や、接続すると何らかの理由で困ってしまうような場合に使用します。この方式を実行するには、サーバ側に暗号鍵を用意しておく必要があることに注意してください。また、この方式は最終手段としてのみ使用されるべきものであるほか、同時に 1 つのパーティションしか解錠できないことにも注意してください。
オフライン解錠を実行するには、 cryptctl offline-unlock
コマンドを実行します。これを実行するには、あらかじめ対象のパーティションに対応するサーバ側の鍵ファイル ( /var/lib/cryptctl/keydb/パーティションの_UUID
) を用意しておく必要があります。
メンテナンス中にパーティションが不正に解読されてしまわないようにするため、メンテナンス時にはクライアント側を停止し、 cryptctl
サーバを無効化しておくことをお勧めします。具体的には、下記のいずれかを実行します:
cryptctl-server
サービスを停止します:
#
systemctl stop cryptctl-server
cryptctl
サーバをネットワークから切り離します。
メンテナンスの際には cryptctl-server を停止しておかないと必要なデータが正しく保存されなくなってしまう一方、これによって暗号鍵を利用しているシステムが動作できなくなり、システムの停止が発生してしまいます。このような問題を避けるため、 cryptctl-server で HA (高可用性) 環境を構築しておくことを強くお勧めします。この場合、少なくとも 2 台のノードから構成される高可用性クラスタを構築することになります。下記では、自己署名型の証明書を使用して、 cryptctl-server 向けの HA クラスタを構築するための手順を説明しています。
まずは下記の要件を全て満たしていることを確認します:
少なくとも 2 台以上のサーバを用意します。これらは SUSE Linux Enterprise Server と High Availability 拡張の両方のほか、 cryptctl パッケージをインストールしておきます。また、全てのサーバは SSH を介して相互にアクセスできる必要があります。
新しいクラスタを構築する場合は、クラスタの HA Web Console 向けの追加 IP アドレス ( AdminIP ) を用意します。
また、 cryptctl-server 向けに別途の IP アドレス ( CrypServerIP ) を用意します。
さらに cryptctl-server 向けの DNS ホスト名 ( CrypServerHostName ) を用意します。このホスト名は、上述の IP アドレスを指し示すものとします。
鍵を保存するための HA が有効化されたブロックデバイスか、 NFS 共有を用意します。
下記の例では、 nfs-server.example.org/data/cryptctl-keys
という名前の NFS 共有を使用します。この共有は /var/lib/cryptctl/keydb
という標準的なディレクトリにマウントします。
このほか、 SBD デバイスを使用しておくことを強くお勧めします。
Node1 (ノード#1) に root
でログインします。
13.1項 「cryptctl
サーバの設定」 に書かれた手順で cryptctl-server を構築します。このとき、下記に注意してください:
証明書を作成する場合は、 cryptctl サーバでの CrypServerHostName に対応する証明書を用意してください。ホスト名に対応する証明書 ではありません 。
cryptctl サーバに用意した個別の IP アドレス CrypServerIP を使用してください。既定の IP アドレス設定をそのまま使用しては なりません 。
KMIP サーバを構築してはなりません。
cryptctl
サーバの起動を行うかどうかを尋ねられた場合は、 n
(いいえ) と入力してください。
2 ノードの HA クラスタを構築します:
ここでは、 cryptctl サーバを構築したマシンが Node1 というホスト名であるものとします。
cryptctl サーバを設定したマシンで、最初のノードを起動します:
#
crm cluster init -i ネットワークデバイス名 -A AdminIP -n クラスタ名
あとは Node2 (ノード#2) にログインして、クラスタへの参加を実施します:
#
ssh Node2
#
crm cluster join -y Node1
さらに詳しい情報については、 Installation and Setup Quick Start をご覧ください。
cryptctl サーバに対するリソースグループを設定します:
cryptcl の crm-shell-script を利用することで、全てのノードで必要な全てのリソースエージェントを設定し、必要なファイルをコピーすることができます。まずは適切に構築できているかどうかを確認しておくことを強くお勧めします:
#
crm script verify cryptctl \ cert-path=/etc/cryptctl/servertls/CertificateFileName \ cert-key-path=/etc/cryptctl/servertls/CertificateKeyFileName \ virtual-ip:ip=CrypServerIP \ filesystem:device=DevicePath filesystem:fstype=FileSystemType
チェックが成功したら、下記のようにスクリプトを実行してクラスタグループの構築を行います:
#
crm script verify cryptctl \ cert-path=/etc/cryptctl/servertls/CertificateFileName \ cert-key-path=/etc/cryptctl/servertls/CertificateKeyFileName \ virtual-ip:ip=CrypServerIP \ filesystem:device=DevicePath filesystem:fstype=FileSystemType
名前 |
必須かどうか |
既定値 |
説明 |
---|---|---|---|
id | いいえ | cryptctl | リソースグループ名 |
cert-path | はい | 作成した証明書のフルパス | |
cert-key-path | はい | 作成した証明書に対応する機密鍵のフルパス | |
virtual-ip:id | いいえ | cryptctl-vip | cryptctl サーバの仮想 IP リソース ID |
virtual-ip:ip | はい | cryptctl サーバの仮想 IP アドレス | |
virtual-ip:nic | いいえ | (virtual-ip リソースエージェントによって検出されます) | cryptctl が接続を待ち受けるべきネットワークデバイス名 (IP アドレスからデバイス名が検出できない場合にのみ必要) |
virtual-ip:cidr_netmask | いいえ | (virtual-ip リソースエージェントによって検出されます) | cryptctl の IP アドレスに対応するネットマスク (IP アドレスからネットマスクが検出できない場合にのみ必要) |
virtual-ip:broadcast | いいえ | (virtual-ip リソースエージェントによって検出されます) | cryptctl サーバの IP アドレスに対応するブロードキャストアドレス (IP アドレスから検出できない場合にのみ必要) |
filesystem:id | いいえ | cryptctl-filesystem | ディスクの暗号鍵とレコードを含むファイルシステムリソースの ID |
filesystem:device | はい | ファイルシステムを含むデバイス名。 /dev/sda... のようにブロックデバイス名のほか、 server:/path のように NFS 共有を指定することができます。 | |
filesystem:directory | いいえ | /var/lib/cryptctl/keydb | ファイルシステムのマウント先ディレクトリ名。 /dev/sda... のようにブロックデバイス名のほか、 server:/path のように NFS 共有を指定することができます。 |
filesystem:fstype | はい | ファイルシステムの種類 (NFS, XFS, EXT4 等) | |
filesystem:options | いいえ | (選択したファイルシステムに対応する既定値と同じ) | ファイルシステムのマウントオプション。 |
さらに詳しい情報については、プロジェクトのホームページ https://github.com/SUSE/cryptctl/ をご覧ください。