I got a problem with SSL/TLS Termination on Kong API Gateway. HTTPS Requests using curl and Insomnia got response that SSL certificate problem: unable to get local issuer certificate. Certificate is valid and issued by well known issuer, so CA certificate is already in the clients known CA list. In Browser HTTPS requests works fine.
I'm using Kong version 2.7.1
docker-compose.yaml configured in next way:
kong:
image: kong:2.7.1
container_name: kong-api-gw
restart: always
networks:
kong-net:
ipv4_address: 172.16.1.11
volumes:
- kong-volume:/etc/kong
- kong-volume-conf:/usr/local/kong
environment:
KONG_DATABASE: postgres
KONG_PG_HOST: kong-database
KONG_PG_DATABASE: kong
KONG_PG_USER: ${KONG_PG_USER}
KONG_PG_PASSWORD: ${KONG_PG_PASSWORD}
KONG_PROXY_LISTEN: 0.0.0.0:8000, 0.0.0.0:8443 ssl
KONG_ADMIN_LISTEN: 0.0.0.0:8001, 0.0.0.0:8444 ssl
KONG_SSL: "on"
KONG_SSL_CERT: /etc/kong/ssl/kong.crt
KONG_SSL_CERT_KEY: /etc/kong/ssl/kong.key
KONG_PROXY_ACCESS_LOG: /dev/stdout
KONG_PROXY_ERROR_LOG: /dev/stdout
depends_on:
- kong-database
healthcheck:
test: ["CMD", "kong", "health"]
interval: 10s
timeout: 10s
retries: 10
ports:
- "8000:8000"
- "8001:8001"
- "8443:8443"
- "8444:8444"
deploy:
resources:
limits:
cpus: "2"
memory: "4000M"
logging:
driver: "json-file"
options:
max-file: "3"
max-size: "10M"
Certificate was added using Admin API and Konga UI, i tried pem and crt, both of them.
curl -X POST http://127.0.0.1:8001/certificates -H 'Content-Type: multipart/form-data' -F cert=@./kong.pem -F key=@./kong.key -F snis[]=example.com
Inside docker container i put mycert.crt and mycert.key to /etc/kong/ssl/, but nothing helped and there are no errors in logs.
Response from GET Request to https://example.com:8444/certificates (when disable SSL Validation in Insomnia)
{
"data": [
{
"key_alt": null,
"created_at": 1650871124,
"cert_alt": null,
"key": "-----BEGIN RSA PRIVATE KEY-----\cert-key-example\n-----END RSA PRIVATE KEY-----",
"id": "7ebdca61-4598-4e17-bdf8-2239c41ce09b",
"tags": null,
"snis": [
"example.com"
],
"cert": "-----BEGIN CERTIFICATE-----\cert-example\n-----END CERTIFICATE-----"
}
],
"next": null
}
Curl example
curl -i -v https://example.com:8443/api
* Trying ip:8443...
* TCP_NODELAY set
* Connected to example.com (ip) port 8443 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
* successfully set certificate verify locations:
* CAfile: /etc/ssl/certs/ca-certificates.crt
CApath: /etc/ssl/certs
* TLSv1.3 (OUT), TLS handshake, Client hello (1):
* TLSv1.3 (IN), TLS handshake, Server hello (2):
* TLSv1.3 (IN), TLS handshake, Encrypted Extensions (8):
* TLSv1.3 (IN), TLS handshake, Certificate (11):
* TLSv1.3 (OUT), TLS alert, unknown CA (560):
* SSL certificate problem: unable to get local issuer certificate
* Closing connection 0
curl: (60) SSL certificate problem: unable to get local issuer certificate
More details here: https://curl.haxx.se/docs/sslcerts.html
curl failed to verify the legitimacy of the server and therefore could not
establish a secure connection to it. To learn more about this situation and
how to fix it, please visit the web page mentioned above.
It's not a bug, i figured it out, Kong needs ca-bundle certificate not just crt. So you need to combine root and intermediate certificates. Together with your server certificate (issued specifically for your domain), these files complete the SSL chain of trust. At the end i just used Kong Admin API to upload certificate using Konga Web UI or POST request like: