wip
This commit is contained in:
parent
a59c981238
commit
3246f67a81
6 changed files with 49 additions and 83 deletions
|
@ -1,3 +1,6 @@
|
|||
from ipaddress import ip_interface
|
||||
|
||||
|
||||
@metadata_reactor.provides(
|
||||
'dns',
|
||||
)
|
||||
|
@ -20,16 +23,35 @@ def acme_records(metadata):
|
|||
|
||||
|
||||
@metadata_reactor.provides(
|
||||
'bind/acls/acme',
|
||||
'bind/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', {})
|
||||
}
|
||||
|
||||
return {
|
||||
'bind': {
|
||||
'acls': {
|
||||
'acme': {
|
||||
'key acme',
|
||||
'!{ !{' + ' '.join(f'{ip};' for ip in sorted(allowed_ips)) + '}; any;}',
|
||||
},
|
||||
},
|
||||
'keys': {
|
||||
'acme': {},
|
||||
},
|
||||
'views': {
|
||||
'external': {
|
||||
'zones': {
|
||||
metadata.get('bind/acme_zone'): {
|
||||
'dynamic': True,
|
||||
'allow_update': {
|
||||
'acme',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
|
|
|
@ -1,20 +1,16 @@
|
|||
% for acl_name, acl_content in acls.items():
|
||||
acl "${acl_name}" {
|
||||
% for ac in sorted(acl_content, key=lambda e: (not e.startswith('!'), not e.startswith('key'))):
|
||||
% for ac in sorted(acl_content, key=lambda e: (not e.startswith('!'), not e.startswith('key'), e)):
|
||||
${ac};
|
||||
% endfor
|
||||
};
|
||||
% endfor
|
||||
|
||||
% for view_name, view_conf in views.items():
|
||||
% for zone_name, zone_conf in view_conf['zones'].items():
|
||||
% if zone_conf.get('key', False):
|
||||
key "${view_name}.${zone_name}" {
|
||||
% for key_name, key_conf in sorted(keys.items()):
|
||||
key "${key_name}" {
|
||||
algorithm hmac-sha512;
|
||||
secret "${zone_conf['key']}";
|
||||
secret "${key_conf['token']}";
|
||||
};
|
||||
% endif
|
||||
% endfor
|
||||
% endfor
|
||||
|
||||
% for view_name, view_conf in views.items():
|
||||
|
@ -46,8 +42,12 @@ view "${view_name}" {
|
|||
% if type == 'slave':
|
||||
masters { ${master_ip}; };
|
||||
% endif
|
||||
% if type == 'master' and zone_conf.get('key', False):
|
||||
allow-update { !{ !our-nets; any; }; key "${view_name}.${zone_name}"; };
|
||||
% if zone_conf.get('allow_update', False):
|
||||
allow-update {
|
||||
% for allow_update in zone_conf['allow_update']:
|
||||
${allow_update};
|
||||
% endfor
|
||||
};
|
||||
% endif
|
||||
file "/var/lib/bind/${view_name}/db.${zone_name}";
|
||||
};
|
||||
|
|
|
@ -81,6 +81,7 @@ files['/etc/bind/named.conf.local'] = {
|
|||
for view_name, view_conf in master_node.metadata.get('bind/views').items()
|
||||
},
|
||||
},
|
||||
'keys': master_node.metadata.get('bind/keys'),
|
||||
'views': dict(sorted(
|
||||
master_node.metadata.get('bind/views').items(),
|
||||
key=lambda e: (e[1].get('default', False), e[0]),
|
||||
|
@ -130,7 +131,7 @@ for view_name, view_conf in node.metadata.get('bind/views').items():
|
|||
files[f"/var/lib/bind/{view_name}/db.{zone_name}"].update({
|
||||
'source': 'db',
|
||||
'content_type': 'mako',
|
||||
'unless': f"test -f /var/lib/bind/{view_name}/db.{zone_name}" if zone_conf.get('dynamic', False) else 'false',
|
||||
'unless': f"test -f /var/lib/bind/{view_name}/db.{zone_name}" if zone_conf.get('allow_update', False) else 'false',
|
||||
'context': {
|
||||
'serial': datetime.now().strftime('%Y%m%d%H'),
|
||||
'records': zone_conf['records'],
|
||||
|
|
|
@ -38,6 +38,7 @@ defaults = {
|
|||
},
|
||||
},
|
||||
'zones': {},
|
||||
'keys': {},
|
||||
},
|
||||
'telegraf': {
|
||||
'config': {
|
||||
|
@ -174,29 +175,23 @@ def slaves(metadata):
|
|||
|
||||
|
||||
@metadata_reactor.provides(
|
||||
'bind/views',
|
||||
'bind/keys',
|
||||
)
|
||||
def generate_keys(metadata):
|
||||
return {
|
||||
'bind': {
|
||||
'views': {
|
||||
view_name: {
|
||||
'zones': {
|
||||
zone_name: {
|
||||
'key': repo.libs.hmac.hmac_sha512(
|
||||
f'{view_name}.{zone_name}',
|
||||
str(repo.vault.random_bytes_as_base64_for(
|
||||
f"{metadata.get('id')} bind {view_name} key {zone_name}",
|
||||
length=32,
|
||||
)),
|
||||
)
|
||||
}
|
||||
for zone_name, zone_conf in view_conf['zones'].items()
|
||||
if zone_conf.get('dynamic', False)
|
||||
}
|
||||
'keys': {
|
||||
key: {
|
||||
'token':repo.libs.hmac.hmac_sha512(
|
||||
key,
|
||||
str(repo.vault.random_bytes_as_base64_for(
|
||||
f"{metadata.get('id')} bind key {key}",
|
||||
length=32,
|
||||
)),
|
||||
)
|
||||
}
|
||||
for view_name, view_conf in metadata.get('bind/views').items()
|
||||
}
|
||||
for key in metadata.get('bind/keys')
|
||||
},
|
||||
}
|
||||
|
||||
|
|
|
@ -30,8 +30,8 @@ files = {
|
|||
'context': {
|
||||
'server': ip_interface(acme_node.metadata.get('network/external/ipv4')).ip,
|
||||
'zone': acme_node.metadata.get('bind/acme_zone'),
|
||||
'acme_key_name': 'external' + acme_node.metadata.get('bind/acme_zone'),
|
||||
'acme_key': acme_node.metadata.get('bind/views/external/zones/'+acme_node.metadata.get('bind/acme_zone')+'/key'),
|
||||
'acme_key_name': 'acme',
|
||||
'acme_key': acme_node.metadata.get('bind/keys/acme/token'),
|
||||
'domains': node.metadata.get('letsencrypt/domains'),
|
||||
},
|
||||
'mode': '0755',
|
||||
|
|
|
@ -18,55 +18,3 @@ defaults = {
|
|||
},
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
@metadata_reactor.provides(
|
||||
'systemd-timers/letsencrypt',
|
||||
'mirror/certs',
|
||||
)
|
||||
def renew(metadata):
|
||||
delegated_node = metadata.get('letsencrypt/delegate_to_node', False)
|
||||
|
||||
if delegated_node:
|
||||
delegated_ip = ip_interface(repo.get_node(delegated_node).metadata.get('network/internal/ipv4')).ip
|
||||
return {
|
||||
'mirror': {
|
||||
'certs': {
|
||||
'from': f"{delegated_ip}:/var/lib/dehydrated/certs",
|
||||
'to': '/var/lib/dehydrated',
|
||||
},
|
||||
},
|
||||
}
|
||||
else:
|
||||
return {
|
||||
'systemd-timers': {
|
||||
'letsencrypt': {
|
||||
'command': '/bin/bash -c "/usr/bin/dehydrated --cron --accept-terms --challenge dns-01 && /usr/bin/dehydrated --cleanup"',
|
||||
'when': 'daily',
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
@metadata_reactor.provides(
|
||||
'letsencrypt/domains',
|
||||
'dns',
|
||||
)
|
||||
def delegated_domains(metadata):
|
||||
delegated_domains = {
|
||||
domain: conf
|
||||
for other_node in repo.nodes
|
||||
if other_node.has_bundle('letsencrypt')
|
||||
and other_node.metadata.get('letsencrypt/delegate_to_node', None) == node.name
|
||||
for domain, conf in other_node.metadata.get('letsencrypt/domains').items()
|
||||
}
|
||||
|
||||
return {
|
||||
'letsencrypt': {
|
||||
'domains': delegated_domains,
|
||||
},
|
||||
'dns': {
|
||||
domain: repo.libs.dns.get_a_records(metadata, internal=False)
|
||||
for domain in delegated_domains.keys()
|
||||
},
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue