BETA

Chef InSpecでインフラ管理の手を抜く

投稿日:2019-12-16
最終更新:2019-12-16

Chef InSpec とは

皆さん、インフラはやってますでしょうか?!。大規模になるとインストールなんかはChefとかansibleとかでチャチャっと対応できますが、その後のパラメータ設定管理やバージョン管理、コンプライアンス対応やセキュリティの持続確認、それを確認したエビデンスだすのめんどくさくないですか?ついつい手を抜いてませんか?

今回、その手を抜いてはいけないところに対して、手を抜くことを焦点に当てたく、Chef InSpec(以後、InSpec)を、インストールと初期状態で動かすところまで紹介したいと思います。

InSpecとは、公式ページによると、アプリケーションとインフラをテストおよび監査するオープンソースのテストフレームワークです。

具体的には

  • 特定のユーザが存在するか?それはどういう権限を持っているか?
  • 特定のフォルダは存在するか?
  • 想定するパッケージが含まれているか?そのバージョンは想定通りか?
  • 特定のポートでリスンされているか?それはTCPか?
  • sshd_confiの設定でrootでのログインが許可されていないか?
  • 特定の設定ファイルの設定はあっているか?

のような事を、サーバやクラウドのサービスに対してテストたり、その結果を出力したりするとができます。もちろん、CIと連携して継続的に確認することもできます。というか、そうしましょう。

テストの対象

テストの対象はは、ここに乗っていますが、Red Hat Linux,Ubuntu ,windows,Mac OS等、よく使わるOSはサポートされています。Rubyベースで組まれているので、rubyが動けば他のOSでも動きそうですね。細かいバージョンは直接HPをみてください。

また通常のOSとは別に、GCP、AWS、Azureのクラウドサービスのユーザ管理機能や、AD、各VMの設定等、各種クラウド特有の内容にも対応しているようです。素晴らしいですね。

大まかな流れ

InSpecは、インストール後に一般的には以下の流れで作業を行います。単純なので一回やってしまいましょう。

  1. プロファイルを作る(決まった構成のディレクトリで、プロジェクトみたいなもの)
  2. コントロールを作る(具体的なチェックコードです)
  3. ターゲットに対してテストを実施する

INSPECのインストール

インストール方法は、dokcerやgemを利用する方法もありますが、rpmでのインストールを例にします。
今回はCentos7で進めていますのでここからバージョンに合ったダウンロードしてください。

インストール

wget  https://packages.chef.io/files/stable/inspec/4.18.39/el/7/inspec-4.18.39-1.el7.x86_64.rpm  
rpm -ivh inspec-4.18.39-1.el7.x86_64.rpm  
省略・・・   
Thank you for installing InSpec!   

※ wgetがない場合はブラウザでDLしておくか、 yum install wget でwgetを入れておきましょう

以下のバージョン確認を行い、正常に起動するかを確認します。
inspecのコマンドを一番初めにうつと、ライセンスの確認が入るので、yesとしておいてください。

inspec -v   
4.18.39  

プロファイルを作成

inspecは実際のチェックにコントロールというスクリプト(設定?)を作成し、それを動かすことで確認処理が動きます。コントロールを1つだけ作成して動かすこともできますが、大体はもっと複雑な条件を一気に確認することが多いと思います。その時にプロファイルという単位で管理していく事になります。

実際は下記のようなディレクトリ構成になっており、スケルトンをinspecのコマンドで作成することができます。ちなみにプロファイルの説明が ここに説明が載っていますが、正直説明がよくわからないので、まあよくある「プロジェクト」単位でディレクトリを作るイメージを考えておいてください。

examples/profile  

├── README.md  
├── controls  
│   ├── example.rb  
├── libraries  
│   └── extension.rb  
|── files  
│   └── extras.conf  
└── inspec.yml

プロファイルは以下のコマンドで作成します。 server01は任意の名前で構いません

 inspec init profile server01  

で、以下のようにディレクトリと必要なファイルが作成されます。

Creating new profile at /root/server01  
  Creating file README.md  
  Creating directory controls  
  Creating file controls/example.rb  
  Creating file inspec.yml  
  Creating directory libraries  

今回はこのディレクトリ構成の細かい説明を省きますが詳しくはここをみてください。

具体的なテストを実施するスクリプトは、server01/controls/example.rb に作成されています。

cd ./server01/controls  
cat example.rb   
----------------------------example.rb の中身  
# copyright: 2018, The Authors  

title "sample section"  

# you can also use plain tests  
describe file("/tmp") do  
  it { should be_directory }  
end  

<もっとあるが、今回は省略>  
----------------------------  

のような中身です。

注目は、

describe file("/tmp") do  
  it { should be_directory }  
end  

のブロックで、これは「 /tmp」がディレクトリであること を確認するテストです。
このfileの部分をリソースといい、InSpecはこのリソースに対して何等かのテストを実施していく事になります。

具体的なリソースはここを見ていただければイメージがわくのではないかと思いますが、例えば

  • package (インストールパッケージの名称やバージョン等のチェック)
  • iptables(iptablesのルールの等チェック)
  • file (ファイルやディレクトリ等のパーミッションやタイプ等のチェック)
  • passwd(/etc/passwdに特定のユーザが含まれているか等のチェック)
    などがあります。

例えば、 nginxがインストールされおり、バージョンは1.9.5であることを確認するのが以下の内容になります。直感的でわかりやすいですよね。

describe package('nginx') do  
  it { should be_installed }  
  its('version') { should eq '1.9.5' }  
end  

それ以外にはcommandのリソースのように特定のコマンドを起動してその結果がマッチするかや、それでも難しい場合は自分でカスタムリソースという独自のリソースを作成することもできます。 

describe のブロックを1ファイルに複数書くこともできますし、controlsデレクトリ配下に複数のファイルを作成してテストを実施することもできます。

テストの実施

それではserver01のディレクトリにある場所に移動して、テストを実施してみましょう。
テスト実施のコマンドの代表的な定義は以下のとおりです。sshやWinRMを利用してリモートから接続することがわかりますね。

ispec exec ./server01 ※ローカルのサーバをテスト  
ispec exec ./server01 -t [ターゲットのサーバ] ターゲットとなるサーバをテスト  
例)公式サイトからの転用  
$ inspec exec server01-t ssh://[email protected]:11022  # Login to remote machine using ssh as root.  
$ inspec exec  server01 -t ssh://[email protected]:1234 -i /path/to/user_key  # Login to hostname on port 1234 as user using given ssh key.  
$ inspec exec  -t winrm://UserName:[email protected]:1234  # Login to windowsmachine over WinRM as UserName.  
$ inspec exec  -t winrm://windowsmachine --user '[email protected]' --password 'Secret123!' # Login to windowsmachine as [email protected]  
$ inspec exec  -t docker://container_id # Login to a Docker container.  

 

プロファイルの作成単位の考察 :
プロファイルはどの単位で作成すればいいのかの解がまだ解がわかっていません。
InSpecはプロファイルに対して、1つのターゲット(サーバ等のテスト対象)を指定しテストをします。ただ、ターゲット事にプロファイルを作る場合、サーバが100台あったら100プロファイルを作成する必要があります。これは非常に怠けることができない事態となります。
それを避ける場合を考慮すると、やはりOS単位や役割単位ではないでしょうか? 例えばOSの設定内容等の、ある程度共通的にテスト実施できる部分と、webサーバとAPサーバならインストールするミドルウェアに違いがあるので、そういう特殊部分だけのプロファイルを管理して、出来るだけ数を減らし管理しやすいようにするのがよいのではないかと思っています。
 
 inspec exec ./server01  

以下の結果が表示されます。 成功すると画面に緑色の文字で、失敗すると赤色の文字で結果が表示されます。/tmpがディレクトリなのですべてのテストで成功すると思います。以後、いろいろなリソースを追加してテスト内容を増やしていくながれになります。

Profile: InSpec Profile (server01)  
Version: 0.1.0  
Target:  local://  

    tmp-1.0: Create /tmp directory  
       File /tmp should be directory  

  File /tmp  
       should be directory  

Profile Summary: 1 successful control, 0 control failures, 0 controls skipped  
Test Summary: 2 successful, 0 failures, 0 skipped  

次回はより具体的な内容を記載します。

技術ブログをはじめよう Qrunch(クランチ)は、プログラマの技術アプトプットに特化したブログサービスです
駆け出しエンジニアからエキスパートまで全ての方々のアウトプットを歓迎しております!
or 外部アカウントで 登録 / ログイン する
クランチについてもっと詳しく

この記事が掲載されているブログ

@sankit25がまあまあ頑張ってブログを書きます。 偉そうな事も書くので、こっぱずかしいので家族に見つからないように書いてます。

よく一緒に読まれる記事

0件のコメント

ブログ開設 or ログイン してコメントを送ってみよう