diff --git a/bundles/bind/files/db.acme b/bundles/bind/files/db.acme new file mode 100644 index 0000000..33526bf --- /dev/null +++ b/bundles/bind/files/db.acme @@ -0,0 +1,13 @@ +$TTL 600 +@ IN SOA acme.${hostname}. admin.acme.${hostname}. ( + 2021070821 ;Serial + 3600 ;Refresh + 200 ;Retry + 1209600 ;Expire + 900 ;Negative response caching TTL +) + +@ IN A 162.55.188.157 +@ IN AAAA 2a01:4f8:1c1c:4121::2 +@ IN NS resolver.name. +@ IN NS second.resolver.name. diff --git a/bundles/bind/files/named.conf.local b/bundles/bind/files/named.conf.local index 0198d49..5c429fe 100644 --- a/bundles/bind/files/named.conf.local +++ b/bundles/bind/files/named.conf.local @@ -4,6 +4,11 @@ acl "${view['name']}" { }; % endfor +key "acme" { + algorithm hmac-sha512; + secret "${acme_key}"; +}; + % for view in views: view "${view['name']}" { match-clients { ${view['name']}; }; @@ -35,6 +40,13 @@ view "${view['name']}" { }; % endfor + zone "acme.${hostname}" { + type master; + file "/var/lib/bind/${view['name']}/db.acme.${hostname}"; + masterfile-format text; + allow-update { key "acme"; }; + }; + include "/etc/bind/named.conf.default-zones"; include "/etc/bind/zones.rfc1918"; }; diff --git a/bundles/bind/items.py b/bundles/bind/items.py index a166f2b..8fabddd 100644 --- a/bundles/bind/items.py +++ b/bundles/bind/items.py @@ -93,6 +93,8 @@ files['/etc/bind/named.conf.local'] = { 'master_ip': master_ip, 'views': views, 'zones': sorted(zones), + 'hostname': node.metadata.get('bind/hostname'), + 'acme_key': node.metadata.get('bind/acme_key'), }, 'owner': 'root', 'group': 'bind', @@ -135,6 +137,24 @@ for view in views: 'svc_systemd:bind9:restart', ], } + files[f"/var/lib/bind/{view['name']}/db.acme.{node.metadata.get('bind/hostname')}"] = { + 'source': 'db.acme', + 'content_type': 'mako', + 'context': { + 'hostname': node.metadata.get('bind/hostname'), + }, + 'owner': 'root', + 'group': 'bind', + 'needs': [ + 'pkg_apt:bind9', + ], + 'needed_by': [ + 'svc_systemd:bind9', + ], + 'triggers': [ + 'svc_systemd:bind9:restart', + ], + } for zone, records in zones.items(): unique_records = [ @@ -175,5 +195,6 @@ actions['named-checkconf'] = { 'unless': 'named-checkconf -z', 'needs': [ 'svc_systemd:bind9', + 'svc_systemd:bind9:restart', ] } diff --git a/bundles/bind/metadata.py b/bundles/bind/metadata.py index bc949b4..75c2d7a 100644 --- a/bundles/bind/metadata.py +++ b/bundles/bind/metadata.py @@ -26,6 +26,23 @@ defaults = { } +@metadata_reactor.provides( + 'bind/acme_key', +) +def acme_key(metadata): + return { + 'bind': { + 'acme_key': repo.libs.hmac.hmac_sha512( + 'acme', + str(repo.vault.random_bytes_as_base64_for( + f"{metadata.get('id')} bind key acme", + length=32, + )), + ), + } + } + + @metadata_reactor.provides( 'bind/type', ) diff --git a/bundles/letsencrypt/README.md b/bundles/letsencrypt/README.md new file mode 100644 index 0000000..190b818 --- /dev/null +++ b/bundles/letsencrypt/README.md @@ -0,0 +1 @@ +https://github.com/dehydrated-io/dehydrated/wiki/example-dns-01-nsupdate-script diff --git a/bundles/letsencrypt/files/dns-challenge.sh b/bundles/letsencrypt/files/dns-challenge.sh new file mode 100644 index 0000000..59756f2 --- /dev/null +++ b/bundles/letsencrypt/files/dns-challenge.sh @@ -0,0 +1,28 @@ +#!/usr/bin/env bash + +set -e +set -u +set -o pipefail + +OPERATION=$1 +DOMAIN=$2 +TOKEN=$4 +TTL=300 + +case "$1" in + "deploy_challenge") + + ;; + "clean_challenge") + ;; + "deploy_cert") + ;; + "unchanged_cert") + ;; + "startup_hook") + ;; + "exit_hook") + ;; +esac + +exit 0 diff --git a/libs/hmac.py b/libs/hmac.py new file mode 100644 index 0000000..44321c3 --- /dev/null +++ b/libs/hmac.py @@ -0,0 +1,10 @@ +import hmac, hashlib, base64 + +def hmac_sha512(secret, iv): + return base64.b64encode( + hmac.new( + bytes(iv , 'latin-1'), + msg=bytes(secret , 'latin-1'), + digestmod=hashlib.sha512 + ).digest() + ).decode()