Chef Server/Client構成の環境であればknife
コマンドを使用して、knife data bag create DATA_BAG_NAME DATA_BAG_ITEM --secret-file FILE
で
Data Bag Itemを暗号化することができますが、Chef Solo環境ではこれが使えません。
代替策としてChefのencrypted_data_bag_item
ライブラリをロードしてencrypt_data_bag_item
メソッドを直接呼び出す方法がありますが、
knife-solo_data_bagを使うとこれが簡単に出来る、ということで、
Linuxユーザのユーザ名とパスワードをData Bagに格納しレシピからそれらを使用するところまでをやってみました。
環境
- ワーク端末 : Mac OSX 10.9
- Chef : 11.14.0.alpha.1
- knife-solo : 0.4.1
- リモートサーバ : CentOS 6.4
knife-solo_data_bagインストール
gemでインストールします。
$ gem install knife-solo_data_bag
bundlerを使ってインストールする場合は、Gemfile
にgem knife-solo_data_bag
を追加してbundle install
を実行します。
共通鍵生成
暗号化で使用する共通鍵を作成します。
今回はopensslコマンドを使ってChefレポジトリの.chef
ディレクトリ下にdata_bag_key
という名称で鍵を作成しました。
$ cd <Chef Repository Name>
$ openssl rand -base64 512 | tr -d '\r\n' > .chef/data_bag_key
knife.rb設定
.chef/knife.rb
で、Data Bagディレクトリ(jsonファイルを格納するディレクトリ)のパス(data_bag_path
)と共通鍵のファイルパス(encrypted_data_bag_secret
)を指定します。
data_bag_path "data_bags"
encrypted_data_bag_secret ".chef/data_bag_key"
共通鍵のファイルパスはData Bagの作成時にknife solo
のコマンドラインオプションで指定することができます。ただし、
knife solo cook
実行時にはknife.rb
の設定が参照されるので上記のようにknife.rb
での設定が必要です。
(encrypted_data_bag_secret
で指定した共通鍵がリモートサーバにアップロードされます。)
EDITOR環境変数設定
knife soloコマンドでData bagを作成すると、環境変数EDITOR
で指定されたエディタが自動的に起動しData Bagのjsonファイルがオープンされます。
使用したいエディタを予め.bash_profile
などで定義しておくと便利です。
# vimを使う場合
export EDITOR='vim'
# atomを使う場合
export EDITOR='atom -w'
# sublime textを使う場合
export EDITOR='subl -w'
AtomやSublime Textを使う場合は予めそれぞれのシェルコマンドを作成しておいて、
それらを-w
付き(wait mode)で起動するように環境変数を設定します。
knife-solo_data_bag
では、knife solo data bag create
コマンドでData bagの作成と暗号化を行います。
Data bagの作成と暗号化は、
- tempディレクトリ($TMPDIRで指定されたディレクトリ)にテンポラリのjsonファイルが作成される
- jsonファイルを編集する(この時点ではData Bag Itemは暗号化されていない)
- 編集後、エディタを閉じたタイミングでData BagディレクトリにData Bag Itemが暗号化されたjsonファイルが作成される
という3ステップで行わるので、エディタを-w
付きで起動する設定にしておかないと1.の時点(エディタの起動が完了した時点)でknife solo
コマンドが終了してしまい、
Data Bagディレクトリに”id”キーだけのjsonファイルが作成される一方でtempファイルを虚しく編集する結果となってしまいます。
Data Bag作成
knife solo
コマンドを実行しData Bagを作成します。
以下はusersという名前のData Bagとyuyawataという名前のData Bag Itemを作成する例です。
(Data Bagディレクトリ下にusersディレクトリが作成され、その下にyuyawata.jsonが作成されます。)
$ knife solo data bag create users yuyawata --secret-file .chef/data_bag_key
EDITOR環境変数で指定したエディタが起動するので、jsonファイルを編集&保存し、エディタを閉じます。
以下はLinuxユーザのユーザ名とそのパスワードを定義する例です。
````` { “id”: “yuyawata”, “username”: “yuyawata”, “password”: “$6$MySalt$OLjTmmVn..5nCbb7sgph9B0QlLklMrC/gs8PiCAfyuJLqO2wkOdvsmXkmdN/i5lY8me8zcZfvF4BZAK3Qw93F/” }
Linuxユーザのパスワードは``shadow password``の形式で指定する必要があります。
### MD5でパスワードを指定する
``openssl``コマンドを使うとMD5でshadow passwordを生成することができます。パスワードSALTを__MySalt__、パスワードを__databagtest__とする場合は以下のようにコマンドを実行します。
```sh
openssl password -1 -salt "MySalt" "databagtest"
SHA512でパスワードを指定する
opensslコマンドはMD5にしか対応していません。SHA256やSHA512でshadow passwordを生成する方法はいくつかあるようですが、 今回はRuby製のunix-cryptを使ってSHA512でshadow passwordを生成する方法を書いておきます。
unix-crypt
はgemでインストールします。unix-crypt
をインストールするとmkunixcrypt
というコマンドも同時にインストールされるので、これを使います。
# unix-cryptインストール
$ gem install unix-crypt
# shadow password生成
# -sでパスワードSALTを指定。パスワードは対話式で指定する。
$ mkunixcrypt -s MySalt
Enter password:
Verify password:
Data Bagの確認
作成されたjsonファイルを開くと、Data Bag Itemが暗号化されていることが確認できます。 “id”は暗号化の対象外で、それ以外のキーの値(今回の例ではusernameとpassword)が暗号化されます。
{
"id": "yuyawata",
"username": {
"encrypted_data": "6SDEzXiMjwumOr3cxxFlTQUxQ0jDKESKV37/2lq8Z1A=\n",
"iv": "dlFVfjO94+qfdENJOdIg6g==\n",
"version": 1,
"cipher": "aes-256-cbc"
},
"password": {
"encrypted_data":"3k4YbyRfUY0ri67gZYaRTe74oTZznpYz5M0Ssu7R4DxXjlwTanWDDx4Fte+S\nNvt75/TIgzDK0dAUwaxxeTM3Ff2G59uoN/diuW9GwB0UeyR7F/sy59UR+38p\nCdM0iCrmgu6XKQsNlYyE7Y0PgDf3Au1D1qUZ7VXFl1kRVdjHM7o=\n",
"iv": "HV8/ilxMRkRTpvTpxvQOMw==\n",
"version": 1,
"cipher": "aes-256-cbc"
}
}
Data Bagの編集
暗号化されたData Bag Itemはknife solo data bag edit
で編集できます。createと同様に自動でエディタが起動し、Data Bag Itemが復号化された状態でjsonファイルが開きます。
$ knife solo data bag edit users yuyawata --secret-file .chef/data_bag_key
暗号化されたData Bag Itemの取得
暗号化されたData Bag Itemは、Chef::EncryptedDataBagItem.load('DATA_BAG_NAME', 'DATA_BAG_ITEMID', 'SECRET_KEY')
で取得します。
'SECRET_KEY'
には共通鍵を文字列で指定します。今回はknife.rb
に共通鍵のパスを指定しているので、'SECRET_KEY'
の指定は省略可能です。
以下はLinuxユーザを作成する場合のレシピの例です。
user_data = Chef::EncryptedDataBagItem.load('users', 'yuyawata')
user user_data['username'] do
comment 'data_bag_test_user'
home '/home/yuyawata'
shell '/bin/bash'
password user_data['password']
supports manage_home: true
action :create
end
参考サイト/書籍
- knife-solo - knife soloでdata_bagsを使う - Qiita
- Chef Solo + Knife Solo で暗号化データバッグを使う - Qiita
- Chefのdata_bagでsecret_keyの管理 - Qiita
- Chef の Data Bag を使ってユーザー作成の自動化をしてみる | girigiribauer.com
- アルパカchef日記3日目 data bagについて / またはユーザ管理クックブックなど - アルパカDiary
- knife-solo_data_bagを使ってEncrypted Data Bagで暗号化したファイルを配布する - 頑張ってる途中
- Chefで公開したくないJSONデータを暗号化するためにDataBagsを利用してみた記録 - さよならインターネット
- 入門Chef Solo - Infrastructure as Code - 達人出版会
- Chef活用ガイド コードではじめる構成管理 - 達人出版会