Compare commits
3 Commits
test-apach
...
route53-cr
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
955a22d203 | ||
|
|
69e252d74a | ||
|
|
0b91c4e670 |
@@ -12,6 +12,8 @@ Named Arguments
|
||||
to propagate before asking the ACME
|
||||
server to verify the DNS record.
|
||||
(Default: 10)
|
||||
``--dns-route53-credentials`` Load AWS credentials from specified
|
||||
file. (Default: None)
|
||||
======================================== =====================================
|
||||
|
||||
|
||||
@@ -62,26 +64,40 @@ the required permissions <https://docs.aws.amazon.com/Route53/latest
|
||||
|
||||
The `access keys <https://docs.aws.amazon.com/general/latest/gr
|
||||
/aws-sec-cred-types.html#access-keys-and-secret-access-keys>`_ for an account
|
||||
with these permissions must be supplied in one of the following ways, which are
|
||||
discussed in more detail in the Boto3 library's documentation about `configuring
|
||||
credentials <https://boto3.readthedocs.io/en/latest/guide/configuration.html
|
||||
#best-practices-for-configuring-credentials>`_.
|
||||
|
||||
* Using the ``AWS_ACCESS_KEY_ID`` and ``AWS_SECRET_ACCESS_KEY`` environment
|
||||
variables.
|
||||
* Using a credentials configuration file at the default location,
|
||||
``~/.aws/config``.
|
||||
* Using a credentials configuration file at a path supplied using the
|
||||
``AWS_CONFIG_FILE`` environment variable.
|
||||
with these permissions should be supplied by setting the
|
||||
``--dns-route53-credentials`` option to a credentials file using standard format:
|
||||
|
||||
.. code-block:: ini
|
||||
:name: config.ini
|
||||
:caption: Example credentials config file:
|
||||
:caption: Example AWS credentials config file:
|
||||
|
||||
[default]
|
||||
aws_access_key_id=AKIAIOSFODNN7EXAMPLE
|
||||
aws_secret_access_key=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
|
||||
|
||||
**It is recommended to set ``--dns-route53-credentials``.** Otherwise Boto3 will
|
||||
attempt to obtain credentials using files at ``$HOME`` or from
|
||||
environment variables, which can differ at renewals. The following sources will
|
||||
be tried (this is discussed in more detail in the Boto3 library's documentation
|
||||
about `configuring credentials <https://boto3.readthedocs.io/en/latest
|
||||
/guide/configuration.html#best-practices-for-configuring-credentials>`_):
|
||||
|
||||
* Using the ``AWS_ACCESS_KEY_ID`` and ``AWS_SECRET_ACCESS_KEY`` environment
|
||||
variables.
|
||||
* Using a shared credentials file at the default location,
|
||||
``~/.aws/credentials``.
|
||||
* Using a shared credentials file at a path supplied using the
|
||||
``AWS_SHARED_CREDENTIALS_FILE`` environment variable.
|
||||
* Using a credentials configuration file at the default location,
|
||||
``~/.aws/config``.
|
||||
* Using a credentials configuration file at a path supplied using the
|
||||
``AWS_CONFIG_FILE`` environment variable..
|
||||
|
||||
Finally, if any of the above methods is used, and certbot is running in an EC2
|
||||
instance which has an `IAM role attached <https://docs.aws.amazon.com/AWSEC2
|
||||
/latest/UserGuide/iam-roles-for-amazon-ec2.html>`_, credentials for that role
|
||||
will be used.
|
||||
|
||||
.. caution::
|
||||
You should protect these API credentials as you would a password. Users who
|
||||
can read this file can use these credentials to issue some types of API calls
|
||||
|
||||
@@ -6,6 +6,7 @@ import time
|
||||
import boto3
|
||||
import zope.interface
|
||||
from botocore.exceptions import NoCredentialsError, ClientError
|
||||
from botocore.credentials import SharedCredentialProvider
|
||||
|
||||
from certbot import errors
|
||||
from certbot import interfaces
|
||||
@@ -35,9 +36,21 @@ class Authenticator(dns_common.DNSAuthenticator):
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(Authenticator, self).__init__(*args, **kwargs)
|
||||
self.r53 = boto3.client("route53")
|
||||
if self.conf("credentials"):
|
||||
creds = SharedCredentialProvider(self.conf("credentials")).load()
|
||||
if creds is None:
|
||||
raise errors.PluginError("Couldn't load AWS credentials")
|
||||
self.r53 = boto3.client("route53",
|
||||
aws_access_key_id=creds.access_key, aws_secret_access_key=creds.secret_key)
|
||||
else:
|
||||
self.r53 = boto3.client("route53")
|
||||
self._resource_records = collections.defaultdict(list) # type: DefaultDict[str, List[Dict[str, str]]]
|
||||
|
||||
@classmethod
|
||||
def add_parser_arguments(cls, add): # pylint: disable=arguments-differ
|
||||
super(Authenticator, cls).add_parser_arguments(add)
|
||||
add('credentials', help='Load AWS credentials from specified file.')
|
||||
|
||||
def more_info(self): # pylint: disable=missing-docstring,no-self-use
|
||||
return "Solve a DNS01 challenge using AWS Route53"
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
"""Tests for certbot_dns_route53.dns_route53.Authenticator"""
|
||||
|
||||
import os
|
||||
import unittest
|
||||
|
||||
import mock
|
||||
@@ -8,9 +9,15 @@ from botocore.exceptions import NoCredentialsError, ClientError
|
||||
from certbot import errors
|
||||
from certbot.plugins import dns_test_common
|
||||
from certbot.plugins.dns_test_common import DOMAIN
|
||||
from certbot.tests import util as test_util
|
||||
|
||||
CREDS_FILE = '''[default]
|
||||
aws_access_key_id=AKIAIOSFODNN7EXAMPLE
|
||||
aws_secret_access_key=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
|
||||
'''
|
||||
|
||||
|
||||
class AuthenticatorTest(unittest.TestCase, dns_test_common.BaseAuthenticatorTest):
|
||||
class AuthenticatorTest(test_util.TempDirTestCase, dns_test_common.BaseAuthenticatorTest):
|
||||
# pylint: disable=protected-access
|
||||
|
||||
def setUp(self):
|
||||
@@ -18,7 +25,11 @@ class AuthenticatorTest(unittest.TestCase, dns_test_common.BaseAuthenticatorTest
|
||||
|
||||
super(AuthenticatorTest, self).setUp()
|
||||
|
||||
self.config = mock.MagicMock()
|
||||
path = os.path.join(self.tempdir, '.ini')
|
||||
with open(path, "w") as creds_file:
|
||||
creds_file.write(CREDS_FILE)
|
||||
|
||||
self.config = mock.MagicMock(route53_credentials=path)
|
||||
|
||||
self.auth = Authenticator(self.config, "route53")
|
||||
|
||||
@@ -75,7 +86,7 @@ class AuthenticatorTest(unittest.TestCase, dns_test_common.BaseAuthenticatorTest
|
||||
self.auth.cleanup([self.achall])
|
||||
|
||||
|
||||
class ClientTest(unittest.TestCase):
|
||||
class ClientTest(test_util.TempDirTestCase):
|
||||
# pylint: disable=protected-access
|
||||
|
||||
PRIVATE_ZONE = {
|
||||
@@ -115,7 +126,11 @@ class ClientTest(unittest.TestCase):
|
||||
|
||||
super(ClientTest, self).setUp()
|
||||
|
||||
self.config = mock.MagicMock()
|
||||
path = os.path.join(self.tempdir, '.ini')
|
||||
with open(path, "w") as creds_file:
|
||||
creds_file.write(CREDS_FILE)
|
||||
|
||||
self.config = mock.MagicMock(route53_credentials=path)
|
||||
|
||||
self.client = Authenticator(self.config, "route53")
|
||||
|
||||
|
||||
Reference in New Issue
Block a user