diff --git a/lemur/plugins/lemur_acme/plugin.py b/lemur/plugins/lemur_acme/plugin.py index 02f08f9a..b6a5dbbf 100644 --- a/lemur/plugins/lemur_acme/plugin.py +++ b/lemur/plugins/lemur_acme/plugin.py @@ -107,21 +107,45 @@ class AcmeHandler(object): metrics.send('complete_dns_challenge_error_no_dnsproviders', 'counter', 1) raise Exception("No DNS providers found for domain: {}".format(authz_record.host)) - for dns_challenge in authz_record.dns_challenge: - response = dns_challenge.response(acme_client.client.net.key) + for dns_provider in dns_providers: + # Grab account number (For Route53) + dns_provider_options = json.loads(dns_provider.credentials) + account_number = dns_provider_options.get("account_id") + dns_provider_plugin = self.get_dns_provider(dns_provider.provider_type) + for change_id in authz_record.change_id: + try: + dns_provider_plugin.wait_for_dns_change(change_id, account_number=account_number) + except Exception: + metrics.send('complete_dns_challenge_error', 'counter', 1) + sentry.captureException() + current_app.logger.debug( + f"Unable to resolve DNS challenge for change_id: {change_id}, account_id: " + f"{account_number}", exc_info=True) + raise - verified = response.simple_verify( - dns_challenge.chall, - authz_record.host, - acme_client.client.net.key.public_key() - ) + for dns_challenge in authz_record.dns_challenge: + response = dns_challenge.response(acme_client.client.net.key) + + verified = response.simple_verify( + dns_challenge.chall, + authz_record.host, + acme_client.client.net.key.public_key() + ) if not verified: metrics.send('complete_dns_challenge_verification_error', 'counter', 1) raise ValueError("Failed verification") time.sleep(5) - acme_client.answer_challenge(dns_challenge, response) + res = acme_client.answer_challenge(dns_challenge, response) + current_app.logger.debug(f"answer_challenge response: {res}") + + def get_dns_challenge(self, authzr): + for challenge in authzr.body.challenges: + if challenge.chall.typ == 'dns-01': + return challenge + else: + raise Exception("Could not find an HTTP challenge!") def request_certificate(self, acme_client, authorizations, order): for authorization in authorizations: @@ -132,6 +156,7 @@ class AcmeHandler(object): try: orderr = acme_client.poll_and_finalize(order, deadline) + except (AcmeError, TimeoutError): sentry.captureException(extra={"order_url": str(order.uri)}) metrics.send('request_certificate_error', 'counter', 1) @@ -480,6 +505,7 @@ class ACMEIssuerPlugin(IssuerPlugin): "pending_cert": entry["pending_cert"], }) except (PollError, AcmeError, Exception) as e: + raise sentry.captureException() metrics.send('get_ordered_certificates_resolution_error', 'counter', 1) order_url = order.uri diff --git a/requirements-dev.txt b/requirements-dev.txt index f9f1b8f3..0652df34 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -11,7 +11,7 @@ cfgv==1.6.0 # via pre-commit chardet==3.0.4 # via requests docutils==0.14 # via readme-renderer flake8==3.5.0 -identify==1.4.1 # via pre-commit +identify==1.4.2 # via pre-commit idna==2.8 # via requests importlib-metadata==0.9 # via pre-commit invoke==1.2.0 @@ -31,6 +31,6 @@ toml==0.10.0 # via pre-commit tqdm==4.31.1 # via twine twine==1.13.0 urllib3==1.24.2 # via requests -virtualenv==16.4.3 # via pre-commit +virtualenv==16.5.0 # via pre-commit webencodings==0.5.1 # via bleach -zipp==0.3.3 # via importlib-metadata +zipp==0.4.0 # via importlib-metadata diff --git a/requirements-docs.txt b/requirements-docs.txt index 5f69328d..4b75a502 100644 --- a/requirements-docs.txt +++ b/requirements-docs.txt @@ -7,7 +7,7 @@ acme==0.33.1 alabaster==0.7.12 # via sphinx alembic-autogenerate-enums==0.0.2 -alembic==1.0.9 +alembic==1.0.10 amqp==2.4.2 aniso8601==6.0.0 arrow==0.13.1 @@ -17,8 +17,8 @@ babel==2.6.0 # via sphinx bcrypt==3.1.6 billiard==3.6.0.0 blinker==1.4 -boto3==1.9.134 -botocore==1.12.134 +boto3==1.9.138 +botocore==1.12.138 celery[redis]==4.3.0 certifi==2019.3.9 certsrv==2.1.1 @@ -38,7 +38,7 @@ flask-migrate==2.4.0 flask-principal==0.4.0 flask-restful==0.3.7 flask-script==2.0.6 -flask-sqlalchemy==2.3.2 +flask-sqlalchemy==2.4.0 flask==1.0.2 future==0.17.1 gunicorn==19.9.0 @@ -47,7 +47,7 @@ idna==2.8 imagesize==1.1.0 # via sphinx inflection==0.3.1 itsdangerous==1.1.0 -javaobj-py3==0.2.4 +javaobj-py3==0.3.0 jinja2==2.10.1 jmespath==0.9.4 josepy==1.1.0 @@ -62,10 +62,10 @@ mock==2.0.0 ndg-httpsclient==0.5.1 packaging==19.0 # via sphinx paramiko==2.4.2 -pbr==5.1.3 +pbr==5.2.0 pem==19.1.0 psycopg2==2.8.2 -pyasn1-modules==0.2.4 +pyasn1-modules==0.2.5 pyasn1==0.4.5 pycparser==2.19 pycryptodomex==3.8.1 diff --git a/requirements-tests.txt b/requirements-tests.txt index 9dd01574..0a4660d0 100644 --- a/requirements-tests.txt +++ b/requirements-tests.txt @@ -7,11 +7,11 @@ asn1crypto==0.24.0 # via cryptography atomicwrites==1.3.0 # via pytest attrs==19.1.0 # via pytest -aws-sam-translator==1.10.0 # via cfn-lint +aws-sam-translator==1.11.0 # via cfn-lint aws-xray-sdk==2.4.2 # via moto -boto3==1.9.134 # via aws-sam-translator, moto +boto3==1.9.138 # via aws-sam-translator, moto boto==2.49.0 # via moto -botocore==1.12.134 # via aws-xray-sdk, boto3, moto, s3transfer +botocore==1.12.138 # via aws-xray-sdk, boto3, moto, s3transfer certifi==2019.3.9 # via requests cffi==1.12.3 # via cryptography cfn-lint==0.19.1 # via moto @@ -42,7 +42,7 @@ mock==2.0.0 # via moto more-itertools==7.0.0 # via pytest moto==1.3.8 nose==1.3.7 -pbr==5.1.3 # via mock +pbr==5.2.0 # via mock pluggy==0.9.0 # via pytest py==1.8.0 # via pytest pyasn1==0.4.5 # via rsa @@ -55,7 +55,7 @@ python-dateutil==2.8.0 # via botocore, faker, freezegun, moto python-jose==3.0.1 # via moto pytz==2019.1 # via moto pyyaml==5.1 -requests-mock==1.5.2 +requests-mock==1.6.0 requests==2.21.0 # via cfn-lint, docker, moto, requests-mock, responses responses==0.10.6 # via moto rsa==4.0 # via python-jose diff --git a/requirements.txt b/requirements.txt index 2d17b930..74290471 100644 --- a/requirements.txt +++ b/requirements.txt @@ -6,7 +6,7 @@ # acme==0.33.1 alembic-autogenerate-enums==0.0.2 -alembic==1.0.9 # via flask-migrate +alembic==1.0.10 # via flask-migrate amqp==2.4.2 # via kombu aniso8601==6.0.0 # via flask-restful arrow==0.13.1 @@ -15,8 +15,8 @@ asyncpool==1.0 bcrypt==3.1.6 # via flask-bcrypt, paramiko billiard==3.6.0.0 # via celery blinker==1.4 # via flask-mail, flask-principal, raven -boto3==1.9.134 -botocore==1.12.134 +boto3==1.9.138 +botocore==1.12.138 celery[redis]==4.3.0 certifi==2019.3.9 certsrv==2.1.1 @@ -36,7 +36,7 @@ flask-migrate==2.4.0 flask-principal==0.4.0 flask-restful==0.3.7 flask-script==2.0.6 -flask-sqlalchemy==2.3.2 +flask-sqlalchemy==2.4.0 flask==1.0.2 future==0.17.1 gunicorn==19.9.0 @@ -44,7 +44,7 @@ hvac==0.8.2 idna==2.8 # via requests inflection==0.3.1 itsdangerous==1.1.0 # via flask -javaobj-py3==0.2.4 # via pyjks +javaobj-py3==0.3.0 # via pyjks jinja2==2.10.1 jmespath==0.9.4 # via boto3, botocore josepy==1.1.0 # via acme @@ -58,10 +58,10 @@ marshmallow==2.19.2 mock==2.0.0 # via acme ndg-httpsclient==0.5.1 paramiko==2.4.2 -pbr==5.1.3 # via mock +pbr==5.2.0 # via mock pem==19.1.0 psycopg2==2.8.2 -pyasn1-modules==0.2.4 # via pyjks, python-ldap +pyasn1-modules==0.2.5 # via pyjks, python-ldap pyasn1==0.4.5 # via ndg-httpsclient, paramiko, pyasn1-modules, pyjks, python-ldap pycparser==2.19 # via cffi pycryptodomex==3.8.1 # via pyjks