This commit is contained in:
mwiegand 2021-11-06 12:44:32 +01:00
parent c252ae4734
commit 3859db1146
7 changed files with 58 additions and 29 deletions

View file

@ -27,8 +27,9 @@ def acme_zone(metadata):
'bind': { 'bind': {
'zones': { 'zones': {
metadata.get('bind/acme_hostname'): { metadata.get('bind/acme_hostname'): {
'keys': ['acme'], 'dynamic': True,
'records': set(), 'records': set(),
'views': ['external'],
}, },
}, },
}, },

View file

@ -33,15 +33,14 @@ view "${view['name']}" {
}; };
% for zone, conf in sorted(zones.items()): % for zone, conf in sorted(zones.items()):
<% if view['name'] not in conf.get('views', ['internal', 'external']): continue %>
zone "${zone}" { zone "${zone}" {
type ${type}; type ${type};
% if type == 'slave': % if type == 'slave':
masters { ${master_ip}; }; masters { ${master_ip}; };
% endif % endif
% if type == 'master': % if type == 'master' and zone in keys:
% for key in conf.get('keys', []): allow-update { key "${zone}"; };
allow-update { key "${key}"; };
% endfor
% endif % endif
file "/var/lib/bind/${view['name']}/db.${zone}"; file "/var/lib/bind/${view['name']}/db.${zone}";
}; };

View file

@ -144,6 +144,9 @@ for view in views:
} }
for zone, conf in zones.items(): for zone, conf in zones.items():
if view['name'] not in conf.get('views', ['internal', 'external']):
continue
records = conf['records'] records = conf['records']
unique_records = [ unique_records = [
dict(record_tuple) dict(record_tuple)
@ -155,19 +158,7 @@ for view in views:
files[f"/var/lib/bind/{view['name']}/db.{zone}"] = { files[f"/var/lib/bind/{view['name']}/db.{zone}"] = {
'owner': 'bind', 'owner': 'bind',
'group': 'bind', 'group': 'bind',
'source': 'db', 'content_type': 'any',
'content_type': 'mako',
'unless': f"test -f /var/lib/bind/{view['name']}/db.{zone}" if 'keys' in conf else 'false',
'context': {
'view': view['name'],
'serial': datetime.now().strftime('%Y%m%d%H'),
'records': list(filter(
lambda record: record_matches_view(record, records, view['name']),
unique_records
)),
'hostname': node.metadata.get('bind/hostname'),
'type': node.metadata.get('bind/type'),
},
'needs': [ 'needs': [
f"directory:/var/lib/bind/{view['name']}", f"directory:/var/lib/bind/{view['name']}",
], ],
@ -178,6 +169,23 @@ for view in views:
'svc_systemd:bind9:restart', 'svc_systemd:bind9:restart',
], ],
} }
if node.metadata.get('bind/type') == 'master':
files[f"/var/lib/bind/{view['name']}/db.{zone}"].update({
'source': 'db',
'content_type': 'mako',
'unless': f"test -f /var/lib/bind/{view['name']}/db.{zone}" if conf.get('dynamic', False) else 'false',
'context': {
'view': view['name'],
'serial': datetime.now().strftime('%Y%m%d%H'),
'records': list(filter(
lambda record: record_matches_view(record, records, view['name']),
unique_records
)),
'hostname': node.metadata.get('bind/hostname'),
'type': node.metadata.get('bind/type'),
'keys': node.metadata.get('bind/keys'),
},
})
svc_systemd['bind9'] = {} svc_systemd['bind9'] = {}

View file

@ -145,15 +145,15 @@ def generate_keys(metadata):
return { return {
'bind': { 'bind': {
'keys': { 'keys': {
key: repo.libs.hmac.hmac_sha512( zone: repo.libs.hmac.hmac_sha512(
'acme', zone,
str(repo.vault.random_bytes_as_base64_for( str(repo.vault.random_bytes_as_base64_for(
f"{metadata.get('id')} bind key {key}", f"{metadata.get('id')} bind key {zone}",
length=32, length=32,
)), )),
) )
for zone, conf in metadata.get('bind/zones').items() for zone, conf in metadata.get('bind/zones').items()
for key in set(conf.get('keys', [])) if conf.get('dynamic', False)
}, },
}, },
} }

