rework iptables configuration
All checks were successful
bundlewrap/pipeline/head This commit looks good
All checks were successful
bundlewrap/pipeline/head This commit looks good
This commit is contained in:
parent
d3ea06c3e8
commit
b943d2d465
8 changed files with 93 additions and 98 deletions
|
@ -56,13 +56,13 @@ def get_listen_interfaces(metadata):
|
||||||
)
|
)
|
||||||
def iptables(metadata):
|
def iptables(metadata):
|
||||||
rules = set()
|
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']))
|
rules.add('iptables -A INPUT -i {} -p udp --dport 67:68 -j ACCEPT'.format(subnet['interface']))
|
||||||
|
|
||||||
return {
|
return {
|
||||||
'iptables': {
|
'iptables': {
|
||||||
'bundle_rules': {
|
'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)),
|
'dhcpd': sorted(list(rules)),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
from json import loads
|
from json import loads
|
||||||
from os.path import join
|
from os.path import join
|
||||||
|
|
||||||
|
from bundlewrap.metadata import atomic
|
||||||
|
|
||||||
defaults = {
|
defaults = {
|
||||||
'apt': {
|
'apt': {
|
||||||
'repos': {
|
'repos': {
|
||||||
|
@ -100,25 +102,13 @@ def add_users_from_json(metadata):
|
||||||
|
|
||||||
|
|
||||||
@metadata_reactor.provides(
|
@metadata_reactor.provides(
|
||||||
'iptables/bundle_rules/icinga2',
|
'iptables/port_rules/5665',
|
||||||
)
|
)
|
||||||
def iptables(metadata):
|
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 {
|
return {
|
||||||
'iptables': {
|
'iptables': {
|
||||||
'bundle_rules': {
|
'port_rules': {
|
||||||
'icinga2': list(sorted(rules)),
|
'5665': atomic(metadata.get('icinga2/restrict-to', set())),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
51
bundles/iptables/metadata.py
Normal file
51
bundles/iptables/metadata.py
Normal 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)),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
|
@ -1,3 +1,5 @@
|
||||||
|
from bundlewrap.metadata import atomic
|
||||||
|
|
||||||
defaults = {
|
defaults = {
|
||||||
'apt': {
|
'apt': {
|
||||||
'packages': {
|
'packages': {
|
||||||
|
@ -17,25 +19,13 @@ defaults = {
|
||||||
|
|
||||||
|
|
||||||
@metadata_reactor.provides(
|
@metadata_reactor.provides(
|
||||||
'iptables/bundle_rules/netdata',
|
'iptables/port_rules/19999',
|
||||||
)
|
)
|
||||||
def iptables(metadata):
|
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 {
|
return {
|
||||||
'iptables': {
|
'iptables': {
|
||||||
'bundle_rules': {
|
'port_rules': {
|
||||||
'netdata': list(sorted(rules)),
|
'19999': atomic(metadata.get('netdata/restrict-to', set('*'))),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
from bundlewrap.metadata import atomic
|
||||||
|
|
||||||
defaults = {
|
defaults = {
|
||||||
'apt': {
|
'apt': {
|
||||||
'repos': {
|
'repos': {
|
||||||
|
@ -150,31 +152,15 @@ def monitoring(metadata):
|
||||||
|
|
||||||
|
|
||||||
@metadata_reactor.provides(
|
@metadata_reactor.provides(
|
||||||
'iptables/bundle_rules/nginx',
|
'iptables/port_rules/80',
|
||||||
|
'iptables/port_rules/443',
|
||||||
)
|
)
|
||||||
def iptables(metadata):
|
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 {
|
return {
|
||||||
'iptables': {
|
'iptables': {
|
||||||
'bundle_rules': {
|
'port_rules': {
|
||||||
'nginx': list(sorted(rules)),
|
'80': atomic(metadata.get('nginx/restrict-to', set('*'))),
|
||||||
|
'443': atomic(metadata.get('nginx/restrict-to', set('*'))),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
from bundlewrap.metadata import atomic
|
||||||
|
|
||||||
defaults = {
|
defaults = {
|
||||||
'apt': {
|
'apt': {
|
||||||
'packages': {
|
'packages': {
|
||||||
|
@ -34,37 +36,15 @@ defaults = {
|
||||||
|
|
||||||
|
|
||||||
@metadata_reactor.provides(
|
@metadata_reactor.provides(
|
||||||
'iptables/bundle_rules/transmission',
|
'iptables/port_rules',
|
||||||
)
|
)
|
||||||
def iptables(metadata):
|
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 {
|
return {
|
||||||
'iptables': {
|
'iptables': {
|
||||||
'bundle_rules': {
|
'port_rules': {
|
||||||
'transmission': list(sorted(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('*'))),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
from bundlewrap.metadata import atomic
|
||||||
|
|
||||||
defaults = {
|
defaults = {
|
||||||
'apt': {
|
'apt': {
|
||||||
'packages': {
|
'packages': {
|
||||||
|
@ -38,28 +40,14 @@ def cpu_cores_to_config_values(metadata):
|
||||||
|
|
||||||
|
|
||||||
@metadata_reactor.provides(
|
@metadata_reactor.provides(
|
||||||
'iptables/bundle_rules/unbound',
|
'iptables/port_rules',
|
||||||
)
|
)
|
||||||
def iptables(metadata):
|
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 {
|
return {
|
||||||
'iptables': {
|
'iptables': {
|
||||||
'bundle_rules': {
|
'port_rules': {
|
||||||
'unbound': list(sorted(rules)),
|
'53': atomic(metadata.get('unbound/restrict-to', set())),
|
||||||
|
'53/udp': atomic(metadata.get('unbound/restrict-to', set())),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
10
groups/os.py
10
groups/os.py
|
@ -39,6 +39,16 @@ groups['linux'] = {
|
||||||
'backup-client': {
|
'backup-client': {
|
||||||
'server': 'franzi-home.kunbox.net:2022',
|
'server': 'franzi-home.kunbox.net:2022',
|
||||||
},
|
},
|
||||||
|
'iptables': {
|
||||||
|
'port_rules': {
|
||||||
|
'*': {
|
||||||
|
'ovh.icinga2',
|
||||||
|
},
|
||||||
|
'*/udp': {
|
||||||
|
'ovh.icinga2',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
'pip_command': 'pip3',
|
'pip_command': 'pip3',
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue