AWS has support for mutually authenticating clients that present X509 certificates to Application Load Balancer (ALB). You can learn more about mTLS with ALB in AWS’s blog post.
To make sure AWS/ALB works with the Header Cert Auth plugin with mTLS enabled, we first need to generate the required certificates.
For development certificates, you can use OpenSSL to generate certificates or tools such as mkcert
.
Add HTTPS listener to the ALB
Configure the ALB by adding an HTTPS listener.
- In the Listener configuration, configure the following settings:
- Protocol: HTTPS
- Port: 443
- Routing actions: Forward to target groups
- In the Secure listener settings, configure the certificate from AWS Certificate Manager (ACM).
Make sure to upload your certificates to ACM and use them in the ALB.
- Certificate source: From ACM
- Certificate (from ACM): Select the certificate that you want to use
- Client certificate handling: Select Mutual authentication (mTLS) with Passthrough
Configure Kong Gateway with certificate and plugin
Next, configure Kong Gateway.
-
Add the root CA to the CA certificates:
curl -sX POST https://localhost:8001/ca_certificates -F cert=@cert.pem { "tags": null, "created_at": 1566597621, "cert": "-----BEGIN CERTIFICATE-----\FullPEMOmittedForBrevity==\n-----END CERTIFICATE-----\n", "id": "322dce96-d434-4e0d-9038-311b3520f0a3" }
-
Add the Header Cert Auth plugin to the service (or route).
- We need to update the
certificate_header_name
toX-Amzn-Mtls-Clientcert
. - The
certificate_header_format
should beurl_encoded
for AWS/ALB.
curl -X POST http://localhost:8001/services/{serviceName|Id}/plugins \ --header "accept: application/json" \ --header "Content-Type: application/json" \ --data ' { "name": "header-cert-auth", "config": { "ca_certificates": [ "0D769DE8-7CC0-4541-989B-F9C23E20054C" ], "certificate_header_name": "X-Amzn-Mtls-Clientcert", "certificate_header_format": "url_encoded", "secure_source": false } }
- We need to update the
Validate
Use the certificate and key to proxy the traffic:
curl -k --cert <client_certificate> --key <client_key> https://test-alb-<id>.us-east-2.elb.amazonaws.com/test
You should then be able to see the certificate in the response headers:
"X-Amzn-Mtls-Clientcert": "-----BEGIN%20CERTIFICATE-----%0AMIIDbDCCAdSgAwIBAgIUa...-----END%20CERTIFICATE-----"