Projet

Général

Profil

Révision 0ba57c66

ID0ba57c66a35ed4e9b570d8a6315a33a1c4ba3181
Enfant a534e044

Ajouté par mh il y a plus de 4 ans

initial release

Voir les différences:

README.md
1
# nftables puppet module
2

  
3
This module manages an opinionated nftables configuration
4

  
5
By default it sets up a firewall that drops every incoming
6
and outgoing connection.
7

  
8
It only allows outgoing dns,ntp and web traffic.
9

  
10
The config file has a inet filter and a ip nat table setup.
11

  
12
Additionally, the module comes with a basic infrastrcuture
13
to hook into different places.
14

  
15
## nftables config
16

  
17
The main configuration file loaded by the nftables service
18
will be `files/config/puppet.nft`, all other files created
19
by that module go into `files/config/puppet` and will also
20
be purged if not managed anymore.
21

  
22
The main configuration file includes dedicated files for
23
the filter and nat tables, as well as processes any
24
`custom-*.nft` files before hand.
25

  
26
The filter and NAT tables both have all the master chains
27
(INPUT,OUTPUT,FORWARD) configured, to which you can hook
28
in your own chains that can contain specific rules.
29

  
30
All filter masterchains drop by default.
31
By default we have a set of default_MASTERCHAIN chains
32
configured to which you can easily add your custom rules.
33

  
34
For specific needs you can add your own chain.
35

  
36
There is a global chain, that defines the default behavior
37
for all masterchains.
38

  
39
INPUT and OUTPUT to the loopback device is allowed by default,
40
though you could restrict it later.
41

  
42
### nftables::config
43

  
44
Manages a raw file in `/etc/nftables/puppet/${name}.nft`
45

  
46
Use this for any custom table files.
47

  
48
## nftables::chain_file
49

  
50
Prepares a chain file as a `concat` file to which you will be
51
able to add dedicated rules through `concat::fragments`.
52

  
53
The name must follow the pattern `TABLE@chain_name`, e.g.
54
`filter@my_chain`. This will a) prepare a snippet defining
55
the chain, that will be included in the filter table.
56

  
57
This define is more intended as a helper to setup chains
58
that will be used for the different tables, through their
59
own defines. See `nftables::filter::chain` as an example.
60

  
61
## nftables::filter::chain
62

  
63
This setups a chain for the filter table. You will be able
64
to add rules to that chain by using `nftables::filter::chain::rule`.
65

  
66
The name must follow the pattern: `MASTERCHAIN-new_chain_name`, which
67
defines to which masterchain that custom chain should be hooked into.
68

  
69
new_chain_name must be unique for all chains.
70

  
71
There is automatically a `jump` instruction added to the masterchain,
72
with the order preference.
73

  
74
## nftables::filter::chain::rule
75

  
76
A simple way to add rules to your custom chain. The name must be:
77
`CHAIN_NAME-rulename`, where CHAIN_NAME refers to your chain and
78
an arbitrary name for your rule.
79
The rule will be a `concat::fragment` to the chain `concat`.
80

  
81
You can define the order by using the `order` param.
files/config/puppet-filter.nft
1
table inet filter {
2
  include "/etc/nftables/puppet/filter-chains-*.nft"
3

  
4
  # something we want for all
5
  chain global {
6
    ct state established,related accept
7
    ct state invalid drop
8

  
9
    ip protocol icmp limit rate 4/second accept
10
    ip6 nexthdr ipv6-icmp limit rate 4/second accept
11
    ip protocol igmp limit rate 4/second accept
12
  }
13

  
14
  chain INPUT {
15
    type filter hook input priority 0
16
    policy drop
17

  
18
    jump global
19

  
20
    iifname lo accept
21

  
22
    include "/etc/nftables/puppet/filter-input-chains-*.nft"
23

  
24
    log prefix "[nftables] INPUT Rejected: " flags all counter reject with icmpx type port-unreachable
25
  }
26

  
27
  chain FORWARD {
28
    type filter hook forward priority 0
29
    policy drop
30

  
31
    jump global
32

  
33
    include "/etc/nftables/puppet/filter-forward-chains-*.nft"
34

  
35
    log prefix "[nftables] FORWARD Rejected: " flags all counter reject with icmpx type port-unreachable
36
  }
37

  
38
  chain OUTPUT {
39
    type filter hook output priority 0
40
    policy drop
41

  
42
    jump global
43

  
44
    oifname lo accept
45

  
46
    include "/etc/nftables/puppet/filter-output-chains-*.nft"
47

  
48
    log prefix "[nftables] OUTPUT Rejected: " flags all counter reject with icmpx type port-unreachable
49
  }
50
}
files/config/puppet-nat.nft
1
table nat {
2
  include "/etc/nftables/puppet/nat-chains-*.nft"
3

  
4
  chain PREROUTING {
5
    type nat hook prerouting priority 0
6
    policy accept
7

  
8
    include "/etc/nftables/puppet/nat-chain-prerouting-*.nft"
9
  }
10
  chain INPUT {
11
    type nat hook input priority 100
12
    policy accept
13

  
14
    include "/etc/nftables/puppet/nat-chain-input-*.nft"
15
  }
16
  chain OUTPUT            {
17
    type nat hook output priority 0
18
    policy accept
19

  
20
    include "/etc/nftables/puppet/nat-chain-output-*.nft"
21
  }
22

  
23
  chain POSTROUTING {
24
    type nat hook postrouting priority 100
25
    policy accept
26

  
27
    include "/etc/nftables/puppet/nat-chain-postrouting-*.nft"
28
  }
29
}
files/config/puppet.nft
1
# drop any existing nftables ruleset
2
flush ruleset
3

  
4
include "/etc/nftables/puppet/custom-*.nft"
5

  
6
include "/etc/nftables/puppet/filter.nft"
7

  
8
include "/etc/nftables/puppet/nat.nft"
9

  
manifests/chain_file.pp
1
# manage a chain file
2
# chain must be:
3
#   TABLE@chain_name
4
define nftables::chain_file(
5
  Pattern[/^[a-z0-9]+@[a-z0-9_]+$/] $chain = $title,
6
){
7
  $data = split($chain,'@')
8
  $concat_name = "nftables-chain-${data[0]}-${data[1]}"
9
  concat{
10
    $concat_name:
11
      path           => "/etc/nftables/puppet/${data[0]}-chains-${data[1]}.nft",
12
      owner          => root,
13
      group          => root,
14
      mode           => '0644',
15
      ensure_newline => true,
16
      require        => Package['nftables'],
17
      notify         => Service['nftables'],
18
  }
19
  concat::fragment{
20
    default:
21
      target => $concat_name;
22
    "${chain}-header":
23
      order   => '00',
24
      content => "chain ${data[1]} {";
25
    "${chain}-footer":
26
      order   => '99',
27
      content => '}';
28
  }
29
}
manifests/config.pp
1
# manage a config snippet
2
define nftables::config(
3
  Optional[String]
4
    $content = undef,
5
  Optional[Variant[String,Array[String,1]]]
6
    $source = undef,
7
){
8
  Package['nftables'] -> file{
9
    "/etc/nftables/puppet/${name}.nft":
10
      owner => root,
11
      group => root,
12
      mode  => '0640',
13
  } ~> Service['nftables']
14

  
15
  if $source {
16
    File["/etc/nftables/puppet/${name}.nft"]{
17
      source => $source,
18
    }
19
  } else {
20
    File["/etc/nftables/puppet/${name}.nft"]{
21
      content => $content,
22
    }
23
  }
24
}
manifests/filter/chain.pp
1
# register a filter chain
2
# Name should match the following pattern:
3
#
4
#  MASTERCHAIN-new_chain_name
5
define nftables::filter::chain(
6
  Pattern[/^[a-z0-9]+\-[a-z0-9_]+$/]
7
    $chain_name = $title,
8
  Pattern[/^\d{2}$/]
9
    $order      = '50',
10
){
11
  $data = split($chain_name,'-')
12
  nftables::config{
13
    "filter-${data[0]}-chains-${order}-${data[1]}":
14
      content => "jump ${data[1]}",
15
  }
16
  nftables::chain_file{
17
    "filter@${data[1]}":;
18
  }
19
}
manifests/filter/chain/rule.pp
1
# manage a filter chain rule
2
# Name should be:
3
#   TABLE_NAME-rulename
4
define nftables::filter::chain::rule(
5
  Enum['present','absent']
6
    $ensure = 'present',
7
  Pattern[/^[a-z0-9_]+\-[0-9a-z]+$/]
8
    $rulename = $title,
9
  Pattern[/^\d\d$/]
10
    $order = '50',
11
  Optional[String]
12
    $content = undef,
13
  Optional[Variant[String,Array[String,1]]]
14
    $source = undef,
15
){
16
  if $ensure == 'present' {
17
    $data = split($rulename,'-')
18
    concat::fragment{
19
      "nftables-filter-chain-rule-${rulename}":
20
        order   => $order,
21
        target => "nftables-chain-filter-${data[0]}",
22
    }
23

  
24
    if $content {
25
      Concat::Fragment["nftables-filter-chain-rule-${rulename}"]{
26
        content => "  ${content}",
27
      }
28
    } else {
29
      Concat::Fragment["nftables-filter-chain-rule-${rulename}"]{
30
        source => $source,
31
      }
32
    }
33
  }
34
}
manifests/init.pp
1
# manage nftables
2
class nftables {
3
  package{'nftables':
4
    ensure => installed,
5
  } -> file_line{
6
    'enable_nftables':
7
      line   => 'include "/etc/nftables/puppet.nft"',
8
      path   => '/etc/sysconfig/nftables.conf',
9
      notify => Service['nftables'],
10
  } -> file{
11
    default:
12
      owner  => 'root',
13
      group  => 'root',
14
      mode   => '0640';
15
    '/etc/nftables/puppet.nft':
16
      source => 'puppet:///modules/nftables/config/puppet.nft';
17
    '/etc/nftables/puppet':
18
      ensure  => directory,
19
      purge   => true,
20
      force   => true,
21
      recurse => true;
22
  } ~> service{'nftables':
23
    ensure    => running,
24
    enable    => true,
25
  }
26

  
27
  nftables::config{
28
    'filter':
29
      source => 'puppet:///modules/nftables/config/puppet-filter.nft';
30
    'nat':
31
      source => 'puppet:///modules/nftables/config/puppet-nat.nft';
32
  }
33

  
34
  nftables::filter::chain{
35
    [
36
      'forward-default_fwd',
37
      'output-default_out',
38
      'input-default_in',
39
    ]:;
40
  }
41
  # basic outgoing rules
42
  nftables::filter::chain::rule{
43
    'default_out-dnsudp':
44
      content => 'udp dport 53 accept';
45
    'default_out-dnstcp':
46
      content => 'tcp dport 53 accept';
47
    'default_out-web':
48
      content => 'tcp dport {80, 443} accept';
49
  }
50
}
manifests/rules/out/chrony.pp
1
# manage out chrony
2
class nftables::rules::out::chrony {
3
  nftables::filter::chain::rule{
4
    'default_out-chrony':
5
      content => 'udp dport 123 accept',
6
  }
7
}
manifests/rules/out/smtp.pp
1
# manage out smtp
2
class nftables::rules::out::smtp {
3
  nftables::filter::chain::rule{
4
    'default_out-smtp':
5
      content => 'tcp dport 25 accept',
6
  }
7
}
manifests/rules/out/ssh.pp
1
# manage out ssh
2
class nftables::rules::out::ssh {
3
  nftables::filter::chain::rule{
4
    'default_out-ssh':
5
      content => 'tcp dport 22 accept',
6
  }
7
}
manifests/rules/out/ssh/remove.pp
1
# disable outgoing ssh
2
class nftables::rules::out::ssh::remove inherits nftables::rules::out::ssh {
3
  Nftables::Filter::Chain::Rule['default_out-ssh']{
4
    ensure => absent,
5
  }
6
}
manifests/rules/ssh.pp
1
# manage in ssh
2
class nftables::rules::ssh(
3
  Array[Integer,1]
4
    $ports = [22],
5
) {
6
  nftables::filter::chain::rule{
7
    'default_in-ssh':
8
      content => "tcp dport {${join($ports,', ')}} accept",
9
  }
10
}

Formats disponibles : Unified diff