acme_challenge_cert_helper: add support for IP identifiers (#53661)

* Add IP address identifier support to acme_challenge_cert_helper.

* Add changelog.

* type -> identifier_type.
This commit is contained in:
Felix Fontein 2019-03-13 10:15:57 +01:00 committed by René Moser
parent 9e63b196c8
commit 028facdfed
2 changed files with 31 additions and 6 deletions

View file

@ -0,0 +1,2 @@
minor_changes:
- "acme_challenge_cert_helper - add support for IP address identifiers."

View file

@ -106,9 +106,24 @@ EXAMPLES = '''
RETURN = '''
domain:
description:
- "The domain the challenge is for."
- "The domain the challenge is for. The certificate should be provided if
this is specified in the request's the C(Host) header."
returned: always
type: str
identifier_type:
description:
- "The identifier type for the actual resource identifier. Will be C(dns)
or C(ip)."
returned: always
type: str
version_added: "2.8"
identifier:
description:
- "The identifier for the actual resource. Will be a domain name if the
type is C(dns), or an IP address if the type is C(ip)."
returned: always
type: str
version_added: "2.8"
challenge_certificate:
description:
- "The challenge certificate in PEM format."
@ -149,6 +164,7 @@ try:
import cryptography.hazmat.primitives.asymmetric.utils
import cryptography.x509
import cryptography.x509.oid
import ipaddress
from distutils.version import LooseVersion
HAS_CRYPTOGRAPHY = (LooseVersion(cryptography.__version__) >= LooseVersion('1.3'))
_cryptography_backend = cryptography.hazmat.backends.default_backend()
@ -206,11 +222,16 @@ def main():
# Some common attributes
domain = to_text(challenge_data['resource'])
subject = issuer = cryptography.x509.Name([
cryptography.x509.NameAttribute(cryptography.x509.oid.NameOID.COMMON_NAME, domain),
])
identifier_type, identifier = to_text(challenge_data.get('resource_original', 'dns:' + challenge_data['resource'])).split(':', 1)
subject = issuer = cryptography.x509.Name([])
not_valid_before = datetime.datetime.utcnow()
not_valid_after = datetime.datetime.utcnow() + datetime.timedelta(days=10)
if identifier_type == 'dns':
san = cryptography.x509.DNSName(identifier)
elif identifier_type == 'ip':
san = cryptography.x509.IPAddress(ipaddress.ip_address(identifier))
else:
raise ModuleFailException('Unsupported identifier type "{0}"'.format(identifier_type))
# Generate regular self-signed certificate
regular_certificate = cryptography.x509.CertificateBuilder().subject_name(
@ -226,7 +247,7 @@ def main():
).not_valid_after(
not_valid_after
).add_extension(
cryptography.x509.SubjectAlternativeName([cryptography.x509.DNSName(domain)]),
cryptography.x509.SubjectAlternativeName([san]),
critical=False,
).sign(
private_key,
@ -250,7 +271,7 @@ def main():
).not_valid_after(
not_valid_after
).add_extension(
cryptography.x509.SubjectAlternativeName([cryptography.x509.DNSName(domain)]),
cryptography.x509.SubjectAlternativeName([san]),
critical=False,
).add_extension(
cryptography.x509.UnrecognizedExtension(
@ -267,6 +288,8 @@ def main():
module.exit_json(
changed=True,
domain=domain,
identifier_type=identifier_type,
identifier=identifier,
challenge_certificate=challenge_certificate.public_bytes(cryptography.hazmat.primitives.serialization.Encoding.PEM),
regular_certificate=regular_certificate.public_bytes(cryptography.hazmat.primitives.serialization.Encoding.PEM)
)