from os.path import join, exists from re import sub from cryptography.hazmat.primitives import serialization as crypto_serialization from cryptography.hazmat.primitives.asymmetric import rsa from cryptography.hazmat.backends import default_backend as crypto_default_backend defaults = { 'apt': { 'packages': { 'opendkim': {}, 'opendkim-tools': {}, }, }, 'opendkim': { 'keys': {}, }, } @metadata_reactor.provides( 'opendkim/keys', ) def keys(metadata): keys = {} for domain in metadata.get('mailserver/domains'): if domain in metadata.get(f'opendkim/keys'): continue pubkey_path = join(repo.path, 'data', 'dkim', f'{domain}.pubkey') privkey_path = join(repo.path, 'data', 'dkim', f'{domain}.privkey.enc') if not exists(pubkey_path) or not exists(privkey_path): key = rsa.generate_private_key( backend=crypto_default_backend(), public_exponent=65537, key_size=2048 ) with open(pubkey_path, 'w') as file: file.write( ''.join( key.public_key().public_bytes( crypto_serialization.Encoding.PEM, crypto_serialization.PublicFormat.SubjectPublicKeyInfo ).decode().split('\n')[1:-2] ) ) with open(privkey_path, 'w') as file: file.write( repo.vault.encrypt( key.private_bytes( crypto_serialization.Encoding.PEM, crypto_serialization.PrivateFormat.PKCS8, crypto_serialization.NoEncryption() ).decode() ) ) with open(pubkey_path, 'r') as pubkey: with open(privkey_path, 'r') as privkey: keys[domain] = { 'public': pubkey.read(), 'private': repo.vault.decrypt(privkey.read()), } return { 'opendkim': { 'keys': keys, } } @metadata_reactor.provides( 'dns', ) def dns(metadata): dns = {} for domain, keys in metadata.get('opendkim/keys').items(): raw_key = sub('^ssh-rsa ', '', keys['public']) dns[f'mail._domainkey.{domain}'] = { 'TXT': [f'v=DKIM1; k=rsa; p={raw_key}'], } return { 'dns': dns, }