LoginSignup
7
6

More than 5 years have passed since last update.

serverspecでiptables のルールを検証する

Posted at

Serverspec

公式ドキュメントのiptablesセクション では、iptables があるルールを持っているか検証するために、have_rule マッチャーを使うべきと記載されています。

describe iptables do
  it { should have_rule('-P INPUT ACCEPT') }
end

が、何故か fail する

例えば、iptables に 下記ルールを設定したとして

-A INPUT -m tcp -p tcp --dport 80 -j ACCEPT

serverspec では 下記のように書けば、pass するはず。

describe iptables do
  it { should have_rule('-A INPUT -m tcp -p tcp --dport 80 -j ACCEPT') }
end

が、なぜか fail します。

serverspec / specinfra を読む

ドキュメントには詳しく書かれていないので、コードを読むことにします。
まずは serverspec。

RSpec::Matchers.define :have_rule do |rule|
  match do |subject|
    if subject.class.name == 'Serverspec::Type::Iptables' || subject.class.name == 'Serverspec::Type::Ip6tables'
      subject.has_rule?(rule, @table, @chain)
    else
      subject.has_rule?(rule)
    end
  end

これだけではなぜfail しているのか不明なので、さらに specinfra を読みます。

class Specinfra::Command::Linux::Base::Iptables < Specinfra::Command::Base::Iptables
  class << self
    def check_has_rule(rule, table=nil, chain=nil)
      cmd = "iptables"
      cmd += " -t #{escape(table)}" if table
      cmd += " -S"
      cmd += " #{escape(chain)}" if chain
      cmd += " | grep -- #{escape(rule)}"
      cmd
    end
  end
end

見つけました。 iptables -S の結果を grep しているようです。

実際に、iptables -S すると、

$ iptables -S
-P INPUT DROP
-P FORWARD DROP
-P OUTPUT ACCEPT
...
-A INPUT -p tcp -m tcp --dport 80 -j ACCEPT

という結果が得られます。

describe iptables do
  it { should have_rule('-A INPUT -m tcp -p tcp --dport 80 -j ACCEPT') }
end

iptables -S の結果に対して評価してることが分かれば、なぜ上のspecがfailするのかは明らかで、"-m tcp -p tcp" の順序が逆だからということになります。

まとめ

serverspec の have_rule は "iptables -S" の結果を grep で評価してるよ、ということを覚えておくと役に立つかもしれません。

7
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
6