aboutsummaryrefslogtreecommitdiff
path: root/spec
diff options
context:
space:
mode:
Diffstat (limited to 'spec')
-rw-r--r--spec/acceptance/ferm_spec.rb92
-rw-r--r--spec/classes/ferm_spec.rb61
-rw-r--r--spec/defines/chain_spec.rb30
-rw-r--r--spec/defines/rule_spec.rb119
-rw-r--r--spec/spec_helper.rb5
5 files changed, 272 insertions, 35 deletions
diff --git a/spec/acceptance/ferm_spec.rb b/spec/acceptance/ferm_spec.rb
index 1b0f794..b0c41a5 100644
--- a/spec/acceptance/ferm_spec.rb
+++ b/spec/acceptance/ferm_spec.rb
@@ -12,27 +12,29 @@ manage_initfile = case sut_os
false
end
+basic_manifest = %(
+ class { 'ferm':
+ manage_service => true,
+ manage_configfile => true,
+ manage_initfile => #{manage_initfile}, # CentOS-6 does not provide init script
+ forward_policy => 'DROP',
+ output_policy => 'DROP',
+ input_policy => 'DROP',
+ rules => {
+ 'allow_acceptance_tests' => {
+ chain => 'INPUT',
+ action => 'ACCEPT',
+ proto => tcp,
+ dport => 22,
+ },
+ },
+ ip_versions => ['ip'], #only ipv4 available with CI
+ }
+)
+
describe 'ferm' do
context 'with basics settings' do
- pp = %(
- class { 'ferm':
- manage_service => true,
- manage_configfile => true,
- manage_initfile => #{manage_initfile}, # CentOS-6 does not provide init script
- forward_policy => 'DROP',
- output_policy => 'DROP',
- input_policy => 'DROP',
- rules => {
- 'allow acceptance_tests' => {
- chain => 'INPUT',
- policy => 'ACCEPT',
- proto => tcp,
- dport => 22,
- },
- },
- ip_versions => ['ip'], #only ipv4 available with CI
- }
- )
+ pp = basic_manifest
it 'works with no error' do
apply_manifest(pp, catch_failures: true)
@@ -54,7 +56,57 @@ describe 'ferm' do
end
describe iptables do
- it { is_expected.to have_rule('-A INPUT -p tcp -m comment --comment "allow acceptance_tests" -m tcp --dport 22 -j ACCEPT').with_table('filter').with_chain('INPUT') }
+ it do
+ is_expected.to have_rule('-A INPUT -p tcp -m comment --comment ["]*allow_acceptance_tests["]* -m tcp --dport 22 -j ACCEPT'). \
+ with_table('filter'). \
+ with_chain('INPUT')
+ end
+ end
+
+ context 'with custom chains' do
+ advanced_manifest = %(
+ ferm::chain { 'check-http':
+ chain => 'HTTP',
+ disable_conntrack => true,
+ log_dropped_packets => false,
+ }
+ ferm::rule { 'jump_http':
+ chain => 'INPUT',
+ action => 'HTTP',
+ proto => 'tcp',
+ dport => '80',
+ require => Ferm::Chain['check-http'],
+ }
+ ferm::rule { 'allow_http_localhost':
+ chain => 'HTTP',
+ action => 'ACCEPT',
+ proto => 'tcp',
+ dport => '80',
+ saddr => '127.0.0.1',
+ require => Ferm::Chain['check-http'],
+ }
+ )
+ pp = [basic_manifest, advanced_manifest].join("\n")
+
+ it 'works with no error' do
+ apply_manifest(pp, catch_failures: true)
+ end
+ it 'works idempotently' do
+ apply_manifest(pp, catch_changes: true)
+ end
+
+ describe iptables do
+ it do
+ is_expected.to have_rule('-A INPUT -p tcp -m comment --comment ["]*jump_http["]* -m tcp --dport 80 -j HTTP'). \
+ with_table('filter'). \
+ with_chain('INPUT')
+ end
+ it do
+ is_expected.to have_rule('-A HTTP -s 127.0.0.1/32 -p tcp -m comment --comment ["]*allow_http_localhost["]* -m tcp --dport 80 -j ACCEPT'). \
+ with_table('filter'). \
+ with_chain('HTTP')
+ end
+ end
end
end
end
diff --git a/spec/classes/ferm_spec.rb b/spec/classes/ferm_spec.rb
index e5669b8..225577b 100644
--- a/spec/classes/ferm_spec.rb
+++ b/spec/classes/ferm_spec.rb
@@ -64,6 +64,17 @@ describe 'ferm' do
is_expected.to contain_concat__fragment('ferm.conf'). \
without_content(%r{@preserve;})
end
+ it { is_expected.to contain_concat__fragment('raw-PREROUTING-config-include') }
+ it { is_expected.to contain_concat__fragment('raw-OUTPUT-config-include') }
+ it { is_expected.to contain_concat__fragment('nat-PREROUTING-config-include') }
+ it { is_expected.to contain_concat__fragment('nat-INPUT-config-include') }
+ it { is_expected.to contain_concat__fragment('nat-OUTPUT-config-include') }
+ it { is_expected.to contain_concat__fragment('nat-POSTROUTING-config-include') }
+ it { is_expected.to contain_concat__fragment('mangle-PREROUTING-config-include') }
+ it { is_expected.to contain_concat__fragment('mangle-INPUT-config-include') }
+ it { is_expected.to contain_concat__fragment('mangle-FORWARD-config-include') }
+ it { is_expected.to contain_concat__fragment('mangle-OUTPUT-config-include') }
+ it { is_expected.to contain_concat__fragment('mangle-POSTROUTING-config-include') }
end
context 'with managed initfile' do
let :params do
@@ -77,18 +88,62 @@ describe 'ferm' do
end
end
context 'it creates chains' do
- it { is_expected.to contain_concat__fragment('FORWARD-policy') }
- it { is_expected.to contain_concat__fragment('INPUT-policy') }
- it { is_expected.to contain_concat__fragment('OUTPUT-policy') }
+ it { is_expected.to contain_concat__fragment('raw-PREROUTING-policy') }
+ it { is_expected.to contain_concat__fragment('raw-OUTPUT-policy') }
+ it { is_expected.to contain_concat__fragment('nat-PREROUTING-policy') }
+ it { is_expected.to contain_concat__fragment('nat-INPUT-policy') }
+ it { is_expected.to contain_concat__fragment('nat-OUTPUT-policy') }
+ it { is_expected.to contain_concat__fragment('nat-POSTROUTING-policy') }
+ it { is_expected.to contain_concat__fragment('mangle-PREROUTING-policy') }
+ it { is_expected.to contain_concat__fragment('mangle-INPUT-policy') }
+ it { is_expected.to contain_concat__fragment('mangle-FORWARD-policy') }
+ it { is_expected.to contain_concat__fragment('mangle-OUTPUT-policy') }
+ it { is_expected.to contain_concat__fragment('mangle-POSTROUTING-policy') }
+ it { is_expected.to contain_concat__fragment('filter-INPUT-policy') }
+ it { is_expected.to contain_concat__fragment('filter-FORWARD-policy') }
+ it { is_expected.to contain_concat__fragment('filter-OUTPUT-policy') }
if facts[:os]['release']['major'].to_i == 10
+ it { is_expected.to contain_concat('/etc/ferm/ferm.d/chains/raw-PREROUTING.conf') }
+ it { is_expected.to contain_concat('/etc/ferm/ferm.d/chains/raw-OUTPUT.conf') }
+ it { is_expected.to contain_concat('/etc/ferm/ferm.d/chains/nat-PREROUTING.conf') }
+ it { is_expected.to contain_concat('/etc/ferm/ferm.d/chains/nat-INPUT.conf') }
+ it { is_expected.to contain_concat('/etc/ferm/ferm.d/chains/nat-OUTPUT.conf') }
+ it { is_expected.to contain_concat('/etc/ferm/ferm.d/chains/nat-POSTROUTING.conf') }
+ it { is_expected.to contain_concat('/etc/ferm/ferm.d/chains/mangle-PREROUTING.conf') }
+ it { is_expected.to contain_concat('/etc/ferm/ferm.d/chains/mangle-INPUT.conf') }
+ it { is_expected.to contain_concat('/etc/ferm/ferm.d/chains/mangle-FORWARD.conf') }
+ it { is_expected.to contain_concat('/etc/ferm/ferm.d/chains/mangle-OUTPUT.conf') }
+ it { is_expected.to contain_concat('/etc/ferm/ferm.d/chains/mangle-POSTROUTING.conf') }
it { is_expected.to contain_concat('/etc/ferm/ferm.d/chains/FORWARD.conf') }
it { is_expected.to contain_concat('/etc/ferm/ferm.d/chains/INPUT.conf') }
it { is_expected.to contain_concat('/etc/ferm/ferm.d/chains/OUTPUT.conf') }
else
+ it { is_expected.to contain_concat('/etc/ferm.d/chains/raw-PREROUTING.conf') }
+ it { is_expected.to contain_concat('/etc/ferm.d/chains/raw-OUTPUT.conf') }
+ it { is_expected.to contain_concat('/etc/ferm.d/chains/nat-PREROUTING.conf') }
+ it { is_expected.to contain_concat('/etc/ferm.d/chains/nat-INPUT.conf') }
+ it { is_expected.to contain_concat('/etc/ferm.d/chains/nat-OUTPUT.conf') }
+ it { is_expected.to contain_concat('/etc/ferm.d/chains/nat-POSTROUTING.conf') }
+ it { is_expected.to contain_concat('/etc/ferm.d/chains/mangle-PREROUTING.conf') }
+ it { is_expected.to contain_concat('/etc/ferm.d/chains/mangle-INPUT.conf') }
+ it { is_expected.to contain_concat('/etc/ferm.d/chains/mangle-FORWARD.conf') }
+ it { is_expected.to contain_concat('/etc/ferm.d/chains/mangle-OUTPUT.conf') }
+ it { is_expected.to contain_concat('/etc/ferm.d/chains/mangle-POSTROUTING.conf') }
it { is_expected.to contain_concat('/etc/ferm.d/chains/FORWARD.conf') }
it { is_expected.to contain_concat('/etc/ferm.d/chains/INPUT.conf') }
it { is_expected.to contain_concat('/etc/ferm.d/chains/OUTPUT.conf') }
end
+ it { is_expected.to contain_ferm__chain('raw-PREROUTING') }
+ it { is_expected.to contain_ferm__chain('raw-OUTPUT') }
+ it { is_expected.to contain_ferm__chain('nat-PREROUTING') }
+ it { is_expected.to contain_ferm__chain('nat-INPUT') }
+ it { is_expected.to contain_ferm__chain('nat-OUTPUT') }
+ it { is_expected.to contain_ferm__chain('nat-POSTROUTING') }
+ it { is_expected.to contain_ferm__chain('mangle-PREROUTING') }
+ it { is_expected.to contain_ferm__chain('mangle-INPUT') }
+ it { is_expected.to contain_ferm__chain('mangle-FORWARD') }
+ it { is_expected.to contain_ferm__chain('mangle-OUTPUT') }
+ it { is_expected.to contain_ferm__chain('mangle-POSTROUTING') }
it { is_expected.to contain_ferm__chain('FORWARD') }
it { is_expected.to contain_ferm__chain('OUTPUT') }
it { is_expected.to contain_ferm__chain('INPUT') }
diff --git a/spec/defines/chain_spec.rb b/spec/defines/chain_spec.rb
index 9425821..4a598b3 100644
--- a/spec/defines/chain_spec.rb
+++ b/spec/defines/chain_spec.rb
@@ -15,25 +15,25 @@ describe 'ferm::chain', type: :define do
context 'default params creates INPUT2 chain' do
let :params do
{
- policy: 'DROP',
disable_conntrack: false,
log_dropped_packets: true
}
end
it { is_expected.to compile.with_all_deps }
+ it { is_expected.to contain_concat__fragment('filter-INPUT2-config-include') }
it do
- is_expected.to contain_concat__fragment('INPUT2-policy'). \
+ is_expected.to contain_concat__fragment('filter-INPUT2-policy'). \
with_content(%r{ESTABLISHED RELATED})
end
it do
- is_expected.to contain_concat__fragment('INPUT2-footer'). \
+ is_expected.to contain_concat__fragment('filter-INPUT2-footer'). \
with_content(%r{LOG log-prefix 'INPUT2: ';})
end
if facts[:os]['release']['major'].to_i == 10
- it { is_expected.to contain_concat('/etc/ferm/ferm.d/chains/INPUT2.conf') }
+ it { is_expected.to contain_concat('/etc/ferm/ferm.d/chains/filter-INPUT2.conf') }
else
- it { is_expected.to contain_concat('/etc/ferm.d/chains/INPUT2.conf') }
+ it { is_expected.to contain_concat('/etc/ferm.d/chains/filter-INPUT2.conf') }
end
it { is_expected.to contain_ferm__chain('INPUT2') }
end
@@ -41,7 +41,6 @@ describe 'ferm::chain', type: :define do
context 'without conntrack' do
let :params do
{
- policy: 'DROP',
disable_conntrack: true,
log_dropped_packets: false
}
@@ -49,15 +48,28 @@ describe 'ferm::chain', type: :define do
it { is_expected.to compile.with_all_deps }
it do
- is_expected.to contain_concat__fragment('INPUT2-policy')
- is_expected.not_to contain_concat__fragment('INPUT2-policy'). \
+ is_expected.to contain_concat__fragment('filter-INPUT2-policy')
+ is_expected.not_to contain_concat__fragment('filter-INPUT2-policy'). \
with_content(%r{ESTABLISHED RELATED})
end
it do
- is_expected.not_to contain_concat__fragment('INPUT2-footer'). \
+ is_expected.not_to contain_concat__fragment('filter-INPUT2-footer'). \
with_content(%r{LOG log-prefix 'INPUT2: ';})
end
end
+
+ context 'with policy setting for custom chain' do
+ let :params do
+ {
+ chain: 'INPUT2',
+ policy: 'DROP',
+ disable_conntrack: true,
+ log_dropped_packets: false
+ }
+ end
+
+ it { is_expected.to compile.and_raise_error(%r{Can only set a default policy for builtin chains}) }
+ end
end
end
end
diff --git a/spec/defines/rule_spec.rb b/spec/defines/rule_spec.rb
index 1bec758..ef20e17 100644
--- a/spec/defines/rule_spec.rb
+++ b/spec/defines/rule_spec.rb
@@ -11,7 +11,37 @@ describe 'ferm::rule', type: :define do
'include ferm'
end
- context 'without a specific interface' do
+ context 'without policy or action' do
+ let(:title) { 'filter-ssh' }
+ let :params do
+ {
+ chain: 'INPUT',
+ proto: 'tcp',
+ dport: '22',
+ saddr: '127.0.0.1'
+ }
+ end
+
+ it { is_expected.to compile.and_raise_error(%r{Exactly one of "action" or the deprecated "policy" param is required}) }
+ end
+
+ context 'with both policy and action' do
+ let(:title) { 'filter-ssh' }
+ let :params do
+ {
+ chain: 'INPUT',
+ policy: 'ACCEPT',
+ action: 'ACCEPT',
+ proto: 'tcp',
+ dport: '22',
+ saddr: '127.0.0.1'
+ }
+ end
+
+ it { is_expected.to compile.and_raise_error(%r{Cannot specify both policy and action}) }
+ end
+
+ context 'without a specific interface using legacy policy param' do
let(:title) { 'filter-ssh' }
let :params do
{
@@ -26,12 +56,32 @@ describe 'ferm::rule', type: :define do
it { is_expected.to compile.with_all_deps }
it { is_expected.to contain_concat__fragment('INPUT-filter-ssh').with_content("mod comment comment 'filter-ssh' proto tcp dport 22 saddr @ipfilter((127.0.0.1)) ACCEPT;\n") }
end
+
+ context 'without a specific interface' do
+ let(:title) { 'filter-ssh' }
+ let :params do
+ {
+ chain: 'INPUT',
+ action: 'ACCEPT',
+ proto: 'tcp',
+ dport: '22',
+ saddr: '127.0.0.1'
+ }
+ end
+
+ it { is_expected.to compile.with_all_deps }
+ it { is_expected.to contain_concat__fragment('INPUT-filter-ssh').with_content("mod comment comment 'filter-ssh' proto tcp dport 22 saddr @ipfilter((127.0.0.1)) ACCEPT;\n") }
+ it { is_expected.to contain_concat__fragment('filter-INPUT-config-include') }
+ it { is_expected.to contain_concat__fragment('filter-FORWARD-config-include') }
+ it { is_expected.to contain_concat__fragment('filter-OUTPUT-config-include') }
+ end
+
context 'with a specific interface' do
let(:title) { 'filter-ssh' }
let :params do
{
chain: 'INPUT',
- policy: 'ACCEPT',
+ action: 'ACCEPT',
proto: 'tcp',
dport: '22',
saddr: '127.0.0.1',
@@ -44,12 +94,13 @@ describe 'ferm::rule', type: :define do
it { is_expected.to contain_concat__fragment('INPUT-eth0-aaa').with_content("interface eth0 {\n") }
it { is_expected.to contain_concat__fragment('INPUT-eth0-zzz').with_content("}\n") }
end
+
context 'with a specific interface using array for daddr' do
let(:title) { 'filter-ssh' }
let :params do
{
chain: 'INPUT',
- policy: 'ACCEPT',
+ action: 'ACCEPT',
proto: 'tcp',
dport: '22',
daddr: ['127.0.0.1', '123.123.123.123', ['10.0.0.1', '10.0.0.2']],
@@ -62,6 +113,68 @@ describe 'ferm::rule', type: :define do
it { is_expected.to contain_concat__fragment('INPUT-eth0-aaa').with_content("interface eth0 {\n") }
it { is_expected.to contain_concat__fragment('INPUT-eth0-zzz').with_content("}\n") }
end
+
+ context 'with jumping to custom chains' do
+ # create custom chain
+ let(:pre_condition) do
+ 'include ferm ;
+ ferm::chain{"check-ssh":
+ chain => "SSH",
+ disable_conntrack => true,
+ log_dropped_packets => false,
+ }'
+ end
+ let(:title) { 'filter-ssh' }
+ let :params do
+ {
+ chain: 'INPUT',
+ action: 'SSH',
+ proto: 'tcp',
+ dport: '22'
+ }
+ end
+
+ it { is_expected.to compile.with_all_deps }
+ it { is_expected.to contain_concat__fragment('filter-SSH-policy') }
+ it do
+ is_expected.to contain_concat__fragment('INPUT-filter-ssh').\
+ with_content("mod comment comment 'filter-ssh' proto tcp dport 22 jump SSH;\n"). \
+ that_requires('Ferm::Chain[check-ssh]')
+ end
+ it { is_expected.to contain_concat__fragment('filter-INPUT-config-include') }
+ if facts[:os]['release']['major'].to_i == 10
+ it { is_expected.to contain_concat('/etc/ferm/ferm.d/chains/filter-SSH.conf') }
+ else
+ it { is_expected.to contain_concat('/etc/ferm.d/chains/filter-SSH.conf') }
+ end
+ end
+
+ context 'definining rules in custom chains' do
+ # create custom chain
+ let(:pre_condition) do
+ 'include ferm ;
+ ferm::chain{"check-ssh":
+ chain => "SSH",
+ disable_conntrack => true,
+ log_dropped_packets => false,
+ }'
+ end
+ let(:title) { 'allow-ssh-localhost' }
+ let :params do
+ {
+ chain: 'SSH',
+ action: 'ACCEPT',
+ proto: 'tcp',
+ dport: '22',
+ saddr: '127.0.0.1'
+ }
+ end
+
+ it { is_expected.to compile.with_all_deps }
+ it { is_expected.to contain_concat__fragment('SSH-allow-ssh-localhost').with_content("mod comment comment 'allow-ssh-localhost' proto tcp dport 22 saddr @ipfilter((127.0.0.1)) ACCEPT;\n") }
+ it { is_expected.to contain_concat__fragment('filter-INPUT-config-include') }
+ it { is_expected.to contain_concat__fragment('filter-SSH-config-include') }
+ end
end
end
end
diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb
index f16fb15..96f14d5 100644
--- a/spec/spec_helper.rb
+++ b/spec/spec_helper.rb
@@ -10,6 +10,11 @@ require 'rspec-puppet-facts'
require 'bundler'
include RspecPuppetFacts
+if ENV['DEBUG']
+ Puppet::Util::Log.level = :debug
+ Puppet::Util::Log.newdestination(:console)
+end
+
if File.exist?(File.join(__dir__, 'default_module_facts.yml'))
facts = YAML.load(File.read(File.join(__dir__, 'default_module_facts.yml')))
if facts