Merge pull request #103 from chef/iptables

Merged change 9dbb0f0f-be5a-43ad-9a8e-b6c21349cd1c

From review branch iptables into master

Signed-off-by: drichter <drichter@chef.io>
This commit is contained in:
chef-delivery 2015-10-12 02:43:09 -07:00
commit 3a507dc5b1
6 changed files with 120 additions and 1 deletions

View file

@ -190,10 +190,25 @@ RSpec::Matchers.define :be_resolvable do
end
chain :by do |_type|
fail '[UNSUPPORTED] `by` is not supported in combination with `be_resolvable`'
fail "[UNSUPPORTED] `by` is not supported in combination with `be_resolvable`. Please use the following syntax `host('example.com', port: 53, proto: 'udp')`."
end
failure_message do |host|
"expected that host #{host} is resolvable"
end
end
# matcher for iptables
RSpec::Matchers.define :have_rule do |rule|
match do |tables|
tables.has_rule?(rule)
end
chain :with_table do |_table|
fail "[UNSUPPORTED] `with_table` is not supported in combination with `have_rule`. Please use the following syntax `iptables(table:'mangle', chain: 'input')`."
end
chain :with_chain do |_chain|
fail "[UNSUPPORTED] `with_table` is not supported in combination with `with_chain`. Please use the following syntax `iptables(table:'mangle', chain: 'input')`."
end
end

65
lib/resources/iptables.rb Normal file
View file

@ -0,0 +1,65 @@
# encoding: utf-8
# author: Christoph Hartmann
# author: Dominik Richter
# Usage:
# describe iptables do
# it { should have_rule('-P INPUT ACCEPT') }
# end
#
# The following serverspec sytax is not implemented:
# describe iptables do
# it { should have_rule('-P INPUT ACCEPT').with_table('mangle').with_chain('INPUT') }
# end
# Please use the new sytax:
# describe iptables(table:'mangle', chain: 'input') do
# it { should have_rule('-P INPUT ACCEPT') }
# end
#
# Note: Docker containers normally do not have iptables installed
#
# @see http://ipset.netfilter.org/iptables.man.html
# @see http://ipset.netfilter.org/iptables.man.html
# @see https://www.frozentux.net/iptables-tutorial/iptables-tutorial.html
class IpTables < Vulcano.resource(1)
name 'iptables'
def initialize(params = {})
@table = params[:table] || nil
@chain = params[:chain] || nil
# we're done if we are on linux
return if vulcano.os.linux?
# ensures, all calls are aborted for non-supported os
@iptables_cache = []
skip_resource 'The `iptables` resource is not supported on your OS yet.'
end
def has_rule?(rule = nil, _table = nil, _chain = nil)
found = false
retrieve_rules.each { |line|
# checks if the rule is part of the ruleset
# for now, we expect an excact match
found = true if line.downcase == rule.downcase
}
found
end
def retrieve_rules
return @iptables_cache if defined?(@iptables_cache)
# construct iptables command to read all rules
@table.nil? ? table_cmd = '' : table_cmd = " -t #{@table} "
@chain.nil? ? chain_cmd = '' : chain_cmd = " #{@chain}"
cmd = vulcano.command(format('iptables %s -S %s', table_cmd, chain_cmd).strip)
return [] if cmd.exit_status.to_i != 0
# split rules, returns array or rules
@iptables_cache = cmd.stdout.chomp.split("\n")
end
def to_s
format('iptables %s %s', @table.nil? ? '' : "table: #{@table}", @chain.nil? ? '' : "chain: #{@chain}").strip
end
end

View file

@ -38,6 +38,7 @@ require 'resources/group_policy'
require 'resources/host'
require 'resources/inetd_conf'
require 'resources/interface'
require 'resources/iptables'
require 'resources/json'
require 'resources/kernel_module'
require 'resources/kernel_parameter'

View file

@ -175,6 +175,8 @@ class MockLoader
'ping -w 1 -c 1 example.com' => cmd.call('ping-example.com'),
# apt
"find /etc/apt/ -name *.list -exec sh -c 'cat {} || echo -n' \\;" => cmd.call('etc-apt'),
# iptables
'iptables -S' => cmd.call('iptables-s'),
}
# set os emulation

View file

@ -0,0 +1,6 @@
-P INPUT DROP
-P FORWARD DROP
-P OUTPUT ACCEPT
-A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
-A INPUT -i eth0 -p tcp -m tcp --dport 22 -m state --state NEW -j ACCEPT
-A INPUT -i eth0 -p tcp -m tcp --dport 80 -m state --state NEW -j ACCEPT

View file

@ -0,0 +1,30 @@
# encoding: utf-8
# author: Christoph Hartmann
# author: Dominik Richter
require 'helper'
require 'vulcano/resource'
describe 'Vulcano::Resources::Iptables' do
# ubuntu 14.04
it 'verify iptables on ubuntu' do
resource = MockLoader.new(:ubuntu1404).load_resource('iptables')
_(resource.has_rule?('-P OUTPUT ACCEPT')).must_equal true
_(resource.has_rule?('-P OUTPUT DROP')).must_equal false
end
it 'verify iptables on windows' do
resource = MockLoader.new(:windows).load_resource('iptables')
_(resource.has_rule?('-P OUTPUT ACCEPT')).must_equal false
_(resource.has_rule?('-P OUTPUT DROP')).must_equal false
end
# undefined
it 'verify iptables on unsupported os' do
resource = MockLoader.new(:undefined).load_resource('iptables')
_(resource.has_rule?('-P OUTPUT ACCEPT')).must_equal false
_(resource.has_rule?('-P OUTPUT DROP')).must_equal false
end
end