Projet

Général

Profil

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

root / spec / classes / nftables_spec.rb @ 3016d428

Historique | Voir | Annoter | Télécharger (11,7 ko)

1 c82b960a Steve Traylen
# frozen_string_literal: true
2
3 64134e4e tr
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 8842a597 Tim Meusel
      nft_path = case os_facts[:os]['family']
13
                 when 'Archlinux'
14
                   '/usr/bin/nft'
15
                 else
16
                   '/usr/sbin/nft'
17
                 end
18 008c95d7 Kienan Stewart
      nft_config = case os_facts[:os]['family']
19
                   when 'RedHat'
20
                     '/etc/sysconfig/nftables.conf'
21
                   else
22
                     '/etc/nftables.conf'
23
                   end
24 8842a597 Tim Meusel
25 0b7bcb5d mh
      nft_mode = case os_facts[:os]['family']
26
                 when 'RedHat'
27
                   '0600'
28
                 else
29
                   '0640'
30
                 end
31
32 8842a597 Tim Meusel
      it { is_expected.to compile.with_all_deps }
33 5acb554a tr
34
      it { is_expected.to contain_package('nftables') }
35
36 a528bf59 Steve Traylen
      context 'with clobber_default_config false' do
37
        let(:params) do
38
          { clobber_default_config: false }
39
        end
40
41
        it {
42
          is_expected.to contain_file_line('enable_nftables').with(
43
            line: 'include "/etc/nftables/puppet.nft"',
44
            path: nft_config
45
          )
46
        }
47
48
        it { is_expected.not_to contain_file(nft_config) }
49
      end
50
51
      context 'with clobber_default_config true' do
52
        let(:params) do
53
          { clobber_default_config: true }
54
        end
55
56
        it {
57
          is_expected.to contain_file(nft_config).with(
58
            ensure: 'file',
59
            content: %r{^include "/etc/nftables/puppet.nft"$},
60
            owner: 'root',
61
            group: 'root'
62
          )
63
        }
64
65
        it { is_expected.not_to contain_file_line('enable_nftables') }
66
      end
67
68 01d8a819 tr
      it {
69 0c9bc308 hashworks
        is_expected.to contain_file('/etc/nftables').with(
70
          ensure: 'directory',
71
          owner: 'root',
72
          group: 'root',
73 0b7bcb5d mh
          mode: nft_mode
74 0c9bc308 hashworks
        )
75
      }
76
77
      it {
78 c82b960a Steve Traylen
        expect(subject).to contain_file('/etc/nftables/puppet.nft').with(
79 01d8a819 tr
          ensure: 'file',
80 c82b960a Steve Traylen
          owner: 'root',
81
          group: 'root',
82 0b7bcb5d mh
          mode: nft_mode,
83 fa92e118 Romain Tartière
          content: %r{flush ruleset}
84 01d8a819 tr
        )
85
      }
86
87
      it {
88 331b8d85 Steve Traylen
        expect(subject).to contain_file('/etc/nftables/puppet.nft').with(
89
          content: %r{^include "file-\*\.nft"$}
90
        )
91
      }
92
93
      it {
94 c82b960a Steve Traylen
        expect(subject).to contain_file('/etc/nftables/puppet').with(
95
          ensure: 'directory',
96
          owner: 'root',
97
          group: 'root',
98 0b7bcb5d mh
          mode: nft_mode,
99 c82b960a Steve Traylen
          purge: true,
100
          force: true,
101 fa92e118 Romain Tartière
          recurse: true
102 01d8a819 tr
        )
103
      }
104
105
      it {
106 c82b960a Steve Traylen
        expect(subject).to contain_file('/etc/nftables/puppet-preflight.nft').with(
107 30462da1 Steve Traylen
          ensure: 'file',
108 c82b960a Steve Traylen
          owner: 'root',
109
          group: 'root',
110 0b7bcb5d mh
          mode: nft_mode,
111 fa92e118 Romain Tartière
          content: %r{flush ruleset}
112 30462da1 Steve Traylen
        )
113
      }
114
115
      it {
116 331b8d85 Steve Traylen
        expect(subject).to contain_file('/etc/nftables/puppet-preflight.nft').with(
117
          content: %r{^include "file-\*\.nft"$}
118
        )
119
      }
