136 lines
		
	
	
	
		
			3.6 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			136 lines
		
	
	
	
		
			3.6 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
| from ipaddress import ip_network, ip_interface
 | |
| 
 | |
| from bundlewrap.exceptions import NoSuchNode
 | |
| from bundlewrap.metadata import atomic
 | |
| 
 | |
| repo.libs.wireguard.repo = repo
 | |
| 
 | |
| 
 | |
| defaults = {
 | |
|     'apt': {
 | |
|         'packages': {
 | |
|             'wireguard': {
 | |
|                 'backports': node.os_version < (11,),
 | |
|                 'triggers': [
 | |
|                     'svc_systemd:systemd-networkd.service:restart',
 | |
|                 ],
 | |
|             },
 | |
|         },
 | |
|     },
 | |
|     'nftables': {
 | |
|         'input': {
 | |
|             'udp dport 51820 accept',
 | |
|         },
 | |
|     },
 | |
|     'wireguard': {
 | |
|         's2s': {},
 | |
|         'clients': {},
 | |
|     },
 | |
| }
 | |
| 
 | |
| 
 | |
| @metadata_reactor.provides(
 | |
|     'wireguard/s2s',
 | |
|     'wireguard/clients',
 | |
| )
 | |
| def s2s_peer_specific(metadata):
 | |
|     return {
 | |
|         'wireguard': {
 | |
|             's2s': {
 | |
|                 s2s: {
 | |
|                     'peer_id': repo.get_node(s2s).metadata.get(f'id'),
 | |
|                     'peer_ip': repo.get_node(s2s).metadata.get(f'wireguard/my_ip'),
 | |
|                     'endpoint': f'{repo.get_node(s2s).hostname}:51820',
 | |
|                     'allowed_ips': [
 | |
|                         str(ip_interface(repo.get_node(s2s).metadata.get(f'wireguard/my_ip')).network),
 | |
|                     ],
 | |
|                 }
 | |
|                     for s2s in metadata.get('wireguard/s2s')
 | |
|             },
 | |
|             'clients': {
 | |
|                 client: {
 | |
|                     'peer_id': client,
 | |
|                     'allowed_ips': [
 | |
|                         str(ip_interface(conf['peer_ip']).network),
 | |
|                     ],
 | |
|                 }
 | |
|                     for client, conf in metadata.get('wireguard/clients').items()
 | |
|             },
 | |
|         },
 | |
|     }
 | |
| 
 | |
| 
 | |
| @metadata_reactor.provides(
 | |
|     'systemd/units',
 | |
| )
 | |
| def systemd_networkd_networks(metadata):
 | |
|     network = {
 | |
|         'Match': {
 | |
|             'Name': 'wg0',
 | |
|         },
 | |
|         'Address': {
 | |
|             'Address': metadata.get('wireguard/my_ip'),
 | |
|         },
 | |
|         'Network': {
 | |
|             'DHCP': 'no',
 | |
|             'IPForward': 'yes',
 | |
|             'IPv6AcceptRA': 'no',
 | |
|         },
 | |
|     }
 | |
| 
 | |
|     for peer, config in metadata.get('wireguard/s2s').items():
 | |
|         for route in config.get('allowed_ips', []):
 | |
|             network.update({
 | |
|                 f'Route#{peer}_{route}': {
 | |
|                     'Destination': route,
 | |
|                     'Gateway': str(ip_interface(metadata.get('wireguard/my_ip')).ip),
 | |
|                 }
 | |
|             })
 | |
| 
 | |
|     return {
 | |
|         'systemd': {
 | |
|             'units': {
 | |
|                 'wireguard.network':  network,
 | |
|             },
 | |
|         },
 | |
|     }
 | |
| 
 | |
| 
 | |
| @metadata_reactor.provides(
 | |
|     'systemd/units',
 | |
| )
 | |
| def systemd_networkd_netdevs(metadata):
 | |
|     netdev = {
 | |
|         'NetDev': {
 | |
|             'Name': 'wg0',
 | |
|             'Kind': 'wireguard',
 | |
|             'Description': 'WireGuard server',
 | |
|         },
 | |
|         'WireGuard': {
 | |
|             'PrivateKey': repo.libs.wireguard.privkey(metadata.get('id')),
 | |
|             'ListenPort': 51820,
 | |
|         },
 | |
|     }
 | |
| 
 | |
|     for peer, config in {
 | |
|         **metadata.get('wireguard/s2s'),
 | |
|         **metadata.get('wireguard/clients'),
 | |
|     }.items():
 | |
|         netdev.update({
 | |
|             f'WireGuardPeer#{peer}': {
 | |
|                 'PublicKey': repo.libs.wireguard.pubkey(config['peer_id']),
 | |
|                 'PresharedKey': repo.libs.wireguard.psk(config['peer_id'], metadata.get('id')),
 | |
|                 'AllowedIPs': ', '.join(config.get('allowed_ips', [])),
 | |
|                 'PersistentKeepalive': 30,
 | |
|             }
 | |
|         })
 | |
|         if config.get('endpoint'):
 | |
|             netdev[f'WireGuardPeer#{peer}']['Endpoint'] = config['endpoint']
 | |
| 
 | |
|     return {
 | |
|         'systemd': {
 | |
|             'units': {
 | |
|                 'wireguard.netdev':  netdev,
 | |
|             },
 | |
|         },
 | |
|     }
 |