Puppet Class: nftables

Summary

Configure nftables

Overview

Examples:

allow dns out and do not allow ntp out

class{ 'nftables':
  out_ntp => false,
  out_dns => true,
}

do not flush particular tables, fail2ban in this case

class{ 'nftables':
  noflush_tables => ['inet-f2b-table'],
}

Parameters:

  • out_all (Boolean) (defaults to: false)

    Allow all outbound connections. If ‘true` then all other out parameters `out_ntp`, `out_dns`, … will be assuemed false.

  • out_ntp (Boolean) (defaults to: true)

    Allow outbound to ntp servers.

  • out_http (Boolean) (defaults to: true)

    Allow outbound to http servers.

  • out_dns (Boolean) (defaults to: true)

    Allow outbound to dns servers.

  • out_https (Boolean) (defaults to: true)

    Allow outbound to https servers.

  • out_icmp (Boolean) (defaults to: true)

    Allow outbound ICMPv4/v6 traffic.

  • in_ssh (Boolean) (defaults to: true)

    Allow inbound to ssh servers.

  • in_icmp (Boolean) (defaults to: true)

    Allow inbound ICMPv4/v6 traffic.

  • inet_filter (Boolean) (defaults to: true)

    Add default tables, chains and rules to process traffic.

  • nat (Boolean) (defaults to: true)

    Add default tables and chains to process NAT traffic.

  • nat_table_name (String[1]) (defaults to: 'nat')

    The name of the ‘nat’ table.

  • sets (Hash) (defaults to: {})

    Allows sourcing set definitions directly from Hiera.

  • log_prefix (String) (defaults to: '[nftables] %<chain>s %<comment>s')

    String that will be used as prefix when logging packets. It can contain two variables using standard sprintf() string-formatting:

    * chain: Will be replaced by the name of the chain.
    * comment: Allows chains to add extra comments.
    
  • log_discarded (Boolean) (defaults to: true)

    Allow to log discarded packets

  • log_limit (Variant[Boolean[false], String]) (defaults to: '3/minute burst 5 packets')

    String with the content of a limit statement to be applied to the rules that log discarded traffic. Set to false to disable rate limiting.

  • reject_with (Variant[Boolean[false], Pattern[/icmp(v6|x)? type .+|tcp reset/]]) (defaults to: 'icmpx type port-unreachable')

    How to discard packets not matching any rule. If ‘false`, the fate of the packet will be defined by the chain policy (normally drop), otherwise the packet will be rejected with the REJECT_WITH policy indicated by the value of this parameter.

  • in_out_conntrack (Boolean) (defaults to: true)

    Adds INPUT and OUTPUT rules to allow traffic that’s part of an established connection and also to drop invalid packets.

  • in_out_drop_invalid (Boolean) (defaults to: $in_out_conntrack)

    Drops invalid packets in INPUT and OUTPUT

  • fwd_conntrack (Boolean) (defaults to: false)

    Adds FORWARD rules to allow traffic that’s part of an established connection and also to drop invalid packets.

  • fwd_drop_invalid (Boolean) (defaults to: $fwd_conntrack)

    Drops invalid packets in FORWARD

  • firewalld_enable (Variant[Boolean[false], Enum['mask']]) (defaults to: 'mask')

    Configures how the firewalld systemd service unit is enabled. It might be useful to set this to false if you’re externaly removing firewalld from the system completely.

  • noflush_tables (Optional[Array[Pattern[/^(ip|ip6|inet|arp|bridge|netdev)-[-a-zA-Z0-9_]+$/],1]]) (defaults to: undef)

    If specified only other existings tables will be flushed. If left unset all tables will be flushed via a ‘flush ruleset`

  • rules (Hash) (defaults to: {})

    Specify hashes of ‘nftables::rule`s via hiera

  • configuration_path (Stdlib::Unixpath)

    The absolute path to the principal nftables configuration file. The default varies depending on the system, and is set in the module’s data.

  • nft_path (Stdlib::Unixpath)

    Path to the nft binary

  • echo (Stdlib::Unixpath)

    Path to the echo binary

  • default_config_mode (Stdlib::Filemode)

    The default file & dir mode for configuration files and directories. The default varies depending on the system, and is set in the module’s data.



112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
# File 'manifests/init.pp', line 112