120
121
      it {
122 c82b960a Steve Traylen
        expect(subject).to contain_file('/etc/nftables/puppet-preflight').with(
123
          ensure: 'directory',
124
          owner: 'root',
125
          group: 'root',
126 0b7bcb5d mh
          mode: nft_mode,
127 c82b960a Steve Traylen
          purge: true,
128
          force: true,
129 fa92e118 Romain Tartière
          recurse: true
130 30462da1 Steve Traylen
        )
131
      }
132
133
      it {
134 3016d428 canihavethisone
        expect(subject).not_to contain_exec('nftables_memory_state_check')
135 0b1e3353 canihavethisone
      }
136
137
      it {
138 0b2ccdda canihavethisone
        expect(subject).not_to contain_exec('nftables_generate_hash')
139 0b1e3353 canihavethisone
      }
140
141
      it {
142
        expect(subject).not_to contain_file('/run/puppet-nft-memhash')
143
      }
144
145
      it {
146 c82b960a Steve Traylen
        expect(subject).to contain_exec('nft validate').with(
147 30462da1 Steve Traylen
          refreshonly: true,
148 8842a597 Tim Meusel
          command: %r{^#{nft_path} -I /etc/nftables/puppet-preflight -c -f /etc/nftables/puppet-preflight.nft.*}
149 30462da1 Steve Traylen
        )
150
      }
151
152
      it {
153 c82b960a Steve Traylen
        expect(subject).to contain_service('nftables').with(
154 01d8a819 tr
          ensure: 'running',
155
          enable: true,
156 30462da1 Steve Traylen
          hasrestart: true,
157 cc9fc807 Tim Meusel
          restart: %r{PATH=/usr/bin:/bin systemctl reload nft.*}
158 01d8a819 tr
        )
159
      }
160
161 008c95d7 Kienan Stewart
      it {
162
        expect(subject).to contain_systemd__dropin_file('puppet_nft.conf').with(
163
          content: %r{^ExecReload=#{nft_path} -I /etc/nftables/puppet -f #{nft_config}$}
164
        )
165
      }
166
167
      case os_facts[:os]['family']
168
      when 'Archlinux'
169 ce22630b Steve Traylen
170 0c9bc308 hashworks
        it {
171
          expect(subject).to contain_service('firewalld').with(
172
            ensure: 'stopped',
173
            enable: false
174
          )
175
        }
176 008c95d7 Kienan Stewart
      when 'Debian'
177 0c9bc308 hashworks
        it {
178 008c95d7 Kienan Stewart
          is_expected.to contain_service('firewalld').with(
179
            ensure: 'stopped',
180
            enable: false
181 0c9bc308 hashworks
          )
182
        }
183 008c95d7 Kienan Stewart
      else
184 0c9bc308 hashworks
        it {
185
          expect(subject).to contain_service('firewalld').with(
186
            ensure: 'stopped',
187
            enable: 'mask'
188
          )
189
        }
190
      end
191 c82b960a Steve Traylen
192 7b9d6ffc Nacho Barrientos
      it { is_expected.to contain_class('nftables::inet_filter') }
193
      it { is_expected.to contain_class('nftables::ip_nat') }
194 e17693e3 Steve Traylen
      it { is_expected.to contain_class('nftables::rules::out::http') }
195
      it { is_expected.to contain_class('nftables::rules::out::https') }
196
      it { is_expected.to contain_class('nftables::rules::out::dns') }
197
      it { is_expected.to contain_class('nftables::rules::out::chrony') }
198
      it { is_expected.not_to contain_class('nftables::rules::out::all') }
199
      it { is_expected.not_to contain_nftables__rule('default_out-all') }
200
201
      context 'with out_all set true' do
202 b171ac7f mh
        let(:params) do
203
          {
204
            out_all: true,
205
          }
206 e17693e3 Steve Traylen
        end
207
208
        it { is_expected.to contain_class('nftables::rules::out::all') }
209
        it { is_expected.not_to contain_class('nftables::rules::out::http') }
210
        it { is_expected.not_to contain_class('nftables::rules::out::https') }
211
        it { is_expected.not_to contain_class('nftables::rules::out::dns') }
212
        it { is_expected.not_to contain_class('nftables::rules::out::chrony') }
213
        it { is_expected.to contain_nftables__rule('default_out-all').with_content('accept') }
214
        it { is_expected.to contain_nftables__rule('default_out-all').with_order('90') }
215
      end
216 b3a7a6dd tr
217
      context 'with custom rules' do
218
        let(:params) do
219
          {
220
            rules: {
221
              'INPUT-web_accept' => {
222
                order: '50',
223
                content: 'iifname eth0 tcp dport { 80, 443 } accept',
224
              },
225
            },
226
          }
227
        end
228
229
        it {
230 c82b960a Steve Traylen
          expect(subject).to contain_concat__fragment('nftables-inet-filter-chain-INPUT-rule-web_accept').with(
231
            target: 'nftables-inet-filter-chain-INPUT',
232 b3a7a6dd tr
            content: %r{^  iifname eth0 tcp dport \{ 80, 443 \} accept$},
233 c82b960a Steve Traylen
            order: '50-nftables-inet-filter-chain-INPUT-rule-web_accept-b'
234 b3a7a6dd tr
          )
235
        }
236
      end
237 ae9872e2 Nacho Barrientos
238 802d80d1 Nacho Barrientos
      context 'with custom sets' do
239
        let(:params) do
240
          {
241
            sets: {
242
              'testset1' => {
243
                type: 'ipv4_addr',
244
                gc_interval: 2,
245
              },
246
              'testset2' => {
247
                type: 'ipv6_addr',
248
                elements: ['2a02:62:c601::dead:beef'],
249
              },
250
            },
251
          }
252
        end
253
254
        it {
255 c82b960a Steve Traylen
          expect(subject).to contain_nftables__set('testset1').with(
256 802d80d1 Nacho Barrientos
            type: 'ipv4_addr',
257
            gc_interval: 2,
258 fa92e118 Romain Tartière
            table: 'inet-filter'
259 802d80d1 Nacho Barrientos
          )
260
        }
261 c82b960a Steve Traylen
262 802d80d1 Nacho Barrientos
        it {
263 c82b960a Steve Traylen
          expect(subject).to contain_nftables__set('testset2').with(
264 802d80d1 Nacho Barrientos
            type: 'ipv6_addr',
265
            elements: ['2a02:62:c601::dead:beef'],
266 fa92e118 Romain Tartière
            table: 'inet-filter'
267 802d80d1 Nacho Barrientos
          )
268
        }
269
      end
270
271 ae9872e2 Nacho Barrientos
      context 'without masking firewalld' do
272
        let(:params) do
273
          {
274
            'firewalld_enable' => false,
275
          }
276
        end
277
278
        it {
279 c82b960a Steve Traylen
          expect(subject).to contain_service('firewalld').with(
280 ae9872e2 Nacho Barrientos
            ensure: 'stopped',
281 fa92e118 Romain Tartière
            enable: false
282 ae9872e2 Nacho Barrientos
          )
283
        }
284
      end
285 03d9e7da Steve Traylen
286 7b9d6ffc Nacho Barrientos
      context 'with no default filtering rules' do
287
        let(:params) do
288
          {
289
            'inet_filter' => false,
290
          }
291
        end
292
293
        it { is_expected.to contain_class('nftables::ip_nat') }
294
        it { is_expected.not_to contain_class('nftables::inet_filter') }
295
      end
296
297
      context 'with no default tables, chains or rules' do
298
        let(:params) do
299
          {
300
            'inet_filter' => false,
301
            'nat' => false,
302
          }
303
        end
304
305
        it { is_expected.not_to contain_class('nftables::ip_nat') }
306
        it { is_expected.not_to contain_class('nftables::inet_filter') }
307
        it { is_expected.to have_nftables__config_resource_count(0) }
308
        it { is_expected.to have_nftables__chain_resource_count(0) }
309
        it { is_expected.to have_nftables__rule_resource_count(0) }
310
        it { is_expected.to have_nftables__set_resource_count(0) }
311
      end
312
313 0b1e3353 canihavethisone
      context 'when purging unmanaged rules' do
314
        let(:params) do
315
          {
316
            'purge_unmanaged_rules' => true,
317
            'inmem_rules_hash_file' => '/foo/bar',
318
          }
319
        end
320
321
        it { is_expected.not_to contain_file('/foo/bar') }
322
        it {
323 3016d428 canihavethisone
          is_expected.to contain_exec('nftables_memory_state_check').with(
324 0b1e3353 canihavethisone
            command: %r{^echo "reloading nftables"$},
325
            notify: 'Service[nftables]',
326 0b2ccdda canihavethisone
            unless: %r{^/usr/bin/test -s /foo/bar -a "\$\(nft -s list ruleset \| sha1sum\)" = "\$\(cat /foo/bar\)"$}
327 0b1e3353 canihavethisone
          )
328
        }
329
        it {
330 0b2ccdda canihavethisone
          is_expected.to contain_exec('nftables_generate_hash').with(
331 0b1e3353 canihavethisone
            command: %r{^nft -s list ruleset \| sha1sum > /foo/bar$},
332
            subscribe: 'Service[nftables]',
333
            refreshonly: true,
334
          )
335
        }
336
      end
337
338 1fd3f550 Luis Fernández Álvarez
      %w[ip ip6 inet arp bridge netdev].each do |family|
339
        context "with noflush_tables parameter set to valid family #{family}" do
340
          let(:params) do
341
            {
342
              noflush_tables: ["#{family}-f2b-table"],
343
            }
344
          end
345 03d9e7da Steve Traylen
346 1fd3f550 Luis Fernández Álvarez
          context 'with no nftables fact' do
347
            it { is_expected.to contain_file('/etc/nftables/puppet-preflight.nft').with_content(%r{^flush ruleset$}) }
348 03d9e7da Steve Traylen
          end
349
350 1fd3f550 Luis Fernández Álvarez
          context 'with nftables fact matching' do
351
            let(:facts) do
352
              super().merge(nftables: { tables: %W[#{family}-abc #{family}-f2b-table] })
353
            end
354 c82b960a Steve Traylen
355 1fd3f550 Luis Fernández Álvarez
            it {
356
              expect(subject).to contain_file('/etc/nftables/puppet-preflight.nft').
357
                with_content(%r{^table #{family} abc \{\}$})
358
            }
359 c82b960a Steve Traylen
360 1fd3f550 Luis Fernández Álvarez
            it {
361
              expect(subject).to contain_file('/etc/nftables/puppet-preflight.nft').
362
                with_content(%r{^flush table #{family} abc$})
363
            }
364 03d9e7da Steve Traylen
          end
365
366 1fd3f550 Luis Fernández Álvarez
          context 'with nftables fact not matching' do
367
            let(:facts) do
368
              super().merge(nftables: { tables: %W[#{family}-abc #{family}-ijk] })
369
            end
370
371
            it {
372
              expect(subject).to contain_file('/etc/nftables/puppet-preflight.nft').
373
                with_content(%r{^table #{family} abc \{\}$})
374
            }
375
376
            it {
377
              expect(subject).to contain_file('/etc/nftables/puppet-preflight.nft').
378
                with_content(%r{^flush table #{family} abc$})
379
            }
380
381
            it {
382
              expect(subject).to contain_file('/etc/nftables/puppet-preflight.nft').
383
                with_content(%r{^table #{family} ijk \{\}$})
384
            }
385
386
            it {
387
              expect(subject).to contain_file('/etc/nftables/puppet-preflight.nft').
388
                with_content(%r{^flush table #{family} ijk$})
389
            }
390
          end
391
        end
392
      end
393 c82b960a Steve Traylen
394 1fd3f550 Luis Fernández Álvarez
      %w[it ip7 inter arpa brid netdevs].each do |family|
395
        context "with noflush_tables parameter set to invalid family #{family}" do
396
          let(:params) do
397
            {
398
              noflush_tables: ["#{family}-f2b-table"],
399
            }
400
          end
401 c82b960a Steve Traylen
402 1fd3f550 Luis Fernández Álvarez
          it { is_expected.not_to compile }
403 03d9e7da Steve Traylen
        end
404
      end
405 64134e4e tr
    end
406
  end
407
end