Mutual TLS Authentication
The clients will provide their certificates to the server and the server will check whether the cert is signed by the supplied CA and decide whether to serve the request.
How to configure
Generate self-signed key pairs, including ca, server, client key pairs.
Modify configuration items in :
- Run command:
apisix init
apisix reload
Please replace the following certificate paths and domain name with your real ones.
- Note: The same CA certificate as the server needs to be used *
curl --cacert /data/certs/mtls_ca.crt --key /data/certs/mtls_client.key --cert /data/certs/mtls_client.crt https://admin.apisix.dev:9180/apisix/admin/routes -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1'
How to configure
If APISIX does not trust the CA certificate that used by etcd server, we need to set up the CA certificate.
apisix:
ssl:
ssl_trusted_certificate: /path/to/certs/ca-certificates.crt # path of CA certificate used by the etcd server
Using mTLS is a way to verify clients cryptographically. It is useful and important in cases where you want to have encrypted and secure traffic in both directions.
How to configure
When configuring ssl
, use parameter client.ca
and client.depth
to configure the root CA that signing client certificates and the max length of certificate chain. Please refer to for details.
Here is an example Python script to create SSL with mTLS (id is 1
, changes admin API url if needed):
#!/usr/bin/env python
# coding: utf-8
# save this file as ssl.py
import sys
# sudo pip install requests
import requests
if len(sys.argv) < 4:
print("bad argument")
sys.exit(1)
with open(sys.argv[1]) as f:
cert = f.read()
with open(sys.argv[2]) as f:
key = f.read()
sni = sys.argv[3]
reqParam = {
"cert": cert,
"key": key,
"snis": [sni],
}
if len(sys.argv) >= 5:
print("Setting mTLS")
reqParam["client"] = {}
with open(sys.argv[4]) as f:
clientCert = f.read()
reqParam["client"]["ca"] = clientCert
if len(sys.argv) >= 6:
reqParam["client"]["depth"] = int(sys.argv[5])
resp = requests.put("http://127.0.0.1:9080/apisix/admin/ssl/1", json=reqParam, headers={
"X-API-KEY": api_key,
})
print(resp.status_code)
print(resp.text)
Please make sure that the SNI fits the certificate domain.
Sometimes the upstream requires mTLS. In this situation, the APISIX acts as the client, it needs to provide client certificate to communicate with upstream.
How to configure
When configuring upstreams
, we could use parameter tls.client_cert
and tls.client_key
to configure the client certificate APISIX used to communicate with upstreams. Please refer to for details.
This feature requires APISIX to run on APISIX-Base.
# coding: utf-8
# save this file as patch_upstream_mtls.py
import sys
import requests
if len(sys.argv) < 4:
print("bad argument")
sys.exit(1)
with open(sys.argv[2]) as f:
cert = f.read()
with open(sys.argv[3]) as f:
key = f.read()
id = sys.argv[1]
api_key = "edd1c9f034335f136f87ad84b625c8f1" # Change it
reqParam = {
"tls": {
"client_cert": cert,
"client_key": key,
},
}
resp = requests.patch("http://127.0.0.1:9080/apisix/admin/upstreams/"+id, json=reqParam, headers={
"X-API-KEY": api_key,
})
print(resp.status_code)
print(resp.text)
Patch existed upstream with id testmtls
: