bundles/wireguard: rework metadata.py
Some checks failed
bundlewrap/pipeline/head There was a failure building this commit
Some checks failed
bundlewrap/pipeline/head There was a failure building this commit
This commit is contained in:
parent
b679f568eb
commit
6e423c24fb
7 changed files with 155 additions and 64 deletions
|
@ -1,8 +0,0 @@
|
|||
[Match]
|
||||
Name=wg0
|
||||
|
||||
[Network]
|
||||
Address=${my_ip}
|
||||
|
||||
[Route]
|
||||
Destination=${network}
|
|
@ -1,21 +1,16 @@
|
|||
from ipaddress import ip_network
|
||||
|
||||
assert node.has_bundle('systemd-networkd')
|
||||
|
||||
network = ip_network(node.metadata['wireguard']['my_ip'], strict=False)
|
||||
|
||||
files = {
|
||||
'/etc/systemd/network/99-wg0.netdev': {
|
||||
'source': 'wg0.netdev',
|
||||
'/etc/systemd/network/wg0.netdev': {
|
||||
'content_type': 'mako',
|
||||
'context': node.metadata['wireguard'],
|
||||
'needs': {
|
||||
'pkg_apt:wireguard',
|
||||
'context': {
|
||||
'network': f'{network.network_address}/{network.prefixlen}',
|
||||
**node.metadata['wireguard'],
|
||||
},
|
||||
'triggers': {
|
||||
'svc_systemd:systemd-networkd:restart',
|
||||
},
|
||||
},
|
||||
'/etc/systemd/network/99-wg0.network': {
|
||||
'source': 'wg0.network',
|
||||
'content_type': 'mako',
|
||||
'context': node.metadata['wireguard'],
|
||||
'needs': {
|
||||
'pkg_apt:wireguard',
|
||||
},
|
||||
|
|
|
@ -1,5 +1,9 @@
|
|||
from ipaddress import ip_network
|
||||
|
||||
from bundlewrap.exceptions import NoSuchNode
|
||||
from bundlewrap.metadata import atomic
|
||||
|
||||
|
||||
defaults = {
|
||||
'apt': {
|
||||
'packages': {
|
||||
|
@ -16,10 +20,10 @@ defaults = {
|
|||
},
|
||||
'iptables': {
|
||||
'bundle_rules': {
|
||||
'wireguard': [
|
||||
'wireguard': {
|
||||
'iptables_both -A FORWARD -i wg0 -j ACCEPT',
|
||||
'iptables_both -A FORWARD -o wg0 -j ACCEPT',
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
'wireguard': {
|
||||
|
@ -29,51 +33,77 @@ defaults = {
|
|||
|
||||
|
||||
@metadata_reactor.provides(
|
||||
'wireguard/network',
|
||||
'wireguard/peers',
|
||||
)
|
||||
def get_wireguard_network_from_server(metadata):
|
||||
# FIXME This will break if more than one node sets 'wireguard/network'
|
||||
for rnode in repo.nodes:
|
||||
if not rnode.has_bundle('wireguard'):
|
||||
continue
|
||||
def peer_psks(metadata):
|
||||
peers = {}
|
||||
|
||||
if node.name in rnode.metadata.get('wireguard/peers', {}).keys():
|
||||
network = rnode.metadata.get('wireguard/network', None)
|
||||
for peer_name in metadata.get('wireguard/peers', {}):
|
||||
peers[peer_name] = {}
|
||||
|
||||
if network:
|
||||
return {
|
||||
'wireguard': {
|
||||
'network': network,
|
||||
},
|
||||
}
|
||||
if node.name < peer_name:
|
||||
peers[peer_name] = {
|
||||
'psk': repo.vault.random_bytes_as_base64_for(f'{node.name} wireguard {peer_name}'),
|
||||
}
|
||||
else:
|
||||
peers[peer_name] = {
|
||||
'psk': repo.vault.random_bytes_as_base64_for(f'{peer_name} wireguard {node.name}'),
|
||||
}
|
||||
|
||||
return {}
|
||||
return {
|
||||
'wireguard': {
|
||||
'peers': peers,
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
@metadata_reactor.provides(
|
||||
'wireguard/peers',
|
||||
)
|
||||
def get_my_wireguard_peers(metadata):
|
||||
def peer_pubkeys(metadata):
|
||||
peers = {}
|
||||
|
||||
for rnode in repo.nodes:
|
||||
if not rnode.has_bundle('wireguard'):
|
||||
for peer_name in metadata.get('wireguard/peers', {}):
|
||||
try:
|
||||
rnode = repo.get_node(peer_name)
|
||||
except NoSuchNode:
|
||||
continue
|
||||
|
||||
if node.name in rnode.metadata.get('wireguard/peers', {}).keys():
|
||||
peers[rnode.name] = {
|
||||
'pubkey': repo.libs.keys.get_pubkey_from_privkey(repo, f'{node.name} wireguard {rnode.name}', rnode.metadata.get('wireguard/privatekey')),
|
||||
'psk': rnode.metadata.get('wireguard/psk', metadata.get('wireguard/psk', None)),
|
||||
}
|
||||
peers[peer_name] = {
|
||||
'pubkey': repo.libs.keys.get_pubkey_from_privkey(
|
||||
repo,
|
||||
f'{rnode.name} wireguard pubkey',
|
||||
rnode.metadata.get('wireguard/privatekey'),
|
||||
),
|
||||
}
|
||||
|
||||
if not rnode.metadata.get(f'wireguard/peers/{node.name}/do_not_initiate_a_connection_from_your_side', False):
|
||||
peers[rnode.name]['endpoint'] = f'{rnode.hostname}:51820'
|
||||
return {
|
||||
'wireguard': {
|
||||
'peers': peers,
|
||||
},
|
||||
}
|
||||
|
||||
peers[rnode.name]['ips'] = rnode.metadata.get('wireguard/subnets', set())
|
||||
|
||||
your_ip = rnode.metadata.get('wireguard/my_ip', None)
|
||||
if your_ip:
|
||||
peers[rnode.name]['ips'].add(your_ip)
|
||||
@metadata_reactor.provides(
|
||||
'wireguard/peers',
|
||||
)
|
||||
def peer_ips_and_endpoints(metadata):
|
||||
peers = {}
|
||||
|
||||
for peer_name in metadata.get('wireguard/peers', {}):
|
||||
try:
|
||||
rnode = repo.get_node(peer_name)
|
||||
except NoSuchNode:
|
||||
continue
|
||||
|
||||
ips = rnode.metadata.get('wireguard/subnets', set())
|
||||
ips.add(rnode.metadata.get('wireguard/my_ip').split('/')[0])
|
||||
ips = repo.libs.tools.remove_more_specific_subnets(ips)
|
||||
|
||||
peers[rnode.name] = {
|
||||
'endpoint': '{}:51820'.format(rnode.metadata.get('wireguard/external_hostname', rnode.hostname)),
|
||||
'ips': ips,
|
||||
}
|
||||
|
||||
return {
|
||||
'wireguard': {
|
||||
|
@ -109,10 +139,63 @@ def icinga2(metadata):
|
|||
'iptables/port_rules',
|
||||
)
|
||||
def iptables(metadata):
|
||||
sources = set(metadata.get('wireguard/restrict-to', set()))
|
||||
for peer_name in metadata.get('wireguard/peers'):
|
||||
try:
|
||||
rnode = repo.get_node(peer_name)
|
||||
except NoSuchNode: # roadwarrior
|
||||
continue
|
||||
else:
|
||||
sources.add(peer_name)
|
||||
|
||||
return {
|
||||
'iptables': {
|
||||
'port_rules': {
|
||||
'51820/udp': atomic(metadata.get('wireguard/restrict-to', set(metadata.get('wireguard/peers', {}).keys()))),
|
||||
'51820/udp': atomic(sources),
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
@metadata_reactor.provides(
|
||||
'interfaces/wg0/ips',
|
||||
)
|
||||
def interface_ips(metadata):
|
||||
return {
|
||||
'interfaces': {
|
||||
'wg0': {
|
||||
'ips': {
|
||||
metadata.get('wireguard/my_ip'),
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
@metadata_reactor.provides(
|
||||
'interfaces/wg0/routes',
|
||||
)
|
||||
def routes(metadata):
|
||||
network = ip_network(metadata.get('wireguard/my_ip'), strict=False)
|
||||
ips = {
|
||||
f'{network.network_address}/{network.prefixlen}',
|
||||
}
|
||||
routes = {}
|
||||
|
||||
for _, peer_config in metadata.get('wireguard/peers', {}).items():
|
||||
for ip in peer_config['ips']:
|
||||
ips.add(ip)
|
||||
|
||||
if '0.0.0.0/0' in ips:
|
||||
ips.remove('0.0.0.0/0')
|
||||
|
||||
for ip in repo.libs.tools.remove_more_specific_subnets(ips):
|
||||
routes[ip] = {}
|
||||
|
||||
return {
|
||||
'interfaces': {
|
||||
'wg0': {
|
||||
'routes': routes,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
|
|
@ -55,3 +55,26 @@ def resolve_identifier(repo, identifier):
|
|||
ip_dict['ipv6'].add(ip)
|
||||
|
||||
return ip_dict
|
||||
|
||||
|
||||
def remove_more_specific_subnets(input_subnets) -> list:
|
||||
final_subnets = []
|
||||
|
||||
for subnet in sorted(input_subnets):
|
||||
source = ip_network(subnet)
|
||||
|
||||
if not source in final_subnets:
|
||||
subnet_found = False
|
||||
|
||||
for dest_subnet in final_subnets:
|
||||
if source.subnet_of(dest_subnet):
|
||||
subnet_found = True
|
||||
|
||||
if not subnet_found:
|
||||
final_subnets.append(source)
|
||||
|
||||
out = []
|
||||
for net in final_subnets:
|
||||
out.append(str(net))
|
||||
|
||||
return out
|
||||
|
|
|
@ -172,17 +172,15 @@ nodes['home.router'] = {
|
|||
},
|
||||
},
|
||||
'wireguard': {
|
||||
# TODO autogenerate?
|
||||
'my_ip': '172.19.136.2/32',
|
||||
'external_hostname': 'franzi-home.kunbox.net', # Set via DynDNS
|
||||
'my_ip': '172.19.136.2/22',
|
||||
'peers': {
|
||||
'ovh.wireguard': {},
|
||||
},
|
||||
'subnets': {
|
||||
'172.19.138.0/24',
|
||||
'172.19.139.0/24',
|
||||
},
|
||||
'peers': {
|
||||
'ovh.wireguard': {
|
||||
'do_not_initiate_a_connection_from_your_side': True,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
|
|
@ -113,7 +113,7 @@ nodes['ovh.icinga2'] = {
|
|||
'service_filter': '"checks_with_sms" in service.groups'
|
||||
},
|
||||
'wireguard': {
|
||||
'my_ip': '172.19.136.3/32',
|
||||
'my_ip': '172.19.136.3/22',
|
||||
'peers': {
|
||||
'ovh.wireguard': {},
|
||||
},
|
||||
|
|
|
@ -24,10 +24,10 @@ nodes['ovh.wireguard'] = {
|
|||
'ram': 2,
|
||||
},
|
||||
'wireguard': {
|
||||
'network': '172.19.136.0/22',
|
||||
'my_ip': '172.19.136.1/32',
|
||||
'psk': vault.random_bytes_as_base64_for('ovh.icinga2 wireguard psk'),
|
||||
'my_ip': '172.19.136.1/22',
|
||||
'peers': {
|
||||
'ovh.icinga2': {},
|
||||
'home.router': {},
|
||||
'kunsi-oneplus3': {
|
||||
'ips': {
|
||||
'172.19.136.100/32',
|
||||
|
|
Loading…
Reference in a new issue