| title | ACME | |||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| name | ACME | |||||||||||||||
| content_type | plugin | |||||||||||||||
| publisher | kong-inc | |||||||||||||||
| description | Let's Encrypt and ACMEv2 integration with {{site.base_gateway}} | |||||||||||||||
| related_resources |
|
|||||||||||||||
| products |
|
|||||||||||||||
| works_on |
|
|||||||||||||||
| topologies |
|
|||||||||||||||
| icon | acme.png | |||||||||||||||
| categories |
|
|||||||||||||||
| tags |
|
|||||||||||||||
| search_aliases |
|
|||||||||||||||
| notes | <b>Serverless Gateways</b>: This plugin is not supported in serverless gateways because the TLS handshake does not occur at the Kong layer in this setup. | |||||||||||||||
| min_version |
|
The ACME plugin allows {{site.base_gateway}} to apply SSL certificates from Let's Encrypt or any other ACMEv2 service and serve them dynamically for TLS requests. You can also configure a threshold time for automatic renewal.
The ACME plugin uses the HTTP-01 challenge, which lets you verify domain ownership before issuing an SSL certificate. The plugin generates a challenge token and key thumbprint, then presents them to Let's Encrypt or another ACMEv2 service when requested.
To use this plugin, you need:
- A public IP and a resolvable DNS
- This challenge can only be done on port 80, so {{site.base_gateway}} needs to accept proxy traffic this port. You can configure this with
proxy_listeninkong.conf.
Wildcard (*) certificates are not supported. Each domain must have its own certificate.
This plugin can only be configured as a global plugin.
The plugin terminates the /.well-known/acme-challenge/ path for matching domains.
To create certificates and terminate challenges only for certain domains, refer to the configuration reference.
In a database-backed deployment, the plugin creates an SNI and certificate entity in {{site.base_gateway}} to serve the certificate. If the SNI or certificate for the current request is already set in the database, it will be overwritten.
In DB-less mode, the plugin takes over certificate handling. The plugin overrides the SNI or certificate entity if they are already defined in {{site.base_gateway}}.
The ACME plugin needs a backend storage to store certificates, challenge tokens, and key thumbprints.
You can set the backend storage for the plugin using the config.storage parameter.
The backend storage available depends on the topology of your {{site.base_gateway}} environment:
{% feature_table %} item_title: Storage type columns:
- title: Description key: description
- title: Traditional mode key: traditional
- title: Hybrid mode key: hybrid
- title: DB-less key: dbless
- title: "{{site.konnect_short_name}}" key: konnect features:
- title: "
shm" description: "Lua shared dict storage. This storage is volatile between Nginx restarts (not reloads)." traditional: true hybrid: false dbless: true konnect: false - title: "
kong1" description: "{{site.base_gateway}} database storage." traditional: true hybrid: true dbless: false konnect: false - title: "
redis" description: "Redis-based storage." traditional: true hybrid: true dbless: true konnect: true - title: "
consul" description: "HashiCorp Consul storage." traditional: true hybrid: true dbless: true konnect: true - title: "
vault" description: "HashiCorp Vault storage. Only the KV V2 backend is supported." traditional: true hybrid: true dbless: true konnect: true {% endfeature_table %}
{:.info}
[1]: Due to the current limitations of hybrid mode,
kongstorage only supports certificate generation from the Admin API but not the proxy side, as the Data Planes don't have access to the {{site.base_gateway}} database. See the hybrid mode workflow for details.
To configure a storage type other than kong (default), see the ACME plugin example configurations.
An HTTP-01 challenge workflow between the {{site.base_gateway}} and the ACME server looks like this:
- The client sends a proxy or Admin API request that triggers certificate generation for
example-domain.com. - {{site.base_gateway}} sends a request to the ACME server to start the validation process.
- If
example-domain.comis publicly resolvable to the {{site.base_gateway}} instance that serves the challenge response, then the ACME server returns challenge instructions to {{site.base_gateway}}. - {{site.base_gateway}} executes the challenge against the
example-domain.com, validates the results against the ACME server, - If the challenge passes, {{site.base_gateway}} downloads the SSL certificate from the ACME server and uses it to serve TLS requests.
See the following diagram, which breaks down the process in more detail:
{% mermaid %}
sequenceDiagram
autonumber
participant client as Client
participant kong as {{site.base_gateway}}
participant acme as ACME Server
participant domain as example-domain.com
participant storage as Storage
(internal or external)
client->>kong: Proxy or Admin API request <br> for example-domain.com
kong->>acme: Start validation for example-domain.com
note left of acme: example-domain.com is <br> publicly resolvable to {{site.base_gateway}}
acme->>kong: Return challenge instructions
kong->>domain: Use challenge against example-domain.com
domain->>kong: Execute challenge and send response
kong->>acme: Check challenge status
acme->>kong: Download SSL certificate
kong->>storage: Place certificate in storage
storage->>kong: Use new SSL certificate for TLS requests
{% endmermaid %}
In hybrid mode, the process is essentially the same, but both the Control Plane and Data Planes need access to the same storage. If the storage is external, they both need to connect to the same external storage cluster. We also recommend setting up replicas to avoid having the Data Planes and Control Planes connect to same node directly for external storage.
The plugin runs daily checks and automatically renews all certificates that
will expire in less than the configured config.renew_threshold_days value. If the renewal
of an individual certificate throws an error, the plugin will continue renewing the
other certificates. It will try renewing all certificates, including those that previously
failed, once per day.
Renewal configuration is stored in the configured storage backend. If the storage is cleared or modified outside of {{site.base_gateway}}, renewal might not complete properly.
You can also actively trigger the renewal by sending the following request that schedules a renewal in the background:
curl http://localhost:8001/acme -XPATCH{{site.base_gateway}} tracks SSL certificates in the defined storage type only.
For example, if the storage type is set to kong, the certificates and their renewal configuration will be stored in the {{site.base_gateway}} database.
If you change the storage type, the previous configuration will be lost.
For example, if you have the storage type set to kong and change it to redis, all certificates that were tracked for renewal when using the Kong DB for storage will no longer be tracked and renewed automatically.
When switching between storage types, we recommend deleting existing certificates.
You can see what certificates {{site.base_gateway}} is currently is aware of using the /acme/certificates endpoint of the Admin API.
The ACME plugin supports external account binding (EAB) with the config.eab_kid and config.eab_hmac_key values.
If you're using ZeroSSL, the provider's external account can be registered automatically, without specifying the KID or HMAC key.
{% include plugins/redis-cloud-auth.md %}