Projet

Général

Profil

Révision 03d9e7da

ID03d9e7daab529101204acd9b22d888103860b545
Parent 9fe75e32
Enfant c3be15e0

Ajouté par Steve Traylen il y a plus de 4 ans

New parameter noflush_tables to selectivly skip flush

Introduces a new structured fact nftables

```yaml
nftables:
tables:
- inet-filter
- ip-nat
- ip6-nat
- inet-f2b-table
```

By default the nft script will continue to contain `nft flush ruleset`

If noflush_tables is specified e.g.

```puppet
class{nftables:
noflush_tables => ['inet-f2b-table'],
}
```
the results script will explicity flush the other tables only.
i.e.

```
flush table inet filter
flush table ip nat
flush table ip6 nat
```

Motivation here is to allow a maintence of chain to managed by something else.
This example for fail2ban but could be docker, ...

Voir les différences:

files/systemd/puppet_nft.conf
1
# Specify directory to look for relative includes
2
[Service]
3
ExecStart=
4
ExecStart=/sbin/nft -I /etc/nftables/puppet -f /etc/sysconfig/nftables.conf
5
ExecReload=
6
ExecReload=/sbin/nft -I /etc/nftables/puppet 'flush ruleset; include "/etc/sysconfig/nftables.conf";'
7

  
lib/facter/nftables.rb
1
#
2
# Produce an array of nftables.
3
# nft list tables
4
# table inet filter
5
# table ip nat
6
# table ip6 nat
7
# table inet f2b-table
8
#
9
Facter.add(:nftables) do
10
  @nft_cmd = Facter::Util::Resolution.which('nft')
11
  confine { @nft_cmd }
12

  
13
  setcode do
14
    tables = []
