lemur_acme package¶
lemur_acme
Module¶
acme_handlers
Module¶
- class lemur.plugins.lemur_acme.acme_handlers.AcmeDnsHandler
Bases:
AcmeHandler
- autodetect_dns_providers(domain)
Get DNS providers associated with a domain when it has not been provided for certificate creation. :param domain: :return: dns_providers: List of DNS providers that have the correct zone.
- cleanup_dns_challenges(acme_client, authorizations)
Best effort attempt to delete DNS challenges that may not have been deleted previously. This is usually called on an exception
- Parameters:
acme_client
authorizations
- Returns:
- complete_dns_challenge(acme_client, authz_record)
- finalize_authorizations(acme_client, authorizations)
- get_all_zones(dns_provider)
- get_authorizations(acme_client, order, order_info)
The list can be empty if all hostname validations are still valid
- get_cname(domain)
- Parameters:
domain – Domain name to look up a CNAME for.
- Returns:
First CNAME target or False if no CNAME record exists.
- get_dns_challenges(host, authorizations)
Get dns challenges for provided domain Also indicate if the hostname is already validated
- get_dns_provider(type)
- start_dns_challenge(acme_client, account_number, domain, target_domain, dns_provider, order, dns_provider_options)
- class lemur.plugins.lemur_acme.acme_handlers.AcmeHandler
Bases:
object
- extract_cert_and_chain(fullchain_pem, alternative_fullchains_pem, preferred_issuer=None)
- get_domains(options)
Fetches all domains currently requested :param options: :return:
- log_remaining_validation(authorizations, acme_account)
- maybe_add_extension(host, dns_provider_options)
- request_certificate(acme_client, authorizations, order)
- reuse_account(authority)
- revoke_certificate(certificate, crl_reason=0)
- setup_acme_client(authority)
- setup_acme_client_no_retry(authority)
- strip_wildcard(host)
Removes the leading wildcard and returns Host and whether it was removed or not (True/False)
- class lemur.plugins.lemur_acme.acme_handlers.AuthorizationRecord(domain, target_domain, authz, dns_challenge, change_id, cname_delegation)
Bases:
object
challenge_types
Module¶
- class lemur.plugins.lemur_acme.challenge_types.AcmeChallenge
Bases:
object
This is the base class, all ACME challenges will need to extend, allowing for future extendability
- cleanup(challenge, acme_client, validation_target)
Ideally the challenge should be cleaned up, after the validation is done :param challenge: Needed to identify the challenge to be removed :param acme_client: an already bootstrapped acme_client, to avoid passing all issuer_options and so on :param validation_target: Needed to remove the validation
- create_certificate(csr, issuer_options)
Create the new certificate, using the provided CSR and issuer_options. Right now this is basically a copy of the create_certificate methods in the AcmeHandlers, but should be cleaned and tried to make use of the deploy and cleanup methods
- Parameters:
csr
issuer_options
- Returns:
- deploy(challenge, acme_client, validation_target)
In here the challenge validation is fetched and deployed somewhere that it can be validated by the provider
- Parameters:
self
challenge – the challenge object, must match for the challenge implementation
acme_client – an already bootstrapped acme_client, to avoid passing all issuer_options and so on
validation_target – an identifier for the validation target, e.g. the name of a DNS provider
- exception lemur.plugins.lemur_acme.challenge_types.AcmeChallengeMissmatchError(*args, **kwargs)
Bases:
LemurException
- class lemur.plugins.lemur_acme.challenge_types.AcmeDnsChallenge
Bases:
AcmeChallenge
- cleanup(authorizations, acme_client, validation_target=None)
Best effort attempt to delete DNS challenges that may not have been deleted previously. This is usually called on an exception
- Parameters:
authorizations – all the authorizations to be cleaned up
acme_client – an already bootstrapped acme_client, to avoid passing all issuer_options and so on
validation_target – Unused right now
- Returns:
- create_certificate(csr, issuer_options)
Creates an ACME certificate.
- Parameters:
csr
issuer_options
- Returns:
- raise Exception:
- create_certificate_immediately(acme_client, order_info, csr)
- deploy(challenge, acme_client, validation_target)
In here the challenge validation is fetched and deployed somewhere that it can be validated by the provider
- Parameters:
self
challenge – the challenge object, must match for the challenge implementation
acme_client – an already bootstrapped acme_client, to avoid passing all issuer_options and so on
validation_target – an identifier for the validation target, e.g. the name of a DNS provider
- class lemur.plugins.lemur_acme.challenge_types.AcmeHttpChallenge
Bases:
AcmeChallenge
- cleanup(token_path, validation_target)
Ideally the challenge should be cleaned up, after the validation is done :param challenge: Needed to identify the challenge to be removed :param acme_client: an already bootstrapped acme_client, to avoid passing all issuer_options and so on :param validation_target: Needed to remove the validation
- create_certificate(csr, issuer_options)
Creates an ACME certificate using the HTTP-01 challenge.
- Parameters:
csr
issuer_options
- Returns:
- raise Exception:
- deploy(challenge, acme_client, validation_target)
In here the challenge validation is fetched and deployed somewhere that it can be validated by the provider
- Parameters:
self
challenge – the challenge object, must match for the challenge implementation
acme_client – an already bootstrapped acme_client, to avoid passing all issuer_options and so on
validation_target – an identifier for the validation target, e.g. the name of a DNS provider
cloudflare
Module¶
- lemur.plugins.lemur_acme.cloudflare.cf_api_call()
- lemur.plugins.lemur_acme.cloudflare.create_txt_record(host, value, account_number)
- lemur.plugins.lemur_acme.cloudflare.delete_txt_record(change_ids, account_number, host, value)
- lemur.plugins.lemur_acme.cloudflare.find_zone_id(host)
- lemur.plugins.lemur_acme.cloudflare.wait_for_dns_change(change_id, account_number=None)
dyn
Module¶
- lemur.plugins.lemur_acme.dyn.create_txt_record(domain, token, account_number)
- lemur.plugins.lemur_acme.dyn.delete_acme_txt_records(domain)
- lemur.plugins.lemur_acme.dyn.delete_txt_record(change_id, account_number, domain, token)
- lemur.plugins.lemur_acme.dyn.get_authoritative_nameserver(domain)
- lemur.plugins.lemur_acme.dyn.get_dynect_session()
- lemur.plugins.lemur_acme.dyn.get_zone_name(domain)
- lemur.plugins.lemur_acme.dyn.get_zones(account_number)
- lemur.plugins.lemur_acme.dyn.wait_for_dns_change(change_id, account_number=None)
nsone
Module¶
ACME DNS providor for NS1
- lemur.plugins.lemur_acme.nsone.create_txt_record(domain, token, account_number=None)
Create a TXT record for the given domain and token and return a change_id tuple
- Parameters:
domain – FQDN
token – challenge value
account_number
- Returns:
tuple of domain/token
- lemur.plugins.lemur_acme.nsone.delete_txt_record(change_id, account_number, domain, token)
Delete the TXT record for the given domain and token
- Parameters:
change_id – tuple of domain/token
account_number
domain – FQDN
token – challenge to delete
- Returns:
- lemur.plugins.lemur_acme.nsone.get_zones()
Retrieve authoritative zones from the NS1 API and return a list of zones
- Raise:
Exception
- Returns:
list of Zone Objects
- lemur.plugins.lemur_acme.nsone.wait_for_dns_change(change_id, account_number=None)
Checks the authoritative DNS Server to see if changes have propagated.
- Parameters:
change_id – tuple of domain/token
account_number
- Returns:
plugin
Module¶
- class lemur.plugins.lemur_acme.plugin.ACMEHttpIssuerPlugin(*args, **kwargs)
Bases:
IssuerPlugin
- author: str | None = 'Netflix'
- author_url: str | None = 'https://github.com/netflix/lemur.git'
- cancel_ordered_certificate(pending_cert, **kwargs)
- static create_authority(options)
Creates an authority, this authority is then used by Lemur to allow a user to specify which Certificate Authority they want to sign their certificate.
- Parameters:
options
- Returns:
- create_certificate(csr, issuer_options)
Creates an ACME certificate using the HTTP-01 challenge.
- Parameters:
csr
issuer_options
- Returns:
- raise Exception:
- description: str | None = "Enables the creation of certificates via ACME CAs (including Let's Encrypt), using the HTTP-01 challenge"
- options: List[Dict[str, Any]] = [{'helpMessage': 'Must be a valid web url starting with http[s]://', 'name': 'acme_url', 'required': True, 'type': 'str', 'validation': 'http[s]?://(?:[a-zA-Z]|[0-9]|[$_@.&+-]|[!*\\(\\),]|(?:%[0-9a-fA-F][0-9a-fA-F]))+'}, {'default': '', 'helpMessage': 'Telephone to use', 'name': 'telephone', 'type': 'str'}, {'default': '', 'helpMessage': 'Email to use', 'name': 'email', 'type': 'str', 'validation': '([-!#-\'*+/-9=?A-Z^-~]+(\\.[-!#-\'*+/-9=?A-Z^-~]+)*|\\"([]!#-[^-~ \\t]|(\\\\[\\t -~]))+\\")@([-!#-\'*+/-9=?A-Z^-~]+(\\.[-!#-\'*+/-9=?A-Z^-~]+)*|\\[[\\t -Z^-~]*])'}, {'default': '', 'helpMessage': 'ACME root Certificate', 'name': 'certificate', 'type': 'textarea', 'validation': '^-----BEGIN CERTIFICATE-----'}, {'default': False, 'helpMessage': 'Disable to create a new account for each ACME request', 'name': 'store_account', 'required': False, 'type': 'bool'}, {'default': '', 'helpMessage': 'Key identifier for the external account.', 'name': 'eab_kid', 'required': False, 'type': 'str'}, {'default': '', 'helpMessage': 'HMAC key for the external account.', 'name': 'eab_hmac_key', 'required': False, 'type': 'str'}, {'default': '', 'helpMessage': 'Account Private Key. Will be encrypted.', 'name': 'acme_private_key', 'required': False, 'type': 'textarea'}, {'default': '', 'helpMessage': 'Account Registration', 'name': 'acme_regr', 'required': False, 'type': 'textarea'}, {'helpMessage': 'The destination to use to deploy the token.', 'name': 'tokenDestination', 'required': True, 'type': 'destinationSelect'}, {'default': False, 'helpMessage': 'Drops the last certificate, i.e., the Cross Signed root, from the Chain', 'name': 'drop_last_cert_from_chain', 'required': False, 'type': 'bool'}]
- revoke_certificate(certificate, reason)
- slug: str | None = 'acme-http-issuer'
- title: str | None = 'Acme HTTP-01'
- version = 'unknown'
- class lemur.plugins.lemur_acme.plugin.ACMEIssuerPlugin(*args, **kwargs)
Bases:
IssuerPlugin
- author: str | None = 'Netflix'
- author_url: str | None = 'https://github.com/netflix/lemur.git'
- cancel_ordered_certificate(pending_cert, **kwargs)
- static create_authority(options)
Creates an authority, this authority is then used by Lemur to allow a user to specify which Certificate Authority they want to sign their certificate.
- Parameters:
options
- Returns:
- create_certificate(csr, issuer_options)
Creates an ACME certificate using the DNS-01 challenge.
- Parameters:
csr
issuer_options
- Returns:
- raise Exception:
- description: str | None = "Enables the creation of certificates via ACME CAs (including Let's Encrypt), using the DNS-01 challenge"
- get_ordered_certificate(pending_cert)
- get_ordered_certificates(pending_certs)
- options: List[Dict[str, Any]] = [{'helpMessage': 'ACME resource URI. Must be a valid web url starting with http[s]://', 'name': 'acme_url', 'required': True, 'type': 'str', 'validation': 'http[s]?://(?:[a-zA-Z]|[0-9]|[$_@.&+-]|[!*\\(\\),]|(?:%[0-9a-fA-F][0-9a-fA-F]))+'}, {'default': '', 'helpMessage': 'Telephone to use', 'name': 'telephone', 'type': 'str'}, {'default': '', 'helpMessage': 'Email to use', 'name': 'email', 'type': 'str', 'validation': '([-!#-\'*+/-9=?A-Z^-~]+(\\.[-!#-\'*+/-9=?A-Z^-~]+)*|\\"([]!#-[^-~ \\t]|(\\\\[\\t -~]))+\\")@([-!#-\'*+/-9=?A-Z^-~]+(\\.[-!#-\'*+/-9=?A-Z^-~]+)*|\\[[\\t -Z^-~]*])'}, {'default': '', 'helpMessage': 'ACME root certificate', 'name': 'certificate', 'type': 'textarea', 'validation': '^-----BEGIN CERTIFICATE-----'}, {'default': False, 'helpMessage': 'Disable to create a new account for each ACME request', 'name': 'store_account', 'required': False, 'type': 'bool'}, {'helpMessage': 'Key identifier for the external account.', 'name': 'eab_kid', 'required': False, 'type': 'str'}, {'helpMessage': 'HMAC key for the external account.', 'name': 'eab_hmac_key', 'required': False, 'type': 'str'}, {'default': '', 'helpMessage': 'Account Private Key. Will be encrypted.', 'name': 'acme_private_key', 'required': False, 'type': 'textarea'}, {'default': '', 'helpMessage': 'Account Registration', 'name': 'acme_regr', 'required': False, 'type': 'textarea'}, {'default': False, 'helpMessage': 'Drops the last certificate, i.e., the Cross Signed root, from the Chain', 'name': 'drop_last_cert_from_chain', 'required': False, 'type': 'bool'}]
- revoke_certificate(certificate, reason)
- slug: str | None = 'acme-issuer'
- title: str | None = 'Acme'
- version = 'unknown'
powerdns
Module¶
- class lemur.plugins.lemur_acme.powerdns.Record(_data)
Bases:
object
This class implements a PowerDNS record.
- property content
- property disabled
- property name
- property ttl
- property type
- class lemur.plugins.lemur_acme.powerdns.Zone(_data)
Bases:
object
This class implements a PowerDNS zone in JSON.
- property id
Zone id, has a trailing “.” at the end, which we manually remove.
- property kind
Indicates whether the zone is setup as a PRIMARY or SECONDARY
- property name
Zone name, has a trailing “.” at the end, which we manually remove.
- lemur.plugins.lemur_acme.powerdns.create_txt_record(domain, token, account_number)
Create a TXT record for the given domain and token and return a change_id tuple
- Parameters:
domain – FQDN
token – challenge value
account_number
- Returns:
tuple of domain/token
- lemur.plugins.lemur_acme.powerdns.delete_txt_record(change_id, account_number, domain, token)
Delete the TXT record for the given domain and token
- Parameters:
change_id – tuple of domain/token
account_number
domain – FQDN
token – challenge to delete
- Returns:
- lemur.plugins.lemur_acme.powerdns.get_zones(account_number)
Retrieve authoritative zones from the PowerDNS API and return a list of zones
- Parameters:
account_number
- Raise:
Exception
- Returns:
list of Zone Objects
- lemur.plugins.lemur_acme.powerdns.wait_for_dns_change(change_id, account_number=None)
Checks the authoritative DNS Server to see if changes have propagated.
- Parameters:
change_id – tuple of domain/token
account_number
- Returns:
route53
Module¶
- lemur.plugins.lemur_acme.route53.change_txt_record(action, zone_id, domain, value, client=None)
- lemur.plugins.lemur_acme.route53.create_txt_record(host, value, account_number)
- lemur.plugins.lemur_acme.route53.delete_txt_record(change_ids, account_number, host, value)
- lemur.plugins.lemur_acme.route53.find_zone_id(domain, client=None)
- lemur.plugins.lemur_acme.route53.get_zones(client=None)
- lemur.plugins.lemur_acme.route53.wait_for_dns_change(change_id, client=None)
ultradns
Module¶
- class lemur.plugins.lemur_acme.ultradns.Record(_data)
Bases:
object
This class implements an Ultra DNS record.
Accepts the response from the API call as the argument.
- property name
- property rdata
- property rrtype
- property ttl
- class lemur.plugins.lemur_acme.ultradns.Zone(_data, _client='Client')
Bases:
object
This class implements an Ultra DNS zone.
- property authoritative_type
Indicates whether the zone is setup as a PRIMARY or SECONDARY
- property name
Zone name, has a trailing “.” at the end, which we manually remove.
- property record_count
- property status
Returns the status of the zone - ACTIVE, SUSPENDED, etc
- lemur.plugins.lemur_acme.ultradns.create_txt_record(domain, token, account_number)
Create a TXT record for the given domain.
The part of the domain that matches with the zone becomes the zone name. The remainder becomes the owner name (referred to as node name here) Example: Let’s say we have a zone named “exmaple.com” in UltraDNS and we get a request to create a cert for lemur.example.com Domain - _acme-challenge.lemur.example.com Matching zone - example.com Owner name - _acme-challenge.lemur
- lemur.plugins.lemur_acme.ultradns.delete_acme_txt_records(domain)
- lemur.plugins.lemur_acme.ultradns.delete_txt_record(change_id, account_number, domain, token)
Delete the TXT record that was created in the create_txt_record() function.
UltraDNS handles records differently compared to Dyn. It creates an RRSet which is a set of records of the same type and owner. This means that while deleting the record, we cannot delete any individual record from the RRSet. Instead, we have to delete the entire RRSet. If multiple certs are being created for the same domain at the same time, the challenge TXT records that are created will be added under the same RRSet. If the RRSet had more than 1 record, then we create a new RRSet on UltraDNS minus the record that has to be deleted.
- lemur.plugins.lemur_acme.ultradns.get_authoritative_nameserver(domain)
Get the authoritative nameserver for the given domain
- lemur.plugins.lemur_acme.ultradns.get_public_authoritative_nameserver()
- lemur.plugins.lemur_acme.ultradns.get_ultradns_token()
Function to call the UltraDNS Authorization API.
Returns the Authorization access_token which is valid for 1 hour. Each request calls this function and we generate a new token every time.
- lemur.plugins.lemur_acme.ultradns.get_zone_name(domain, account_number)
Get the matching zone for the given domain
- lemur.plugins.lemur_acme.ultradns.get_zones(account_number)
Get zones from the UltraDNS
- lemur.plugins.lemur_acme.ultradns.wait_for_dns_change(change_id, account_number=None)
Waits and checks if the DNS changes have propagated or not.
First check the domains authoritative server. Once this succeeds, we ask a public DNS server (Google <8.8.8.8> in our case).