From b47667b73e08f47a649c79427a252e0a628ec831 Mon Sep 17 00:00:00 2001 From: csine-nflx Date: Wed, 28 Oct 2020 20:51:35 -0700 Subject: [PATCH] cname redirection working --- lemur/plugins/lemur_acme/plugin.py | 48 ++++++++++++++------- lemur/plugins/lemur_acme/tests/test_acme.py | 12 +++--- 2 files changed, 37 insertions(+), 23 deletions(-) diff --git a/lemur/plugins/lemur_acme/plugin.py b/lemur/plugins/lemur_acme/plugin.py index 2a09dbdf..4105465a 100644 --- a/lemur/plugins/lemur_acme/plugin.py +++ b/lemur/plugins/lemur_acme/plugin.py @@ -37,7 +37,8 @@ from retrying import retry class AuthorizationRecord(object): - def __init__(self, host, authz, dns_challenge, change_id): + def __init__(self, domain, host, authz, dns_challenge, change_id): + self.domain = domain self.host = host self.authz = authz self.dns_challenge = dns_challenge @@ -91,6 +92,7 @@ class AcmeHandler(object): self, acme_client, account_number, + domain, host, dns_provider, order, @@ -99,11 +101,9 @@ class AcmeHandler(object): current_app.logger.debug("Starting DNS challenge for {0}".format(host)) change_ids = [] - dns_challenges = self.get_dns_challenges(host, order.authorizations) + dns_challenges = self.get_dns_challenges(domain, order.authorizations) host_to_validate, _ = self.strip_wildcard(host) - host_to_validate = self.maybe_add_extension( - host_to_validate, dns_provider_options - ) + host_to_validate = self.maybe_add_extension(host_to_validate, dns_provider_options) if not dns_challenges: sentry.captureException() @@ -111,15 +111,20 @@ class AcmeHandler(object): raise Exception("Unable to determine DNS challenges from authorizations") for dns_challenge in dns_challenges: + + # Only prepend '_acme-challenge' if not using CNAME redirection + if domain == host: + host_to_validate = dns_challenge.validation_domain_name(host_to_validate) + change_id = dns_provider.create_txt_record( - dns_challenge.validation_domain_name(host_to_validate), + host_to_validate, dns_challenge.validation(acme_client.client.net.key), account_number, ) change_ids.append(change_id) return AuthorizationRecord( - host, order.authorizations, dns_challenges, change_ids + domain, host, order.authorizations, dns_challenges, change_ids ) def complete_dns_challenge(self, acme_client, authz_record): @@ -312,18 +317,23 @@ class AcmeHandler(object): for domain in order_info.domains: - # Replace domain if doing CNAME delegation + # If CNAME exists, set host to the target address + host = domain if current_app.config.get("ACME_ENABLE_DELEGATED_CNAME", False): - cname = self.get_cname(domain) - if cname: - domain = cname + val_domain, _ = self.strip_wildcard(domain) + val_domain = challenges.DNS01().validation_domain_name(val_domain) + cname_res = self.get_cname(val_domain) + if cname_res: + host = cname_res + self.autodetect_dns_providers(host) - if not self.dns_providers_for_domain.get(domain): + if not self.dns_providers_for_domain.get(host): metrics.send( "get_authorizations_no_dns_provider_for_domain", "counter", 1 ) - raise Exception("No DNS providers found for domain: {}".format(domain)) - for dns_provider in self.dns_providers_for_domain[domain]: + raise Exception("No DNS providers found for domain: {}".format(host)) + + for dns_provider in self.dns_providers_for_domain[host]: dns_provider_plugin = self.get_dns_provider(dns_provider.provider_type) dns_provider_options = json.loads(dns_provider.credentials) account_number = dns_provider_options.get("account_id") @@ -331,6 +341,7 @@ class AcmeHandler(object): acme_client, account_number, domain, + host, dns_provider_plugin, order, dns_provider.options, @@ -377,10 +388,12 @@ class AcmeHandler(object): host_to_validate = self.maybe_add_extension( host_to_validate, dns_provider_options ) + if authz_record.domain == authz_record.host: + host_to_validate = dns_challenge.validation_domain_name(host_to_validate), dns_provider_plugin.delete_txt_record( authz_record.change_id, account_number, - dns_challenge.validation_domain_name(host_to_validate), + host_to_validate, dns_challenge.validation(acme_client.client.net.key), ) @@ -409,13 +422,16 @@ class AcmeHandler(object): host_to_validate = self.maybe_add_extension( host_to_validate, dns_provider_options ) + dns_provider_plugin = self.get_dns_provider(dns_provider.provider_type) for dns_challenge in dns_challenges: + if authz_record.domain == authz_record.host: + host_to_validate = dns_challenge.validation_domain_name(host_to_validate), try: dns_provider_plugin.delete_txt_record( authz_record.change_id, account_number, - dns_challenge.validation_domain_name(host_to_validate), + host_to_validate, dns_challenge.validation(acme_client.client.net.key), ) except Exception as e: diff --git a/lemur/plugins/lemur_acme/tests/test_acme.py b/lemur/plugins/lemur_acme/tests/test_acme.py index ab246563..cce97d32 100644 --- a/lemur/plugins/lemur_acme/tests/test_acme.py +++ b/lemur/plugins/lemur_acme/tests/test_acme.py @@ -49,7 +49,7 @@ class TestAcme(unittest.TestCase): self.assertEqual(expected, result) def test_authz_record(self): - a = plugin.AuthorizationRecord("host", "authz", "challenge", "id") + a = plugin.AuthorizationRecord("domain", "host", "authz", "challenge", "id") self.assertEqual(type(a), plugin.AuthorizationRecord) @patch("acme.client.Client") @@ -79,7 +79,7 @@ class TestAcme(unittest.TestCase): iterator = iter(values) iterable.__iter__.return_value = iterator result = self.acme.start_dns_challenge( - mock_acme, "accountid", "host", mock_dns_provider, mock_order, {} + mock_acme, "accountid", "domain", "host", mock_dns_provider, mock_order, {} ) self.assertEqual(type(result), plugin.AuthorizationRecord) @@ -270,11 +270,9 @@ class TestAcme(unittest.TestCase): result, [options["common_name"], "test2.netflix.net"] ) - @patch( - "lemur.plugins.lemur_acme.plugin.AcmeHandler.start_dns_challenge", - return_value="test", - ) - def test_get_authorizations(self, mock_start_dns_challenge): + @patch("lemur.plugins.lemur_acme.plugin.AcmeHandler.start_dns_challenge", return_value="test") + @patch("lemur.plugins.lemur_acme.plugin.current_app", return_value=False) + def test_get_authorizations(self, mock_current_app, mock_start_dns_challenge): mock_order = Mock() mock_order.body.identifiers = [] mock_domain = Mock()