dns+certs: add a new cert_alternate_names hook + improve custom_dns_rules hook

This commit is contained in:
Alexandre Aubin 2024-06-08 16:35:44 +02:00
parent 4769242dc5
commit 46372a0f22
2 changed files with 29 additions and 53 deletions

View file

@ -556,6 +556,7 @@ def _fetch_and_enable_new_certificate(domain, no_checks=False):
def _prepare_certificate_signing_request(domain, key_file, output_folder): def _prepare_certificate_signing_request(domain, key_file, output_folder):
from OpenSSL import crypto # lazy loading this module for performance reasons from OpenSSL import crypto # lazy loading this module for performance reasons
from yunohost.hook import hook_callback
# Init a request # Init a request
csr = crypto.X509Req() csr = crypto.X509Req()
@ -563,41 +564,23 @@ def _prepare_certificate_signing_request(domain, key_file, output_folder):
# Set the domain # Set the domain
csr.get_subject().CN = domain csr.get_subject().CN = domain
from yunohost.domain import domain_config_get
# If XMPP is enabled for this domain, add xmpp-upload and muc subdomains
# in subject alternate names
if domain_config_get(domain, key="feature.xmpp.xmpp") == 1:
xmpp_records = (
Diagnoser.get_cached_report(
"dnsrecords", item={"domain": domain, "category": "xmpp"}
).get("data")
or {}
)
sanlist = [] sanlist = []
hook_results = hook_callback("cert_alternate_names", env={"domain": domain})
# Handle the boring case where the domain is not the root of the dns zone etc... for hook_name, results in hook_results.items():
from yunohost.dns import ( #
_get_relative_name_for_dns_zone, # There can be multiple results per hook name, so results look like
_get_dns_zone_for_domain, # {'/some/path/to/hook1':
) # { 'state': 'succeed',
# 'stdreturn': ["foo", "bar"]
base_dns_zone = _get_dns_zone_for_domain(domain) # },
basename = _get_relative_name_for_dns_zone(domain, base_dns_zone) # '/some/path/to/hook2':
suffix = f".{basename}" if basename != "@" else "" # { ... },
# [...]
for sub in ("xmpp-upload", "muc"): #
subdomain = sub + "." + domain # Loop over the sub-results
if xmpp_records.get("CNAME:" + sub + suffix) == "OK": for result in results.values():
sanlist.append(("DNS:" + subdomain)) if results["stdreturn"]:
else: sanlist += results["stdreturn"]
logger.warning(
m18n.n(
"certmanager_warning_subdomain_dns_record",
subdomain=subdomain,
domain=domain,
)
)
if sanlist: if sanlist:
csr.add_extensions( csr.add_extensions(
@ -605,7 +588,7 @@ def _prepare_certificate_signing_request(domain, key_file, output_folder):
crypto.X509Extension( crypto.X509Extension(
b"subjectAltName", b"subjectAltName",
False, False,
(", ".join(sanlist)).encode("utf-8"), (", ".join(["DNS:{sub}.{domain}" for sub in sanlist])).encode("utf-8"),
) )
] ]
) )

View file

@ -235,15 +235,8 @@ def _build_dns_conf(base_domain, include_empty_AAAA_if_no_ipv6=False):
# Custom records # # Custom records #
################## ##################
# Defined by custom hooks ships in apps for example ... # Defined by custom hooks shipped in apps for example ...
hook_results = hook_callback("custom_dns_rules", env={"base_domain": base_domain, "suffix": suffix})
# FIXME : this ain't practical for apps that may want to add
# custom dns records for a subdomain ... there's no easy way for
# an app to compare the base domain is the parent of the subdomain ?
# (On the other hand, in sep 2021, it looks like no app is using
# this mechanism...)
hook_results = hook_callback("custom_dns_rules", args=[base_domain])
for hook_name, results in hook_results.items(): for hook_name, results in hook_results.items():
# #
# There can be multiple results per hook name, so results look like # There can be multiple results per hook name, so results look like