- 2014-09-25 (木) 13:52
- Ansible
Bash 脆弱性が出ましたね。対策がまだの方はお早めに。
修正 RPM が提供されているとはいえ、複数サーバにログインして、yum update
していくのは、骨が折れる作業です。元から構成管理ツールを導入していて、一括更新出来る場合は良いのですが、なかなか導入できていないところも多いでしょう。
このエントリでは、Ansible を使って、複数サーバに対して、一括で RPM 更新を行う方法を見ていきます。
Ansible インストール
Ansible の操作を行う PC or サーバにインストールします。これは ansible コマンドを実行する環境にのみインストールします。例えば、サーバ管理者の PC などです。チームで行う場合は、操作用のサーバにインストールして、SSH で操作サーバにログインして、実行すると良いでしょう。
OSX なら、Homebrew で入れるのが簡単です。
$ brew install ansible
RHEL / CentOS なら、EPEL で配布されているので、yum でインストールできます。
$ rpm -ivh http://ftp.riken.jp/Linux/fedora/epel/6/i386/epel-release-6-8.noarch.rpm $ yum -y install ansible
インストールが完了したら、ansible コマンドが動作するか確認しておきます。
$ ansible --version ansible 1.7.1
対象ホスト
対象ホストは、SSH でログインができれば、別途インストールは不要です。(実際は、Python がインストールされている必要があるのですが、多くの Linux 環境ではインストールされています。)
あと、リモートホスト上で実行したい操作に root 権限が必要な場合(RPM の更新には必要)は、root ユーザでログインするか、SSH ログインするユーザが sudo できる状態にしておく必要があります。
対象ホストをインベントリファイルに記述
処理対象のホストを指定するためにインベントリファイルを作成します。インベントリファイルには、対象サーバのホスト名や接続情報を記述します。
下記では、host1.exmaple.com と host2.example.com を処理対象のホストとして指定しています。
$ vim hosts host1.example.com host2.example.com
インベントリファイルでは、SSH接続情報をパラメータとして指定することができます。良く使うパラメータは以下です。
- ansible_ssh_port = SSH接続ポート(22 以外を使う場合に指定)
- ansible_ssh_user = SSH接続ユーザ名(指定が無ければ、ansible コマンドを実行したユーザ)
- ansible_ssh_pass = SSH接続パスワード(パスワード認証の場合。パスワードを書くのは好ましくないので、–ask-pass をオプションを指定した方が良い)
- ansible_ssh_private_key_file = 公開鍵認証時の秘密鍵ファイルパス
インベントリファイルでは、下記のように指定します。
host1.example.com ansible_ssh_user=user1 ansible_ssh_private_key_file=/path/to/secret_key host2.example.com ansible_ssh_user=ec2-user
ホストをグループ化(ロールやプロジェクト等)したい場合、インベントリファイルを分ける(projectA_hosts, projectB_hosts)か、グループを指定することができます。
イベントリファイルでグループを指定する場合は、下記のように記述します。
[groupA] host1 host2 [groupB] host3
ansible コマンドの実行
ansible コマンドを実行してみましょう。
ansible コマンドを使って、リモートホストでコマンドを実行する場合、下記のようにオプションを指定します。
$ ansible 処理対象ホスト -i イベントリファイル -m shell -a "コマンド"
ansible コマンドに続いて、処理対象のホストを指定します。これはイベントリファイルに含まれている必要があります。全てのホストを対象とする場合は、all
を指定します。グループ内のホストを対象をする場合は、グループ名を指定します。
-i
オプションでイベントリファイルを指定します。
そして、実行するモジュールを指定します。ここでは、shell モジュールを使って、コマンドをリモートホストで実行したいので、-m shell -a
オプションを指定します。
下記が実行例です。ここでは、hosts
に書かれた全てのホスト上で、uname -a
コマンドを実行します。それぞれのホストでの実行結果が表示されており、コマンドが実行できたことが確認できます。
$ ansible all -i hosts -m shell -a "uname -a" host1.example.com | success | rc=0 >> Linux host1.example.com 2.6.32-431.11.2.el6.x86_64 #1 SMP Tue Mar 25 19:59:55 UTC 2014 x86_64 x86_64 x86_64 GNU/Linux host2.example.com | success | rc=0 >> Linux host2.example.com 2.6.32-431.11.2.el6.x86_64 #1 SMP Tue Mar 25 19:59:55 UTC 2014 x86_64 x86_64 x86_64 GNU/Linux
ansible コマンドには、shell モジュール以外にも多くの機能があるのですが、ここではこのモジュールのみ利用します。
RPM のバージョン確認
では、実際に RPM の更新を ansible コマンドで実行してみましょう。ここでは、対象 RPM を bash とします。
まずは現在の RPM のバージョンを確認しておきます。もちろん、これにも ansible コマンドを使います。RPM のバージョン確認には、rpm -qv
コマンドを使います。
実行結果が以下です。それぞれの bash のバージョンが表示されています。host1 は、現段階(2014/09/25)での最新版となっていますが、host2は、まだ古いままとなっています。
$ ansible all -i hosts -m shell -a "rpm -qv bash" host1.example.com | success | rc=0 >> bash-4.1.2-15.el6_5.1.x86_64 host2.example.com | success | rc=0 >> bash-4.1.2-15.el6_4.x86_64
ansible で RPM を更新
RPM の更新を行ないます。
RPM の更新では、yum -y update bash
コマンドで行ないます。通常、yum update
すると Yes
or No
の確認が入るのですが、ここでは自動実行するので、-y
オプションを付けておきます。
では実行してみましょう。
$ ansible host1.example.com -i hosts -m shell -a "yum -y update bash" host1.example.com | success | rc=1 >> Loaded plugins: downloadonly, fastestmirror, securityYou need to be root to perform this command.
おっと、エラーが発生しました。yum update では、root 権限が必要なためです。では、--sudo
オプションを付けて、再実行してみましょう。
次は、無事に更新することができました。
$ ansible host1.example.com -i hosts --sudo -m shell -a "yum -y update bash" host1.example.com | success | rc=0 >> Loaded plugins: fastestmirror Loading mirror speeds from cached hostfile (snip) Updated: bash.x86_64 0:4.1.2-15.el6_5.1 Complete!
念のため、バージョンを確認しておきます。両ホスト共に最新版となりました。
$ ansible all -i hosts -m shell -a "rpm -qv bash" host1.example.com | success | rc=0 >> bash-4.1.2-15.el6_5.1.x86_64 host2.example.com | success | rc=0 >> bash-4.1.2-15.el6_5.1.x86_64
さいごに
Ansible で、複数ホストの RPM を更新してみました。
本文で見てきたように、Ansible は、SSH ログインができるリモートホストなら、エージェントなどをインストールしなくても利用できるのが利点の一つです。ツールによる構成管理ができていない環境でも、操作用の環境にさえ Ansible をインストールすれば気軽に使いはじめることができます。
OpenSSL に続き、今回の Bash 脆弱性発覚、もちろん RPM 更新以外にもサーバ運用では何かと一括で操作を行うタスクが発生します。
Ansible を活用して、こうしたタスクの手間を削減してみてはどうでしょう。
なお、Ansible には、今回紹介したスポットでのコマンド実行の他にも、構成管理やデプロイなど、サーバ構築や運用のタスクを自動化する機能があります。10/11 に開催される PHP カンファレンスでは、そのあたりをお話したいと思いますので、ぜひご参加下さい:D
http://phpcon.php.gr.jp/w/2014/
参考
Ansible Documentation
Ansible チュートリアル | Ansible Tutorial in Japanese