Document updated on Oct 23, 2023
mTLS is an authentication mechanism used traditionally in business-to-business (B2B) applications where clients provide a certificate that allows to connect to the KrakenD server.
As KrakenD is a piece of software in the middle of two parts, there are different types of mTLS supported, that can work together or separately.
In both cases, the certificates must be recognized by your system’s Certification Authority (CA) or be added under the ca_certs
list.
From the configuration file perspective, Mutual TLS Authentication is no more than a flag enable_mtls
under the tls
section.
When mTLS is enabled, all KrakenD endpoints require clients to provide a known client-side X.509 authentication certificate. KrakenD relies on the system’s CA to validate certificates.
To enable it you need a configuration like this:
{
"version": 3,
"tls": {
"public_key": "/path/to/cert.pem",
"private_key": "/path/to/key.pem",
"enable_mtls": true,
"ca_certs": [
"./rootCA.pem"
]
}
}
And these are the options you can include under tls
:
keys
, or
null
object
| An array with all the CA certificates you would like to load to KrakenD when using mTLS, in addition to the certificates present in the system’s CA. Each certificate in the list is a relative or absolute path to the PEM file. If you have a format other than PEM, you must convert the certificate to PEM using a conversion tool. See also disable_system_ca_pool to avoid system’s CA.Example: ["ca.pem"] Defaults to [] | ||||
| The list of cipher suites as defined in the documentation. Defaults to [4865,4866,4867] | ||||
| The list of all the identifiers for the curve preferences. Use 23 for CurveP256, 24 for CurveP384 or 25 for CurveP521.Defaults to [23,24,25] | ||||
| Ignore any certificate in the system’s CA. The only certificates loaded will be the ones in the ca_certs list when true.Defaults to false | ||||
| A flag to disable TLS (useful while in development). Defaults to false | ||||
| Whether to enable or not Mutual Authentication. When mTLS is enabled, all KrakenD endpoints require clients to provide a known client-side X.509 authentication certificate. KrakenD relies on the system’s CA to validate certificates. Defaults to false | ||||
| An array with all the key pairs you want the TLS to work with. You can support multiple and unrelated domains in a single process.
Each item is an object with the following properties:
| ||||
| Maximum TLS version supported. Possible values are: "SSL3.0" , "TLS10" , "TLS11" , "TLS12" , "TLS13" Defaults to "TLS13" | ||||
| Minimum TLS version supported. When specifiying very old and insecure versions under TLS12 you must provide the ciphers_list .Possible values are: "SSL3.0" , "TLS10" , "TLS11" , "TLS12" , "TLS13" Defaults to "TLS13" | ||||
| Declaration of the private_key under the tls object is now deprecated. Please move this attribute inside the keys array. | ||||
| Declaration of the public_key under the tls object is now deprecated. Please move this attribute inside the keys array. |
Important: Connections not having a recognized certificate in KrakenD’s system CA, will be rejected. For further documentation on TLS, see the TLS documentation
If you want that all connections to backends use mTLS, add the following configuration:
{
"version": 3,
"client_tls": {
"client_certs": [
{
"certificate": "cert.pem",
"private_key": "cert.key"
}
]
}
}
"client_tls"
| The list of cipher suites as defined in the documentation.
Each item is an object with the following properties:
|
If instead of enabling mTLS against all backends, you can enable mTLS in a specific backend only. This option is available only in the Enterprise Edition
An example configuration would be:
{
"endpoint": "/foo",
"backend": [
{
"host": ["https://api-needing-mtls"],
"url_pattern": "/foo",
"extra_config": {
"backend/http/client": {
"client_tls": {
"client_certs": [
{
"certificate": "cert.pem",
"private_key": "cert.key"
}
]
}
}
}
}
]
}
Configuration needed (Enterprise Edition only):
"client_tls"
| The list of cipher suites as defined in the documentation.
Each item is an object with the following properties:
|
This is the schema needed for client mTLS, but the HTTP Client settings have many other options not related to mTLS.
To use mTLS you need to generate the client and server certificates. The following script example creates the needed files to enable mTLS. Notice that in the CN
of the certificates we are adding localhost
as we want to connect to KrakenD from and to localhost.
# Private key for the certificate authority
openssl genrsa -des3 -out rootCA.protected.key 2048
openssl rsa -in rootCA.protected.key -out rootCA.key
# Generate the CA
openssl req -x509 -new -nodes -key rootCA.key -sha256 -days 1024 -out rootCA.pem -subj "/C=US/ST=California/L=Mountain View/O=Your Organization/OU=Your Unit/CN=example.com"
# Generate a key for the client certificate
openssl genrsa -out client.key 2048
# Generate the certificate request for the client
openssl req -new -key client.key -out client.csr -subj "/C=US/ST=California/L=Mountain View/O=Your Organization/OU=Your Unit/CN=localhost"
# Sign the certificate request for the client
openssl x509 -req -in client.csr -extensions client -CA rootCA.pem -CAkey rootCA.key -CAcreateserial -out client.crt -days 500 -sha256
# Generate a key for the server certificate
openssl genrsa -out server.key 2048
# Generate the certificate request for the server
openssl req -new -key server.key -out server.csr -subj "/C=US/ST=California/L=Mountain View/O=Your Organization/OU=Your Unit/CN=localhost"
# Sign the certificate request for the server
openssl x509 -req -in server.csr -extensions server -CA rootCA.pem -CAkey rootCA.key -CAcreateserial -out server.crt -days 500 -sha256
The KrakenD configuration needed is as follows (no endpoints used for this demo):
{
"version": 3,
"$schema": "https://www.krakend.io/schema/v2.7/krakend.json",
"port": 443,
"tls": {
"public_key": "./server.crt",
"private_key": "./server.key",
"enable_mtls": true,
"ca_certs": [
"./rootCA.pem"
],
"disable_system_ca_pool": true
}
}
At this moment KrakenD accepts only clients passing a valid certificate. Let’s connect to the /__health
endpoint:
$curl \
--cacert rootCA.pem \
--key client.key \
--cert client.crt \
https://localhost/__health
{"agents":{},"now":"2022-11-07 11:43:53.444657401 +0000 UTC m=+25.777003978","status":"ok"}
If we don’t provide the valid certs we get an error instead:
$curl -k https://localhost/__health
curl: (56) OpenSSL SSL_read: error:14094412:SSL routines:ssl3_read_bytes:sslv3 alert bad certificate, errno 0
The documentation is only a piece of the help you can get! Whether you are looking for Open Source or Enterprise support, see more support channels that can help you.