ufw = Uncomplicated FireWall です。

レシピはこんなのを作りました。opscode のレシピとか使うと、何設定し
ているか分からず結局全部読むことになるので自前で書いてます。

execute 'ufw reload' do
  action :nothing
end

execute 'ufw default deny' do
  not_if 'ufw status verbose | fgrep "Default: deny (incoming)"'
  notifies :run, 'execute[ufw reload]'
end

execute 'ufw allow http' do
  not_if 'ufw status | egrep "^80 +ALLOW"'
  notifies :run, 'execute[ufw reload]'
end

execute 'ufw allow ssh' do
  not_if 'ufw status | egrep "^22 +ALLOW"'
  notifies :run, 'execute[ufw reload]'
end

execute 'ufw enable' do
  command 'yes | ufw enable'
  not_if 'ufw status | fgrep "Status: active"'
end

serverspec はだいたいこんな感じです。

describe package 'ufw' do
  it { should be_installed }
end

describe service 'ufw' do
  it { should be_enabled }
  it { should be_running }
end

# serverspec では `$ telnet masutaka.net 80` 相当のテストは
# 出来ないため、`$ ufw status verbose` の出力結果をテストする。
describe command 'ufw status verbose' do
  its(:stdout) { should include 'Status: active' }
  its(:stdout) { should include 'Default: deny (incoming), allow (outgoing), disabled (routed)' }

  describe 'ssh' do
    its(:stdout) { should contain %r(^22 +ALLOW IN +Anywhere) }
  end

  describe 'http' do
    its(:stdout) { should contain %r(^80 +ALLOW IN +Anywhere) }
  end
end

ufw は初めから入って稼働していると思うので、package と service の
テストはお好みで。

私の理解が間違ってなければ serverspec は中からテストするので、ufw
でポートを閉じた場合の振る舞いのテストは出来ないと思います。
例: $ telnet masutaka.net 80 が繋がるか?

振る舞いのテストが出来ないのは不本意ですが、ないよりマシなのでこの
テストにしました。

例えば以下のテストは $ ufw allow http のテストではなく、http サー
バが稼働しているかのテストです。http サーバを停止するとテストが通
らなくなります。

describe port 80 do
  it { should be_listening }
end

ググると勘違いしている記事が多いので、間違えないようにしましょう。