15
    table_result = Facter::Core::Execution.execute(%(#{@nft_cmd} list tables))
16
    table_result.each_line do |line|
17
      tables.push(line.split(' ')[1, 2].join('-'))
18
    end
19
    { 'tables' => tables }
20
  end
21
end
manifests/init.pp
1 1
# @summary Configure nftables
2 2
#
3
# @example
3
# @example allow dns out and do not allow ntp out
4 4
#   class{'nftables:
5 5
#     out_ntp = false,
6 6
#     out_dns = true,
7 7
#   }
8 8
#
9
# @example do not flush particular tables
10
# In this case ignoring the fail2ban maintained
11
# table
12
#   class{'nftables':
13
#     noflush_tables = ['inet-f2b-table'],
14
#   }
15
#
9 16
# @param out_all
10 17
#   Allow all outbound connections. If `true` then all other
11 18
#   out parameters `out_ntp`, `out_dns`, ... will be assuemed
......
64 71
#   useful to set this to false if you're externaly removing firewalld from
65 72
#   the system completely.
66 73
#
74
# @param noflush_tables
75
#   If specified only other existings tables will be flushed.
76
#   If left unset all tables will be flushed via a `flush ruleset`
77
#
67 78
class nftables (
68 79
  Boolean $in_ssh                = true,
69 80
  Boolean $in_icmp               = true,
......
85 96
    $reject_with                 = 'icmpx type port-unreachable',
86 97
  Variant[Boolean[false], Enum['mask']]
87 98
    $firewalld_enable            = 'mask',
99
  Optional[Array[Pattern[/^(ip|ip6|inet)-[-a-zA-Z0-9_]+$/],1]]
100
    $noflush_tables = undef,
88 101
) {
89 102

  
90 103
  package{'nftables':
......
107 120
      recurse => true;
108 121
    '/etc/nftables/puppet-preflight.nft':
109 122
      ensure  => file,
110
      content => epp('nftables/config/puppet.nft.epp', { 'nat' => $nat });
123
      content => epp('nftables/config/puppet.nft.epp', { 'nat' => $nat, 'noflush' => $noflush_tables });
111 124
  } ~> exec{
112 125
    'nft validate':
113 126
      refreshonly => true,
......
119 132
      mode  => '0640';
120 133
    '/etc/nftables/puppet.nft':
121 134
      ensure  => file,
122
      content => epp('nftables/config/puppet.nft.epp', { 'nat' => $nat });
135
      content => epp('nftables/config/puppet.nft.epp', { 'nat' => $nat, 'noflush' => $noflush_tables });
123 136
    '/etc/nftables/puppet':
124 137
      ensure  => directory,
125 138
      mode    => '0750',
......
134 147
  }
135 148

  
136 149
  systemd::dropin_file{'puppet_nft.conf':
137
    ensure => present,
138
    unit   => 'nftables.service',
139
    source => 'puppet:///modules/nftables/systemd/puppet_nft.conf',
140
    notify => Service['nftables'],
150
    ensure  => present,
151
    unit    => 'nftables.service',
152
    content => epp('nftables/systemd/puppet_nft.conf.epp', { 'noflush' => $noflush_tables }),
153
    notify  => Service['nftables'],
141 154
  }
142 155

  
143 156
  service{'firewalld':
spec/classes/nftables_spec.rb
167 167
          )
168 168
        }
169 169
      end
170

  
171
      context 'with with noflush_tables parameter' do
172
        let(:params) do
173
          {
174
            noflush_tables: ['inet-f2b-table'],
175
          }
176
        end
177

  
178
        context 'with no nftables fact' do
179
          it {
180
            is_expected.to contain_systemd__dropin_file('puppet_nft.conf')
181
              .with_content(%r{^ExecReload.*flush ruleset; include.*$})
182
          }
183
          it { is_expected.to contain_file('/etc/nftables/puppet-preflight.nft').with_content(%r{^flush ruleset$}) }
184
        end
185

  
186
        context 'with nftables fact matching' do
187
          let(:facts) do
188
            super().merge(nftables: { tables: ['inet-abc', 'inet-f2b-table'] })
189
          end
190

  
191
          it {
192
            is_expected.to contain_systemd__dropin_file('puppet_nft.conf')
193
              .with_content(%r{^ExecReload.*flush table inet abc; include.*$})
194
          }
195
          it {
196
            is_expected.to contain_file('/etc/nftables/puppet-preflight.nft')
197
              .with_content(%r{^flush table inet abc$})
198
          }
199
        end
200
        context 'with nftables fact not matching' do
201
          let(:facts) do
202
            super().merge(nftables: { tables: ['inet-abc', 'inet-ijk'] })
203
          end
204

  
205
          it {
206
            is_expected.to contain_systemd__dropin_file('puppet_nft.conf')
207
              .with_content(%r{^ExecReload.*flush table inet abc; flush table inet ijk; include.*$})
208
          }
209
          it {
210
            is_expected.to contain_file('/etc/nftables/puppet-preflight.nft')
211
              .with_content(%r{^flush table inet abc; flush table inet ijk$})
212
          }
213
        end
214
      end
170 215
    end
171 216
  end
172 217
end
spec/unit/facter/nftables_spec.rb
1
require 'spec_helper'
2

  
3
describe 'nftables' do
4
  before(:each) do
5
    Facter.clear
6
    Process.stubs(:uid).returns(0)
7
    Facter::Util::Resolution.stubs(:which).with('nft').returns('/usr/sbin/nft')
8
    Facter::Core::Execution.stubs(:execute).with('/usr/sbin/nft list tables').returns(nft_result)
9
  end
10

  
11
  context 'nft rules present' do
12
    let(:nft_result) { "table inet firewalld\ntable ip firewalld\n" }
13

  
14
    it 'returns valid tables' do
15
      expect(Facter.fact('nftables').value).to eq('tables' => ['inet-firewalld', 'ip-firewalld'])
16
    end
17
  end
18

  
19
  context 'nft fails' do
20
    let(:nft_result) { :failed }
21

  
22
    it 'does not return a fact' do
23
      Facter::Core::Execution.stubs(:execute).with('/usr/sbin/nft list tables', on_fail: :failed).returns(:failed)
24

  
25
      expect(Facter.fact('nftables').value).to be_nil
26
    end
27
  end
28
end
templates/config/puppet.nft.epp
1
<%- |
2
  Boolean $nat,
3
  Optional[Array[String[1],1]] $noflush = undef,
4
|-%>
5
<%-
6
if $noflush and $facts['nftables'] and $facts['nftables']['tables'] {
7
 $_flush_command = $facts['nftables']['tables'].filter |$_tab| { ! ($_tab in $noflush) }.map |$_table| {
8
   "flush table ${regsubst($_table,'-',' ')}"
9
 }
10
} else {
11
 $_flush_command = ['flush ruleset']
12
}
13
-%>
1 14
# puppet-preflight.nft is only used by puppet for validating new configs
2 15
# puppet.nft is real configuration that the nftables services uses.
3 16
# To process either the -I flag must be specified.
......
5 18
# nft -c -I /etc/nftables/puppet-preflight -f /etc/nftables/puppet-preflight.nft
6 19

  
7 20
# drop any existing nftables ruleset
8
flush ruleset
21
<%= $_flush_command.join('; ') %>
9 22

  
10 23
include "custom-*.nft"
11 24
include "inet-filter.nft"
templates/systemd/puppet_nft.conf.epp
1
<%- |
2
  Optional[Array[String[1]]] $noflush = undef,
3
| -%>
4
<%-
5
if $noflush and $facts['nftables'] and $facts['nftables']['tables'] {
6
 $_flush_command = $facts['nftables']['tables'].filter |$_tab| { !( $_tab in $noflush) }.map |$_table| {
7
     "flush table ${regsubst($_table,'-',' ')}"
8
 }
9
} else {
10
 $_flush_command = ['flush ruleset']
11
}
12
-%>
13
# Specify directory to look for relative includes
14
[Service]
15
ExecStart=
16
ExecStart=/sbin/nft -I /etc/nftables/puppet -f /etc/sysconfig/nftables.conf
17
ExecReload=
18
ExecReload=/sbin/nft -I /etc/nftables/puppet '<%= $_flush_command.join('; ') %>; include "/etc/sysconfig/nftables.conf";'
19

  

Formats disponibles : Unified diff