Chefで ~/.ssh/authorized_keys を配置する

Chefでコンフィグレーションをさせることを先日から取り組んでいて、その中でサーバに接続する予定のユーザの公開鍵を予め配置しておきたいと思っていたところ以外とあっさりとできたのでそのメモ。

状況的にはチームで共有しているユーザがあって、

  • 対象のサーバに存在するそのユーザを利用して複数の端末から公開鍵認証でのSSH接続を行いたい
  • そのため各端末の公開鍵を予め管理してコンフィグレーションする際に自動的に設定したい

が、満たせれば満足。これができれば自分たちの状況であれば、LXCを作るたびにこのレシピを適用すればすぐにチームメンバがSSH接続を特定のユーザでログインできる様になります。

まず、公開鍵を配置するdefinitionを新しく定義します。

# site-cookbooks/base/definition/authorized_keys_for.rb
define :authorized_keys_for, :keys => "public-keys", :group => nil, :home => nil do
user  = params[:name]
group = params[:group] || user
home  = params[:home]  || "/home/#{user}"
keys  = data_bag params[:keys]
if keys.any?
ssh_public_keys = keys.map do |key|
data_bag_item(params[:keys], key)
end
directory "#{home}/.ssh" do
owner user
group group
mode 0700
action :create
only_if "test -d #{home}"
end
file "#{home}/.ssh/authorized_keys" do
owner user
group group
content ssh_public_keys.collect{ |x| "#{x['key']} ##{x['id']}" }.join("\n")
end
end
end

次に配置したい公開鍵をdata bagとして定義します。今後配置したい鍵が増えればその毎に定義を増やしていけばよくなります。

data_bags/public-keys/(ユーザ名).json に足していきます。

# data_bags/public-keys/hideack.json
{
"id": "hideack",
"key": "ssh-rsa AAAAB3…."
}

ここまで準備できたら、上のdefinitionをレシピ中で使えるので、記述します。

# site-cookbooks/base/recipes/default.rb
authorized_keys_for 'remper'   # ← これが上のdefinition呼出
%w{}.each do |pkg|
package pkg do
action :install
end
end

実行してみます。

$ knife solo cook remper@*****
Running Chef on ****...
Checking Chef version...
Enter the password for remper@*****:
Uploading the kitchen...
Generating solo config...
Running Chef...
Starting Chef Client, version 11.8.0
Compiling Cookbooks...
Converging 10 resources
Recipe: base::default
* directory[/home/remper/.ssh] action create
- change mode from '0775' to '0700'
* file[/home/remper/.ssh/authorized_keys] action create
- update content in file /home/remper/.ssh/authorized_keys from d0209a to 5cf54f
(略)

これで、Chefを適用したサーバに対してSSH接続の認証に利用するための公開鍵の配置が行われました。地味に楽になりました...。

参照