Projet

Général

Profil

Paste
Télécharger au format
Statistiques
| Branche: | Révision:

root / spec / classes / nftables_spec.rb @ 435a5db2

Historique | Voir | Annoter | Télécharger (8,32 ko)

1
# frozen_string_literal: true
2

    
3
require 'spec_helper'
4

    
5
describe 'nftables' do
6
  let(:pre_condition) { 'Exec{path => "/bin"}' }
7

    
8
  on_supported_os.each do |os, os_facts|
9
    context "on #{os}" do
10
      let(:facts) { os_facts }
11

    
12
      it { is_expected.to compile }
13

    
14
      it { is_expected.to contain_package('nftables') }
15

    
16
      it {
17
        is_expected.to contain_file('/etc/nftables').with(
18
          ensure: 'directory',
19
          owner: 'root',
20
          group: 'root',
21
          mode: '0750'
22
        )
23
      }
24

    
25
      it {
26
        expect(subject).to contain_file('/etc/nftables/puppet.nft').with(
27
          ensure: 'file',
28
          owner: 'root',
29
          group: 'root',
30
          mode: '0640',
31
          content: %r{flush ruleset}
32
        )
33
      }
34

    
35
      it {
36
        expect(subject).to contain_file('/etc/nftables/puppet').with(
37
          ensure: 'directory',
38
          owner: 'root',
39
          group: 'root',
40
          mode: '0750',
41
          purge: true,
42
          force: true,
43
          recurse: true
44
        )
45
      }
46

    
47
      it {
48
        expect(subject).to contain_file('/etc/nftables/puppet-preflight.nft').with(
49
          ensure: 'file',
50
          owner: 'root',
51
          group: 'root',
52
          mode: '0640',
53
          content: %r{flush ruleset}
54
        )
55
      }
56

    
57
      it {
58
        expect(subject).to contain_file('/etc/nftables/puppet-preflight').with(
59
          ensure: 'directory',
60
          owner: 'root',
61
          group: 'root',
62
          mode: '0750',
63
          purge: true,
64
          force: true,
65
          recurse: true
66
        )
67
      }
68

    
69
      it {
70
        expect(subject).to contain_exec('nft validate').with(
71
          refreshonly: true,
72
          command: %r{^/usr/sbin/nft -I /etc/nftables/puppet-preflight -c -f /etc/nftables/puppet-preflight.nft.*}
73
        )
74
      }
75

    
76
      it {
77
        expect(subject).to contain_service('nftables').with(
78
          ensure: 'running',
79
          enable: true,
80
          hasrestart: true,
81
          restart: %r{/usr/bin/systemctl reload nft.*}
82
        )
83
      }
84

    
85
      if os_facts[:os]['family'] == 'Archlinux'
86
        it {
87
          expect(subject).to contain_systemd__dropin_file('puppet_nft.conf').with(
88
            content: %r{^ExecReload=/sbin/nft -I /etc/nftables/puppet -f /etc/nftables.conf$}
89
          )
90
        }
91

    
92
        it {
93
          expect(subject).to contain_service('firewalld').with(
94
            ensure: 'stopped',
95
            enable: false
96
          )
97
        }
98
      else
99
        it {
100
          expect(subject).to contain_systemd__dropin_file('puppet_nft.conf').with(
101
            content: %r{^ExecReload=/sbin/nft -I /etc/nftables/puppet -f /etc/sysconfig/nftables.conf$}
102
          )
103
        }
104

    
105
        it {
106
          expect(subject).to contain_service('firewalld').with(
107
            ensure: 'stopped',
108
            enable: 'mask'
109
          )
110
        }
111
      end
112

    
113
      it { is_expected.to contain_class('nftables::inet_filter') }
114
      it { is_expected.to contain_class('nftables::ip_nat') }
115
      it { is_expected.to contain_class('nftables::rules::out::http') }
116
      it { is_expected.to contain_class('nftables::rules::out::https') }
117
      it { is_expected.to contain_class('nftables::rules::out::dns') }
118
      it { is_expected.to contain_class('nftables::rules::out::chrony') }
119
      it { is_expected.not_to contain_class('nftables::rules::out::all') }
120
      it { is_expected.not_to contain_nftables__rule('default_out-all') }
121

    
122
      context 'with out_all set true' do
123
        let(:params) do
124
          {
125
            out_all: true,
126
          }
127
        end
128

    
129
        it { is_expected.to contain_class('nftables::rules::out::all') }
130
        it { is_expected.not_to contain_class('nftables::rules::out::http') }
131
        it { is_expected.not_to contain_class('nftables::rules::out::https') }
132
        it { is_expected.not_to contain_class('nftables::rules::out::dns') }
133
        it { is_expected.not_to contain_class('nftables::rules::out::chrony') }
134
        it { is_expected.to contain_nftables__rule('default_out-all').with_content('accept') }
