mirror of
https://github.com/inspec/inspec
synced 2024-11-26 14:40:26 +00:00
Merge pull request #5883 from inspec/ss/resource-ipnat
CFINSPEC-77 : Add Ipnat resource
This commit is contained in:
commit
6eb7d1ae00
7 changed files with 177 additions and 0 deletions
|
@ -25,6 +25,12 @@ The following resources work on Linux operating systems.
|
|||
|
||||
{{< inspec_resources platform="linux" >}}
|
||||
|
||||
### BSD
|
||||
|
||||
The following resources work on BSD operating systems.
|
||||
|
||||
{{< inspec_resources platform="bsd" >}}
|
||||
|
||||
### Windows
|
||||
|
||||
The following resources work on Windows operating systems.
|
||||
|
|
64
docs-chef-io/content/inspec/resources/ipnat.md
Normal file
64
docs-chef-io/content/inspec/resources/ipnat.md
Normal file
|
@ -0,0 +1,64 @@
|
|||
+++
|
||||
title = "ipnat resource"
|
||||
draft = false
|
||||
gh_repo = "inspec"
|
||||
platform = "bsd"
|
||||
|
||||
[menu]
|
||||
[menu.inspec]
|
||||
title = "ipnat"
|
||||
identifier = "inspec/resources/os/ipnat.md ipnat resource"
|
||||
parent = "inspec/resources/os"
|
||||
+++
|
||||
|
||||
Use the `ipnat` Chef InSpec audit resource to test rules that are defined for `IP NAT`. The purpose of the ipnat utility is to add or remove set of IP NAT rules. Rules are added to the end of the internal lists, matching the order in which they appear when given to ipnat. `ipnat -l` helps to view the current NAT table entry mappings. The rule match is done against the output rules of `ipnat -l`.
|
||||
|
||||
## Availability
|
||||
|
||||
### Installation
|
||||
|
||||
This resource is distributed along with Chef InSpec itself. You can use it automatically.
|
||||
|
||||
## Syntax
|
||||
|
||||
An `ipnat` resource block declares tests for rules set for IP NAT:
|
||||
|
||||
describe ipnat do
|
||||
it { should have_rule("RULE") }
|
||||
end
|
||||
|
||||
where
|
||||
|
||||
- `have_rule('RULE')` tests the active rule for IP NAT. This must match the entire line taken from `ipnat -l`.
|
||||
|
||||
## Examples
|
||||
|
||||
The following examples show how to use this Chef InSpec audit resource.
|
||||
|
||||
### Test to ensure mapping rule of the internally used IP address with ISP provided 8-bit subnet at 10.9.0.1
|
||||
|
||||
describe ipnat do
|
||||
it { should have_rule("map en0 192.0.0.0/8 -> 10.9.0.1/24") }
|
||||
end
|
||||
|
||||
### Test to ensure if there is a NAT rule to use the builtin ftp-proxy
|
||||
|
||||
describe ipnat do
|
||||
it { should have_rule("map en0 192.0.0.0/8 -> 10.9.0.1/32 proxy port ftp ftp/tcp") }
|
||||
end
|
||||
|
||||
{{< note >}}
|
||||
|
||||
The rule specification must match the output of `ipnat -l` that depends on how you have built your rules.
|
||||
|
||||
{{< /note >}}
|
||||
|
||||
## Matchers
|
||||
|
||||
For a full list of available matchers, please visit our [matchers page](/inspec/matchers/).
|
||||
|
||||
### have_rule
|
||||
|
||||
The `have_rule` matcher tests the named rule against the information in the output rule of `ipnat -l`:
|
||||
|
||||
it { should have_rule("RULE") }
|
|
@ -138,6 +138,7 @@ require "inspec/resources/xinetd_conf"
|
|||
require "inspec/resources/yum"
|
||||
require "inspec/resources/zfs_dataset"
|
||||
require "inspec/resources/zfs_pool"
|
||||
require "inspec/resources/ipnat"
|
||||
|
||||
# file formats, depend on json implementation
|
||||
require "inspec/resources/json"
|
||||
|
|
58
lib/inspec/resources/ipnat.rb
Normal file
58
lib/inspec/resources/ipnat.rb
Normal file
|
@ -0,0 +1,58 @@
|
|||
require "inspec/resources/command"
|
||||
module Inspec::Resources
|
||||
class IpNat < Inspec.resource(1)
|
||||
name "ipnat"
|
||||
supports platform: "bsd"
|
||||
supports platform: "solaris"
|
||||
desc "Use the ipnat InSpec audit resource to test rules that are defined for IP NAT"
|
||||
example <<~EXAMPLE
|
||||
describe ipnat do
|
||||
it { should have_rule("map net1 192.168.0.0/24 -> 0/32") }
|
||||
end
|
||||
EXAMPLE
|
||||
|
||||
def initialize
|
||||
# checks if the instance is either bsd or solaris
|
||||
return if (inspec.os.bsd? && !inspec.os.darwin?) || inspec.os.solaris?
|
||||
|
||||
# ensures, all calls are aborted for non-supported os
|
||||
@ipnat_cache = []
|
||||
skip_resource "The `ipnat` resource is not supported on your OS yet."
|
||||
end
|
||||
|
||||
def has_rule?(rule = nil)
|
||||
# checks if the rule is part of the ruleset
|
||||
retrieve_rules.any? { |line| line.casecmp(rule) == 0 }
|
||||
end
|
||||
|
||||
def retrieve_rules
|
||||
# this would be true if the OS family was not bsd/solaris when checked in initliaze
|
||||
return @ipnat_cache if defined?(@ipnat_cache)
|
||||
|
||||
# construct ipnat command to show the list of current IP NAT table entry mappings
|
||||
bin = find_ipnat_or_error
|
||||
ipnat_cmd = "#{bin} -l"
|
||||
cmd = inspec.command(ipnat_cmd)
|
||||
|
||||
# Return empty array when command is not executed successfully
|
||||
return [] if cmd.exit_status.to_i != 0
|
||||
|
||||
# split rules, returns array or rules
|
||||
@ipnat_cache = cmd.stdout.split("\n").map(&:strip)
|
||||
end
|
||||
|
||||
def to_s
|
||||
"Ipnat"
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def find_ipnat_or_error
|
||||
%w{/usr/sbin/ipnat /sbin/ipnat ipnat}.each do |cmd|
|
||||
return cmd if inspec.command(cmd).exist?
|
||||
end
|
||||
|
||||
raise Inspec::Exceptions::ResourceFailed, "Could not find `ipnat`"
|
||||
end
|
||||
end
|
||||
end
|
7
test/fixtures/cmd/ipnat-l
vendored
Normal file
7
test/fixtures/cmd/ipnat-l
vendored
Normal file
|
@ -0,0 +1,7 @@
|
|||
List of active MAP/Redirect filters:
|
||||
map en0 192.0.0.0/8 -> 10.9.0.1/32 proxy port ftp ftp/tcp
|
||||
map en0 192.0.0.0/8 -> 10.9.0.1/32 portmap tcp/udp 20000:40000 mssclamp 1452
|
||||
map en0 192.0.0.0/8 -> 10.9.0.1/32
|
||||
map net1 192.168.0.0/24 -> 0/32
|
||||
|
||||
List of active sessions:
|
|
@ -369,6 +369,9 @@ class MockLoader
|
|||
# ip6tables
|
||||
"/usr/sbin/ip6tables -S" => cmd.call("ip6tables-s"),
|
||||
%{sh -c 'type "/usr/sbin/ip6tables"'} => empty.call,
|
||||
# ipnat
|
||||
"/usr/sbin/ipnat -l" => cmd.call("ipnat-l"),
|
||||
%{type "/usr/sbin/ipnat"} => empty.call,
|
||||
# apache_conf
|
||||
"sh -c 'find /etc/apache2/ports.conf -type f -maxdepth 1'" => cmd.call("find-apache2-ports-conf"),
|
||||
"sh -c 'find /etc/httpd/conf.d/*.conf -type f -maxdepth 1'" => cmd.call("find-httpd-ssl-conf"),
|
||||
|
|
38
test/unit/resources/ipnat_test.rb
Normal file
38
test/unit/resources/ipnat_test.rb
Normal file
|
@ -0,0 +1,38 @@
|
|||
require "helper"
|
||||
require "inspec/resource"
|
||||
require "inspec/resources/ipnat"
|
||||
|
||||
describe "Inspec::Resources::Ipnat" do
|
||||
# freebsd11
|
||||
it "verify ipfilter on freebsd" do
|
||||
resource = MockLoader.new(:freebsd11).load_resource("ipnat")
|
||||
_(resource.has_rule?("map net1 192.168.0.0/24 -> 0/32")).must_equal true
|
||||
_(resource.has_rule?(nil)).must_equal false
|
||||
end
|
||||
|
||||
# solaris11
|
||||
it "verify ipfilter on solaris11" do
|
||||
resource = MockLoader.new(:solaris11).load_resource("ipnat")
|
||||
_(resource.has_rule?("map net1 192.168.0.0/24 -> 0/32")).must_equal true
|
||||
_(resource.has_rule?("rule which does not exist")).must_equal false
|
||||
end
|
||||
|
||||
# ubuntu
|
||||
it "verify ipfilter on ubuntu" do
|
||||
resource = MockLoader.new(:ubuntu).load_resource("ipnat")
|
||||
_(resource.has_rule?("map net1 192.168.0.0/24 -> 0/32")).must_equal false
|
||||
end
|
||||
|
||||
# windows
|
||||
it "verify ipfilter on windows" do
|
||||
resource = MockLoader.new(:windows).load_resource("ipnat")
|
||||
_(resource.has_rule?("map net1 192.168.0.0/24 -> 0/32")).must_equal false
|
||||
end
|
||||
|
||||
# undefined
|
||||
it "verify ipfilter on unsupported os" do
|
||||
resource = MockLoader.new(:undefined).load_resource("ipnat")
|
||||
_(resource.has_rule?("map net1 192.168.0.0/24 -> 0/32")).must_equal false
|
||||
end
|
||||
|
||||
end
|
Loading…
Reference in a new issue