rework iptables configuration
All checks were successful
bundlewrap/pipeline/head This commit looks good

This commit is contained in:
Franzi 2021-03-21 10:30:04 +01:00
parent d3ea06c3e8
commit b943d2d465
Signed by: kunsi
GPG key ID: 12E3D2136B818350
8 changed files with 93 additions and 98 deletions

View file

@ -56,13 +56,13 @@ def get_listen_interfaces(metadata):
)
def iptables(metadata):
rules = set()
for _, subnet in node.metadata.get('dhcpd/subnets', {}).items():
for subnet in node.metadata.get('dhcpd/subnets', {}).values():
rules.add('iptables -A INPUT -i {} -p udp --dport 67:68 -j ACCEPT'.format(subnet['interface']))
return {
'iptables': {
'bundle_rules': {
# iptables bundle relies on this being a list.
# can't use port_rules here. We're generating interface based rules here.
'dhcpd': sorted(list(rules)),
},
}

View file

@ -1,6 +1,8 @@
from json import loads
from os.path import join
from bundlewrap.metadata import atomic
defaults = {
'apt': {
'repos': {
@ -100,25 +102,13 @@ def add_users_from_json(metadata):
@metadata_reactor.provides(
'iptables/bundle_rules/icinga2',
'iptables/port_rules/5665',
)
def iptables(metadata):
identifiers = metadata.get('icinga2/restrict-to', set())
rules = set()
if identifiers:
for identifier in sorted(identifiers):
resolved = repo.libs.tools.resolve_identifier(repo, identifier)
for address in resolved['ipv4']:
rules.add(f'iptables -A INPUT -p tcp -s {address} --dport 5665 -j ACCEPT')
else:
rules.add('iptables -A INPUT -p tcp --dport 5665 -j ACCEPT')
return {
'iptables': {
'bundle_rules': {
'icinga2': list(sorted(rules)),
'port_rules': {
'5665': atomic(metadata.get('icinga2/restrict-to', set())),
},
},
}

View file

@ -0,0 +1,51 @@
@metadata_reactor.provides(
'iptables/bundle_rules/iptables',
)
def port_rules_to_iptables(metadata):
# Using this, bundles can simply set up port based rules. This
# reactor will then take care of converting those rules to actual
# iptables rules
ruleset = set()
# Plese note we do not set any defaults for ports. Bundles are
# expected to know themselves which default to use.
for portdef, targets in metadata.get('iptables/port_rules', {}).items():
if '/' in portdef:
port, proto = portdef.split('/', 2)
if proto not in {'udp'}:
raise Exception(f'iptables/port_rules: illegal identifier {portdef} in metadata for {node.name}')
else:
port = portdef
proto = 'tcp'
for target in targets:
if port == '*' and target == '*':
raise Exception('iptables/port_rules: setting both port and target to * is unsupported')
comment = f'-m comment --comment "iptables port_rules {target}"'
if port != '*':
port_str = f'--dport {port}'
else:
port_str = ''
if target == '*':
ruleset.add(f'iptables_both -A INPUT -p {proto} {port_str} {comment} -j ACCEPT')
else:
resolved = repo.libs.tools.resolve_identifier(repo, target)
for address in resolved['ipv4']:
ruleset.add(f'iptables -A INPUT -p {proto} -s {address} {port_str} {comment} -j ACCEPT')
for address in resolved['ipv6']:
ruleset.add(f'ip6tables -A INPUT -p {proto} -s {address} {port_str} {comment} -j ACCEPT')
return {
'iptables': {
'bundle_rules': {
# order does not matter here.
'iptables': list(sorted(ruleset)),
},
},
}

View file

@ -1,3 +1,5 @@
from bundlewrap.metadata import atomic
defaults = {
'apt': {
'packages': {
@ -17,25 +19,13 @@ defaults = {
@metadata_reactor.provides(
'iptables/bundle_rules/netdata',
'iptables/port_rules/19999',
)
def iptables(metadata):
identifiers = metadata.get('netdata/restrict-to', set())
rules = set()
if identifiers:
for identifier in sorted(identifiers):
resolved = repo.libs.tools.resolve_identifier(repo, identifier)
for address in resolved['ipv4']:
rules.add(f'iptables -A INPUT -p tcp -s {address} --dport 19999 -j ACCEPT')
else:
rules.add('iptables -A INPUT -p tcp --dport 19999 -j ACCEPT')
return {
'iptables': {
'bundle_rules': {
'netdata': list(sorted(rules)),
'port_rules': {
'19999': atomic(metadata.get('netdata/restrict-to', set('*'))),
},
},
}

View file

@ -1,3 +1,5 @@
from bundlewrap.metadata import atomic
defaults = {
'apt': {
'repos': {
@ -150,31 +152,15 @@ def monitoring(metadata):
@metadata_reactor.provides(
'iptables/bundle_rules/nginx',
'iptables/port_rules/80',
'iptables/port_rules/443',
)
def iptables(metadata):
identifiers = metadata.get('nginx/restrict-to', set())
rules = set()
if identifiers:
for identifier in sorted(identifiers):
resolved = repo.libs.tools.resolve_identifier(repo, identifier)
for address in resolved['ipv4']:
rules.add(f'iptables -A INPUT -p tcp -s {address} --dport 80 -j ACCEPT')
rules.add(f'iptables -A INPUT -p tcp -s {address} --dport 443 -j ACCEPT')
for address in resolved['ipv6']:
rules.add(f'ip6tables -A INPUT -p tcp -s {address} --dport 80 -j ACCEPT')
rules.add(f'ip6tables -A INPUT -p tcp -s {address} --dport 443 -j ACCEPT')
else:
rules.add('iptables_both -A INPUT -p tcp --dport 80 -j ACCEPT')
rules.add('iptables_both -A INPUT -p tcp --dport 443 -j ACCEPT')
return {
'iptables': {
'bundle_rules': {
'nginx': list(sorted(rules)),
'port_rules': {
'80': atomic(metadata.get('nginx/restrict-to', set('*'))),
'443': atomic(metadata.get('nginx/restrict-to', set('*'))),
},
},
}

View file

@ -1,3 +1,5 @@
from bundlewrap.metadata import atomic
defaults = {
'apt': {
'packages': {
@ -34,37 +36,15 @@ defaults = {
@metadata_reactor.provides(
'iptables/bundle_rules/transmission',
'iptables/port_rules',
)
def iptables(metadata):
identifiers = metadata.get('transmission/restrict-to', set())
rules = set()
rules.add('iptables_both -A INPUT -p udp --dport {} -j ACCEPT'.format(
metadata.get('transmission/config/peer-port'),
))
rules.add('iptables_both -A INPUT -p tcp --dport {} -j ACCEPT'.format(
metadata.get('transmission/config/peer-port'),
))
if identifiers:
for identifier in sorted(identifiers):
resolved = repo.libs.tools.resolve_identifier(repo, identifier)
for address in resolved['ipv4']:
rules.add('iptables -A INPUT -p tcp -s {} --dport {} -j ACCEPT'.format(
address,
metadata.get('transmission/config/rpc-port'),
))
else:
rules.add('iptables -A INPUT -p tcp --dport {} -j ACCEPT'.format(
metadata.get('transmission/config/rpc-port'),
))
return {
'iptables': {
'bundle_rules': {
'transmission': list(sorted(rules)),
'port_rules': {
str(metadata.get('transmission/config/peer-port')): set('*'),
str(metadata.get('transmission/config/peer-port')) + '/udp': set('*'),
str(metadata.get('transmission/config/rpc-port')): atomic(metadata.get('transmission/restrict-to', set('*'))),
},
},
}

View file

@ -1,3 +1,5 @@
from bundlewrap.metadata import atomic
defaults = {
'apt': {
'packages': {
@ -38,28 +40,14 @@ def cpu_cores_to_config_values(metadata):
@metadata_reactor.provides(
'iptables/bundle_rules/unbound',
'iptables/port_rules',
)
def iptables(metadata):
identifiers = metadata.get('unbound/restrict-to', set())
rules = set()
if identifiers:
for identifier in sorted(identifiers):
resolved = repo.libs.tools.resolve_identifier(repo, identifier)
for address in resolved['ipv4']:
rules.add(f'iptables -A INPUT -p tcp -s {address} --dport 53 -j ACCEPT')
rules.add(f'iptables -A INPUT -p udp -s {address} --dport 53 -j ACCEPT')
for address in resolved['ipv6']:
rules.add(f'ip6tables -A INPUT -p tcp -s {address} --dport 53 -j ACCEPT')
rules.add(f'ip6tables -A INPUT -p udp -s {address} --dport 53 -j ACCEPT')
return {
'iptables': {
'bundle_rules': {
'unbound': list(sorted(rules)),
'port_rules': {
'53': atomic(metadata.get('unbound/restrict-to', set())),
'53/udp': atomic(metadata.get('unbound/restrict-to', set())),
},
},
}

View file

@ -39,6 +39,16 @@ groups['linux'] = {
'backup-client': {
'server': 'franzi-home.kunbox.net:2022',
},
'iptables': {
'port_rules': {
'*': {
'ovh.icinga2',
},
'*/udp': {
'ovh.icinga2',
},
},
},
},
'pip_command': 'pip3',
}