class nftables (
  Stdlib::Unixpath $echo,
  Stdlib::Unixpath $configuration_path,
  Stdlib::Unixpath $nft_path,
  Stdlib::Filemode $default_config_mode,
  Boolean $in_ssh = true,
  Boolean $in_icmp = true,
  Boolean $out_ntp = true,
  Boolean $out_dns = true,
  Boolean $out_http = true,
  Boolean $out_https = true,
  Boolean $out_icmp = true,
  Boolean $out_all = false,
  Boolean $in_out_conntrack = true,
  Boolean $in_out_drop_invalid = $in_out_conntrack,
  Boolean $fwd_conntrack = false,
  Boolean $fwd_drop_invalid = $fwd_conntrack,
  Boolean $inet_filter = true,
  Boolean $nat = true,
  Hash $rules = {},
  Hash $sets = {},
  String $log_prefix = '[nftables] %<chain>s %<comment>s',
  String[1] $nat_table_name = 'nat',
  Boolean $log_discarded = true,
  Variant[Boolean[false], String] $log_limit = '3/minute burst 5 packets',
  Variant[Boolean[false], Pattern[/icmp(v6|x)? type .+|tcp reset/]] $reject_with = 'icmpx type port-unreachable',
  Variant[Boolean[false], Enum['mask']] $firewalld_enable = 'mask',
  Optional[Array[Pattern[/^(ip|ip6|inet|arp|bridge|netdev)-[-a-zA-Z0-9_]+$/],1]] $noflush_tables = undef,
) {
  package { 'nftables':
    ensure => installed,
  } -> file_line {
    'enable_nftables':
      line   => 'include "/etc/nftables/puppet.nft"',
      path   => $configuration_path,
      notify => Service['nftables'],
  } -> file {
    default:
      owner => 'root',
      group => 'root',
      mode  => $default_config_mode;
    '/etc/nftables':
      ensure => directory,
      mode   => $default_config_mode;
    '/etc/nftables/puppet-preflight':
      ensure  => directory,
      mode    => $default_config_mode,
      purge   => true,
      force   => true,
      recurse => true;
    '/etc/nftables/puppet-preflight.nft':
      ensure  => file,
      content => epp('nftables/config/puppet.nft.epp', {
          'inet_filter' => $inet_filter,
          'nat'         => $nat,
          'noflush'     => $noflush_tables
        }
      );
  } ~> exec {
    'nft validate':
      refreshonly => true,
      command     => "${nft_path} -I /etc/nftables/puppet-preflight -c -f /etc/nftables/puppet-preflight.nft || ( ${echo} '#CONFIG BROKEN' >> /etc/nftables/puppet-preflight.nft && /bin/false)"; # lint:ignore:check_unsafe_interpolations
  } -> file {
    default:
      owner => 'root',
      group => 'root',
      mode  => $default_config_mode;
    '/etc/nftables/puppet.nft':
      ensure  => file,
      content => epp('nftables/config/puppet.nft.epp', {
          'inet_filter' => $inet_filter,
          'nat'         => $nat,
          'noflush'     => $noflush_tables
        }
      );
    '/etc/nftables/puppet':
      ensure  => directory,
      mode    => $default_config_mode,
      purge   => true,
      force   => true,
      recurse => true;
  } ~> service { 'nftables':
    ensure     => running,
    enable     => true,
    hasrestart => true,
    restart    => 'PATH=/usr/bin:/bin systemctl reload nftables',
  }

  systemd::dropin_file { 'puppet_nft.conf':
    ensure  => present,
    unit    => 'nftables.service',
    content => epp('nftables/systemd/puppet_nft.conf.epp', {
        'configuration_path' => $configuration_path,
        'nft_path'           => $nft_path,
    }),
    notify  => Service['nftables'],
  }

  # firewalld.enable can be mask or false depending upon if firewalld is installed or not
  # https://tickets.puppetlabs.com/browse/PUP-10814
  service { 'firewalld':
    ensure => stopped,
    enable => $firewalld_enable,
  }

  if $inet_filter {
    include nftables::inet_filter
  }

  if $nat {
    include nftables::ip_nat
  }

  # inject custom rules e.g. from hiera
  $rules.each |$n,$v| {
    nftables::rule {
      $n:
        * => $v,
    }
  }

  # inject custom sets e.g. from hiera
  $sets.each |$n,$v| {
    nftables::set {
      $n:
        * => $v,
    }
  }
}