rework firewall setup

This commit is contained in:
Franzi 2023-09-24 20:59:58 +02:00
parent be62c1270f
commit cd48cf495d
Signed by: kunsi
GPG key ID: 12E3D2136B818350
30 changed files with 145 additions and 122 deletions

View file

@ -19,6 +19,13 @@ table inet filter {
ip protocol icmp accept
ip6 nexthdr ipv6-icmp accept
% for ruleset, rules in sorted(input.items()):
# ${ruleset}
% for rule in rules:
${rule}
% endfor
% endfor
}
chain output {
@ -32,15 +39,36 @@ table inet filter {
icmp type timestamp-request drop
icmp type timestamp-reply drop
% for ruleset, rules in sorted(forward.items()):
# ${ruleset}
% for rule in rules:
${rule}
% endfor
% endfor
}
}
table nat {
chain prerouting {
type nat hook prerouting priority -100
% for ruleset, rules in sorted(prerouting.items()):
# ${ruleset}
% for rule in rules:
${rule}
% endfor
% endfor
}
chain postrouting {
type nat hook postrouting priority 100
% for ruleset, rules in sorted(postrouting.items()):
# ${ruleset}
% for rule in rules:
${rule}
% endfor
% endfor
}
}

View file

@ -15,8 +15,12 @@ directories = {
files = {
'/etc/nftables.conf': {
'needs': {
'directory:/etc/nftables-rules.d',
'content_type': 'mako',
'context': {
'forward': node.metadata.get('nftables/forward', {}),
'input': node.metadata.get('nftables/input', {}),
'postrouting': node.metadata.get('nftables/postrouting', {}),
'prerouting': node.metadata.get('nftables/prerouting', {}),
},
'triggers': {
'svc_systemd:nftables:reload',
@ -32,21 +36,6 @@ files = {
},
}
for ruleset, rules in node.metadata.get('nftables/rules', {}).items():
files[f'/etc/nftables-rules.d/{ruleset}'] = {
'source': 'rules-template',
'content_type': 'mako',
'context': {
'rules': rules,
},
'needed_by': {
'svc_systemd:nftables',
},
'triggers': {
'svc_systemd:nftables:reload',
},
}
svc_systemd = {
'nftables': {
'needs': {

View file

@ -35,7 +35,7 @@ if not node.has_bundle('vmhost'):
}
@metadata_reactor.provides(
'nftables/rules/99-port_rules',
'nftables/input/99-port_rules',
)
def port_rules_to_nftables(metadata):
# Using this, bundles can simply set up port based rules. This
@ -49,46 +49,47 @@ def port_rules_to_nftables(metadata):
if '/' in portdef:
port, proto = portdef.split('/', 2)
if proto not in {'udp'}:
if proto not in ('tcp', 'udp'):
raise BundleError(f'firewall/port_rules: illegal identifier {portdef} in metadata for {node.name}')
else:
port = portdef
proto = 'tcp'
proto = None
for target in targets:
if port == '*' and target == '*':
raise BundleError('firewall/port_rules: setting both port and target to * is unsupported')
if (
(port == '*' and target == '*')
or (target == '*' and proto is None)
or (port != '*' and proto is None)
):
raise BundleError(f'firewall/port_rules: illegal combination of port, target and protocol: "{port}" "{target}" "{proto}"')
comment = f'comment "port_rules {target}"'
if port != '*':
if ':' in port:
parts = port.split(':')
port_str = f'{proto} dport {{ {parts[0]}-{parts[1]} }}'
port_str = f'{proto} dport {{ {parts[0]}-{parts[1]} }} '
else:
port_str = f'{proto} dport {port}'
port_str = f'{proto} dport {port} '
elif proto is not None:
port_str = f'meta l4proto {proto} '
else:
port_str = f'meta l4proto {proto}'
port_str = ''
if target in ('ipv4', 'ipv6'):
version_str = f'meta nfproto {target}'
else:
version_str = ''
if target in ('*', 'ipv4', 'ipv6'):
ruleset.add(f'inet filter input {version_str} {port_str} accept {comment}')
if target == '*':
ruleset.add(f'{port_str}accept {comment}')
else:
resolved = repo.libs.tools.resolve_identifier(repo, target, linklocal=True)
for address in resolved['ipv4']:
ruleset.add(f'inet filter input meta nfproto ipv4 {port_str} ip saddr {address} accept {comment}')
ruleset.add(f'{port_str}ip saddr {address} accept {comment}')
for address in resolved['ipv6']:
ruleset.add(f'inet filter input meta nfproto ipv6 {port_str} ip6 saddr {address} accept {comment}')
ruleset.add(f'{port_str}ip6 saddr {address} accept {comment}')
return {
'nftables': {
'rules': {
'input': {
# order does not matter here.
'99-port_rules': sorted(ruleset),
},