wip
This commit is contained in:
parent
ce7b3a0fc7
commit
7c3c1cabf5
4 changed files with 83 additions and 95 deletions
|
@ -8,13 +8,12 @@ from ipaddress import ip_network, ip_interface
|
||||||
repo = Repository(dirname(dirname(realpath(__file__))))
|
repo = Repository(dirname(dirname(realpath(__file__))))
|
||||||
|
|
||||||
server_node = repo.get_node('htz.mails')
|
server_node = repo.get_node('htz.mails')
|
||||||
server_pubkey = repo.libs.keys.get_pubkey_from_privkey(f'{server_node.name} wireguard pubkey', server_node.metadata.get('wireguard/privatekey'))
|
server_pubkey = repo.libs.wireguard.pubkey(server_node.metadata.get('id'))
|
||||||
data = server_node.metadata.get(f'wireguard/clients/{argv[1]}')
|
data = server_node.metadata.get(f'wireguard/clients/{argv[1]}')
|
||||||
|
|
||||||
sortable_client_routes = [
|
sortable_client_routes = [
|
||||||
ip_interface(server_node.metadata.get('network/internal/ipv4')).network,
|
ip_interface(server_node.metadata.get('network/internal/ipv4')).network,
|
||||||
]
|
]
|
||||||
|
|
||||||
for peer in server_node.metadata.get('wireguard/peers').values():
|
for peer in server_node.metadata.get('wireguard/peers').values():
|
||||||
for network in peer.get('route'):
|
for network in peer.get('route'):
|
||||||
sortable_client_routes.append(ip_network(network))
|
sortable_client_routes.append(ip_network(network))
|
||||||
|
|
|
@ -3,6 +3,7 @@ from ipaddress import ip_network, ip_interface
|
||||||
from bundlewrap.exceptions import NoSuchNode
|
from bundlewrap.exceptions import NoSuchNode
|
||||||
from bundlewrap.metadata import atomic
|
from bundlewrap.metadata import atomic
|
||||||
|
|
||||||
|
repo.libs.wireguard.repo = repo
|
||||||
|
|
||||||
defaults = {
|
defaults = {
|
||||||
'apt': {
|
'apt': {
|
||||||
|
@ -19,12 +20,79 @@ defaults = {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
'wireguard': {
|
|
||||||
'privatekey': repo.vault.random_bytes_as_base64_for(f'{node.name} wireguard privatekey'),
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@metadata_reactor.provides(
|
||||||
|
'wireguard/privkey',
|
||||||
|
)
|
||||||
|
def privkey(metadata):
|
||||||
|
return {
|
||||||
|
'wireguard': {
|
||||||
|
'privkey': repo.libs.wireguard.privkey(metadata.get('id')),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@metadata_reactor.provides(
|
||||||
|
'wireguard/peers',
|
||||||
|
)
|
||||||
|
def s2s_peer_specific(metadata):
|
||||||
|
return {
|
||||||
|
'wireguard': {
|
||||||
|
'peers': {
|
||||||
|
peer: {
|
||||||
|
'id': repo.get_node(peer).metadata.get(f'id'),
|
||||||
|
'privkey': repo.get_node(peer).metadata.get(f'wireguard/privkey'),
|
||||||
|
'ip': repo.get_node(peer).metadata.get(f'wireguard/my_ip'),
|
||||||
|
'endpoint': f'{repo.get_node(peer).hostname}:51820',
|
||||||
|
|
||||||
|
}
|
||||||
|
for peer in metadata.get('wireguard/peers')
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@metadata_reactor.provides(
|
||||||
|
'wireguard/clients',
|
||||||
|
)
|
||||||
|
def client_peer_specific(metadata):
|
||||||
|
return {
|
||||||
|
'wireguard': {
|
||||||
|
'clients': {
|
||||||
|
client: {
|
||||||
|
'id': client,
|
||||||
|
'privkey': repo.libs.wireguard.privkey(client),
|
||||||
|
}
|
||||||
|
for client in metadata.get('wireguard/clients')
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@metadata_reactor.provides(
|
||||||
|
'wireguard/peers',
|
||||||
|
'wireguard/clients',
|
||||||
|
)
|
||||||
|
def common_peer_data(metadata):
|
||||||
|
peers = {
|
||||||
|
'peers': {},
|
||||||
|
'clients': {},
|
||||||
|
}
|
||||||
|
|
||||||
|
for peer_type in peers:
|
||||||
|
for peer_name, peer_data in metadata.get(f'wireguard/{peer_type}', {}).items():
|
||||||
|
peers[peer_type][peer_name] = {
|
||||||
|
'psk': repo.libs.wireguard.psk(node.metadata.get('id'), peer_data['id']),
|
||||||
|
'pubkey': repo.libs.wireguard.pubkey(peer_data['id']),
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
'wireguard': peers,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@metadata_reactor.provides(
|
@metadata_reactor.provides(
|
||||||
'systemd/units',
|
'systemd/units',
|
||||||
)
|
)
|
||||||
|
@ -82,7 +150,7 @@ def systemd_networkd_netdevs(metadata):
|
||||||
'Description': 'WireGuard server',
|
'Description': 'WireGuard server',
|
||||||
},
|
},
|
||||||
'WireGuard': {
|
'WireGuard': {
|
||||||
'PrivateKey': metadata.get('wireguard/privatekey'),
|
'PrivateKey': metadata.get('wireguard/privkey'),
|
||||||
'ListenPort': 51820,
|
'ListenPort': 51820,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -112,64 +180,3 @@ def systemd_networkd_netdevs(metadata):
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@metadata_reactor.provides(
|
|
||||||
'wireguard/peers',
|
|
||||||
)
|
|
||||||
def s2s_peer_specific(metadata):
|
|
||||||
return {
|
|
||||||
'wireguard': {
|
|
||||||
'peers': {
|
|
||||||
peer: {
|
|
||||||
'id': repo.get_node(peer).metadata.get(f'id'),
|
|
||||||
'privkey': repo.get_node(peer).metadata.get(f'wireguard/privatekey'),
|
|
||||||
'ip': repo.get_node(peer).metadata.get(f'wireguard/my_ip'),
|
|
||||||
'endpoint': f'{repo.get_node(peer).hostname}:51820',
|
|
||||||
|
|
||||||
}
|
|
||||||
for peer in metadata.get('wireguard/peers')
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@metadata_reactor.provides(
|
|
||||||
'wireguard/clients',
|
|
||||||
)
|
|
||||||
def client_peer_specific(metadata):
|
|
||||||
return {
|
|
||||||
'wireguard': {
|
|
||||||
'clients': {
|
|
||||||
client: {
|
|
||||||
'id': client,
|
|
||||||
'privkey': repo.vault.random_bytes_as_base64_for(f'{client} wireguard privatekey'),
|
|
||||||
}
|
|
||||||
for client in metadata.get('wireguard/clients')
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@metadata_reactor.provides(
|
|
||||||
'wireguard/peers',
|
|
||||||
'wireguard/clients',
|
|
||||||
)
|
|
||||||
def common_peer_data(metadata):
|
|
||||||
peers = {
|
|
||||||
'peers': {},
|
|
||||||
'clients': {},
|
|
||||||
}
|
|
||||||
|
|
||||||
for peer_type in peers:
|
|
||||||
for peer_name, peer_data in metadata.get(f'wireguard/{peer_type}', {}).items():
|
|
||||||
first, second = sorted([node.metadata.get('id'), peer_data['id']])
|
|
||||||
|
|
||||||
peers[peer_type][peer_name] = {
|
|
||||||
'psk': repo.vault.random_bytes_as_base64_for(f'{first} wireguard {second}'),
|
|
||||||
'pubkey': repo.libs.keys.get_pubkey_from_privkey(f'{peer_name} wireguard pubkey', peer_data['privkey']),
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
'wireguard': peers,
|
|
||||||
}
|
|
||||||
|
|
15
libs/keys.py
15
libs/keys.py
|
@ -1,15 +0,0 @@
|
||||||
import base64
|
|
||||||
from nacl.public import PrivateKey
|
|
||||||
from nacl.encoding import Base64Encoder
|
|
||||||
from bundlewrap.utils import Fault
|
|
||||||
|
|
||||||
def gen_privkey(repo, identifier):
|
|
||||||
return repo.vault.random_bytes_as_base64_for(identifier)
|
|
||||||
|
|
||||||
def get_pubkey_from_privkey(identifier, privkey):
|
|
||||||
# FIXME this assumes the privkey is always a base64 encoded string
|
|
||||||
def derive_pubkey():
|
|
||||||
pub_key = PrivateKey(base64.b64decode(str(privkey))).public_key
|
|
||||||
return pub_key.encode(encoder=Base64Encoder).decode('ascii')
|
|
||||||
|
|
||||||
return Fault(f'pubkey from privkey {identifier}', derive_pubkey)
|
|
|
@ -1,15 +1,12 @@
|
||||||
connections = {}
|
import base64
|
||||||
|
from nacl.public import PrivateKey
|
||||||
|
from nacl.encoding import Base64Encoder
|
||||||
|
|
||||||
def get_connection(node, other_node):
|
def privkey(id):
|
||||||
global connections
|
return str(repo.vault.random_bytes_as_base64_for(f"wireguard privkey {id}"))
|
||||||
|
|
||||||
node_id, other_node_id = node.metadata.get('id'), other_node.metadata.get('id')
|
|
||||||
sorted_ids = tuple(sorted([node_id, other_node_id]))
|
|
||||||
|
|
||||||
if sorted_ids not in connections:
|
|
||||||
connections[sorted_ids] = {
|
|
||||||
'pubkey': node.repo.libs.keys.get_pubkey_from_privkey(f'{other_node_id} wireguard pubkey', other_node.metadata.get('wireguard/privatekey')),
|
|
||||||
'psk': node.repo.vault.random_bytes_as_base64_for(f"{sorted_ids[0]} wireguard {sorted_ids[1]}"),
|
|
||||||
}
|
|
||||||
|
|
||||||
return connections[sorted_ids]
|
def pubkey(id):
|
||||||
|
return PrivateKey(base64.b64decode(privkey(id))).public_key.encode(encoder=Base64Encoder).decode('ascii')
|
||||||
|
|
||||||
|
def psk(id1, id2):
|
||||||
|
return repo.vault.random_bytes_as_base64_for(f"wireguard psk {' '.join(sorted([id1, id2]))}")
|
||||||
|
|
Loading…
Reference in a new issue