Merge pull request 'nftables' (#41) from kunsi-nftables into main
All checks were successful
bundlewrap/pipeline/head This commit looks good
All checks were successful
bundlewrap/pipeline/head This commit looks good
Reviewed-on: https://git.kunsmann.eu/kunsi/bundlewrap/pulls/41
This commit is contained in:
commit
949690ad59
37 changed files with 370 additions and 349 deletions
|
@ -37,18 +37,20 @@ def get_static_allocations(metadata):
|
||||||
|
|
||||||
|
|
||||||
@metadata_reactor.provides(
|
@metadata_reactor.provides(
|
||||||
'iptables/bundle_rules/dhcpd',
|
'nftables/rules/input/dhcpd',
|
||||||
)
|
)
|
||||||
def iptables(metadata):
|
def nftables(metadata):
|
||||||
rules = set()
|
rules = set()
|
||||||
for subnet in node.metadata.get('dhcpd/subnets', {}):
|
for iface in node.metadata.get('dhcpd/subnets', {}):
|
||||||
rules.add('iptables -A INPUT -i {} -p udp --dport 67:68 -j ACCEPT'.format(subnet))
|
rules.add(f'udp dport {{ 67, 68 }} iif {iface} accept')
|
||||||
|
|
||||||
return {
|
return {
|
||||||
'iptables': {
|
'nftables': {
|
||||||
'bundle_rules': {
|
'rules': {
|
||||||
# can't use port_rules here, because we're generating interface based rules.
|
'input': {
|
||||||
'dhcpd': sorted(list(rules)),
|
# can't use port_rules here, because we're generating interface based rules.
|
||||||
|
'dhcpd': sorted(rules),
|
||||||
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -76,13 +76,13 @@ def import_database_settings_from_postfixadmin(metadata):
|
||||||
|
|
||||||
|
|
||||||
@metadata_reactor.provides(
|
@metadata_reactor.provides(
|
||||||
'iptables/port_rules/143',
|
'firewall/port_rules/143',
|
||||||
'iptables/port_rules/993',
|
'firewall/port_rules/993',
|
||||||
'iptables/port_rules/4190',
|
'firewall/port_rules/4190',
|
||||||
)
|
)
|
||||||
def iptables(metadata):
|
def firewall(metadata):
|
||||||
return {
|
return {
|
||||||
'iptables': {
|
'firewall': {
|
||||||
'port_rules': {
|
'port_rules': {
|
||||||
# imap(s)
|
# imap(s)
|
||||||
'143': atomic(metadata.get('dovecot/restrict-to', {'*'})),
|
'143': atomic(metadata.get('dovecot/restrict-to', {'*'})),
|
||||||
|
|
|
@ -103,11 +103,11 @@ def add_users_from_json(metadata):
|
||||||
|
|
||||||
|
|
||||||
@metadata_reactor.provides(
|
@metadata_reactor.provides(
|
||||||
'iptables/port_rules/5665',
|
'firewall/port_rules/5665',
|
||||||
)
|
)
|
||||||
def iptables(metadata):
|
def firewall(metadata):
|
||||||
return {
|
return {
|
||||||
'iptables': {
|
'firewall': {
|
||||||
'port_rules': {
|
'port_rules': {
|
||||||
'5665': atomic(metadata.get('icinga2/restrict-to', set())),
|
'5665': atomic(metadata.get('icinga2/restrict-to', set())),
|
||||||
},
|
},
|
||||||
|
|
|
@ -1,85 +0,0 @@
|
||||||
#!/bin/bash
|
|
||||||
|
|
||||||
% if not node.metadata.get('iptables/enabled', True):
|
|
||||||
exit 0
|
|
||||||
% endif
|
|
||||||
|
|
||||||
lock_try=0
|
|
||||||
while ! mkdir /run/bw-iptables.lock >/dev/null 2>&1
|
|
||||||
do
|
|
||||||
((lock_try++))
|
|
||||||
if (( lock_try == 10 ))
|
|
||||||
then
|
|
||||||
echo 'FATAL: iptables-enforce: Could not get lock!' >&2
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
sleep 1
|
|
||||||
done
|
|
||||||
trap 'rmdir /run/bw-iptables.lock' EXIT
|
|
||||||
|
|
||||||
iptables_both()
|
|
||||||
{
|
|
||||||
iptables "$@"
|
|
||||||
ip6tables "$@"
|
|
||||||
}
|
|
||||||
|
|
||||||
iptables_both -P INPUT DROP
|
|
||||||
iptables_both -P OUTPUT ACCEPT
|
|
||||||
iptables_both -P FORWARD DROP
|
|
||||||
iptables_both -F
|
|
||||||
iptables_both -X
|
|
||||||
iptables_both -t nat -F
|
|
||||||
iptables_both -t nat -X
|
|
||||||
iptables_both -t nat -Z
|
|
||||||
iptables_both -t filter -F
|
|
||||||
iptables_both -t filter -X
|
|
||||||
iptables_both -t filter -Z
|
|
||||||
iptables_both -t mangle -F
|
|
||||||
iptables_both -t mangle -X
|
|
||||||
iptables_both -t mangle -Z
|
|
||||||
|
|
||||||
# Workaround for CVE-2019-11477, CVE-2019-11478 and CVE-2019-11479
|
|
||||||
# https://www.openwall.com/lists/oss-security/2019/06/17/5
|
|
||||||
# https://people.canonical.com/~ubuntu-security/cve/2019/CVE-2019-11477.html
|
|
||||||
iptables_both -I INPUT -p tcp -m tcpmss --mss 1:500 -j DROP
|
|
||||||
|
|
||||||
# Dummy rules to make sure the conntrack table(s) will be updated.
|
|
||||||
iptables_both -I INPUT -m state --state NEW,ESTABLISHED,RELATED
|
|
||||||
iptables_both -I OUTPUT -m state --state NEW,ESTABLISHED,RELATED
|
|
||||||
iptables_both -I FORWARD -m state --state NEW,ESTABLISHED,RELATED
|
|
||||||
|
|
||||||
# open up local loopback
|
|
||||||
iptables_both -A INPUT -i lo -j ACCEPT
|
|
||||||
|
|
||||||
# Set Up counting rules
|
|
||||||
% for ip in sorted(ipv4):
|
|
||||||
iptables -A INPUT -d ${ip}
|
|
||||||
iptables -A OUTPUT -s ${ip}
|
|
||||||
% endfor
|
|
||||||
|
|
||||||
% for ip in sorted(ipv6):
|
|
||||||
ip6tables -A INPUT -d ${ip}
|
|
||||||
ip6tables -A OUTPUT -s ${ip}
|
|
||||||
% endfor
|
|
||||||
|
|
||||||
iptables -A INPUT -p ICMP --icmp-type timestamp-request -j DROP
|
|
||||||
iptables -A INPUT -p ICMP --icmp-type timestamp-reply -j DROP
|
|
||||||
# allow ICMP -- answers for IPv4 are covered by conntrack
|
|
||||||
iptables -A INPUT -p icmp -j ACCEPT
|
|
||||||
|
|
||||||
# ICMP6 is used for so many things, we should under no circumstances
|
|
||||||
# ignore it and thus should not rely on any conntrack heuristics.
|
|
||||||
ip6tables -A INPUT -p ipv6-icmp -j ACCEPT
|
|
||||||
|
|
||||||
# Allow incoming answers. Install this first (before the larger ruleset
|
|
||||||
# from /etc/network/iptables-rules.d/), so that iptables can match/exit
|
|
||||||
# early.
|
|
||||||
iptables_both -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
|
|
||||||
|
|
||||||
shopt -s nullglob
|
|
||||||
for i in /etc/iptables-rules.d/*
|
|
||||||
do
|
|
||||||
. "$i"
|
|
||||||
done
|
|
||||||
|
|
||||||
cat /etc/sysctl.d/*.conf /etc/sysctl.conf | sysctl -e -p -
|
|
|
@ -1,11 +0,0 @@
|
||||||
[Unit]
|
|
||||||
Description=Run iptables-enforce after networkd startup
|
|
||||||
Requires=network-online.target
|
|
||||||
After=network-online.target
|
|
||||||
|
|
||||||
[Service]
|
|
||||||
Type=oneshot
|
|
||||||
ExecStart=/usr/local/sbin/iptables-enforce
|
|
||||||
|
|
||||||
[Install]
|
|
||||||
WantedBy=multi-user.target
|
|
|
@ -1,66 +0,0 @@
|
||||||
directories = {
|
|
||||||
'/etc/iptables-rules.d': {
|
|
||||||
'purge': True,
|
|
||||||
'triggers': {
|
|
||||||
'action:iptables_enforce',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
files = {
|
|
||||||
'/etc/systemd/system/iptables-enforce.service': {
|
|
||||||
'triggers': {
|
|
||||||
'action:systemd-reload',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
'/usr/local/sbin/iptables-enforce': {
|
|
||||||
'content_type': 'mako',
|
|
||||||
'context': repo.libs.tools.resolve_identifier(repo, node.name),
|
|
||||||
'mode': '0700',
|
|
||||||
'triggers': {
|
|
||||||
'action:iptables_enforce',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
enforce_deps = {
|
|
||||||
'directory:/etc/iptables-rules.d',
|
|
||||||
'file:/usr/local/sbin/iptables-enforce',
|
|
||||||
}
|
|
||||||
|
|
||||||
for bundle, rules in node.metadata.get('iptables/bundle_rules', {}).items():
|
|
||||||
files[f'/etc/iptables-rules.d/20-{bundle}'] = {
|
|
||||||
# We must never use sorted() here. Bundles might rely on their order.
|
|
||||||
'content': '\n'.join(rules) + '\n',
|
|
||||||
'triggers': {
|
|
||||||
'action:iptables_enforce',
|
|
||||||
},
|
|
||||||
}
|
|
||||||
enforce_deps.add(f'file:/etc/iptables-rules.d/20-{bundle}')
|
|
||||||
|
|
||||||
if 'custom_rules' in node.metadata.get('iptables', {}):
|
|
||||||
files['/etc/iptables-rules.d/40-custom'] = {
|
|
||||||
'content': '\n'.join(node.metadata['iptables']['custom_rules']) + '\n',
|
|
||||||
'triggers': {
|
|
||||||
'action:iptables_enforce',
|
|
||||||
},
|
|
||||||
}
|
|
||||||
enforce_deps.add('file:/etc/iptables-rules.d/40-custom')
|
|
||||||
|
|
||||||
|
|
||||||
actions = {
|
|
||||||
'iptables_enforce': {
|
|
||||||
'command': '/usr/local/sbin/iptables-enforce',
|
|
||||||
'triggered': True,
|
|
||||||
'needs': enforce_deps,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
svc_systemd = {
|
|
||||||
'iptables-enforce': {
|
|
||||||
'running': None,
|
|
||||||
'needs': {
|
|
||||||
'file:/etc/systemd/system/iptables-enforce.service',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
|
@ -1,61 +0,0 @@
|
||||||
from bundlewrap.exceptions import BundleError
|
|
||||||
|
|
||||||
defaults = {
|
|
||||||
'pacman': {
|
|
||||||
'packages': {
|
|
||||||
'iptables': {},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
@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 BundleError(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 BundleError('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)),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
|
@ -44,11 +44,11 @@ defaults = {
|
||||||
|
|
||||||
|
|
||||||
@metadata_reactor.provides(
|
@metadata_reactor.provides(
|
||||||
'iptables/port_rules/8080',
|
'firewall/port_rules/8080',
|
||||||
)
|
)
|
||||||
def iptables(metadata):
|
def firewall(metadata):
|
||||||
return {
|
return {
|
||||||
'iptables': {
|
'firewall': {
|
||||||
'port_rules': {
|
'port_rules': {
|
||||||
'8080': atomic(metadata.get('kodi/restrict-to', {'*'})),
|
'8080': atomic(metadata.get('kodi/restrict-to', {'*'})),
|
||||||
},
|
},
|
||||||
|
|
|
@ -26,9 +26,9 @@ defaults = {
|
||||||
|
|
||||||
|
|
||||||
@metadata_reactor.provides(
|
@metadata_reactor.provides(
|
||||||
'iptables/port_rules',
|
'firewall/port_rules',
|
||||||
)
|
)
|
||||||
def iptables(metadata):
|
def firewall(metadata):
|
||||||
sources = metadata.get('mosquitto/restrict-to', {'*'})
|
sources = metadata.get('mosquitto/restrict-to', {'*'})
|
||||||
result = {}
|
result = {}
|
||||||
|
|
||||||
|
@ -36,7 +36,7 @@ def iptables(metadata):
|
||||||
result[listener] = atomic(sources)
|
result[listener] = atomic(sources)
|
||||||
|
|
||||||
return {
|
return {
|
||||||
'iptables': {
|
'firewall': {
|
||||||
'port_rules': result,
|
'port_rules': result,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,11 +19,11 @@ defaults = {
|
||||||
|
|
||||||
|
|
||||||
@metadata_reactor.provides(
|
@metadata_reactor.provides(
|
||||||
'iptables/port_rules/19999',
|
'firewall/port_rules/19999',
|
||||||
)
|
)
|
||||||
def iptables(metadata):
|
def firewall(metadata):
|
||||||
return {
|
return {
|
||||||
'iptables': {
|
'firewall': {
|
||||||
'port_rules': {
|
'port_rules': {
|
||||||
'19999': atomic(metadata.get('netdata/restrict-to', set())),
|
'19999': atomic(metadata.get('netdata/restrict-to', set())),
|
||||||
},
|
},
|
||||||
|
|
|
@ -10,9 +10,9 @@ defaults = {
|
||||||
|
|
||||||
|
|
||||||
@metadata_reactor.provides(
|
@metadata_reactor.provides(
|
||||||
'iptables/port_rules',
|
'firewall/port_rules',
|
||||||
)
|
)
|
||||||
def iptables(metadata):
|
def firewall(metadata):
|
||||||
ips = set()
|
ips = set()
|
||||||
|
|
||||||
for share_items in metadata.get('nfs-server/shares', {}).values():
|
for share_items in metadata.get('nfs-server/shares', {}).values():
|
||||||
|
@ -20,7 +20,7 @@ def iptables(metadata):
|
||||||
ips.add(share_target)
|
ips.add(share_target)
|
||||||
|
|
||||||
return {
|
return {
|
||||||
'iptables': {
|
'firewall': {
|
||||||
'port_rules': {
|
'port_rules': {
|
||||||
'111': atomic(ips),
|
'111': atomic(ips),
|
||||||
'111/udp': atomic(ips),
|
'111/udp': atomic(ips),
|
||||||
|
|
72
bundles/nftables/files/nftables.conf
Normal file
72
bundles/nftables/files/nftables.conf
Normal file
|
@ -0,0 +1,72 @@
|
||||||
|
#!/usb/sbin/nft -f
|
||||||
|
|
||||||
|
flush ruleset
|
||||||
|
|
||||||
|
table inet filter {
|
||||||
|
chain input {
|
||||||
|
type filter hook input priority 0
|
||||||
|
policy drop
|
||||||
|
|
||||||
|
tcp flags syn tcp option maxseg size 1-500 drop
|
||||||
|
|
||||||
|
ct state { established, related } accept
|
||||||
|
ct state invalid drop
|
||||||
|
|
||||||
|
iif lo accept
|
||||||
|
|
||||||
|
icmp type timestamp-request drop
|
||||||
|
icmp type timestamp-reply drop
|
||||||
|
ip protocol icmp accept
|
||||||
|
|
||||||
|
ip6 nexthdr ipv6-icmp accept
|
||||||
|
% for ruleset, rules in sorted(node.metadata.get('nftables/rules/input', {}).items()):
|
||||||
|
|
||||||
|
# ${ruleset}
|
||||||
|
% for rule in rules:
|
||||||
|
${rule}
|
||||||
|
% endfor
|
||||||
|
# / ${ruleset}
|
||||||
|
% endfor
|
||||||
|
}
|
||||||
|
|
||||||
|
chain output {
|
||||||
|
type filter hook output priority 0
|
||||||
|
policy accept
|
||||||
|
}
|
||||||
|
|
||||||
|
chain forward {
|
||||||
|
type filter hook forward priority 0
|
||||||
|
policy drop
|
||||||
|
|
||||||
|
icmp type timestamp-request drop
|
||||||
|
icmp type timestamp-reply drop
|
||||||
|
|
||||||
|
% for ruleset, rules in sorted(node.metadata.get('nftables/rules/forward', {}).items()):
|
||||||
|
|
||||||
|
# ${ruleset}
|
||||||
|
% for rule in rules:
|
||||||
|
${rule}
|
||||||
|
% endfor
|
||||||
|
# / ${ruleset}
|
||||||
|
% endfor
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
table nat {
|
||||||
|
chain prerouting {
|
||||||
|
type nat hook prerouting priority -100
|
||||||
|
|
||||||
|
% for rule in node.metadata.get('nftables/rules/nat_prerouting', []):
|
||||||
|
${rule}
|
||||||
|
% endfor
|
||||||
|
}
|
||||||
|
chain postrouting {
|
||||||
|
type nat hook postrouting priority 100
|
||||||
|
|
||||||
|
% for rule in node.metadata.get('nftables/rules/nat_postrouting', []):
|
||||||
|
${rule}
|
||||||
|
% endfor
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
include "/etc/nftables-rules.d/*-*"
|
35
bundles/nftables/items.py
Normal file
35
bundles/nftables/items.py
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
if node.has_bundle('pacman'):
|
||||||
|
package = 'pkg_pacman:nftables'
|
||||||
|
else:
|
||||||
|
package = 'pkg_apt:nftables'
|
||||||
|
|
||||||
|
directories = {
|
||||||
|
# used by other bundles
|
||||||
|
'/etc/nftables-rules.d': {
|
||||||
|
'purge': True,
|
||||||
|
'triggers': {
|
||||||
|
'svc_systemd:nftables:reload',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
files = {
|
||||||
|
'/etc/nftables.conf': {
|
||||||
|
'content_type': 'mako',
|
||||||
|
'needs': {
|
||||||
|
'directory:/etc/nftables-rules.d',
|
||||||
|
},
|
||||||
|
'triggers': {
|
||||||
|
'svc_systemd:nftables:reload',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
svc_systemd = {
|
||||||
|
'nftables': {
|
||||||
|
'needs': {
|
||||||
|
'file:/etc/nftables.conf',
|
||||||
|
package,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
91
bundles/nftables/metadata.py
Normal file
91
bundles/nftables/metadata.py
Normal file
|
@ -0,0 +1,91 @@
|
||||||
|
from bundlewrap.exceptions import BundleError
|
||||||
|
|
||||||
|
defaults = {
|
||||||
|
'apt': {
|
||||||
|
'packages': {
|
||||||
|
'nftables': {},
|
||||||
|
|
||||||
|
# XXX remove after all systems have been migrated
|
||||||
|
},
|
||||||
|
},
|
||||||
|
'pacman': {
|
||||||
|
'packages': {
|
||||||
|
'nftables': {},
|
||||||
|
'iptables-nft': {
|
||||||
|
# uninstalls iptables automatically
|
||||||
|
'needed_by': {
|
||||||
|
'pkg_pacman:nftables',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
if not node.has_bundle('vmhost'):
|
||||||
|
# see comment in bundles/vmhost/items.py
|
||||||
|
defaults['apt']['packages']['iptables'] = {
|
||||||
|
'installed': False,
|
||||||
|
'needed_by': {
|
||||||
|
'pkg_apt:nftables',
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
@metadata_reactor.provides(
|
||||||
|
'nftables/rules/input/port_rules',
|
||||||
|
)
|
||||||
|
def port_rules_to_nftables(metadata):
|
||||||
|
# Using this, bundles can simply set up port based rules. This
|
||||||
|
# reactor will then take care of converting those rules to actual
|
||||||
|
# nftables 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('firewall/port_rules', {}).items():
|
||||||
|
if '/' in portdef:
|
||||||
|
port, proto = portdef.split('/', 2)
|
||||||
|
|
||||||
|
if proto not in {'udp'}:
|
||||||
|
raise BundleError(f'firewall/port_rules: illegal identifier {portdef} in metadata for {node.name}')
|
||||||
|
else:
|
||||||
|
port = portdef
|
||||||
|
proto = 'tcp'
|
||||||
|
|
||||||
|
for target in targets:
|
||||||
|
if port == '*' and target == '*':
|
||||||
|
raise BundleError('firewall/port_rules: setting both port and target to * is unsupported')
|
||||||
|
|
||||||
|
comment = f'# port_rules {target}'
|
||||||
|
|
||||||
|
if port != '*':
|
||||||
|
if ':' in port:
|
||||||
|
parts = port.split(':')
|
||||||
|
port_str = f'dport {{ {parts[0]}-{parts[1]} }} '
|
||||||
|
else:
|
||||||
|
port_str = f'dport {port} '
|
||||||
|
prefix = ''
|
||||||
|
else:
|
||||||
|
port_str = ''
|
||||||
|
prefix = 'meta l4proto '
|
||||||
|
|
||||||
|
if target == '*':
|
||||||
|
ruleset.add(f'{prefix}{proto} {port_str}accept {comment}')
|
||||||
|
else:
|
||||||
|
resolved = repo.libs.tools.resolve_identifier(repo, target)
|
||||||
|
|
||||||
|
for address in resolved['ipv4']:
|
||||||
|
ruleset.add(f'{prefix}{proto} {port_str}ip saddr {address} accept {comment}')
|
||||||
|
|
||||||
|
for address in resolved['ipv6']:
|
||||||
|
ruleset.add(f'{prefix}{proto} {port_str}ip6 saddr {address} accept {comment}')
|
||||||
|
|
||||||
|
return {
|
||||||
|
'nftables': {
|
||||||
|
'rules': {
|
||||||
|
# order does not matter here.
|
||||||
|
'input': {
|
||||||
|
'port_rules': sorted(ruleset),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
|
@ -169,12 +169,12 @@ def monitoring(metadata):
|
||||||
|
|
||||||
|
|
||||||
@metadata_reactor.provides(
|
@metadata_reactor.provides(
|
||||||
'iptables/port_rules/80',
|
'firewall/port_rules/80',
|
||||||
'iptables/port_rules/443',
|
'firewall/port_rules/443',
|
||||||
)
|
)
|
||||||
def iptables(metadata):
|
def firewall(metadata):
|
||||||
return {
|
return {
|
||||||
'iptables': {
|
'firewall': {
|
||||||
'port_rules': {
|
'port_rules': {
|
||||||
'80': atomic(metadata.get('nginx/restrict-to', {'*'})),
|
'80': atomic(metadata.get('nginx/restrict-to', {'*'})),
|
||||||
'443': atomic(metadata.get('nginx/restrict-to', {'*'})),
|
'443': atomic(metadata.get('nginx/restrict-to', {'*'})),
|
||||||
|
|
|
@ -10,11 +10,11 @@ defaults = {
|
||||||
|
|
||||||
|
|
||||||
@metadata_reactor.provides(
|
@metadata_reactor.provides(
|
||||||
'iptables/port_rules/113',
|
'firewall/port_rules/113',
|
||||||
)
|
)
|
||||||
def iptables(metadata):
|
def firewall(metadata):
|
||||||
return {
|
return {
|
||||||
'iptables': {
|
'firewall': {
|
||||||
'port_rules': {
|
'port_rules': {
|
||||||
'113': atomic(metadata.get('oidentd/restrict-to', {'*'})),
|
'113': atomic(metadata.get('oidentd/restrict-to', {'*'})),
|
||||||
},
|
},
|
||||||
|
|
|
@ -16,11 +16,11 @@ defaults = {
|
||||||
}
|
}
|
||||||
|
|
||||||
@metadata_reactor.provides(
|
@metadata_reactor.provides(
|
||||||
'iptables/port_rules/22',
|
'firewall/port_rules/22',
|
||||||
)
|
)
|
||||||
def iptables(metadata):
|
def firewall(metadata):
|
||||||
return {
|
return {
|
||||||
'iptables': {
|
'firewall': {
|
||||||
'port_rules': {
|
'port_rules': {
|
||||||
'22': atomic(metadata.get('openssh/restrict-to', {'*'})),
|
'22': atomic(metadata.get('openssh/restrict-to', {'*'})),
|
||||||
},
|
},
|
||||||
|
|
|
@ -18,7 +18,7 @@ alias_maps = hash:/etc/aliases
|
||||||
relayhost = ${node.metadata['postfix']['relayhost']}
|
relayhost = ${node.metadata['postfix']['relayhost']}
|
||||||
% endif
|
% endif
|
||||||
|
|
||||||
% if node.has_bundle('postfixadmin') or node.has_bundle('iptables'):
|
% if node.has_bundle('postfixadmin') or node.has_bundle('nftables'):
|
||||||
inet_interfaces = all
|
inet_interfaces = all
|
||||||
% else:
|
% else:
|
||||||
inet_interfaces = 127.0.0.1
|
inet_interfaces = 127.0.0.1
|
||||||
|
|
|
@ -100,11 +100,11 @@ def letsencrypt(metadata):
|
||||||
|
|
||||||
|
|
||||||
@metadata_reactor.provides(
|
@metadata_reactor.provides(
|
||||||
'iptables/port_rules/25',
|
'firewall/port_rules/25',
|
||||||
'iptables/port_rules/587',
|
'firewall/port_rules/587',
|
||||||
'iptables/port_rules/2525',
|
'firewall/port_rules/2525',
|
||||||
)
|
)
|
||||||
def iptables(metadata):
|
def firewall(metadata):
|
||||||
if node.has_bundle('postfixadmin'):
|
if node.has_bundle('postfixadmin'):
|
||||||
default = {'*'}
|
default = {'*'}
|
||||||
else:
|
else:
|
||||||
|
@ -119,7 +119,7 @@ def iptables(metadata):
|
||||||
rules['2525'] = atomic(metadata.get('postfix/restrict-to', default))
|
rules['2525'] = atomic(metadata.get('postfix/restrict-to', default))
|
||||||
|
|
||||||
return {
|
return {
|
||||||
'iptables': {
|
'firewall': {
|
||||||
'port_rules': rules,
|
'port_rules': rules,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
|
@ -182,11 +182,11 @@ def hosts_entries_for_all_dns_servers(metadata):
|
||||||
|
|
||||||
|
|
||||||
@metadata_reactor.provides(
|
@metadata_reactor.provides(
|
||||||
'iptables/port_rules',
|
'firewall/port_rules',
|
||||||
)
|
)
|
||||||
def iptables(metadata):
|
def firewall(metadata):
|
||||||
return {
|
return {
|
||||||
'iptables': {
|
'firewall': {
|
||||||
'port_rules': {
|
'port_rules': {
|
||||||
'53': atomic(metadata.get('powerdns/restrict-to', {'*'})),
|
'53': atomic(metadata.get('powerdns/restrict-to', {'*'})),
|
||||||
'53/udp': atomic(metadata.get('powerdns/restrict-to', {'*'})),
|
'53/udp': atomic(metadata.get('powerdns/restrict-to', {'*'})),
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
rm /etc/iptables-rules.d/90-pppd
|
rm /etc/nftables-rules.d/90-pppd
|
||||||
rm /etc/sysctl.d/90-pppd.conf
|
rm /etc/sysctl.d/90-pppd.conf
|
||||||
|
|
||||||
/usr/local/sbin/iptables-enforce
|
systemctl reload nftables
|
||||||
|
|
|
@ -2,9 +2,9 @@
|
||||||
|
|
||||||
INTERFACE=$1
|
INTERFACE=$1
|
||||||
|
|
||||||
echo "iptables -t nat -A POSTROUTING -o $INTERFACE -j MASQUERADE" > /etc/iptables-rules.d/90-pppd
|
echo "add rule nat postrouting oif $INTERFACE masquerade" > /etc/nftables-rules.d/90-pppd
|
||||||
echo "net.ipv6.conf.$INTERFACE.accept_ra=2" > /etc/sysctl.d/90-pppd.conf
|
echo "net.ipv6.conf.$INTERFACE.accept_ra=2" > /etc/sysctl.d/90-pppd.conf
|
||||||
|
|
||||||
/usr/local/sbin/iptables-enforce
|
systemctl reload nftables
|
||||||
|
|
||||||
rdisc6 $INTERFACE
|
rdisc6 $INTERFACE
|
||||||
|
|
|
@ -32,7 +32,7 @@ directories = {
|
||||||
}
|
}
|
||||||
|
|
||||||
files = {
|
files = {
|
||||||
'/etc/iptables-rules.d/90-pppd': {
|
'/etc/nftables-rules.d/90-pppd': {
|
||||||
'content_type': 'any',
|
'content_type': 'any',
|
||||||
},
|
},
|
||||||
'/etc/ppp/chap-secrets': {
|
'/etc/ppp/chap-secrets': {
|
||||||
|
@ -53,11 +53,11 @@ files = {
|
||||||
'svc_systemd:pppoe:restart',
|
'svc_systemd:pppoe:restart',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
'/etc/ppp/ip-down.d/iptables': {
|
'/etc/ppp/ip-down.d/nftables': {
|
||||||
'source': 'ip-down',
|
'source': 'ip-down',
|
||||||
'mode': '0755',
|
'mode': '0755',
|
||||||
},
|
},
|
||||||
'/etc/ppp/ip-up.d/iptables': {
|
'/etc/ppp/ip-up.d/nftables': {
|
||||||
'source': 'ip-up',
|
'source': 'ip-up',
|
||||||
'mode': '0755',
|
'mode': '0755',
|
||||||
},
|
},
|
||||||
|
|
|
@ -50,11 +50,11 @@ if node.has_bundle('telegraf'):
|
||||||
|
|
||||||
|
|
||||||
@metadata_reactor.provides(
|
@metadata_reactor.provides(
|
||||||
'iptables/port_rules',
|
'firewall/port_rules',
|
||||||
)
|
)
|
||||||
def iptables(metadata):
|
def firewall(metadata):
|
||||||
return {
|
return {
|
||||||
'iptables': {
|
'firewall': {
|
||||||
'port_rules': {
|
'port_rules': {
|
||||||
str(metadata.get('transmission/config/peer-port')): atomic({'*'}),
|
str(metadata.get('transmission/config/peer-port')): atomic({'*'}),
|
||||||
str(metadata.get('transmission/config/peer-port')) + '/udp': atomic({'*'}),
|
str(metadata.get('transmission/config/peer-port')) + '/udp': atomic({'*'}),
|
||||||
|
|
|
@ -10,8 +10,8 @@ server:
|
||||||
|
|
||||||
num-threads: ${threads}
|
num-threads: ${threads}
|
||||||
|
|
||||||
% if node.has_bundle('iptables') and not node.has_bundle('vmhost'):
|
% if node.has_bundle('nftables') and not node.has_bundle('vmhost'):
|
||||||
# Use iptables to manage access to this service
|
# Use nftables to manage access to this service
|
||||||
interface: 0.0.0.0
|
interface: 0.0.0.0
|
||||||
interface: ::0
|
interface: ::0
|
||||||
access-control: 0.0.0.0/0 allow
|
access-control: 0.0.0.0/0 allow
|
||||||
|
|
|
@ -56,11 +56,11 @@ def cpu_cores_to_config_values(metadata):
|
||||||
|
|
||||||
|
|
||||||
@metadata_reactor.provides(
|
@metadata_reactor.provides(
|
||||||
'iptables/port_rules',
|
'firewall/port_rules',
|
||||||
)
|
)
|
||||||
def iptables(metadata):
|
def firewall(metadata):
|
||||||
return {
|
return {
|
||||||
'iptables': {
|
'firewall': {
|
||||||
'port_rules': {
|
'port_rules': {
|
||||||
'53': atomic(metadata.get('unbound/restrict-to', set())),
|
'53': atomic(metadata.get('unbound/restrict-to', set())),
|
||||||
'53/udp': atomic(metadata.get('unbound/restrict-to', set())),
|
'53/udp': atomic(metadata.get('unbound/restrict-to', set())),
|
||||||
|
|
|
@ -3,3 +3,24 @@ files = {
|
||||||
'mode': '0755',
|
'mode': '0755',
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if node.has_bundle('nftables'):
|
||||||
|
# libvirt on debian depends on either iptables or firewalld. Since
|
||||||
|
# we're managing firewall rules using bundlewrap, we don't want either
|
||||||
|
# of thos to interfere. So we install firewalld, then ensure it is
|
||||||
|
# never running. After that, we ensure the bundlewrap managed rules
|
||||||
|
# are active.
|
||||||
|
svc_systemd['firewalld'] = {
|
||||||
|
'running': False,
|
||||||
|
'enabled': False,
|
||||||
|
'masked': True,
|
||||||
|
'needs': {
|
||||||
|
'pkg_apt:firewalld',
|
||||||
|
},
|
||||||
|
'needed_by': {
|
||||||
|
'svc_systemd:nftables',
|
||||||
|
},
|
||||||
|
'triggers': {
|
||||||
|
'svc_systemd:nftables:reload',
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
|
@ -28,3 +28,10 @@ if node.os == 'debian' and node.os_version[0] < 11:
|
||||||
|
|
||||||
if node.has_bundle('zfs'):
|
if node.has_bundle('zfs'):
|
||||||
defaults['apt']['packages']['libvirt-daemon-driver-storage-zfs'] = {}
|
defaults['apt']['packages']['libvirt-daemon-driver-storage-zfs'] = {}
|
||||||
|
|
||||||
|
if node.has_bundle('nftables'):
|
||||||
|
defaults['apt']['packages']['firewalld'] = {
|
||||||
|
'needed_by': {
|
||||||
|
'pkg_apt:libvirt-daemon-system',
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
|
@ -16,11 +16,11 @@ defaults = {
|
||||||
|
|
||||||
|
|
||||||
@metadata_reactor.provides(
|
@metadata_reactor.provides(
|
||||||
'iptables/port_rules',
|
'firewall/port_rules',
|
||||||
)
|
)
|
||||||
def iptables(metadata):
|
def firewall(metadata):
|
||||||
return {
|
return {
|
||||||
'iptables': {
|
'firewall': {
|
||||||
'port_rules': {
|
'port_rules': {
|
||||||
str(metadata.get('webfs/port')): atomic(metadata.get('webfs/restrict-to', {'*'})),
|
str(metadata.get('webfs/port')): atomic(metadata.get('webfs/restrict-to', {'*'})),
|
||||||
},
|
},
|
||||||
|
|
|
@ -4,12 +4,14 @@ defaults = {
|
||||||
'wide-dhcpv6-client': {},
|
'wide-dhcpv6-client': {},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
'iptables': {
|
'nftables': {
|
||||||
'bundle_rules': {
|
'rules': {
|
||||||
'wide-dhcp6c': [
|
'input': {
|
||||||
'ip6tables -A INPUT -p udp -s ff00::/12 -j ACCEPT',
|
'wide-dhcp6c': [
|
||||||
'ip6tables -A INPUT -p udp -s fe80::/10 -j ACCEPT',
|
'udp dport { 546, 547 } ip6 saddr ff00::/12 accept',
|
||||||
],
|
'udp dport { 546, 547 } ip6 saddr fe80::/10 accept',
|
||||||
|
],
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
'icinga2_api': {
|
'icinga2_api': {
|
||||||
|
|
|
@ -18,12 +18,14 @@ defaults = {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
'iptables': {
|
'nftables': {
|
||||||
'bundle_rules': {
|
'rules': {
|
||||||
'wireguard': [
|
'forward': {
|
||||||
'iptables_both -A FORWARD -i wg0 -j ACCEPT',
|
'wireguard': [
|
||||||
'iptables_both -A FORWARD -o wg0 -j ACCEPT',
|
'iif wg0 accept',
|
||||||
],
|
'oif wg0 accept',
|
||||||
|
],
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
'wireguard': {
|
'wireguard': {
|
||||||
|
@ -149,9 +151,9 @@ def icinga2(metadata):
|
||||||
|
|
||||||
|
|
||||||
@metadata_reactor.provides(
|
@metadata_reactor.provides(
|
||||||
'iptables/port_rules',
|
'firewall/port_rules',
|
||||||
)
|
)
|
||||||
def iptables(metadata):
|
def firewall(metadata):
|
||||||
sources = set(metadata.get('wireguard/restrict-to', set()))
|
sources = set(metadata.get('wireguard/restrict-to', set()))
|
||||||
for peer_name in metadata.get('wireguard/peers'):
|
for peer_name in metadata.get('wireguard/peers'):
|
||||||
try:
|
try:
|
||||||
|
@ -162,7 +164,7 @@ def iptables(metadata):
|
||||||
sources.add(peer_name)
|
sources.add(peer_name)
|
||||||
|
|
||||||
return {
|
return {
|
||||||
'iptables': {
|
'firewall': {
|
||||||
'port_rules': {
|
'port_rules': {
|
||||||
'51820/udp': atomic(sources),
|
'51820/udp': atomic(sources),
|
||||||
},
|
},
|
||||||
|
|
|
@ -20,7 +20,7 @@ groups['linux'] = {
|
||||||
'bundles': {
|
'bundles': {
|
||||||
'basic',
|
'basic',
|
||||||
'cron',
|
'cron',
|
||||||
'iptables',
|
'nftables',
|
||||||
'openssh',
|
'openssh',
|
||||||
'postfix',
|
'postfix',
|
||||||
'sshmon',
|
'sshmon',
|
||||||
|
@ -39,7 +39,7 @@ groups['linux'] = {
|
||||||
'backup-client': {
|
'backup-client': {
|
||||||
'server': 'franzi-home.kunbox.net:2022',
|
'server': 'franzi-home.kunbox.net:2022',
|
||||||
},
|
},
|
||||||
'iptables': {
|
'firewall': {
|
||||||
'port_rules': {
|
'port_rules': {
|
||||||
'*': {
|
'*': {
|
||||||
'ovh.icinga2',
|
'ovh.icinga2',
|
||||||
|
|
|
@ -55,7 +55,7 @@ nodes['home.nas'] = {
|
||||||
'groups': {
|
'groups': {
|
||||||
'nas': {},
|
'nas': {},
|
||||||
},
|
},
|
||||||
'iptables': {
|
'firewall': {
|
||||||
'port_rules': {
|
'port_rules': {
|
||||||
'4679': { # Dell ULNM
|
'4679': { # Dell ULNM
|
||||||
'172.19.136.0/25',
|
'172.19.136.0/25',
|
||||||
|
|
|
@ -94,24 +94,27 @@ nodes['home.router'] = {
|
||||||
'vars.notification.sms': True
|
'vars.notification.sms': True
|
||||||
},
|
},
|
||||||
|
|
||||||
'iptables': {
|
'nftables': {
|
||||||
'custom_rules': [
|
'rules': {
|
||||||
# This is a router. Allow forwarding traffic for internal networks.
|
'forward': {
|
||||||
'iptables_both -A FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT',
|
'router': [
|
||||||
'iptables_both -A FORWARD -i enp1s0.23 -o ppp0 -j ACCEPT',
|
# This is a router. Allow forwarding traffic for internal networks.
|
||||||
'iptables_both -A FORWARD -i enp1s0.42 -j ACCEPT',
|
'ct state { related, established } accept',
|
||||||
|
'iif enp1s0.23 oif ppp0 accept',
|
||||||
|
'iif enp1s0.42 accept',
|
||||||
|
|
||||||
# External port 2022 should be home.nas
|
# yaaaaay, IPv6! No NAT!
|
||||||
'iptables -t nat -A PREROUTING -p tcp --dport 2022 -j DNAT --to 172.19.138.20:22',
|
'ip6 nexthdr ipv6-icmp accept',
|
||||||
'iptables -A FORWARD -p tcp -d 172.19.138.20 --dport 22 -j ACCEPT',
|
'tcp dport 22 accept',
|
||||||
|
],
|
||||||
# use MASQUERADE for tun0 (c3voc)
|
},
|
||||||
'iptables -t nat -A POSTROUTING -o tun0 -j MASQUERADE',
|
'nat_prerouting': [
|
||||||
|
'tcp dport 2022 dnat 172.19.138.20:22',
|
||||||
# yaaaaay, IPv6! No NAT!
|
],
|
||||||
'ip6tables -A FORWARD -p ipv6-icmp -j ACCEPT',
|
'nat_postrouting': [
|
||||||
'ip6tables -A FORWARD -p tcp --dport 22 -j ACCEPT',
|
'oif tun0 masquerade',
|
||||||
],
|
],
|
||||||
|
},
|
||||||
},
|
},
|
||||||
'netdata': {
|
'netdata': {
|
||||||
'restrict-to': {
|
'restrict-to': {
|
||||||
|
|
|
@ -83,13 +83,6 @@ nodes['htz-cloud.miniserver'] = {
|
||||||
'icinga_options': {
|
'icinga_options': {
|
||||||
'vars.notification.sms': False,
|
'vars.notification.sms': False,
|
||||||
},
|
},
|
||||||
'iptables': {
|
|
||||||
'custom_rules': [
|
|
||||||
'iptables_both -A INPUT -p udp --dport 60000:61000 -j ACCEPT', # mosh
|
|
||||||
'iptables_both -A INPUT -p tcp --dport 9001 -j ACCEPT', # weechat
|
|
||||||
|
|
||||||
],
|
|
||||||
},
|
|
||||||
'letsencrypt': {
|
'letsencrypt': {
|
||||||
'concat_and_deploy': {
|
'concat_and_deploy': {
|
||||||
'sophie-weechat': {
|
'sophie-weechat': {
|
||||||
|
@ -151,6 +144,16 @@ nodes['htz-cloud.miniserver'] = {
|
||||||
'bot_token': '""',
|
'bot_token': '""',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
'nftables': {
|
||||||
|
'rules': {
|
||||||
|
'input': {
|
||||||
|
'sophie-weechat': [
|
||||||
|
'udp dport { 60000-61000 } accept',
|
||||||
|
'tcp dport 9001 accept',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
'nginx': {
|
'nginx': {
|
||||||
'vhosts': {
|
'vhosts': {
|
||||||
#'dimension.sophies-kitchen.eu': {
|
#'dimension.sophies-kitchen.eu': {
|
||||||
|
|
|
@ -137,24 +137,6 @@ nodes['htz.ex42-1048908'] = {
|
||||||
'icinga_options': {
|
'icinga_options': {
|
||||||
'pretty_name': 'kunsmann.eu',
|
'pretty_name': 'kunsmann.eu',
|
||||||
},
|
},
|
||||||
'iptables': {
|
|
||||||
# TODO move to bundles
|
|
||||||
'custom_rules': [
|
|
||||||
'iptables_both -A INPUT -p udp --dport 60000:61000 -j ACCEPT', # mosh
|
|
||||||
'iptables_both -A INPUT -p tcp --dport 9001 -j ACCEPT', # weechat
|
|
||||||
|
|
||||||
# libvirt rules. These are also added by libvirt itself,
|
|
||||||
# but they would be overridden by our own iptables
|
|
||||||
# management.
|
|
||||||
'iptables -A INPUT -i virbr0 -p udp --dport 53 -j ACCEPT',
|
|
||||||
'iptables -A INPUT -i virbr0 -p tcp --dport 53 -j ACCEPT',
|
|
||||||
'iptables -A INPUT -i virbr0 -p udp --dport 67:68 -j ACCEPT',
|
|
||||||
'iptables -A INPUT -i virbr0 -p tcp --dport 67:68 -j ACCEPT',
|
|
||||||
'iptables -A FORWARD -i virbr0 -j ACCEPT',
|
|
||||||
'iptables -A FORWARD -o virbr0 -j ACCEPT',
|
|
||||||
'iptables -t nat -A POSTROUTING -o enp0s31f6 -j MASQUERADE',
|
|
||||||
],
|
|
||||||
},
|
|
||||||
'letsencrypt': {
|
'letsencrypt': {
|
||||||
'concat_and_deploy': {
|
'concat_and_deploy': {
|
||||||
'kunsi-weechat': {
|
'kunsi-weechat': {
|
||||||
|
@ -247,6 +229,30 @@ nodes['htz.ex42-1048908'] = {
|
||||||
'@.*:franzi\\\\.business',
|
'@.*:franzi\\\\.business',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
'nftables': {
|
||||||
|
'rules': {
|
||||||
|
'input': {
|
||||||
|
'kunsi-weechat': [
|
||||||
|
'udp dport { 60000-61000 } accept',
|
||||||
|
'tcp dport 9001 accept',
|
||||||
|
],
|
||||||
|
'libvirt': [
|
||||||
|
'tcp dport 53 iif virbr0 accept',
|
||||||
|
'udp dport 53 iif virbr0 accept',
|
||||||
|
'udp dport { 67, 68 } iif virbr0 accept',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
'forward': {
|
||||||
|
'libvirt': [
|
||||||
|
'iif virbr0 accept',
|
||||||
|
'oif virbr0 accept',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
'nat_postrouting': {
|
||||||
|
'oif enp0s31f6 masquerade',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
'nginx': {
|
'nginx': {
|
||||||
'vhosts': {
|
'vhosts': {
|
||||||
# TODO maybe some of this can be moved to a bundle?
|
# TODO maybe some of this can be moved to a bundle?
|
||||||
|
|
|
@ -31,7 +31,7 @@ nodes['kunsi-t470'] = {
|
||||||
},
|
},
|
||||||
# there is also wlp4s0, but that's managed by netctl
|
# there is also wlp4s0, but that's managed by netctl
|
||||||
},
|
},
|
||||||
'iptables': {
|
'firewall': {
|
||||||
'port_rules': {
|
'port_rules': {
|
||||||
# For the occasional file-share using `python -m http.server`
|
# For the occasional file-share using `python -m http.server`
|
||||||
'8000': {'*'},
|
'8000': {'*'},
|
||||||
|
|
Loading…
Reference in a new issue