txacme: A Twisted implementation of the ACME protocol

ACME is Automatic Certificate Management Environment, a protocol that allows clients and certificate authorities to automate verification and certificate issuance. The ACME protocol is used by the free Let’s Encrypt Certificate Authority.

txacme is an implementation of the protocol for Twisted, the event-driven networking engine for Python.

txacme is still under heavy development, and currently only an implementation of the client side of the protocol is planned; if you are interested in implementing or have need of the server side, please get in touch!

txacme’s documentation lives at Read the Docs, the code on GitHub. It’s rigorously tested on Python 2.7, 3.4+, and PyPy.

API entry points

There are several possible starting points for making use of txacme.

Server endpoint string

The simplest part of txacme to use is the stream server endpoint. Two endpoint parsers are provided, under the le: (Let’s Encrypt) and lets: (Let’s Encrypt Test in Staging) prefixes. The endpoint takes as parameters a directory to store certificates in, and the underlying endpoint to listen on.

Note

The Let’s Encrypt staging environment generates certificates signed by Fake LE Intermediate X1, but does not have the stringent limits that the production environment has, so using it for testing before switching to the production environment is highly recommended.

A typical example:

twistd -n web --port lets:/srv/www/certs:tcp:443 --path /srv/www/root

Note

The certificate directory must already exist, and be writable by the user the application is running as.

The ACME client key will be stored in client.key in the cert directory. If this file does not exist, a new key will automatically be generated. Certificates (and chain certificates and keys) in PEM format will be stored in files named like some.domain.name.pem in the certificate directory. The appropriate certificate will be selected based on the servername that the client sends by SNI, so clients that do not perform SNI will not be able to connect.

In the event that there is no existing certificate available for a domain, an empty file can be used. This will be treated the same way as an expired certificate, and a new certificate will then be issued on startup. For example:

touch /srv/www/certs/example.com.pem

Note

This endpoint uses the tls-sni-01 challenge type to perform authorization; this requires that the endpoint is reachable on port 443 for those domains (possibly via port forwarding).

Note

A certificate directory can be shared amongst multiple applications, using le: for the application running on port 443 to keep the certificates up to date, and txsni: for the other applications to make use of the same certificates.

At startup, and periodically (every 24 hours), a check will be performed for expiring certificates; if a certificate will expire in less than 30 days’ time, it will be reissued. If the reissue fails, it will be retried at the next check. If a certificate will expire in less than 15 days’ time, and reissue fails, a message will be logged at CRITICAL level.

Server endpoint API

The endpoint can be instantiated directly as well; this allows extra customizations beyond what the string syntax provides for. Most of the parameters that can be passed correspond to the parameters of the issuing service (see below).

class txacme.endpoint.AutoTLSEndpoint(reactor, directory, client_creator, cert_store, cert_mapping, sub_endpoint, check_interval=datetime.timedelta(1), reissue_interval=datetime.timedelta(30), panic_interval=datetime.timedelta(15), panic=<function _default_panic>, generate_key=<functools.partial object>)[source]

A server endpoint that does TLS SNI, with certificates automatically (re)issued from an ACME certificate authority.

Parameters:
  • reactor – The Twisted reactor.
  • directorytwisted.python.url.URL for the ACME directory to use for issuing certs.
  • client_creator (Callable[[reactor, twisted.python.url.URL], Deferred[txacme.client.Client]]) – A callable called with the reactor and directory URL for creating the ACME client. For example, partial(Client.from_url, key=acme_key, alg=RS256).
  • cert_store (ICertificateStore) – The certificate store containing the certificates to manage. For example, txacme.store.DirectoryStore.
  • cert_mapping (dict) – The certificate mapping to use for SNI; for example, txsni.snimap.HostDirectoryMap. Usually this should correspond to the same underlying storage as cert_store.
  • check_interval (timedelta) – How often to check for expiring certificates.
  • reissue_interval (timedelta) – If a certificate is expiring in less time than this interval, it will be reissued.
  • panic_interval (timedelta) – If a certificate is expiring in less time than this interval, and reissuing fails, the panic callback will be invoked.
  • panic (Callable[[Failure, str], Deferred]) – A callable invoked with the failure and server name when reissuing fails for a certificate expiring in the panic_interval. For example, you could generate a monitoring alert. The default callback logs a message at CRITICAL level.
  • generate_key – A 0-arg callable used to generate a private key for a new cert. Normally you would not pass this unless you have specialized key generation requirements.
listen(protocolFactory)[source]

Start an issuing service, and wait until initial issuing is complete.

Issuing service

The endpoint is a simple wrapper that combines the functionality of the txsni endpoint for handling SNI, and the issuing service which takes care of (re)issuing certificates using an ACME service.

class txacme.service.AcmeIssuingService(cert_store, client, clock, responders, check_interval=datetime.timedelta(1), reissue_interval=datetime.timedelta(30), panic_interval=datetime.timedelta(15), panic=<function _default_panic>, generate_key=<functools.partial object>, waiting=NOTHING)[source]

A service for keeping certificates up to date by using an ACME server.

Parameters:
  • cert_store (ICertificateStore) – The certificate store containing the certificates to manage.
  • client (Client) – The ACME client to use. Typically constructed with Client.from_url.
  • clockIReactorTime provider; usually the reactor, when not testing.
  • responders (List[IResponder]) – Challenge responders. Usually only one responder is needed; if more than one responder for the same type is provided, only the first will be used.
  • check_interval (timedelta) – How often to check for expiring certificates.
  • reissue_interval (timedelta) – If a certificate is expiring in less time than this interval, it will be reissued.
  • panic_interval (timedelta) – If a certificate is expiring in less time than this interval, and reissuing fails, the panic callback will be invoked.
  • panic (Callable[[Failure, str], Deferred]) – A callable invoked with the failure and server name when reissuing fails for a certificate expiring in the panic_interval. For example, you could generate a monitoring alert. The default callback logs a message at CRITICAL level.
  • generate_key – A 0-arg callable used to generate a private key for a new cert. Normally you would not pass this unless you have specialized key generation requirements.
when_certs_valid()[source]

Get a notification once the startup check has completed.

When the service starts, an initial check is made immediately; the deferred returned by this function will only fire once reissue has been attempted for any certificates within the panic interval.

Note

The reissue for any of these certificates may not have been successful; the panic callback will be invoked for any certificates in the panic interval that failed reissue.

Return type:Deferred
Returns:A deferred that fires once the initial check has resolved.

The ICertificateStore and IResponder interfaces are the main extension points for using the issuing service directly. For example, a custom implementation might manage the certificate configuration of a cloud load balancer, implementing the dns-01 challenge type by modifying DNS entries in the cloud DNS configuration.

Indices and tables