from ipaddress import ip_interface @metadata_reactor.provides( 'dns', ) def acme_records(metadata): domains = set() for other_node in repo.nodes: for domain, conf in other_node.metadata.get('letsencrypt/domains', {}).items(): domains.add(domain) domains.update(conf.get('aliases', [])) return { 'dns': { f'_acme-challenge.{domain}': { 'CNAME': {f"{domain}.{metadata.get('bind/acme_zone')}."}, } for domain in domains } } @metadata_reactor.provides( 'bind/acls/acme', 'bind/views/external/keys/acme', 'bind/views/external/zones', ) def acme_zone(metadata): allowed_ips = { *{ str(ip_interface(other_node.metadata.get('network/internal/ipv4')).ip) for other_node in repo.nodes if other_node.metadata.get('letsencrypt/domains', {}) }, *{ str(ip_interface(other_node.metadata.get('wireguard/my_ip')).ip) for other_node in repo.nodes if other_node.has_bundle('wireguard') }, } return { 'bind': { 'acls': { 'acme': { 'key acme', '!{ !{' + ' '.join(f'{ip};' for ip in sorted(allowed_ips)) + '}; any;}', }, }, 'views': { 'external': { 'keys': { 'acme': {}, }, 'zones': { metadata.get('bind/acme_zone'): { 'allow_update': { 'acme', }, }, }, }, }, }, } #https://lists.isc.org/pipermail/bind-users/2006-January/061051.html