プロビジョニングツールのスレーブノードに公開鍵をいっせいに配布する

動機

サーバープロビジョニングにansibleやchefを使う前準備として、hostサーバーの公開鍵を複数台のスレーブノードに配布する必要がある。
ノードの数が2~3台程度なら、手順書を作って、各サーバーにsshログインして、エディタでコピペ、という手順でも大した苦にならないが、 サーバーの数が増えてくると、手順書を作ったり、実行したりするだけでもかなりの時間を食ってしまう。

目的

ansibleやchefのスレーブノードに、hostサーバーの公開鍵をコマンド1発で配布できるようにする。 (あと、手順書を簡略化する。)

バージョンとか

クライアントPC : Windows10
ansibleホスト・スレーブ : CentOS7.2

前提

クライアントから各スレーブノードにsshのパスワード認証ログインができる。
クライアントPCでbash,ssh,sshpassが使える。(sshpassはwindows Bashのapt-getでインストールできる。)

結論

sshリモートコマンドでばらまく。
Windows10からはコマンドプロンプトからbashが使えるので、下記のようなBashスクリプトを書いて実行する。 (ネットワーク設定が適切にされていれば、VirtualBox上のLinux仮想マシンでも同様のことができるはず。)

#!/bin/bash
read key < id-rsa.pub
while read ip user pass;do
  sshpass -p $pass ssh ${user}@${ip} "echo $key >> ~/.ssh/authorized_keys" < /dev/null
done <<SERVER
192.168.XXX.XXX user1 pass1
192.168.YYY.YYY user2 pass2
SERVER

※ id-rsa.pub はプロビジョニングツールホストで作成した公開鍵。

ログインするユーザーと、スレーブノードのユーザーが異なる場合は、こんな感じ。 (ログインユーザーがnopassでsudo実行できる前提)

#!/bin/bash
read key < id-rsa.pub
while read ip loginuser loginpass user ;do
  sshpass -p $loginpass ssh ${loginuser}@${ip} "sudo -u $user bash -l" <<<"echo $key >> ~/.ssh/authorized_keys"
done <<SERVER
192.168.XXX.XXX loginuser1 password1 user
192.168.YYY.YYY loginuser2 password2 user
SERVER

やってること

key 変数に公開鍵情報を格納し、sshリモートコマンドで、authorized_keysに追記リダイレクトしている。 ログインユーザーとスレーブノードユーザーが異なる場合は、チルダ展開されるタイミングを、 sudo bash -l環境変数が初期化された後に調整する必要があるため、ヒアストリングでコマンドを渡すようにしている。

補足

踏み台サーバーを経由するような構成の場合は、少し変更が必要。

踏み台サーバーからスレーブノードへssh公開鍵認証が設定済みの場合

sshの公開鍵認証が通っているような構成であれば、sshpassを使わず、同様のコマンドで鍵をばらまくことができる。

#!/bin/bash
read key < id-rsa.pub
while read ip loginuser user ;do
  ssh ${loginuser}@${ip} "sudo -u $user bash" <<<"echo $key >> ~/.ssh/authorized_keys"
done <<SERVER
192.168.56.101 loginuser1 user
192.168.56.102 loginuser2 user
SERVER

踏み台サーバーからスレーブノードへパスワード認証でログインする構成で、かつ、rbashでコマンド制限されている場合。

この場合は、ターミナルのマクロを使って実行する必要がある。(後日githubで公開予定)

注意

authorized_keysへの追記リダイレクト>>を、間違えて上書きリダイレクト>にしてしまうと、 踏み台サーバーからログインできなくなって大変なことになるので、扱いは慎重に。

蛇足

書き込み完了ごとに、確認を入れたり、継続/終了を判断したい場合は、こちらの記事を参考にして、 プログラムを拡張してください。