135
        it { is_expected.to contain_nftables__rule('default_out-all').with_order('90') }
136
      end
137

    
138
      context 'with custom rules' do
139
        let(:params) do
140
          {
141
            rules: {
142
              'INPUT-web_accept' => {
143
                order: '50',
144
                content: 'iifname eth0 tcp dport { 80, 443 } accept',
145
              },
146
            },
147
          }
148
        end
149

    
150
        it {
151
          expect(subject).to contain_concat__fragment('nftables-inet-filter-chain-INPUT-rule-web_accept').with(
152
            target: 'nftables-inet-filter-chain-INPUT',
153
            content: %r{^  iifname eth0 tcp dport \{ 80, 443 \} accept$},
154
            order: '50-nftables-inet-filter-chain-INPUT-rule-web_accept-b'
155
          )
156
        }
157
      end
158

    
159
      context 'with custom sets' do
160
        let(:params) do
161
          {
162
            sets: {
163
              'testset1' => {
164
                type: 'ipv4_addr',
165
                gc_interval: 2,
166
              },
167
              'testset2' => {
168
                type: 'ipv6_addr',
169
                elements: ['2a02:62:c601::dead:beef'],
170
              },
171
            },
172
          }
173
        end
174

    
175
        it {
176
          expect(subject).to contain_nftables__set('testset1').with(
177
            type: 'ipv4_addr',
178
            gc_interval: 2,
179
            table: 'inet-filter'
180
          )
181
        }
182

    
183
        it {
184
          expect(subject).to contain_nftables__set('testset2').with(
185
            type: 'ipv6_addr',
186
            elements: ['2a02:62:c601::dead:beef'],
187
            table: 'inet-filter'
188
          )
189
        }
190
      end
191

    
192
      context 'without masking firewalld' do
193
        let(:params) do
194
          {
195
            'firewalld_enable' => false,
196
          }
197
        end
198

    
199
        it {
200
          expect(subject).to contain_service('firewalld').with(
201
            ensure: 'stopped',
202
            enable: false
203
          )
204
        }
205
      end
206

    
207
      context 'with no default filtering rules' do
208
        let(:params) do
209
          {
210
            'inet_filter' => false,
211
          }
212
        end
213

    
214
        it { is_expected.to contain_class('nftables::ip_nat') }
215
        it { is_expected.not_to contain_class('nftables::inet_filter') }
216
      end
217

    
218
      context 'with no default tables, chains or rules' do
219
        let(:params) do
220
          {
221
            'inet_filter' => false,
222
            'nat' => false,
223
          }
224
        end
225

    
226
        it { is_expected.not_to contain_class('nftables::ip_nat') }
227
        it { is_expected.not_to contain_class('nftables::inet_filter') }
228
        it { is_expected.to have_nftables__config_resource_count(0) }
229
        it { is_expected.to have_nftables__chain_resource_count(0) }
230
        it { is_expected.to have_nftables__rule_resource_count(0) }
231
        it { is_expected.to have_nftables__set_resource_count(0) }
232
      end
233

    
234
      context 'with with noflush_tables parameter' do
235
        let(:params) do
236
          {
237
            noflush_tables: ['inet-f2b-table'],
238
          }
239
        end
240

    
241
        context 'with no nftables fact' do
242
          it { is_expected.to contain_file('/etc/nftables/puppet-preflight.nft').with_content(%r{^flush ruleset$}) }
243
        end
244

    
245
        context 'with nftables fact matching' do
246
          let(:facts) do
247
            super().merge(nftables: { tables: %w[inet-abc inet-f2b-table] })
248
          end
249

    
250
          it {
251
            expect(subject).to contain_file('/etc/nftables/puppet-preflight.nft').
252
              with_content(%r{^table inet abc \{\}$})
253
          }
254

    
255
          it {
256
            expect(subject).to contain_file('/etc/nftables/puppet-preflight.nft').
257
              with_content(%r{^flush table inet abc$})
258
          }
259
        end
260

    
261
        context 'with nftables fact not matching' do
262
          let(:facts) do
263
            super().merge(nftables: { tables: %w[inet-abc inet-ijk] })
264
          end
265

    
266
          it {
267
            expect(subject).to contain_file('/etc/nftables/puppet-preflight.nft').
268
              with_content(%r{^table inet abc \{\}$})
269
          }
270

    
271
          it {
272
            expect(subject).to contain_file('/etc/nftables/puppet-preflight.nft').
273
              with_content(%r{^flush table inet abc$})
274
          }
275

    
276
          it {
277
            expect(subject).to contain_file('/etc/nftables/puppet-preflight.nft').
278
              with_content(%r{^table inet ijk \{\}$})
279
          }
280

    
281
          it {
282
            expect(subject).to contain_file('/etc/nftables/puppet-preflight.nft').
283
              with_content(%r{^flush table inet ijk$})
284
          }
285
        end
286
      end
287
    end
288
  end
289
end