]>
git.siccegge.de Git - tools.git/blob - tls/addrecord
3 # ssh-based server to allow hosts to update their own TLS-related RRs
4 # intended to be used like
5 # command="/srv/tls/bin/addrecord hepworth.siccegge.de" ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOIlLx3R+Q5LgBZbJ6USuzam/uAEQITl6vzOn/ylk4fq christoph@mitoraj
16 def __init__(self
, host
):
18 self
._ports
= {'www': [443],
19 'smtp': [25, 587, 465],
24 self
._tlsa
_re
= re
.compile('TLSA 3 1 1 [0-9a-f]{64}')
25 self
._acme
_re
= re
.compile(r
'[a-zA-Z0-9_-]{43}')
26 with
open('inventory.yaml') as inv
:
27 self
._inventory
= yaml
.load(inv
)
31 host
= input("Hostname: ")
32 service
= input("Service: ")
33 value
= input("Value: ")
34 if host
not in self
._inventory
[self
._host
][service
]:
35 sys
.stderr
.write("Not authorized to update entries for service '%s' on '%s'\n"
39 if re
.fullmatch(self
._tlsa
_re
, value
) is None:
40 sys
.stderr
.write("Not a valid TLSA record: '%s'\n" % value
)
44 for port
in self
._ports
[service
]:
45 records
.append("{0:<35s}\t{1}\n".format("_%d._tcp.%s" % (port
, host
),
47 self
._update
_records
('tlsa', records
)
53 host
= input("Hostname: ")
54 value
= input("Value: ")
56 for value
in self
._inventory
[self
._host
].values():
57 allowed_hosts
= allowed_hosts
.union(value
)
59 if host
not in allowed_hosts
:
60 sys
.stderr
.write("Not authorized to update entries for host '%s'\n" % host
)
63 if re
.fullmatch(self
._acme
_re
, value
) is None:
64 sys
.stderr
.write("Not a valid ACME challenge record: '%s'\n" % value
)
67 records
= [ "{0:<35s}\t{1}\n".format("_acme-challenge.%s" % host
, value
) ]
68 self
._update
_records
('acme', records
)
73 def _update_records(self
, sort
, records
):
74 to_remove
= [ i
.split()[0] for i
in records
]
76 with
open('%s/%s.m4.lock' % (sort
, self
._host
), 'w') as lockfd
:
77 fcntl
.flock(lockfd
, fcntl
.LOCK_EX
)
78 with
open('%s/%s.m4' % (sort
, self
._host
), 'r') as oldzone
:
79 lines
= oldzone
.readlines()
80 lines
= [ line
for line
in lines
81 if line
== '\n' or line
.split()[0] not in to_remove
]
84 lines
.append("; Last updated %s by %s\n"
85 % (datetime
.datetime
.utcnow().isoformat(),
87 lines
= lines
+ records
89 with
open('%s/%s.m4.new' % (sort
, self
._host
), 'w') as newzone
:
90 newtext
= ''.join(lines
)
91 newtext
= re
.sub(r
'\n[\n]+', '\n\n', newtext
)
92 newtext
= re
.sub(r
'\n;.*\n\n;', '\n;', newtext
)
93 newzone
.write(newtext
)
95 os
.rename('%s/%s.m4.new' % (sort
, self
._host
),
96 '%s/%s.m4' % (sort
, self
._host
))
98 # forced-command is make -C ...
99 # rebuilds the actual zone file
100 subprocess
.call(["ssh", "opendnssec@localhost"])
101 fcntl
.flock(lockfd
, fcntl
.LOCK_UN
)
105 command
= os
.environ
['SSH_ORIGINAL_COMMAND']
107 addrecord
= Addrecord(host
)
109 if command
== 'acme':
110 return addrecord
.acme()
111 elif command
== 'tlsa':
112 return addrecord
.tlsa()
115 if __name__
== '__main__':