Ip tables ignore rules comments option added for the resource

Signed-off-by: Nikita Mathur <nikita.mathur@chef.io>
This commit is contained in:
Nikita Mathur 2021-12-27 18:19:07 +05:30
parent a0875c9786
commit 13b8eceff8
3 changed files with 31 additions and 3 deletions

View file

@ -27,7 +27,7 @@ This resource first became available in v1.0.0 of InSpec.
A `iptables` resource block declares tests for rules in IP tables:
describe iptables(rule:'name', table:'name', chain: 'name') do
describe iptables(rule:'name', table:'name', chain: 'name', ignore_comments: true) do
it { should have_rule('RULE') }
end
@ -37,6 +37,7 @@ where
- `rule:'name'` is the name of a rule that matches a set of packets
- `table:'name'` is the packet matching table against which the test is run
- `chain: 'name'` is the name of a user-defined chain or one of `ACCEPT`, `DROP`, `QUEUE`, or `RETURN`
- `ignore_comments: true` is the boolean flag used when comment in the rule needs to be ignored.
- `have_rule('RULE')` tests that rule in the iptables list. This must match the entire line taken from `iptables -S CHAIN`.
## Examples
@ -61,6 +62,12 @@ The following examples show how to use this Chef InSpec audit resource.
it { should have_rule('-A INPUT -p tcp -m tcp -m multiport --dports 5432 -m comment --comment "postgres" -j ACCEPT') }
end
### Test a rule without comments
describe iptables(ignore_comments: true) do
it { should have_rule('-A INPUT -p tcp -m tcp -m multiport --dports 5432 -j ACCEPT') }
end
Note that the rule specification must exactly match what's in the output of `iptables -S INPUT`, which will depend on how you've built your rules.
## Matchers

View file

@ -33,6 +33,7 @@ module Inspec::Resources
def initialize(params = {})
@table = params[:table]
@chain = params[:chain]
@ignore_comments = params[:ignore_comments] || false
# we're done if we are on linux
return if inspec.os.linux?
@ -59,8 +60,13 @@ module Inspec::Resources
cmd = inspec.command(iptables_cmd)
return [] if cmd.exit_status.to_i != 0
# split rules, returns array or rules
@iptables_cache = cmd.stdout.split("\n").map(&:strip)
if @ignore_comments
# split rules, returns array or rules without any comment
@iptables_cache = remove_comments_from_rules(cmd.stdout.split("\n"))
else
# split rules, returns array or rules
@iptables_cache = cmd.stdout.split("\n").map(&:strip)
end
end
def to_s
@ -69,6 +75,16 @@ module Inspec::Resources
private
def remove_comments_from_rules(rules)
rules.each do |rule|
next if rule.nil?
rule.gsub!(/ -m comment --comment "([^"]*)"/, "")
rule.strip
end
rules
end
def find_iptables_or_error
%w{/usr/sbin/iptables /sbin/iptables iptables}.each do |cmd|
return cmd if inspec.command(cmd).exist?

View file

@ -16,6 +16,11 @@ describe "Inspec::Resources::Iptables" do
_(resource.has_rule?('-A INPUT -i eth0 -p tcp -m tcp --dport 80 -m state --state NEW -m comment --comment "http like its 1990" -j ACCEPT')).must_equal true
end
it "verify iptables without comments on ubuntu" do
resource = MockLoader.new(:ubuntu).load_resource("iptables", ignore_comments: true)
_(resource.has_rule?("-A INPUT -i eth0 -p tcp -m tcp --dport 80 -m state --state NEW -j ACCEPT")).must_equal true
end
it "verify iptables on windows" do
resource = MockLoader.new(:windows).load_resource("iptables")
_(resource.has_rule?("-P OUTPUT ACCEPT")).must_equal false