curl -k -i "https://$KONNECT_PROXY_URL/anything" \
--no-progress-meter --fail-with-body Configure HTTP logging over mTLS
To send HTTP logs to a log server over mTLS, store the client certificate and private key as a Certificate entity in Kong Gateway and configure
the HTTP Log plugin’s client_certificate parameter to reference that entity by ID.
Start Kong Gateway with KONG_LUA_SSL_TRUSTED_CERTIFICATE pointing to the CA that signed the log server’s certificate.
Prerequisites
decK v1.64.0+
To complete this tutorial, install decK. We recommend keeping decK up to date with the latest version (1.64.0).
decK is a CLI tool for managing Kong Gateway declaratively with state files.
This guide uses deck gateway apply, which directly applies entity configuration to your Gateway instance.
You can check your current decK version with deck version.
Generate certificates
This guide uses three certificates:
- A CA certificate, used to sign the log server and client certificates
- A log server certificate, presented by the log server during the TLS handshake
- A client certificate, presented by Kong Gateway to the log server
-
Create a working directory and change into it:
mkdir -p ~/http-log-mtls/certs && cd ~/http-log-mtls/certs -
Generate a CA certificate:
openssl req -new -x509 -nodes -days 365 \ -subj '/CN=my-ca' \ -keyout ca.key \ -out ca.crt -
Generate a log server certificate signed by the CA. The
subjectAltNamemust match the hostname that Kong Gateway uses to reach the log server. In this guide, the log server runs as a Docker container on the same network as Kong Gateway under the hostnamelogserver:openssl genrsa -out logserver.key 2048 openssl req -new -key logserver.key -out logserver.csr \ -subj "/CN=logserver" cat > logserver.ext <<EOF authorityKeyIdentifier=keyid,issuer basicConstraints=CA:FALSE keyUsage = digitalSignature, keyEncipherment extendedKeyUsage = serverAuth subjectAltName = DNS:logserver EOF openssl x509 -req \ -in logserver.csr \ -CA ca.crt -CAkey ca.key -CAcreateserial \ -out logserver.crt -days 365 -sha256 -extfile logserver.ext -
Generate a client certificate for Kong Gateway:
openssl genrsa -out client.key 2048 openssl req -new -key client.key -out client.csr \ -subj "/CN=kong-client" openssl x509 -req \ -in client.csr \ -CA ca.crt -CAkey ca.key -CAcreateserial \ -out client.crt -days 365 -sha256
Start Kong Gateway
The HTTP Log plugin verifies the log server’s TLS certificate against a trusted CA. Pass the CA certificate to Kong Gateway at startup so Kong Gateway can validate the log server’s certificate during the mTLS handshake.
-
Export your credentials:
export KONG_LICENSE_DATA='LICENSE-CONTENTS-GO-HERE'export KONNECT_TOKEN='YOUR_KONNECT_PAT' -
Start Kong Gateway using the quickstart script, mounting the CA certificate and configuring it as a trusted CA:
curl -Ls https://get.konghq.com/quickstart | bash -s -- \ -e KONG_LICENSE_DATA \ -v "$(pwd)/ca.crt:/etc/ssl/certs/ca.crt" \ -e KONG_LUA_SSL_TRUSTED_CERTIFICATE="/etc/ssl/certs/ca.crt, system"curl -Ls https://get.konghq.com/quickstart | bash -s -- -k $KONNECT_TOKEN \ -v "$(pwd)/ca.crt:/etc/ssl/certs/ca.crt" \ -e KONG_LUA_SSL_TRUSTED_CERTIFICATE="/etc/ssl/certs/ca.crt, system" \ --deck-outputThis mounts
ca.crtinto the container and tells Kong Gateway to trust it for outbound TLS connections. When Kong Gateway is ready, you’ll see:Kong Gateway ReadyCopy and paste the printed environment variable exports into your terminal to configure your session.
Start the log server
For this tutorial, we’re using an Nginx log server, and configuring it to require a client certificate from any connecting client.
-
Create a directory for the log server and copy the certificates into it:
mkdir -p ~/http-log-mtls/logserver cp ~/http-log-mtls/certs/logserver.crt ~/http-log-mtls/logserver/ cp ~/http-log-mtls/certs/logserver.key ~/http-log-mtls/logserver/ cp ~/http-log-mtls/certs/ca.crt ~/http-log-mtls/logserver/ -
Create a configuration file for Nginx named
nginx.conf:cat <<'EOF' > ~/http-log-mtls/logserver/nginx.conf worker_processes auto; events { worker_connections 1024; } http { default_type application/json; log_format ingestion_format escape=json '$time_iso8601 | $remote_addr | $request_body'; server { listen 443 ssl; server_name logserver; ssl_certificate /etc/ssl/certs/logserver.crt; ssl_certificate_key /etc/ssl/certs/logserver.key; ssl_client_certificate /etc/ssl/certs/ca.crt; ssl_verify_client on; location /health { access_log off; return 200 '{"status":"ok"}'; add_header Content-Type application/json; } location /v1/logs { limit_except POST { deny all; } client_body_in_single_buffer on; client_body_buffer_size 2m; proxy_pass http://127.0.0.1:65534 ; error_page 502 = @log_and_respond; } location @log_and_respond { access_log /var/log/nginx/ingested_logs.log ingestion_format; return 202 '{"status":"accepted"}'; default_type application/json; } } } EOF -
Create the
Dockerfile:cat <<'EOF' > ~/http-log-mtls/logserver/Dockerfile FROM nginx:latest COPY logserver.crt /etc/ssl/certs/logserver.crt COPY logserver.key /etc/ssl/certs/logserver.key COPY ca.crt /etc/ssl/certs/ca.crt COPY nginx.conf /etc/nginx/nginx.conf EXPOSE 443 CMD ["nginx", "-g", "daemon off;"] EOF -
Build and start the log server on the same Docker network as Kong Gateway:
cd ~/http-log-mtls/logserver docker build -t logserver . docker run -d --name logserver --net kong-quickstart-net -p 9443:443 logserver -
Verify that the log server accepts a valid client certificate:
curl -s --cacert ~/http-log-mtls/certs/ca.crt \ --cert ~/http-log-mtls/certs/client.crt \ --key ~/http-log-mtls/certs/client.key \ --resolve logserver:9443:127.0.0.1 \ https://logserver:9443/healthYou should receive:
{"status":"ok"}
Add the client certificate to Kong Gateway
Store the client certificate and private key as a Certificate entity so the HTTP Log plugin can reference it by ID.
Add the Certificate and export its ID:
export DECK_CLIENT_CERT_ID=$(curl -s -X POST http://localhost:8001/certificates \
--data-urlencode "cert=$(cat ~/http-log-mtls/certs/client.crt)" \
--data-urlencode "key=$(cat ~/http-log-mtls/certs/client.key)" | jq -r .id)
echo "Client Certificate ID: $DECK_CLIENT_CERT_ID"Create Service and Route
Configure an example-service and an example-route:
echo '
_format_version: "3.0"
services:
- name: example-service
url: https://httpbin.konghq.com
routes:
- name: example-route
paths:
- "/anything"
' | deck gateway apply -Configure the HTTP Log plugin
Enable the HTTP Log plugin on the Route and reference the Certificate entity:
echo '
_format_version: "3.0"
plugins:
- name: http-log
route: example-route
config:
http_endpoint: https://logserver/v1/logs
ssl_verify: true
client_certificate:
id: "${{ env "DECK_CLIENT_CERT_ID" }}"
method: POST
timeout: 10000
' | deck gateway apply -In this configuration:
-
http_endpoint: The HTTPS URL of the log server. In this example, Kong Gateway resolves the hostnamelogserverover the shared Docker network. -
ssl_verify: Whentrue, Kong Gateway verifies the log server’s certificate against the CA configured inKONG_LUA_SSL_TRUSTED_CERTIFICATE. -
client_certificate: References the Certificate entity containing the client certificate and private key that Kong Gateway presents to the log server.
Validate the flow
Send a request through Kong Gateway:
curl -k -i "https://localhost:8443/anything" \
--no-progress-meter --fail-with-body You should get an HTTP 200 response.
Check the log server to confirm that it received the log entry:
docker exec logserver tail -n 5 /var/log/nginx/ingested_logs.logYou should see a JSON log entry containing the request data.
Cleanup
Clean up certificates and log server
Stop and remove the log server container, then delete the working directory:
docker stop logserver && docker rm logserver
rm -rf ~/http-log-mtlsClean up Konnect environment
If you created a new control plane and want to conserve your free trial credits or avoid unnecessary charges, delete the new control plane used in this tutorial.
Destroy the Kong Gateway container
curl -Ls https://get.konghq.com/quickstart | bash -s -- -d