bundlewrap/bundles/wireguard/metadata.py
mwiegand c9297d2b37 wip
2021-06-25 02:01:52 +02:00

162 lines
4 KiB
Python

from ipaddress import ip_network, ip_interface
from bundlewrap.exceptions import NoSuchNode
from bundlewrap.metadata import atomic
defaults = {
'apt': {
'packages': {
'wireguard': {},
},
},
'wireguard': {
'privatekey': repo.libs.keys.gen_privkey(repo, f'{node.name} wireguard privatekey'),
},
}
@metadata_reactor.provides(
'systemd-networkd/networks',
)
def systemd_networkd_networks(metadata):
return {
'systemd-networkd': {
'networks': {
'wg0': {
'Match': {
'Name': 'wg0',
},
'Address': {
'Address': metadata.get('wireguard/my_ip'),
},
'Route': {
'Destination': str(ip_interface(metadata.get('wireguard/my_ip')).network),
'GatewayOnlink': 'yes',
},
'Network': {
'DHCP': 'no',
'IPForward': 'yes',
'IPMasquerade': 'yes',
'IPv6AcceptRA': 'no',
},
},
},
},
}
@metadata_reactor.provides(
'systemd-networkd/netdevs',
)
def systemd_networkd_netdevs(metadata):
wg0 = {
'NetDev': {
'Name': 'wg0',
'Kind': 'wireguard',
'Description': 'WireGuard server',
},
'WireGuard': {
'PrivateKey': metadata.get('wireguard/privatekey'),
'ListenPort': 51820,
},
}
for name, config in metadata.get('wireguard/peers').items():
wg0.update({
f'WireGuardPeer#{name}': {
'Endpoint': config['endpoint'],
'PublicKey': config['pubkey'],
'PresharedKey': config['psk'],
'AllowedIPs': '0.0.0.0/0', # FIXME
'PersistentKeepalive': 30,
}
})
return {
'systemd-networkd': {
'netdevs': {
'wg0': wg0,
},
},
}
@metadata_reactor.provides(
'wireguard/peers',
)
def peer_psks(metadata):
peers = {}
for peer_name in metadata.get('wireguard/peers', {}):
peers[peer_name] = {}
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 {
'wireguard': {
'peers': peers,
},
}
@metadata_reactor.provides(
'wireguard/peers',
)
def peer_pubkeys(metadata):
peers = {}
for peer_name in metadata.get('wireguard/peers', {}):
try:
rnode = repo.get_node(peer_name)
except NoSuchNode:
continue
peers[peer_name] = {
'pubkey': repo.libs.keys.get_pubkey_from_privkey(
repo,
f'{rnode.name} wireguard pubkey',
rnode.metadata.get('wireguard/privatekey'),
),
}
return {
'wireguard': {
'peers': peers,
},
}
@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': {
'peers': peers,
},
}