From c64aa70b49c0e4feca69ed9064154a6baa3e7d09 Mon Sep 17 00:00:00 2001 From: cronekorkn Date: Fri, 9 Sep 2022 19:50:42 +0200 Subject: [PATCH] nftables --- bundles/bind/metadata.py | 16 ++++--- bundles/dovecot/metadata.py | 13 ++++-- bundles/icinga2/metadata.py | 5 +++ bundles/influxdb2/metadata.py | 5 +++ bundles/nftables/files/nftables.conf | 65 ++++++++++++++++++++++++++++ bundles/nftables/items.py | 22 ++++++++++ bundles/nftables/metadata.py | 14 ++++++ bundles/nginx/metadata.py | 24 +++------- bundles/postfix/metadata.py | 13 ++++-- bundles/postgresql/metadata.py | 5 +++ bundles/wireguard/metadata.py | 9 +++- groups/os/debian.py | 1 + 12 files changed, 158 insertions(+), 34 deletions(-) create mode 100644 bundles/nftables/files/nftables.conf create mode 100644 bundles/nftables/items.py create mode 100644 bundles/nftables/metadata.py diff --git a/bundles/bind/metadata.py b/bundles/bind/metadata.py index 7685406..c90bf80 100644 --- a/bundles/bind/metadata.py +++ b/bundles/bind/metadata.py @@ -41,6 +41,12 @@ defaults = { }, 'zones': set(), }, + 'nftables': { + 'input': { + 'tcp dport 53 accept', + 'udp dport 53 accept', + }, + }, 'telegraf': { 'config': { 'inputs': { @@ -97,7 +103,7 @@ def dns(metadata): def collect_records(metadata): if metadata.get('bind/type') == 'slave': return {} - + views = {} for view_name, view_conf in metadata.get('bind/views').items(): @@ -117,7 +123,7 @@ def collect_records(metadata): name = fqdn[0:-len(zone) - 1] - for type, values in records.items(): + for type, values in records.items(): for value in values: if repo.libs.bind.record_matches_view(value, type, name, zone, view_name, metadata): views\ @@ -128,7 +134,7 @@ def collect_records(metadata): .add( h({'name': name, 'type': type, 'value': value}) ) - + return { 'bind': { 'views': views, @@ -160,7 +166,7 @@ def ns_records(metadata): # FIXME: bw currently cant handle lists of dicts :( h({'name': '@', 'type': 'NS', 'value': f"{nameserver}."}) for nameserver in nameservers - } + } } for zone_name, zone_conf in view_conf['zones'].items() } @@ -177,7 +183,7 @@ def ns_records(metadata): def slaves(metadata): if metadata.get('bind/type') == 'slave': return {} - + return { 'bind': { 'slaves': [ diff --git a/bundles/dovecot/metadata.py b/bundles/dovecot/metadata.py index 58211d1..855aba2 100644 --- a/bundles/dovecot/metadata.py +++ b/bundles/dovecot/metadata.py @@ -13,15 +13,20 @@ defaults = { 'catdoc': {}, # catdoc, catppt, xls2csv }, }, + 'dovecot': { + 'database': { + 'dbname': 'mailserver', + 'dbuser': 'mailserver', + }, + }, 'letsencrypt': { 'reload_after': { 'dovecot', }, }, - 'dovecot': { - 'database': { - 'dbname': 'mailserver', - 'dbuser': 'mailserver', + 'nftables': { + 'input': { + 'tcp dport {143, 993, 4190} accept', }, }, } diff --git a/bundles/icinga2/metadata.py b/bundles/icinga2/metadata.py index 8295ca6..eb20a92 100644 --- a/bundles/icinga2/metadata.py +++ b/bundles/icinga2/metadata.py @@ -20,6 +20,11 @@ defaults = { } }, }, + 'nftables': { + 'input': { + 'tcp dport 5665 accept', + }, + }, 'postgresql': { 'databases': { 'icinga2': { diff --git a/bundles/influxdb2/metadata.py b/bundles/influxdb2/metadata.py index c279c1d..2d345e5 100644 --- a/bundles/influxdb2/metadata.py +++ b/bundles/influxdb2/metadata.py @@ -10,6 +10,11 @@ defaults = { 'deb https://repos.influxdata.com/debian {release} stable', }, }, + 'nftables': { + 'input': { + 'tcp dport 8200 accept', + }, + }, 'influxdb': { 'port': '8200', 'username': 'admin', diff --git a/bundles/nftables/files/nftables.conf b/bundles/nftables/files/nftables.conf new file mode 100644 index 0000000..96497ed --- /dev/null +++ b/bundles/nftables/files/nftables.conf @@ -0,0 +1,65 @@ +#!/usr/sbin/nft -f + +flush ruleset + +table inet filter { + + # INPUT + + chain input { + type filter hook input priority 0; + policy drop; + + # Allow traffic from established and related packets, drop invalid + ct state vmap { established : accept, related : accept, invalid : drop } + + # Allow loopback traffic. + iifname lo accept + + # accepting ping (icmp-echo-request) for diagnostic purposes. + icmp type echo-request limit rate 5/second accept + icmpv6 type { nd-neighbor-solicit, nd-router-advert, nd-neighbor-advert } accept + + # Jump to chain according to layer 3 protocol using a verdict map + meta protocol vmap { ip : jump inbound_ipv4, ip6 : jump inbound_ipv6 } + + #rules +% for rule in sorted(input): + ${rule} +% endfor + } + + chain inbound_ipv4 { + # accepting ping (icmp-echo-request) for diagnostic purposes. + icmp type echo-request limit rate 5/second accept + } + + chain inbound_ipv6 { + # accept neighbour discovery otherwise connectivity breaks + icmpv6 type { nd-neighbor-solicit, nd-router-advert, nd-neighbor-advert } accept + + # accepting ping (icmpv6-echo-request) for diagnostic purposes. + icmpv6 type echo-request limit rate 5/second accept + } + + # FORWARD + + chain forward { + type filter hook forward priority 0; + + #rules +% for rule in sorted(forward): + ${rule} +% endfor + } + + # OUTPUT + + chain output { + type filter hook output priority 0; + +% for rule in sorted(output): + ${rule} +% endfor + } +} diff --git a/bundles/nftables/items.py b/bundles/nftables/items.py new file mode 100644 index 0000000..bc221f9 --- /dev/null +++ b/bundles/nftables/items.py @@ -0,0 +1,22 @@ +files = { + '/etc/nftables.conf': { + 'content_type': 'mako', + 'mode': '0755', + 'context': { + 'input': node.metadata.get('nftables/input'), + 'forward': node.metadata.get('nftables/forward'), + 'output': node.metadata.get('nftables/output'), + }, + 'triggers': [ + 'svc_systemd:nftables.service:reload', + ], + }, +} + +svc_systemd = { + 'nftables.service': { + 'needs': [ + 'pkg_apt:nftables', + ], + }, +} diff --git a/bundles/nftables/metadata.py b/bundles/nftables/metadata.py new file mode 100644 index 0000000..d73fc24 --- /dev/null +++ b/bundles/nftables/metadata.py @@ -0,0 +1,14 @@ +defaults = { + 'apt': { + 'packages': { + 'nftables': {}, + }, + }, + 'nftables': { + 'input': { + 'tcp dport 22 accept', + }, + 'forward': {}, + 'output': {}, + }, +} diff --git a/bundles/nginx/metadata.py b/bundles/nginx/metadata.py index d80dfe1..1e19839 100644 --- a/bundles/nginx/metadata.py +++ b/bundles/nginx/metadata.py @@ -8,26 +8,12 @@ defaults = { 'nginx': {}, }, }, - 'nginx': { - 'default_vhosts': { - '80': { - 'listen': [ - '80', - '[::]:80', - ], - 'location /.well-known/acme-challenge/': { - 'alias': '/var/lib/dehydrated/acme-challenges/', - }, - 'location /': { - 'return': '301 https://$host$request_uri', - }, - }, - 'stub_status': { - 'listen': '127.0.0.1:22999 default_server', - 'server_name': '_', - 'stub_status': '', - }, + 'nftables': { + 'input': { + 'tcp dport {80, 443} accept', }, + }, + 'nginx': { 'vhosts': { # '80': { # 'content': 'nginx/80.conf', diff --git a/bundles/postfix/metadata.py b/bundles/postfix/metadata.py index 1600bf0..3d96018 100644 --- a/bundles/postfix/metadata.py +++ b/bundles/postfix/metadata.py @@ -11,10 +11,18 @@ defaults = { '/var/vmail', }, }, + 'grafana_rows': { + 'postfix_queue', + }, 'letsencrypt': { 'reload_after': { 'postfix', - }, + }, + }, + 'nftables': { + 'input': { + 'tcp dport {25, 465, 587} accept', + }, }, 'telegraf': { 'config': { @@ -23,7 +31,4 @@ defaults = { }, }, }, - 'grafana_rows': { - 'postfix_queue', - }, } diff --git a/bundles/postgresql/metadata.py b/bundles/postgresql/metadata.py index ea70794..5f967be 100644 --- a/bundles/postgresql/metadata.py +++ b/bundles/postgresql/metadata.py @@ -14,6 +14,11 @@ defaults = { '/var/lib/postgresql', }, }, + 'nftables': { + 'input': { + 'tcp dport 5432 accept', + }, + }, 'postgresql': { 'conf': {}, 'roles': { diff --git a/bundles/wireguard/metadata.py b/bundles/wireguard/metadata.py index 791c434..299c29c 100644 --- a/bundles/wireguard/metadata.py +++ b/bundles/wireguard/metadata.py @@ -17,6 +17,11 @@ defaults = { }, }, }, + 'nftables': { + 'input': { + 'tcp dport 51820 accept', + }, + }, 'wireguard': { 's2s': {}, 'clients': {}, @@ -106,7 +111,7 @@ def systemd_networkd_netdevs(metadata): 'ListenPort': 51820, }, } - + for peer, config in { **metadata.get('wireguard/s2s'), **metadata.get('wireguard/clients'), @@ -121,7 +126,7 @@ def systemd_networkd_netdevs(metadata): }) if config.get('endpoint'): netdev[f'WireGuardPeer#{peer}']['Endpoint'] = config['endpoint'] - + return { 'systemd': { 'units': { diff --git a/groups/os/debian.py b/groups/os/debian.py index 4144520..4ac57c1 100644 --- a/groups/os/debian.py +++ b/groups/os/debian.py @@ -4,6 +4,7 @@ ], 'bundles': [ 'apt', + 'nftables', ], 'metadata': { 'apt': {