This plugin allows Kong to apply certificates from Let’s Encrypt or any other ACMEv2 service and serve them dynamically. Renewal is handled with a configurable threshold time.
Configuration Reference
This plugin is compatible with DB-less mode.
In DB-less mode, you configure Kong Gateway declaratively. Therefore, the Admin API is mostly read-only. The only tasks it can perform are all related to handling the declarative config, including:
- Setting a target's health status in the load balancer
- Validating configurations against schemas
- Uploading the declarative configuration using the
/config
endpoint
Example plugin configuration
A plugin which is not associated to any service, route, or consumer is considered global, and will be run on every request. Read the Plugin Reference and the Plugin Precedence sections for more information.
The following examples provide some typical configurations for enabling
the acme
plugin globally.
Parameters
Here's a list of all the parameters which can be used in this plugin's configuration:
Form Parameter | Description |
---|---|
name
required Type: string |
The name of the plugin, in this case acme . |
instance_name
optional Type: string |
An optional custom name to identify an instance of the plugin, for example Useful when running the same plugin in multiple contexts, for example, on multiple services. |
enabled
optional Type: boolean Default value: |
Whether this plugin will be applied. |
config.account_email
Type: string |
The account identifier. Can be reused in a different plugin instance. If keyring database encryption is enabled, this value will be encrypted. This field is referenceable, which means it can be securely stored as a secret in a vault. References must follow a specific format. |
config.api_uri
optional Type: string Default value: |
The ACMEv2 API endpoint to use. You can specify the Let’s Encrypt staging environment for testing. Kong doesn’t automatically delete staging certificates. If you use the same domain in test and production environments, you need to manually delete those certificates after testing. |
config.cert_type
optional Type: string Default value: |
The certificate type to create. The possible values are |
config.domains
optional Type: array of string elements Default value: |
The list of domains to create certificates for. To match subdomains under This parameter is only used to match domains, not to specify the Common Name
or Subject Alternative Name to create certificates. Each domain must have its own certificate.
The ACME plugin checks this configuration before checking any certificate in If this field is left empty, all top-level domains (TLDs) are allowed. |
config.allow_any_domain
optional Type: boolean Default value: |
If set to |
config.fail_backoff_minutes
optional Type: number Default value: |
Minutes to wait for each domain that fails to create a certificate. This applies to both a new certificate and a renewal certificate. |
config.renew_threshold_days
optional Type: number Default value: |
Days remaining to renew the certificate before it expires. |
config.storage
optional Type: string Default value: |
The backend storage type to use. The possible values are |
config.storage_config
optional Type: record |
Storage configs for each backend storage. See Storage configuration considerations for information on its default values. |
config.tos_accepted
optional Type: boolean Default value: |
If you are using Let’s Encrypt, you must set this to |
config.eab_kid
optional Type: string |
External account binding (EAB) key id. You usually don’t need to set this unless it is explicitly required by the CA. If keyring database encryption is enabled, this value will be encrypted. This field is referenceable, which means it can be securely stored as a secret in a vault. References must follow a specific format. |
config.eab_hmac_key
optional Type: string |
External account binding (EAB) base64-encoded URL string of the HMAC key. You usually don’t need to set this unless it is explicitly required by the CA. If keyring database encryption is enabled, this value will be encrypted. This field is referenceable, which means it can be securely stored as a secret in a vault. References must follow a specific format. |
config.rsa_key_size
optional Type: number Default value: |
RSA private key size for the certificate. The possible values are 2048, 3072, or 4096. |
EAB support
External account binding (EAB) is supported as long as eab_kid
and eab_hmac_key
are provided.
The following CA provider’s external account can be registered automatically, without specifying
the eab_kid
or eab_hmac_key
:
Storage configuration considerations
config.storage_config
is a table for all possible storage types. By default, it is:
"storage_config": {
"kong": {},
"shm": {
"shm_name": "kong"
},
"redis": {
"auth": null,
"port": 6379,
"database": 0,
"host": "127.0.0.1",
"ssl": false,
"ssl_verify": false,
"ssl_server_name": null
},
"consul": {
"host": "127.0.0.1",
"port": 8500,
"token": null,
"kv_path": "acme",
"timeout": 2000,
"https": false
},
"vault": {
"host": "127.0.0.1",
"port": 8200,
"token": null,
"kv_path": "acme",
"timeout": 2000,
"https": false,
"tls_verify": true,
"tls_server_name": null,
"auth_method": "token",
"auth_path": null,
"auth_role": null,
"jwt_path": null,
},
}
The consul.token
, redis.auth
, and vault.token
fields are referenceable, which means they can be securely stored as secrets
in a vault. References must follow a specific format.
To configure a storage type other than kong
, refer to lua-resty-acme.
Workflow
A http-01
challenge workflow between the Kong Gateway and the ACME server is described below:
- The client sends a proxy or Admin API request that triggers certificate generation for
mydomain.com
. - The Kong Gateway sends a request to the ACME server to start the validation process.
- The ACME server returns a challenge response detail to the Kong Gateway.
mydomain.com
is publicly resolvable to the Kong Gateway that serves the challenge response.- The ACME server checks if the previous challenge has a response at
mydomain.com
. - The Kong Gateway checks the challenge status and if passed, downloads the certificate from the ACME server.
- The Kong Gateway uses the new certificate to serve TLS requests.
Using the plugin
Configure Kong
- Kong needs to listen on port 80 or proxy a load balancer that listens for port 80.
lua_ssl_trusted_certificate
needs to be set inkong.conf
to ensure the plugin can properly verify the Let’s Encrypt API. The CA-bundle file is usually/etc/ssl/certs/ca-certificates.crt
for Ubuntu/Debian and/etc/ssl/certs/ca-bundle.crt
for CentOS/Fedora/RHEL. Starting with Kong v2.2, users can set this config tosystem
to auto pick CA-bundle from OS.
Configure plugin
Here’s a sample declarative configuration with redis
as storage:
_format_version: "3.0"
# this section is not necessary if there's already a route that matches
# /.well-known/acme-challenge path with http protocol
services:
- name: acme-dummy
url: http://127.0.0.1:65535
routes:
- name: acme-dummy
protocols:
- name: http
paths:
- /.well-known/acme-challenge
plugins:
- name: acme
config:
account_email: example@myexample.com
domains:
- "*.example.com"
- "example.com"
tos_accepted: true
storage: redis
storage_config:
redis:
host: redis.service
port: 6379
Enable the plugin
For each the domain that needs a certificate, make sure DOMAIN/.well-known/acme-challenge
is mapped to a route in Kong. You can check this by sending
curl KONG_IP/.well-known/acme-challenge/x -H "host:DOMAIN"
and getting the response Not found
.
You can also use the Admin API to verify the setup.
If not, add a route and a dummy service to catch this route.
# add a dummy service if needed
curl http://localhost:8001/services \
-d name=acme-dummy \
-d url=http://127.0.0.1:65535
# add a dummy route if needed
curl http://localhost:8001/routes \
-d name=acme-dummy \
-d paths[]=/.well-known/acme-challenge \
-d service.name=acme-dummy
# add the plugin
curl http://localhost:8001/plugins \
-d name=acme \
-d config.account_email=yourname@yourdomain.com \
-d config.tos_accepted=true \
-d config.domains[]=my.secret.domains.com
Note by setting tos_accepted
to true implies that you have read and accepted
terms of service.
This plugin can only be configured as a global plugin. The plugin terminates
/.well-known/acme-challenge/
path for matching domains. To create certificates
and terminate challenges only for certain domains, refer to the
Parameters section.
Trigger certificate creation
Assume Kong proxy is accessible via http://mydomain.com and https://mydomain.com.
# Trigger asynchronous creation from proxy requests
# The following request returns immediately with Kong's default certificate
# Wait up to 1 minute for the background process to finish
curl https://mydomain.com -k
# OR create from Admin API synchronously
# User can also use this endpoint to force "renew" a certificate
curl http://localhost:8001/acme -d host=mydomain.com
# Furthermore, it's possible to run a sanity test on your Kong setup
# before creating any certificate
curl http://localhost:8001/acme -d host=mydomain.com -d test_http_challenge_flow=true
curl https://mydomain.com
# Now gives you a valid Let's Encrypt certicate
Renew certificates
The plugin runs daily checks and automatically renews all certificates that
will expire in less than the configured 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. Note the renewal configuration is stored in the configured storage backend.
If the storage is cleared or modified outside of Kong, renewal might not complete properly.
It’s also possible to actively trigger the renewal. The following request schedules a renewal in the background and returns immediately.
curl http://localhost:8001/acme -XPATCH
Monitoring and debugging
The ACME plugin exposes several endpoints through Admin API that can be used for debugging and monitoring certificate creation and renewal.
Apply certificate
Endpoint
Applies or renews the certificate and returns the result.
Request body
Attribute | Description |
---|---|
host required |
The domain where to create the certificate. |
test_http_challenge_flow optional |
When set, only checks if the configuration is valid. Does not apply the certificate. |
Update certificate
Apply or renew the certificate and return the result. Unlike POST
, PATCH
runs the process in the background.
Endpoint
Request body
Attribute | Description |
---|---|
host required |
The domain where to create the certificate. |
test_http_challenge_flow optional |
When set, only checks if the configuration is valid. Does not apply the certificate. |
Get ACME certificates
List the certificates being created by the ACME plugin. You can use this endpoint to monitor certificate existence and expiry.
Endpoint
Get certificate by host
List certificates with a specific host.
Endpoint
Attribute | Description |
---|---|
HOST |
The IP or hostname of the host to target. |
Example response for listing certificates:
{
"data": [
{
"not_after": "2022-09-21 23:59:59",
"pubkey_type": "id-ecPublicKey",
"digest": "A9:49:55:06:A7:B6:1D:2B:13:47:C5:58:5B:AC:DA:43:B5:25:E0:86",
"issuer_cn": "ZeroSSL ECC Domain Secure Site CA",
"valid": true,
"host": "subdomain1.domain.com",
"not_before": "2022-06-23 00:00:00",
"serial_number": "93:B8:E9:D5:C6:36:ED:B4:A8:B3:FD:C5:9E:A8:08:88"
},
{
"not_after": "2022-09-21 23:59:59",
"pubkey_type": "id-ecPublicKey",
"digest": "26:12:A2:C4:6A:F5:A5:90:9D:03:15:CB:FE:A7:BF:32:1C:42:49:CE",
"issuer_cn": "ZeroSSL ECC Domain Secure Site CA",
"valid": true,
"host": "subdomain2.domain.com",
"not_before": "2022-06-23 00:00:00",
"serial_number": "F1:15:74:E3:E1:DD:21:72:48:C0:4F:06:25:1B:71:F7"
}
]
}
Hybrid mode
"shm"
storage type is not available in Hybrid Mode.
Due to current the limitations of Hybrid Mode, "kong"
storage only supports certificate generation from
the Admin API but not the proxy side.
"kong"
storage in Hybrid Mode works in following flow:
- The client sends an Admin API request that triggers certificate generation for
mydomain.com
. - The Kong Control Plane requests the ACME server to start the validation process.
- The ACME server returns a challenge response detail to the Kong Control Plane.
- The Kong Control Plane propagates the challenge response detail to the Kong Data Plane.
mydomain.com
is publicly resolvable to the Kong Data Plane that serves the challenge response.- The ACME server checks if the previous challenge has a response at
mydomain.com
. - The Kong Control Plane checks the challenge status and if passed, downloads the certificate from the ACME server.
- The Kong Control Plane propagates the new certificates to the Kong Data Plane.
- The Kong Data Plane uses the new certificate to serve TLS requests.
All external storage types work as usual in Hybrid Mode. Note both the Control Plane and Data Planes need to connect to the same external storage cluster. It’s also a good idea to setup replicas to avoid connecting to same node directly for external storage.
External storage in Hybrid Mode works in following flow:
- The client send a proxy or Admin API request that triggers certificate generation for
mydomain.com
. - The Kong Control Plane or Data Plane requests the ACME server to start the validation process.
- The ACME server returns a challenge response detail to the Kong Gateway.
- The Kong Control Plane or Data Plane stores the challenge response detail in external storage.
mydomain.com
is publicly resolvable to the Kong Data Plane that reads and serves the challenge response from external storage.- The ACME server checks if the previous challenge has a response at
mydomain.com
. - The Kong Control Plane or Data Plane checks the challenge status and if passed, downloads the certificate from the ACME server.
- The Kong Control Plane or Data Plane stores the new certificates in external storage.
- The Kong Data Plane reads from external storage and uses the new certificate to serve TLS requests.
Local testing and development
Run ngrok
ngrok exposes a local URL to the internet. Download ngrok and install.
ngrok
is only needed for local testing or development, it’s not a requirement for the plugin itself.
Run ngrok with:
./ngrok http localhost:8000
# Shows something like
# ...
# Forwarding http://e2e034a5.ngrok.io -> http://localhost:8000
# Forwarding https://e2e034a5.ngrok.io -> http://localhost:8000
# ...
# Substitute "e2e034a5.ngrok.io" with the host shows in your ngrok output
export NGROK_HOST=e2e034a5.ngrok.io
Leave the process running.
Configure route and service
curl http://localhost:8001/services \
-d name=acme-test \
-d url=http://mockbin.org
curl http://localhost:8001/routes \
-d service.name=acme-test \
-d hosts=$NGROK_HOST \
-d paths=/mock
Enable plugin
curl localhost:8001/plugins \
-d name=acme \
-d config.account_email=test@test.com \
-d config.tos_accepted=true \
-d config.domains[]=$NGROK_HOST
Trigger certificate creation
curl https://$NGROK_HOST:8443 --resolve $NGROK_HOST:8443:127.0.0.1 -vk
# Wait for several seconds
Check new certificate
echo q |openssl s_client -connect localhost -port 8443 -servername $NGROK_HOST 2>/dev/null |openssl x509 -text -noout
Notes
- In database mode, the plugin creates an SNI and Certificate entity in Kong to serve the certificate. If SNI or Certificate for the current request is already set in the database, they will be overwritten.
- In DB-less mode, the plugin takes over certificate handling. If the SNI or Certificate entity is already defined in Kong, they will be overridden by the response.
- The plugin only supports http-01 challenge, meaning a user will need a public
IP and set up a resolvable DNS. Kong also needs to accept proxy traffic from port
80
. Also, note that a wildcard or star (*
) certificate is not supported. Each domain must have its own certificate.
Changelog
Kong Gateway 3.1.x
- Added the
config.storage_config.redis.ssl
,config.storage_config.redis.ssl_verify
, andconfig.storage_config.redis.ssl_server_name
configuration parameters.
Kong Gateway 3.0.x
- The
storage_config.vault.auth_method
configuration parameter now defaults totoken
. - Added the
allow_any_domain
configuration parameter. If enabled, it lets Kong Gateway ignore thedomains
field.
Kong Gateway 2.8.x
- Added the
rsa_key_size
configuration parameter. - The
consul.token
,redis.auth
, andvault.token
are now marked as now marked as referenceable, which means they can be securely stored as secrets in a vault. References must follow a specific format.
Kong Gateway 2.7.x
- Starting with Kong Gateway 2.7.0.0, if keyring encryption is enabled,
the
account_email
,eab_kid
, andeab_hmac_kid
parameter values will be encrypted.
Kong Gateway 2.4.x
- Added external account binding (EAB) support with the
eab_kid
andeab_hmac_key
configuration parameters.
Kong Gateway 2.1.x
- Added the
fail_backoff_minutes
configuration parameter.