This plugin allows Kong to apply certificates from Let’s Encrypt or any other ACMEv2 service and serve dynamically. Renewal is handled with a configurable threshold time.
Configuration Reference
This plugin is not compatible with DB-less mode.
Enable the plugin globally
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.
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 . |
enabled
required Type: boolean Default value: true |
Whether this plugin will be applied. |
config.account_email
required |
The account identifier, can be reused in different plugin instance. |
config.api_uri
optional Default value: https://acme-v02.api.letsencrypt.org
|
The ACMEv2 API endpoint to use. You can use the Let’s Encrypt staging environment during testing. Note that Kong doesn’t automatically delete staging certificates: if you use same domain to test and use in production, you will need to delete those certificates manually after testing. |
config.cert_type
optional Default value: rsa
|
The certificate type to create, choice of |
config.domains
optional Default value: []
|
The list of domains to create certificate for. To match subdomains under |
config.renew_threshold_days
optional Default value: 14
|
Days before expire to renew the certificate. |
config.storage
optional Default value: shm
|
The backend storage type to use, choice of |
config.storage_config
optional |
Storage configs for each backend storage. See below for its default value. |
config.tos_accepted
optional Default value: false
|
If you are using Let’s Encrypt, you must set this to true to agree the Terms of Service. |
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"
},
"consul": {
"host": "127.0.0.1",
"port": 8500,
"token": null,
"kv_path": "acme"
},
"vault": {
"host": "127.0.0.1",
"port": 8200,
"token": null,
"kv_path": "acme"
},
}
If you are using a cluster of Kong (multiple Kong instances running on different machines),
consider using one of "kong"
, "redis"
, "consul"
or "vault"
to support inter-cluster communication.
To configure a storage type other than kong
, refer to lua-resty-acme.
Workflow
A http-01
challenge workflow between Kong and the ACME server is described below:
- The client sends a proxy or Admin API request that triggers a certificate generation for
mydomain.com
. - Kong sends a request to the ACME server to start the validation process.
- The ACME server returns a challenge response detail to Kong.
mydomain.com
is publicly resolvable to Kong that serves the challenge response.- ACME server checks if the previous challenge is responded at
mydomain.com
. - Kong checks challenge status and if passed, downloads the certificate from the ACME server.
- Kong uses the new certificate to serve TLS requests.
Using the Plugin
Configure Kong
- Kong needs to listen 80 port or proxied by a load balancer that listens for 80 port.
nginx_proxy_lua_ssl_trusted_certificate
needs to be set inkong.conf
to ensure the plugin can properly verify 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.
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
.
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, please refer to the
Parameters section.
Trigger creation of certificate
Assume Kong proxy is accessible via http://mydomain.com and https://mydomain.com.
$ curl https://mydomain.com -k
# Returns Kong's default certificate
# Wait up to 1 minute
$ curl https://mydomain.com
# Now gives you a valid Let's Encrypt certicate
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
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 creation of certificate
$ 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 SNI and Certificate entity in Kong to serve certificate. If SNI or Certificate for current request is already set in 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 from response.
- The plugin only supports http-01 challenge, meaning a user will need a public
IP and setup resolvable DNS. Kong also needs to accept proxy traffic from port
80
. Also, note that wildcard or star (*) certificate is not supported. Each domain will have its own certificate.