Configure mTLS Between APISIX and Upstream
Mutual TLS (mTLS) is a two-way TLS where client and the server authenticate each other. It is typically implemented in high-security environments to prevent unauthorized access and harden security.
This guide will walk you through how to configure mTLS between APISIX and an upstream service, using NGINX as a sample upstream service.
Prerequisite(s)
- Install Docker.
- Install cURL to send requests to the service for test.
- Follow the Getting Started tutorial to start a new APISIX instance in Docker.
Generate Certificates and Keys
Generate the certificate authority (CA) key and certificate:
openssl genrsa -out ca.key 2048 && \
openssl req -new -sha256 -key ca.key -out ca.csr -subj "/CN=ROOTCA" && \
openssl x509 -req -days 36500 -sha256 -extensions v3_ca -signkey ca.key -in ca.csr -out ca.crt
Generate the key and certificate with the common name test.com
for APISIX, and sign with the CA certificate:
openssl genrsa -out server.key 2048 && \
openssl req -new -sha256 -key server.key -out server.csr -subj "/CN=test.com" && \
openssl x509 -req -days 36500 -sha256 -extensions v3_req \
-CA ca.crt -CAkey ca.key -CAserial ca.srl -CAcreateserial \
-in server.csr -out server.crt
Generate the key and certificate with the common name CLIENT
for a client, and sign with the CA certificate:
openssl genrsa -out client.key 2048 && \
openssl req -new -sha256 -key client.key -out client.csr -subj "/CN=CLIENT" && \
openssl x509 -req -days 36500 -sha256 -extensions v3_req \
-CA ca.crt -CAkey ca.key -CAserial ca.srl -CAcreateserial \
-in client.csr -out client.crt
Configure Upstream Service
Start an NGINX server as a sample upstream service in the same Docker network as APISIX:
docker run -d \
--name quickstart-nginx \
--network=apisix-quickstart-net \
-p 8443:8443 \
nginx
Copy CA certificate, server certificate public and private keys into NGINX:
docker cp ca.crt quickstart-nginx:/var/ca.crt
docker cp server.crt quickstart-nginx:/var/server.crt
docker cp server.key quickstart-nginx:/var/server.key
Configure an HTTPS server listening on /hello
and port 8443
in NGINX configuration file:
http {
# ...
server {
listen 8443 ssl;
server_name test.com;
ssl_certificate /var/server.crt;
ssl_certificate_key /var/server.key;
ssl_client_certificate /var/ca.crt;
ssl_verify_client on;
location /hello {
return 200 "Hello APISIX!";
}
}
}
❶ server_name
: set to test.com
to be consistent with the server certificate CN value.
❷ ssl_certificate
: configure the path to the server certificate public key server.crt
.
❸ ssl_certificate_key
: configure the path to the server certificate private key server.key
.
❹ ssl_client_certificate
: configure the path to the CA certificate public key ca.crt
.
❺ ssl_verify_client
: set to on
to verify the client certificate.
Reload the NGINX server to apply the configuration changes:
docker exec quickstart-nginx nginx -s reload
To verify that the NGINX instance is properly configured, send a request to the route with client certificate and key:
curl -ik "https://127.0.0.1:8443/hello" --cert client.crt --key client.key
You should receive an HTTP/1.1 200 OK
response.
Configure mTLS for APISIX
Load the content of client.crt
and client.key
into environment variables:
client_cert=$(cat client.crt)
client_key=$(cat client.key)
Create a route to the NGINX server:
curl -i "http://127.0.0.1:9180/apisix/admin/routes" -X PUT -d '
{
"id": "mtls-nginx",
"uri": "/hello",
"upstream": {
"scheme": "https",
"nodes": {
"quickstart-nginx:8443":1
},
"tls": {
"client_cert": "'"${client_cert}"'",
"client_key": "'"${client_key}"'"
},
"type": "roundrobin"
}
}'
❶ scheme
: set to https
.
❷ nodes
: set to the NGINX server hostname quickstart-nginx
and port 8443
.
❸ tls.client_cert
: configure the certificate public key client.crt
.
❹ tls.client_key
: configure the certificate private key client.key
.
Verify mTLS between APISIX and Upstream Service
Send a request to the route:
curl -ik "http://127.0.0.1:9080/hello"
You should receive an HTTP/1.1 200 OK
response, verifying that the mTLS between APISIX and upstream has been set up successfully.
Next Steps
You have learned how to set up mTLS between APISIX and upstream services. APISIX also supports mTLS between clients and APISIX. See Configure mTLS between Client and APISIX to learn more.