[和訳] Chef Vaultで秘密情報を管理する #getchef
この記事は1年以上前に投稿されました。情報が古い可能性がありますので、ご注意ください。
本稿は Managing Secrets with Chef Vault (2013/09/19) の和訳です。
本記事(訳注:原文)はjtimberman's Code Blogに掲載されたものです。
2年前、PostfixのSASL認証のためにChefの暗号化Data Bagを使う記事を書きました。当時、私のISPが認証なしのSMTPを許可していなかったので、自宅サーバからのcronメールやその他重要なメールを受け取るための解決策を見つけなければいけませんでした。そのあたりをあまり気にしないISPに変更してから、その記事で書いたコードはもう使っていません。
しかし、それは秘密情報を扱わないことを意味するものではありません! 実際、Chefで管理している個人システムでは扱っていませんが、OpscodeのホステッドEnterprise Chef環境ではもちろん扱っています。ウェブアプリケーションで必要なよく上がる秘密情報としては、データベースのパスワード、SSL証明書、サービスのAPIトークンなどがあるでしょう。
そこでchef-vaultがよい選択肢であるかどうか検証することにしました。本記事は、作業記録がどこかに行ってしまったときに思い出せるようにするための備忘録のようなものです。同時に、みなさん独自の環境でも使えるような情報になっていれば幸いです。
Chef Vault
Chef VaultはNordstorm社によって公開されているオープンソースプロジェクトです。RubyGemとして配布されています。機密情報を暗号化する際にはローカルのワークステーションにインストールする必要があり、その情報を復号するあらゆるシステム上にもインストールする必要があります。まず始めにワークステーションにgemをインストールしましょう。なお、これを使うRecipeはあとで紹介します。
% gem install chef-vault
使い方
では、使い方として2つのとても簡単な例を上げて、chef-vaultがどのように動作するのか見ていきましょう。
- ユーザ名とパスワードの組み合わせ。Chefの組み込みResourceであるuserでシステムにvaultuserを作成します。
- 機密情報を含むファイル。ここではvaultuserのためのジャンクRSA秘密鍵を使います。
秘密情報は一般的にこのようなものでしょう。useraddのようなコマンドラインプログラムに渡す値や、SSL証明書やRSA鍵のようにディスクに書き込むファイルです。
コマンドラインの構造
Chef Vaultはワークステーションから秘密情報を管理するためのKnifeプラグインを含んでおり、通常のData Bagのように秘密情報をChef Serverにアップロードできます。秘密情報自体はChef Server上ではData Bag内に格納されます。この「Bag」をchef-vaultでは「vault」(訳注:金庫室)と呼びます。
インストール後、Knifeにはencryptとdecryptサブコマンドが追加されます。
knife encrypt create [VAULT] [ITEM] [VALUES] --mode MODE --search SEARCH --admins ADMINS --json FILE
knife encrypt delete [VAULT] [ITEM] --mode MODE
knife encrypt remove [VAULT] [ITEM] [VALUES] --mode MODE --search SEARCH --admins ADMINS
knife rotate secret [VAULT] [ITEM] --mode MODE
knife encrypt update [VAULT] [ITEM] [VALUES] --mode MODE --search SEARCH --admins ADMINS --json FILE
knife decrypt [VAULT] [ITEM] [VALUES] --mode MODE
MODEはSoloかClientか
私はChefをChef Server (Enterprise Chef)で使っているので、Knifeコマンドに--mode clientを指定しています。
chef-vault KnifeプラグインコマンドでのMODEの指定は、暗号化Data Bagがどこに保存されるかに影響を与えます。ChefはData BagをSoloとClient/Serverの両方でサポートしています。もしchef-soloを使うなら、knife.rbのdata_bag_pathを設定しておく必要があります。Soloを使っているとしてもそれらはKnifeプラグインなので、chef-soloではなくKnifeの設定となります。でも私はChef Serverを使っているので、--mode clientを使っていきます。
パスワードつきのユーザの作成
これから作成するユーザはvaultuserという任意の名前で、極秘パスワードchef-vaultを持っています。私のLinuxシステムではSHA512ハッシュを使っているので、まずmkpasswdを使ってパスワードを生成します。
% mkpasswd -m sha-512
Password: chef-vault
$6$VqEIDjsp$7NtPMhA9cnxvSMTE9l7DMmydJJEymi9b4t1Vhk475vrWlfxMgVb3bDLhpk/RZt0J3X7l5H8WnqFgvq3dIa9Kt/
注意: このmkpasswd(1)コマンドはUbuntu 10.04のmkpasswdパッケージのものです。
Itemの作成
このパスワードは新しい秘密情報なので、これから使うコマンドはknife encrypt createです。ここでは2つの例をお見せしましょう。1つ目は、生のJSONデータを「値」として渡します。もし暗号化していない秘密情報をディスクやレポジトリに格納するつもりがないなら、こうするとよいでしょう。2つ目は、JSONファイルを渡します。暗号化していない秘密情報をディスクやレポジトリに格納するなら、こうしてください。
% knife encrypt create secrets vaultuser \
'{"vaultuser":"$6$VqEIDjsp$7NtPMhA9cnxvSMTE9l7DMmydJJEymi9b4t1Vhk475vrWlfxMgVb3bDLhpk/RZt0J3X7l5H8WnqFgvq3dIa9Kt/"}' \
--search 'role:base' \
--admins jtimberman --mode client
このコマンドでの[VALUES]は、chef-vault Data Bag Itemに作られる生のJSONです。--searchオプションはchef-vaultに、暗号化した値に対するSOLRでの問い合わせにマッチするNodeのパブリックなキーを使うように指示します。Chef実行中、chef-vaultはそれらのNodeのプライベートなキーを、値を復号するために使います。--adminsオプションはchef-vaultに、秘密情報を復号できるChef Serverのユーザの一覧を指示します。複数のadminを指定するには、コンマ区切りの文字列を指定します。最後に、これまで述べた通り私はChef Serverを使っているため、デフォルトは「solo」なので--mode clientを指定しています。
これと同等な、secrets_vaultuser.jsonという名前のJSONファイルを使います。内容は次のようになります。
{"vaultuser":"$6$VqEIDjsp$7NtPMhA9cnxvSMTE9l7DMmydJJEymi9b4t1Vhk475vrWlfxMgVb3bDLhpk/RZt0J3X7l5H8WnqFgvq3dIa9Kt/"}
コマンドは次のようになります。
% knife encrypt create secrets vaultuser \
--json secrets_vaultuser.json
--search 'role:base' \
--admins jtimberman --mode client
それでは、Chef Serverに作成されたものを見てみましょう。Knifeのコアプラグインであるdata bag item showを使います。
% knife data bag show secrets
vaultuser
vaultuser_keys
2つのItemを持った「secrets」というData Bagが作られています。まず、vaultuserが実際の秘密情報を含んだItemです。見てみましょう。
% knife data bag show secrets vaultuser
id: vaultuser
vaultuser:
cipher: aes-256-cbc
encrypted_data: j+/fFM7ist6I7K360GNfzSgu6ix63HGyXN2ZAd99R6H4TAJ4pQKuFNpJXYnC
SXA5n68xn9frxHAJNcLuDXCkEv+F/MnW9vMlTaiuwW/jO++vS5mIxWU170mR
EgeB7gvPH7lfUdJFURNGQzdiTSSFua9E06kAu9dcrT83PpoQQzk=
iv: cu2Ugw+RpTDVRu1QaaAfug==
version: 1
見ての通り、暗号化データです。ではchef-vaultに復号させてみましょう。Knifeプラグインで次のようにします。
% knife decrypt secrets vaultuser 'vaultuser' --mode client
secrets/vaultuser
vaultuser: $6$VqEIDjsp$7NtPMhA9cnxvSMTE9l7DMmydJJEymi9b4t1Vhk475vrWlfxMgVb3bDLhpk/RZt0J3X7l5H8WnqFgvq3dIa9Kt/
クォートされた'vaultuser'は先に指定したJSONデータのハッシュのキーです。見ての通り、パスワードは先にmkpasswdコマンドから生成したものです。
しかし、Nodeが復号したパスワードにどうやってアクセスするんでしょうか? それはchef-vaultがvaultuser_keys Itemに格納したものです。見てみましょう。
% knife data bag show secrets vaultuser_keys
admins: jtimberman
clients:
os-945926465950316
os-2790002246935003
id: vaultuser_keys
jtimberman: 0Q2bhw/kJl2aIVEwqY6wYhrrfdz9fdsf8tCiIrBih2ZORvV7EEIpzzKQggRX
4P4vnVQjMjfkRwIXndTzctCJONQYF50OSZi5ByXWqbich9iCWvVIbnhcLWSp
z5mQoSTNXyZz/JQZGnubkckh4wGLBFDrLJ6WKl6UNXH1dRwqDNo5sEK7/3Wn
b4ztVSRxzB01wVli0wLvFSZzGsKYJYINBcidnbIgLh/xGYGtBJVlgG2z/7TV
uN0b/qvGj8VlhbS6zPlwh39O3mexDdkLwry/+gbO1nj8qKNkKDKaix5zypwE
XdmdfMKNYGaM6kzG8cwuKZXLAgGAgblVUB1HP8+8kQ==
os-2790002246935003: kGQLsxsFmBe9uPuWxZpKiNBnqJq55hQZJLgaKdjG2Vvivv98RrFGz1y8Xbwe
uzeSgPgAURCZmxpNxpHrwvvKcvL77sBOL6TTKiNzs8n5B3ZOawy17dsuG24v
41R0cRMnYLgbLcjln9dpVe4Esr4goPxko+1XqBPik1SBapthQq/pLUJ1BIKh
Fxu1QVGj1w4HPUftLaUzeS33jKbtfvgZyZsYZBdVCVEVidOxC90WRf4wtkd6
Ueyj+0gd1QKv84Q387O1R5LtRMS6u+17PJinrcRIkVNZ6P1z6oT2Dasfvrex
rK3s5vD7v6jpkUW12Wj74Lz3Z6x3sKuIDzCtvEUnWw==
os-945926465950316: XzTJrJ3TZZZ1u9L9p6DZledf3bo2ToH2yrLGZQKPV6/ANzElHXGcYrEdtP0q
14Nz1NzsqEftzviAebUUnc6ke91ltD8s6hNQQrPJRqkUoDlM7lNEwiUiz/dD
+sFI6CSzQptO3zPrUbAlUI1Zog5h7k/CCtiYtmFRD6wbAWnxmCqvLhO1jwqL
VNJ1vfjlFsG77BDm2HFw7jgleuxRGYEgBfCCuBuW70FAdUTvNHIAwKQVkfU/
Am75UYm7N4N0E+W76ZwojLoYtXXTV/iOGG1cw3C75SVAmCsBOuxUK/otub67
zsNDsKToKa+laxzXGylrmkTricYXIqVpIQO8OL5nnw==
見ての通り、2つのNodeが復号されたData Bag ItemにアクセスするためのAPIクライアントとなっています。これらの値はすべてchef-vaultが生成しており、記事の後でこのリストと秘密情報の更新方法を説明します。
ユーザのパスワードの管理
Chef Vaultを使って、暗号化されたData Bagに設定した値によるパスワードつきのユーザのResourceを管理してみましょう。
まず、vaultという名前のCookbookを作成し、これを基本Roleに追加しました。Recipeは次のようになります。
chef_gem "chef-vault"
require "chef-vault"
vault = ChefVault::Item.load("secrets", "vaultuser")
user "vaultuser" do
password vault['vaultuser']
home "/home/vaultuser"
supports :manage_home => true
shell "/bin/bash"
comment "Chef Vault User"
end
1つ1つ見ていきましょう。
chef_gem "chef-vault"
require "chef-vault"
chef-vaultはRubyGemとして配布されているため、Recipeでそれを使いたいのでここでchef_gem Resourceを使います。そして、他のRubyライブラリのように要求しておきます。
vault = ChefVault::Item.load("secrets", "vaultuser")
ここで復号が行われます。chef-shellでは次のように見ることができます。
chef:recipe > vault = ChefVault::Item.load("secrets", "vaultuser")
=> data_bag_item["secrets", "vaultuser", {"id"=>"vaultuser", "vaultuser"=>"$6$VqEIDjsp$7NtPMhA9cnxvSMTE9l7DMmydJJEymi9b4t1Vhk475vrWlfxMgVb3bDLhpk/RZt0J3X7l5H8WnqFgvq3dIa9Kt/"}]
ChefVault::Item.loadは「vault」かData Bag、ここではsecretsと、「item」ここではvaultuserの2つの引数を取り、Data Bag Itemを返します。そしてuser Resourceでパスワードを使います。
user "vaultuser" do
password vault['vaultuser']
home "/home/vaultuser"
supports :manage_home => true
shell "/bin/bash"
comment "Chef Vault User"
end
ここでの重要なResource Attributeはpasswordです。ChefVault::Item.loadによって復号されるItemから得た、ローカル変数vaultをvaultuserキーで使います。Chef実行中は次のようになります。
Recipe: vault::default
* chef_gem[chef-vault] action install
- install version 2.0.1 of package chef-vault
* chef_gem[chef-vault] action install (up to date)
* user[vaultuser] action create
- create user user[vaultuser]
これで、作成したパスワードを使ってvaultuserになることができます。
ubuntu@-2790002246935003:~$ su - vaultuser
Password: chef-vault
vaultuser@os-2790002246935003:~$ id
uid=1001(vaultuser) gid=1001(vaultuser) groups=1001(vaultuser)
vaultuser@os-2790002246935003:~$ pwd
/home/vaultuser
やった! 正しいパスワードでユーザが作成されたか確認するための、DEBUGログ出力がこちらです。
INFO: Processing user[vaultuser] action create ((irb#1) line 12)
DEBUG: user[vaultuser] user does not exist
DEBUG: user[vaultuser] setting comment to Chef Vault User
DEBUG: user[vaultuser] setting password to $6$VqEIDjsp$7NtPMhA9cnxvSMTE9l7DMmydJJEymi9b4t1Vhk475vrWlfxMgVb3bDLhpk/RZt0J3X7l5H8WnqFgvq3dIa9Kt/
DEBUG: user[vaultuser] setting shell to /bin/bash
INFO: user[vaultuser] created
次に、システムに秘密情報を記載したファイルを作ってみましょう。
SSH秘密鍵の作成
このvaultuserは、レポジトリをクローンすることでコードをデプロイするために使われると仮定します。認証のためにSSH秘密鍵が必要なので、この場合は空のパスフレーズで作成しましょう。
% ssh-keygen -b 4096 -t rsa -f vaultuser-ssh
Generating public/private rsa key pair.
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in vaultuser-ssh.
Your public key has been saved in vaultuser-ssh.pub.
秘密鍵のSHA256チェックサムを得ておきます。SHA256を使うのは、Chefがファイル内容のチェックサムとして使っているからです。これを後で検証に使います。
% sha256sum vaultuser-ssh
a83221c243c9d39d20761e87db6c781ed0729b8ff4c3b330214ebca26e2ea89d vaultuser-ssh
このユーザはGitHub上にSSH鍵を作成したとも仮定しましょう。
Data Bag Itemのために、ファイルの内容をJSONの値に入れるには、改行(\n)を削除してJSONを生成します。
ruby -rjson -e 'puts JSON.generate({"vaultuser-ssh-private" => File.read("vaultuser-ssh")})' \
> secrets_vaultuser-ssh-private.json
では、Chef Server上に秘密情報を作成します。
knife encrypt create secrets vaultuser-ssh-private \
--search 'role:base' \
--json secrets_vaultuser-ssh-private.json \
--admins jtimberman \
--mode client
必要なものが作成できたかサーバを検証してみましょう。
% knife data bag show secrets vaultuser-ssh-private
id: vaultuser-ssh-private
vaultuser-ssh-private:
cipher: aes-256-cbc
encrypted_data: mRRToM2N/0F+OyJxkYlHo/cUtHSIuy69ROAKuGoHIhX9Fr5vFTCM4RyWQSTN
(以下省略)
% knife decrypt secrets vaultuser-ssh-private 'vaultuser-ssh-private' --mode client
secrets/vaultuser-ssh-private
vaultuser-ssh-private: -----BEGIN RSA PRIVATE KEY-----
(以下省略)
鍵ファイルの管理
では、vault Cookbookで秘密鍵ファイルを管理してみます。
vault_ssh = ChefVault::Item.load("secrets", "vaultuser-ssh-private")
directory "/home/vaultuser/.ssh" do
owner "vaultuser"
group "vaultuser"
mode 0700
end
file "/home/vaultuser/.ssh/id_rsa" do
content vault_ssh["vaultuser-ssh-private"]
owner "vaultuser"
group "vaultuser"
mode 0600
end
こちらも細かく見ていきましょう。まず、以前にやったように暗号化Data BagからItemを読み込みます。
vault_ssh = ChefVault::Item.load("secrets", "vaultuser-ssh-private")
次に、vaultuserが.sshディレクトリを正しいパーミッションで持つようにします。
directory "/home/vaultuser/.ssh" do
owner "vaultuser"
group "vaultuser"
mode 0700
end
最後に、秘密鍵ファイルの内容をfile Resourceとcontent Resource Attributeで管理します。vault_ssh["vaultuser-ssh-private"]の値は文字列で、\nが埋め込まれており、ディスクに書き込まれた際は正しく表示されます。
file "/home/vaultuser/.ssh/id_rsa" do
content vault_ssh["vaultuser-ssh-private"]
owner "vaultuser"
group "vaultuser"
mode 0600
end
ターゲットNodeでChefを実行してみます。
Recipe: vault::default
* chef_gem[chef-vault] action install (up to date)
* user[vaultuser] action create (up to date)
* directory[/home/vaultuser/.ssh] action create
- create new directory /home/vaultuser/.ssh
- change mode from '' to '0700'
- change owner from '' to 'vaultuser'
- change group from '' to 'vaultuser'
* file[/home/vaultuser/.ssh/id_rsa] action create
- create new file /home/vaultuser/.ssh/id_rsa with content checksum a83221
--- /tmp/chef-tempfile20130909-1918-1v5hezo 2013-09-09 22:41:21.887239999 +0000
+++ /tmp/chef-diff20130909-1918-xwbmsn 2013-09-09 22:41:21.883240065 +0000
@@ -0,0 +1,51 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIJJwIBAAKCAgEAtZmwFTlVOBbr2ZfG+cDtUGx04xCcgaa0p0ISmeyMEoGYH/CP
(以下省略)
内容のチェックサムがa83221であることに注目してください。これが前述のソースファイルのチェックサムと一致していて(スクロールして戻って!)、書き込まれています。
ubuntu@os-2790002246935003:~$ sudo sha256sum /home/vaultuser/.ssh/id_rsa
a83221c243c9d39d20761e87db6c781ed0729b8ff4c3b330214ebca26e2ea89d /home/vaultuser/.ssh/id_rsa
やった! これでGitHubにSSHできます(これはこの例のための偽のGitHubであることに注意してください)。
ubuntu@os-2790002246935003:~$ su - vaultuser
Password: chef-vault
vaultuser@os-2790002246935003:~$ ssh -i .ssh/id_rsa github@172.31.7.15
$ hostname
os-945926465950316
$ id
uid=1002(github) gid=1002(github) groups=1002(github)
秘密情報の更新
秘密情報を更新する必要があったときどうしますか? 例えば、管理者が組織を去ったら、vaultuserのパスワードとSSH秘密鍵を変更したいでしょう。
% mkpasswd -m sha-512
Password: gone-user
$6$zM5STNtXdmsrOSm$svJr0tauijqqxTjnMIGJGJPv5V3ovMFCQo.ZDBleiL.yOxcngRqh9yAjpMAsMBA7RlKPv5DKFd1aPZm/wUoKs.
対象が既に存在していたら、encrypt createコマンドはエラーを返します。
% knife encrypt create secrets vaultuser --search 'role:base' --json secrets_vaultuser.json --admins jtimberman --mode client
ERROR: ChefVault::Exceptions::ItemAlreadyExists: secrets/vaultuser already exists, use 'knife encrypt remove' and 'knife encrypt update' to make changes.
そこで、encrypt updateを使う必要があります。注意: JSONファイルの内容は正しいJSONでなければいけません。
% knife encrypt update secrets vaultuser --search 'role:base' --json secrets_vaultuser.json --admins jtimberman --mode client
encrypt updateは変更点だけを更新するので、次のように短くもできます。
% knife encrypt update secrets vaultuser --json secrets_vaultuser.json --mode client
検証してみます。
% knife decrypt secrets vaultuser 'vaultuser' --mode client
secrets/vaultuser
vaultuser: $6$zM5STNtXdmsrOSm$svJr0tauijqqxTjnMIGJGJPv5V3ovMFCQo.ZDBleiL.yOxcngRqh9yAjpMAsMBA7RlKPv5DKFd1aPZm/wUoKs.
では、関係するNodeでChefを実行しましょう。
Recipe: vault::default
* chef_gem[chef-vault] action install (up to date)
* user[vaultuser] action create
- alter user user[vaultuser]
* directory[/home/vaultuser/.ssh] action create (up to date)
* file[/home/vaultuser/.ssh/id_rsa] action create (up to date)
Chef Client finished, 1 resources updated
これで、gone-userパスワードでvaultuserになれます。
ubuntu@os-2790002246935003:~$ su - vaultuser
Password: gone-user
vaultuser@os-2790002246935003:~$
Itemへのアクセスを管理
vault内のItemへのアクセスの管理を要求する4つの共通のシナリオがあります。
- システムをオフラインにする必要があるか、またはItemへのアクセスを禁止する。
- 新しいシステムがオンラインになり、アクセスを必要とする。
- 管理ユーザが組織を去った。
- 新しい管理ユーザが組織に入った。
何らかの理由でシステムをオフラインにする必要があり、秘密情報へのアクセスを無効にしたいと仮定します。または、管理者だったユーザが組織を去ったとします。その場合、いくつかの方法があります。
Vault Itemの更新
Itemへのアクセスを管理するもっとも単純な方法は、updateやremoveサブコマンドです。
システムの削除
Node DEADNODEを削除したいと仮定した場合、DEADNODEという名前のNodeを除外したものを対象とします。
% knife encrypt update secrets vaultuser \
--search 'role:base NOT name:DEADNODE' \
--json secrets_vaultuser.json \
--admins jtimberman --mode client
この以前に管理者は変更していないので、引数を渡す必要はないことに注意してください。
システムの追加
Nodeで既にChefを走らせていてChef Serverにインデックス化されているなら、単純に検索とupdateコマンドを再実行するだけです。
% knife encrypt update secrets vaultuser \
--search 'role:base' \
--json secrets_vaultuser.json \
--admins jtimberman --mode client
これにはちょっとした「鶏と卵」の問題があります。あらかじめbootstrap中に秘密情報を読み込もうとする場合、新しいNodeは検索インデックスに入っていないということです。例えば、run_listに基本Roleを入れてOpenStackインスタンスを作ろうとしたら、まだNodeは検索に存在しません。解決策として、空のrun_listでNodeを作成してChef Serverに登録し、それからknife bootstrapで正式なrun_listでChefを再実行します。これはめんどくさいですが、chef-vaultは共有の秘密情報の管理についてすべての問題を解決することは求められていません 🙂
管理者の削除
管理者の引数はリストを取ります。先には、私のユーザIDのみを管理者としていました。ここでは「bofh」も管理者としてItemを作成したと仮定します。
% knife encrypt create secrets vaultuser \
--search 'role:base' \
--json secrets_vaultuser.json \
--admins "jtimberman,bofh" --mode client
bofhユーザを削除するには、encrypt removeサブコマンドを使います。この場合、--adminsの引数は追加ではなく削除する管理者のリストになります。
% knife encrypt remove secrets vaultuser --admins bofh --mode client
新しい管理者の追加
「mandi」はとてもすばらしく秘密情報の管理を手伝ってくれるので、管理者に加えようと思います。前述の通り、コンマ区切りの文字列"jtimberman,mandi"を--adminsの引数に渡すだけです。
% knife encrypt update secrets vaultuser \
--search 'role:base' \
--json secrets_vaultuser.json \
--admins "jtimberman,mandi" --mode client
クライアントの再生成
アクセスを禁止するあんまりよろしくない方法は、Chef ServerのAPIクライアントを再生成することです。例えば、私のNodeであるos-945926465950316を削除してみましょう。
% knife client reregister os-945926465950316
-----BEGIN RSA PRIVATE KEY-----
MIIEpAIBAAKCAQEAybzwv53tDLIzW+GHRJwLthZmiGTfZVyqQX6m6RGuZjemEIdy
(以下省略)
もしあなたがChef Serverの認証機構をよく知っているなら、秘密鍵がNodeにコピーされるまで認証が完全に失敗することをご存知でしょう。しかし、一旦/etc/chef/client.pemファイルの内容がKnifeコマンドで更新されたら、NodeはChef VaultのItemの読み込みに失敗するようになります。
================================================================================
Recipe Compile Error in /var/chef/cache/cookbooks/vault/recipes/default.rb
================================================================================
OpenSSL::PKey::RSAError
-----------------------
padding check failed
Cookbook Trace:
---------------
/var/chef/cache/cookbooks/vault/recipes/default.rb:4:in `from_file'
Relevant File Content:
----------------------
/var/chef/cache/cookbooks/vault/recipes/default.rb:
1: chef_gem "chef-vault"
2: require "chef-vault"
3:
4>> vault = ChefVault::Item.load("secrets", "vaultuser")
5:
6: user "vaultuser" do
7: password vault["vaultuser"]
8: home "/home/vaultuser"
9: supports :manage_home => true
10: shell "/bin/bash"
11: comment "Chef Vault User"
12: end
13:
注意: これはあまりよろしくない方法です。もし失敗したら、このNodeがアクセスするために必要な単一の秘密情報を毎回再アップロードする必要があります。
ユーザの削除
単純にChef ServerのOrganizationからユーザの関連付けを解除することでも、Enterprise Chefからユーザアクセスを削除できます。ここでは例示しません。なぜなら、OpscodeのホステッドEnterprise Chef Serverを使っていて私が唯一の管理者だからです 🙂
秘密情報のバックアップ
Chef Serverから暗号化データとして秘密情報をバックアップするには、knife-essentialsを使います。これはChef 11以上で使うことができ、Chef 10にはRubyGemで提供されています。
% knife download data_bags/secrets/
Created data_bags/secrets/vaultuser_keys.json
Created data_bags/secrets/vaultuser.json
Created data_bags/secrets/vaultuser-ssh-private_keys.json
Created data_bags/secrets/vaultuser-ssh-private.json
例えば、vaultuser.jsonファイルは次のようになります。
{
"id": "vaultuser",
"vaultuser": {
"encrypted_data": "3yREwInxdyKpf8nuTIivXAeuEzHt7o4vF4FsOwmVLHmMWol5nCBoMWF0YdaW\n3P3NpEAAAxYEYeJYdVkrdLqjjB2kTJdx0+ceh/RBHBWqmSeHOWFH9pCRGjV8\nfS5XaTueShb320b/+Ia8iqUJJWg6utnbJCDx+VMcGNggPXgPKC8=\n",
"iv": "EI+y74Uj2uwq7EVaP+0K6Q==\n",
"version": 1,
"cipher": "aes-256-cbc"
}
}
AES256という強い暗号で暗号化されているので、レポジトリに格納しても安全です。NSAがそのレポジトリにアクセスできると考えていなければ、ですが 😉
まとめ
秘密情報の管理は大変です! 複数のシステム、サービス、人々が使う秘密情報を格納しなければいけない場合は特にです。Chefの暗号化Data Bag機能は万能薬ではありませんが、確かな助けとなるでしょう。この記事がお役に立てば幸いです。