X-Git-Url: https://git.siccegge.de//index.cgi?p=tools.git;a=blobdiff_plain;f=addrecord;fp=addrecord;h=0000000000000000000000000000000000000000;hp=fa4c840bfd73f0c3762bd8d20a642304e0c3f0a4;hb=76db1f37cc1815129a14e0205518f9cff133d7be;hpb=b8c05041dd8635ea92b904355d0b4e3a49dc9076 diff --git a/addrecord b/addrecord deleted file mode 100644 index fa4c840..0000000 --- a/addrecord +++ /dev/null @@ -1,109 +0,0 @@ -#!/usr/bin/python3 -# -# ssh-based server to allow hosts to update their own TLS-related RRs -# intended to be used like -# command="/srv/tls/bin/addrecord hepworth.siccegge.de" ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOIlLx3R+Q5LgBZbJ6USuzam/uAEQITl6vzOn/ylk4fq christoph@mitoraj - -import os -import sys -import re -import datetime -import fcntl - -import yaml - -class Addrecord: - def __init__(self, host): - self._host = host - self._ports = {'www': [443], - 'smtp': [25, 587, 465], - 'imap': [993, 143], - 'pop': [110, 995], - 'xmpp': [5222, 5269], - } - self._tlsa_re = re.compile('TLSA 3 1 1 [0-9a-f]{64}') - self._acme_re = re.compile(r'[a-zA-Z0-9_-]{43}') - with open('inventory.yaml') as inv: - self._inventory = yaml.load(inv) - - - def tlsa(self): - host = input("Hostname: ") - service = input("Service: ") - value = input("Value: ") - if host not in self._inventory[self._host][service]: - sys.stderr.write("Not authorized to update entries for service '%s' on '%s'\n" - % (service, host)) - return 1 - - if re.fullmatch(self._tlsa_re, value) is None: - sys.stderr.write("Not a valid TLSA record: '%s'\n" % value) - return 2 - - records = [] - for port in self._ports[service]: - records.append("{0:<35s}\t{1}\n".format("_%d._tcp.%s" % (port, host), - value)) - self._update_records('tlsa', records) - print("OK") - return 0 - - - def acme(self): - host = input("Hostname: ") - value = input("Value: ") - allowed_hosts = set() - for value in self._inventory[self._host].values(): - allowed_hosts = allowed_hosts.union(value) - - if host not in allowed_hosts: - sys.stderr.write("Not authorized to update entries for host '%s'\n" % host) - return 1 - - if re.fullmatch(self._acme_re, value) is None: - sys.stderr.write("Not a valid ACME challenge record: '%s'\n" % value) - return 2 - - records = [ "{0:<35s}\t{1}\n".format("_acme-challenge.%s" % host, value) ] - self._update_records('acme', records) - print("OK") - return 0 - - - def _update_records(self, sort, records): - to_remove = [ i.split()[0] for i in records ] - - with open('%s/%s.m4' % (sort, self._host), 'r') as oldzone: - fcntl.flock(oldzone, fcntl.LOCK_EX) - lines = oldzone.readlines() - lines = [ line for line in lines if line == '\n' or line.split()[0] not in to_remove ] - - lines.append('\n') - lines.append("; Last updated %s by %s\n" % (datetime.datetime.utcnow().isoformat(), - self._host)) - lines = lines + records - - with open('%s/%s.m4.new' % (sort, self._host), 'w') as newzone: - newtext = ''.join(lines) - newtext = re.sub(r'\n[\n]+', '\n\n', newtext) - newtext = re.sub(r'\n;.*\n\n;', '\n;', newtext) - newzone.write(newtext) - - os.rename('%s/%s.m4.new' % (sort, self._host), - '%s/%s.m4' % (sort, self._host)) - fcntl.flock(oldzone, fcntl.LOCK_UN) - - -def main(): - command = os.environ['SSH_ORIGINAL_COMMAND'] - host = sys.argv[1] - addrecord = Addrecord(host) - - if command == 'acme': - return addrecord.acme() - elif command == 'tlsa': - return addrecord.tlsa() - - -if __name__ == '__main__': - sys.exit(main())