mirror of
https://github.com/inspec/inspec
synced 2024-11-10 07:04:15 +00:00
Merge pull request #5597 from mitre/firewalld_update
Firewalld update -- exposed more fields, updated docs, added custom matchers
This commit is contained in:
commit
63a5fd26a6
13 changed files with 199 additions and 23 deletions
|
@ -40,6 +40,7 @@ Use the where clause to test open interfaces, sources, and services that are in
|
|||
its('interfaces') { should cmp ['enp0s3', 'eno2'] }
|
||||
its('sources') { should cmp ['192.168.1.0/24', '192.168.1.2'] }
|
||||
its('services') { should cmp ['ssh', 'icmp'] }
|
||||
its('target') { should cmp ['default'] }
|
||||
end
|
||||
|
||||
## Properties
|
||||
|
@ -68,7 +69,31 @@ The `services` property is used in conjunction with the where class to display o
|
|||
its('services') { should cmp ['ssh', 'icmp'] }
|
||||
end
|
||||
|
||||
### `default_zone`
|
||||
### target
|
||||
|
||||
The `target` property is used in conjunction with the where class to display the target action in an active zone.
|
||||
|
||||
describe firewalld.where { zone == 'public' } do
|
||||
its('target') { should cmp ['default'] } # or ['DROP'], ['ACCEPT'], etc.
|
||||
end
|
||||
|
||||
### ports
|
||||
|
||||
The `ports` property is used in conjunction with the where class to display the ports used by an active zone.
|
||||
|
||||
describe firewalld.where { zone == 'public' } do
|
||||
its('ports') { should cmp ["80/tcp", "443/tcp"] }
|
||||
end
|
||||
|
||||
### protocols
|
||||
|
||||
The `protocols` property is used in conjunction with the where class to display the protocols used by an active zone.
|
||||
|
||||
describe firewalld.where { zone == 'public' } do
|
||||
its('protocols') { should cmp ["icmp", "ipv4"] }
|
||||
end
|
||||
|
||||
### default_zone
|
||||
|
||||
The `default_zone` property displays the default active zone to be used.
|
||||
|
||||
|
@ -114,4 +139,16 @@ The `be_running` matcher tests if the firewalld service is running:
|
|||
|
||||
it { should have_rule_enabled('family=ipv4 source address=192.168.0.14 accept', 'public') }
|
||||
|
||||
It is not necessary to add the "rule" string, and you can start with the optional flags that are used in firewalld and end with the action
|
||||
It is not necessary to add the "rule" string, and you can start with the optional flags that are used in firewalld and end with the action.
|
||||
|
||||
### `have_icmp_block_inversion_enabled`
|
||||
|
||||
`have_icmp_block_inversion_enabled` returns true or false if ICMP block inversion flag is set for the indicated zone.
|
||||
|
||||
it { should have_icmp_block_inversion_enabled }
|
||||
|
||||
### `have_masquerade_enabled`
|
||||
|
||||
`have_masquerade_enabled` returns true or false if the masquerade flag is set for the indicated zone.
|
||||
|
||||
it { should have_masquerade_enabled }
|
||||
|
|
|
@ -32,6 +32,17 @@ module Inspec::Resources
|
|||
.register_column(:interfaces, field: "interfaces")
|
||||
.register_column(:sources, field: "sources")
|
||||
.register_column(:services, field: "services")
|
||||
.register_column(:target, field: "target")
|
||||
.register_column(:ports, field: "ports")
|
||||
.register_column(:protocols, field: "protocols")
|
||||
.register_column(:forward_ports, field: "forward_ports")
|
||||
.register_column(:source_ports, field: "source_ports")
|
||||
.register_column(:icmp_blocks, field: "icmp_blocks")
|
||||
.register_column(:rich_rules, field: "rich_rules")
|
||||
.register_custom_matcher(:icmp_block_inversion?) { |x| x.params[0]["icmp_block_inversion"] }
|
||||
.register_custom_matcher(:has_icmp_block_inversion_enabled?) { |x| x.params[0]["icmp_block_inversion"] }
|
||||
.register_custom_matcher(:masquerade?) { |x| x.params[0]["masquerade"] }
|
||||
.register_custom_matcher(:has_masquerade_enabled?) { |x| x.params[0]["masquerade"] }
|
||||
|
||||
filter.install_filter_methods_on_resource(self, :params)
|
||||
|
||||
|
@ -64,28 +75,28 @@ module Inspec::Resources
|
|||
end
|
||||
|
||||
def has_service_enabled_in_zone?(query_service, query_zone = default_zone)
|
||||
firewalld_command("--zone=#{query_zone} --query-service=#{query_service}") == "yes"
|
||||
firewalld_command("--permanent --zone=#{query_zone} --query-service=#{query_service}") == "yes"
|
||||
end
|
||||
|
||||
def service_ports_enabled_in_zone(query_service, query_zone = default_zone)
|
||||
# return: String of ports open
|
||||
# example: ['22/tcp', '4722/tcp']
|
||||
firewalld_command("--zone=#{query_zone} --service=#{query_service} --get-ports --permanent").split(" ")
|
||||
firewalld_command("--permanent --zone=#{query_zone} --service=#{query_service} --get-ports").split(" ")
|
||||
end
|
||||
|
||||
def service_protocols_enabled_in_zone(query_service, query_zone = default_zone)
|
||||
# return: String of protocoals open
|
||||
# return: String of protocols open
|
||||
# example: ['icmp', 'ipv4', 'igmp']
|
||||
firewalld_command("--zone=#{query_zone} --service=#{query_service} --get-protocols --permanent").split(" ")
|
||||
firewalld_command("--permanent --zone=#{query_zone} --service=#{query_service} --get-protocols").split(" ")
|
||||
end
|
||||
|
||||
def has_port_enabled_in_zone?(query_port, query_zone = default_zone)
|
||||
firewalld_command("--zone=#{query_zone} --query-port=#{query_port}") == "yes"
|
||||
firewalld_command("--permanent --zone=#{query_zone} --query-port=#{query_port}") == "yes"
|
||||
end
|
||||
|
||||
def has_rule_enabled?(rule, query_zone = default_zone)
|
||||
rule = "rule #{rule}" unless rule.start_with?("rule")
|
||||
firewalld_command("--zone=#{query_zone} --query-rich-rule='#{rule}'") == "yes"
|
||||
firewalld_command("--permanent --zone=#{query_zone} --query-rich-rule='#{rule}'") == "yes"
|
||||
end
|
||||
|
||||
def to_s
|
||||
|
@ -120,19 +131,82 @@ module Inspec::Resources
|
|||
"interfaces" => line.split(":")[1].split(" "),
|
||||
"services" => services_bound(zone),
|
||||
"sources" => sources_bound(zone),
|
||||
"target" => target_bound(zone),
|
||||
"icmp_block_inversion" => icmp_block_inversion_bound?(zone),
|
||||
"ports" => ports_bound(zone),
|
||||
"protocols" => protocols_bound(zone),
|
||||
"masquerade" => masquerade_bound?(zone),
|
||||
"forward_ports" => forward_ports_bound(zone),
|
||||
"source_ports" => source_ports_bound(zone),
|
||||
"icmp_blocks" => icmp_blocks_bound(zone),
|
||||
"rich_rules" => rich_rules_bound(zone),
|
||||
}
|
||||
end
|
||||
|
||||
def target_bound(query_zone)
|
||||
# result: a target bound for the zone
|
||||
# example: 'DROP'
|
||||
firewalld_command("--permanent --zone=#{query_zone} --get-target").strip
|
||||
end
|
||||
|
||||
def icmp_block_inversion_bound?(query_zone)
|
||||
# result: true/false whether inversion of icmp blocks has been enabled for a zone
|
||||
# example: true
|
||||
firewalld_command("--permanent --zone=#{query_zone} --query-icmp-block-inversion") == "yes"
|
||||
end
|
||||
|
||||
def ports_bound(query_zone)
|
||||
# result: a list of ports bound for a zone
|
||||
# example: ['80/tcp', '443/tcp']
|
||||
firewalld_command("--permanent --zone=#{query_zone} --list-ports").split(" ")
|
||||
end
|
||||
|
||||
def protocols_bound(query_zone)
|
||||
# result: a list of protocols added for a zone
|
||||
# example: ['icmp', 'ipv4', 'igmp']
|
||||
firewalld_command("--permanent --zone=#{query_zone} --list-protocols").split(" ")
|
||||
end
|
||||
|
||||
def masquerade_bound?(query_zone)
|
||||
# result: true/false whether IPv4 masquerading has been enabled for a zone
|
||||
# example: true
|
||||
firewalld_command("--permanent --zone=#{query_zone} --query-masquerade") == "yes"
|
||||
end
|
||||
|
||||
def forward_ports_bound(query_zone)
|
||||
# result: a list of IPv4 forward ports bound to a zone
|
||||
# example: ['port=80:proto=tcp:toport=88', 'port=12345:proto=tcp:toport=54321:toaddr=192.168.1.3']
|
||||
firewalld_command("--permanent --zone=#{query_zone} --list-forward-ports").split("\n")
|
||||
end
|
||||
|
||||
def source_ports_bound(query_zone)
|
||||
# result: a list of source ports bound to a zone
|
||||
# example: ['80/tcp', '8080/tcp']
|
||||
firewalld_command("--permanent --zone=#{query_zone} --list-source-ports").split(" ")
|
||||
end
|
||||
|
||||
def icmp_blocks_bound(query_zone)
|
||||
# result: a list of internet ICMP type blocks bound to a zone
|
||||
# example: ['echo-request', 'echo-reply']
|
||||
firewalld_command("--permanent --zone=#{query_zone} --list-icmp-blocks").split(" ")
|
||||
end
|
||||
|
||||
def rich_rules_bound(query_zone)
|
||||
# result: a list of rich language rules bound to a zone
|
||||
# example: ['rule protocol value="ah" accept', 'rule service name="ftp" log limit value="1/m" audit accept']
|
||||
firewalld_command("--permanent --zone=#{query_zone} --list-rich-rules").split("\n")
|
||||
end
|
||||
|
||||
def sources_bound(query_zone)
|
||||
# result: a list containing either an ip address or ip address with a mask, or a ipset or an ipset with the ipset prefix.
|
||||
# example: ['192.168.0.4', '192.168.0.0/16', '2111:DB28:ABC:12::', '2111:db89:ab3d:0112::0/64']
|
||||
firewalld_command("--zone=#{query_zone} --list-sources").split(" ")
|
||||
firewalld_command("--permanent --zone=#{query_zone} --list-sources").split(" ")
|
||||
end
|
||||
|
||||
def services_bound(query_zone)
|
||||
# result: a list of services bound to a zone.
|
||||
# example: ['ssh', 'dhcpv6-client']
|
||||
firewalld_command("--zone=#{query_zone} --list-services").split(" ")
|
||||
firewalld_command("--permanent --zone=#{query_zone} --list-services").split(" ")
|
||||
end
|
||||
|
||||
def firewalld_command(command)
|
||||
|
@ -145,4 +219,4 @@ module Inspec::Resources
|
|||
result.stdout.strip
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
1
test/fixtures/cmd/firewall-cmd-get-target
vendored
Normal file
1
test/fixtures/cmd/firewall-cmd-get-target
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
default
|
2
test/fixtures/cmd/firewall-cmd-list-forward-ports
vendored
Normal file
2
test/fixtures/cmd/firewall-cmd-list-forward-ports
vendored
Normal file
|
@ -0,0 +1,2 @@
|
|||
port=80:proto=tcp:toport=88:toaddr=
|
||||
port=12345:proto=tcp:toport=54321:toaddr=192.168.1.3
|
1
test/fixtures/cmd/firewall-cmd-list-icmp-blocks
vendored
Normal file
1
test/fixtures/cmd/firewall-cmd-list-icmp-blocks
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
echo-request echo-reply
|
1
test/fixtures/cmd/firewall-cmd-list-ports
vendored
Normal file
1
test/fixtures/cmd/firewall-cmd-list-ports
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
80/tcp 443/tcp
|
1
test/fixtures/cmd/firewall-cmd-list-protocols
vendored
Normal file
1
test/fixtures/cmd/firewall-cmd-list-protocols
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
icmp ipv4
|
2
test/fixtures/cmd/firewall-cmd-list-rich-rules
vendored
Normal file
2
test/fixtures/cmd/firewall-cmd-list-rich-rules
vendored
Normal file
|
@ -0,0 +1,2 @@
|
|||
rule protocol value="ah" accept
|
||||
rule service name="ftp" log limit value="1/m" audit accept
|
1
test/fixtures/cmd/firewall-cmd-list-source-ports
vendored
Normal file
1
test/fixtures/cmd/firewall-cmd-list-source-ports
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
80/tcp 8080/tcp
|
1
test/fixtures/cmd/firewall-cmd-query-icmp-block-inversion
vendored
Normal file
1
test/fixtures/cmd/firewall-cmd-query-icmp-block-inversion
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
no
|
1
test/fixtures/cmd/firewall-cmd-query-masquerade
vendored
Normal file
1
test/fixtures/cmd/firewall-cmd-query-masquerade
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
no
|
|
@ -523,16 +523,25 @@ class MockLoader
|
|||
"firewall-cmd --get-default-zone" => cmd.call("firewall-cmd--get-default-zone"),
|
||||
"firewall-cmd --get-active-zones" => cmd.call("firewall-cmd--get-active-zones"),
|
||||
"firewall-cmd --state" => cmd.call("firewall-cmd--state"),
|
||||
"firewall-cmd --zone=public --query-service=ssh" => cmd.call("firewall-cmd--service-enabled-in-zone"),
|
||||
"firewall-cmd --zone=public --query-port=22/udp" => cmd.call("firewall-cmd-has-port-enabled-in-zone"),
|
||||
"firewall-cmd --zone=public --query-rich-rule='rule family=ipv4 source address=192.168.0.14 accept'" => cmd.call("firewall-cmd-has-rule-enabled"),
|
||||
"firewall-cmd --zone=public --service=ssh --get-ports --permanent" => cmd.call("firewall-cmd-service-ports-enabled-in-zone"),
|
||||
"firewall-cmd --zone=public --service=ssh --get-protocols --permanent" => cmd.call("firewall-cmd-service-protocols-enabled-in-zone"),
|
||||
"firewall-cmd --zone=public --list-services" => cmd.call("firewall-cmd-services-bound"),
|
||||
"firewall-cmd --zone=default --list-services" => cmd.call("firewall-cmd-services-bound"),
|
||||
"firewall-cmd --zone=public --list-sources" => cmd.call("firewall-cmd-sources-bound"),
|
||||
"firewall-cmd --zone=default --list-sources" => cmd.call("firewall-cmd-sources-bound"),
|
||||
"firewall-cmd --zone=public --query-rich-rule=rule family=ipv4 source address=192.168.0.14 accept" => cmd.call("firewall-cmd-has-rule-enabled"),
|
||||
"firewall-cmd --permanent --zone=public --query-service=ssh" => cmd.call("firewall-cmd--service-enabled-in-zone"),
|
||||
"firewall-cmd --permanent --zone=public --query-port=22/udp" => cmd.call("firewall-cmd-has-port-enabled-in-zone"),
|
||||
"firewall-cmd --permanent --zone=public --query-rich-rule='rule family=ipv4 source address=192.168.0.14 accept'" => cmd.call("firewall-cmd-has-rule-enabled"),
|
||||
"firewall-cmd --permanent --zone=public --service=ssh --get-ports" => cmd.call("firewall-cmd-service-ports-enabled-in-zone"),
|
||||
"firewall-cmd --permanent --zone=public --service=ssh --get-protocols" => cmd.call("firewall-cmd-service-protocols-enabled-in-zone"),
|
||||
"firewall-cmd --permanent --zone=public --list-services" => cmd.call("firewall-cmd-services-bound"),
|
||||
"firewall-cmd --permanent --zone=default --list-services" => cmd.call("firewall-cmd-services-bound"),
|
||||
"firewall-cmd --permanent --zone=public --list-sources" => cmd.call("firewall-cmd-sources-bound"),
|
||||
"firewall-cmd --permanent --zone=default --list-sources" => cmd.call("firewall-cmd-sources-bound"),
|
||||
"firewall-cmd --permanent --zone=public --get-target" => cmd.call("firewall-cmd-get-target"),
|
||||
"firewall-cmd --permanent --zone=public --query-icmp-block-inversion" => cmd.call("firewall-cmd-query-icmp-block-inversion"),
|
||||
"firewall-cmd --permanent --zone=public --list-ports" => cmd.call("firewall-cmd-list-ports"),
|
||||
"firewall-cmd --permanent --zone=public --list-protocols" => cmd.call("firewall-cmd-list-protocols"),
|
||||
"firewall-cmd --permanent --zone=public --query-masquerade" => cmd.call("firewall-cmd-query-masquerade"),
|
||||
"firewall-cmd --permanent --zone=public --list-forward-ports" => cmd.call("firewall-cmd-list-forward-ports"),
|
||||
"firewall-cmd --permanent --zone=public --list-source-ports" => cmd.call("firewall-cmd-list-source-ports"),
|
||||
"firewall-cmd --permanent --zone=public --list-icmp-blocks" => cmd.call("firewall-cmd-list-icmp-blocks"),
|
||||
"firewall-cmd --permanent --zone=public --list-rich-rules" => cmd.call("firewall-cmd-list-rich-rules"),
|
||||
"firewall-cmd --permanent --zone=public --query-rich-rule=rule family=ipv4 source address=192.168.0.14 accept" => cmd.call("firewall-cmd-has-rule-enabled"),
|
||||
"sh -c 'type \"firewall-cmd\"'" => cmd.call("firewall-cmd"),
|
||||
"rpm -qia firewalld" => cmd.call("pkg-info-firewalld"),
|
||||
"systemctl is-active sshd --quiet" => empty.call,
|
||||
|
|
|
@ -10,7 +10,7 @@ describe "Inspec::Resources::FirewallD" do
|
|||
_(cent_resource.has_zone?("zonenotinfirewalld")).must_equal false
|
||||
end
|
||||
|
||||
it "verity firewalld is running" do
|
||||
it "verify firewalld is running" do
|
||||
_(cent_resource.running?).must_equal true
|
||||
end
|
||||
|
||||
|
@ -40,6 +40,51 @@ describe "Inspec::Resources::FirewallD" do
|
|||
_(entries.sources).must_equal [["192.168.1.0/24", "192.168.1.2"]]
|
||||
end
|
||||
|
||||
it "detects target in an active zone" do
|
||||
entries = cent_resource.where { zone == "public" }
|
||||
_(entries.target).must_equal ["default"]
|
||||
end
|
||||
|
||||
it "detects whether ICMP block inversion is enabled in an active zone" do
|
||||
entries = cent_resource.where { zone == "public" }
|
||||
_(entries.icmp_block_inversion?).must_equal false
|
||||
end
|
||||
|
||||
it "detects ports in an active zone" do
|
||||
entries = cent_resource.where { zone == "public" }
|
||||
_(entries.ports).must_equal [["80/tcp", "443/tcp"]]
|
||||
end
|
||||
|
||||
it "detects protocols in an active zone" do
|
||||
entries = cent_resource.where { zone == "public" }
|
||||
_(entries.protocols).must_equal [%w{icmp ipv4}]
|
||||
end
|
||||
|
||||
it "detects whether IPv4 masquerading is enabled in an active zone" do
|
||||
entries = cent_resource.where { zone == "public" }
|
||||
_(entries.masquerade?).must_equal false
|
||||
end
|
||||
|
||||
it "detects IPv4 forward ports in an active zone" do
|
||||
entries = cent_resource.where { zone == "public" }
|
||||
_(entries.forward_ports).must_equal [["port=80:proto=tcp:toport=88:toaddr=", "port=12345:proto=tcp:toport=54321:toaddr=192.168.1.3"]]
|
||||
end
|
||||
|
||||
it "detects source ports in an active zone" do
|
||||
entries = cent_resource.where { zone == "public" }
|
||||
_(entries.source_ports).must_equal [["80/tcp", "8080/tcp"]]
|
||||
end
|
||||
|
||||
it "detects ICMP blocks in an active zone" do
|
||||
entries = cent_resource.where { zone == "public" }
|
||||
_(entries.icmp_blocks).must_equal [%w{echo-request echo-reply}]
|
||||
end
|
||||
|
||||
it "detects rich rules in an active zone" do
|
||||
entries = cent_resource.where { zone == "public" }
|
||||
_(entries.rich_rules).must_equal [["rule protocol value=\"ah\" accept", "rule service name=\"ftp\" log limit value=\"1/m\" audit accept"]]
|
||||
end
|
||||
|
||||
it "verify firewalld detects a whether or not a service is allowed in a zone" do
|
||||
_(cent_resource.has_service_enabled_in_zone?("ssh", "public")).must_equal true
|
||||
end
|
||||
|
@ -52,7 +97,7 @@ describe "Inspec::Resources::FirewallD" do
|
|||
_(cent_resource.service_protocols_enabled_in_zone("ssh", "public")).must_equal ["icmp"]
|
||||
end
|
||||
|
||||
it "verify firewalld detects a whether or not a service is allowed in a zone" do
|
||||
it "verify firewalld detects a whether or not a port is allowed in a zone" do
|
||||
_(cent_resource.has_port_enabled_in_zone?("22/udp", "public")).must_equal true
|
||||
end
|
||||
|
||||
|
|
Loading…
Reference in a new issue