View file

@ -7,18 +7,37 @@ deploy_challenge() {
SERVER=${server} SERVER=${server}
DOMAIN=$1 DOMAIN=$1
CHALLENGE=$3 CHALLENGE=$3
KEY=hmac-sha512:acme:${acme_key} KEY=hmac-sha512:acme.sublimity.de:${acme_key}
cmd=" cmd="
server 162.55.188.157 server 162.55.188.157
zone acme.sublimity.de. zone acme.sublimity.de.
update delete $DOMAIN.$ACME_ZONE. TXT
update add $DOMAIN.$ACME_ZONE. 60 IN TXT \"$CHALLENGE\" update add $DOMAIN.$ACME_ZONE. 60 IN TXT \"$CHALLENGE\"
send send
" "
echo "$cmd" echo "$cmd"
echo "$cmd" | nsupdate -y $KEY echo "$cmd" | nsupdate -y $KEY
sleep 10 sleep 20
}
clean_challenge() {
set -e
set -u
set -o pipefail
ACME_ZONE=${zone}
SERVER=${server}
DOMAIN=$1
CHALLENGE=$3
KEY=hmac-sha512:acme.sublimity.de:${acme_key}
cmd="
server 162.55.188.157
zone acme.sublimity.de.
update delete $DOMAIN.$ACME_ZONE. TXT
send
"
echo "$cmd"
echo "$cmd" | nsupdate -y $KEY
} }
deploy_cert() {<%text> deploy_cert() {<%text>
@ -55,6 +74,6 @@ exit_hook() {<%text>
<%text> <%text>
HANDLER="$1"; shift HANDLER="$1"; shift
if [[ "${HANDLER}" =~ ^(deploy_cert|exit_hook|deploy_challenge)$ ]]; then if [[ "${HANDLER}" =~ ^(deploy_cert|exit_hook|deploy_challenge|clean_challenge)$ ]]; then
"$HANDLER" "$@" "$HANDLER" "$@"
fi</%text> fi</%text>

View file

@ -24,7 +24,7 @@ files = {
'context': { 'context': {
'server': node.metadata.get('network/external/ipv4').split('/')[0], 'server': node.metadata.get('network/external/ipv4').split('/')[0],
'zone': node.metadata.get('bind/acme_hostname'), 'zone': node.metadata.get('bind/acme_hostname'),
'acme_key': node.metadata.get('bind/keys/acme'), 'acme_key': node.metadata.get('bind/keys/acme.sublimity.de'),
}, },
'mode': '0755', 'mode': '0755',
}, },
@ -37,7 +37,7 @@ files = {
} }
actions['letsencrypt_update_certificates'] = { actions['letsencrypt_update_certificates'] = {
'command': 'dehydrated --cron --accept-terms --challenge http-01', 'command': 'true || dehydrated --cron --accept-terms --challenge http-01',
'triggered': True, 'triggered': True,
'skip': delegated, 'skip': delegated,
'needs': { 'needs': {
@ -56,6 +56,6 @@ for domain in node.metadata.get('letsencrypt/domains').keys():
'svc_systemd:nginx', 'svc_systemd:nginx',
}, },
'triggers': { 'triggers': {
'action:letsencrypt_update_certificates', 'action:letsencrypt_update_certificates',
}, },
} }

View file

@ -65,6 +65,8 @@
'domains': { 'domains': {
'ckn.li': set(), 'ckn.li': set(),
'test1.ckn.li': set(), 'test1.ckn.li': set(),
'test2.ckn.li': set(),
'test3.ckn.li': set(),
'sublimity.de': set(), 'sublimity.de': set(),
'freibrief.net': set(), 'freibrief.net': set(),
}, },