Chefで、iptablesというCookbookを使用して、
iptableで解放をするTCP/UDPポートを管理するレシピを書いてみたので、
その手順を書き残しておきます。

Chef Cookbook: iptables -Opscode Community
 http://community.opscode.com/cookbooks/iptables

ChefでレシピのレシピでWebサーバやDBサーバをセットアップする場合、
あわせてiptablesでそれぞれのTCP/UDPポートを解放するレシピを書く必要があります。
そこで、
/etc/sysconfig/iptablesファイルをcookbook_fileで配置するアプローチをとると、
本番はWebAP/DBサーバを分けるが、評価用環境でWebAP/DBサーバを共存するような場合などは、
本番・評価で別のiptablesファイルを作っておく必要が出てきます。
なので自前スクリプトでiptablesを書き換えるproviderを作ったりしていたのですが、
Opscode Commnityそのためのcookbookがあったので、使ってみました。

以下のエントリのように、
KnifeSolo+Berkshelfの環境があることを前提に手順を示します。
以下のエントリ同様、CentOS6.4にnginxをセットアップする例で手順を示します。

Chef(Knife)+Berkshelfを使ってサーバを自動構築する手順
 http://takemikami.com/archives/1423

Berkshelfを用いてiptablesのCookbookを取得する

Berksfileを以下の用に変更(nginx/iptablesを追加)します。

Berksfile

site :opscode
cookbook 'nginx'
cookbook 'iptables'

以下のコマンドで、opscodeのリポジトリからnginx,iptablesと依存するcookbookを取得します。

$ bundle exec berks --path=cookbooks

iptables設定用のレシピを作成する

以下のコマンドを実行し、mycookbookというcookbookを作成します。

$ bundle exec knife cookbook create mycookbook -o site-cookbooks/
** Creating cookbook mycookbook
** Creating README for cookbook: mycookbook
** Creating CHANGELOG for cookbook: mycookbook
** Creating metadata for cookbook: mycookbook

作成したCookbookのmetadata.rbにnginx,iptablesへの依存情報を追記します。

site-cookbooks/mycookbook/metadata.rb

depends          'nginx'
depends          'iptables'

解放するポート用のテンプレートファイル(SSH用とHTTP用)を作成します。
# /etc/sysconfig/iptables に記載する内容の一部になります

site-cookbooks/mycookbook/templates/default/ssh.erb

# Port 22 for ssh
-A FWR -p tcp -m tcp --dport 22 -j ACCEPT

site-cookbooks/mycookbook/templates/default/http.erb

# Port 80 for http
-A FWR -p tcp -m tcp --dport 80 -j ACCEPT

iptablesを設定するレシピを作成します。

site-cookbooks/mycookbook/recipes/default.rb

include_recipe "nginx"
include_recipe "iptables"

iptables_rule "ssh"
iptables_rule "http"

iptables設定用のレシピを適用&確認する

対象ノード用のjsonファイルを作成します。

nodes/<対象ノートのホスト名>.json

{ "run_list": [ "recipe[mycookbook]" ] }

以下のコマンドを実行し、レシピを対象ノードに適用します。

$ bundle exec knife solo cook <対象ノートのホスト名>
Running Chef on <対象ノートのホスト名>...
Checking Chef version...
※省略※
Chef Client finished, 30 resources updated

適用が終わったら、ブラウザで対象ホストにアクセスして
「Welcome to nginx on EPEL!」が表示されることを確認します。
# curlとか、でもいいですが

iptablesのCookbookが何をやっているか?

iptablesで解放するTCP/UDPポートの管理は今までの流れで可能ですが、
このCookbookが何をやっているか気になったので、
作成されたファイルを少しのぞいてみることにします。

まずは/etc/sysconfig/iptablesを見てみると、
テンプレートファイル(SSH用とHTTP用)で定義した内容を含まれていることが分かります。

/etc/sysconfig/iptables

*filter
:INPUT ACCEPT
:FORWARD ACCEPT
:OUTPUT ACCEPT
:FWR -
-A INPUT -j FWR
-A FWR -i lo -j ACCEPT

# Any established connection is money
-A FWR -m state --state RELATED,ESTABLISHED -j ACCEPT

# ICMP
-A FWR -p icmp -j ACCEPT
# Port 80 for http
-A FWR -p tcp -m tcp --dport 80 -j ACCEPT

# Port 22 for ssh
-A FWR -p tcp -m tcp --dport 22 -j ACCEPT

# Rejects all remaining connections with port-unreachable errors.
-A FWR -p tcp -m tcp --tcp-flags SYN,RST,ACK SYN -j REJECT --reject-with icmp-port-unreachable
-A FWR -p udp -j REJECT --reject-with icmp-port-unreachable
COMMIT

次に、/etc/iptables.d配下を見てみると、
all_established, all_icmp, http, ssh というファイルがあります。
中を見ると、これらがそれぞれ、
/etc/sysconfig/iptablesのパーツになっていることが分かります。

ここからレシピ適用時には、以下の処理が流れていることが想像できます。

  1. /etc/iptables.d に定義のパーツを作成
  2. パーツを元に/etc/sysconfig/iptablesを再生成
    # 2の実体は、/usr/sbin/rebuild-iptablesというスクリプト

うまく設定できない場合などは、
このあたりのファイルがどうなっているかなどを追ってみると良いかと思います。