tzssangglass opened a new issue #4730:
URL: https://github.com/apache/apisix/issues/4730
This question can be extended to how to configure mTLS connections between
Client and APISIX, between Control Plane and APISIX, between APISIX and
Upstream, and between APISIX and etcd。
The mTLS connection on the route is the mTLS connection between the Client
and APISIX.
The pre-requisites for enabling the mTLS protocol are: CA certificate,
client certificate, client key, server certificate, and server key. The below
example uses the certificate file from APISIX for the test case.
1. Upload certificates
APISIX provides an API to upload certificates dynamically, you can also
upload certificates in APISIX-Dashboard. For visualization, I use a test case
to upload ssl certificate, example.
```perl
=== TEST 1: set ssl(sni: admin.apisix.dev)
--- config
location /t {
content_by_lua_block {
local core = require("apisix.core")
local t = require("lib.test_admin")
local ssl_cert = t.read_file("t/certs/mtls_server.crt")
local ssl_key = t.read_file("t/certs/mtls_server.key")
local ssl_cacert = t.read_file("t/certs/mtls_ca.crt")
local data = {cert = ssl_cert, key = ssl_key, sni =
"admin.apisix.dev", client = {ca = ssl_cacert, depth = 5}}
local code, body = t.test('/apisix/admin/ssl/1',
ngx.HTTP_PUT,
core.json.encode(data),
[[{
"node": {
"value": {
"sni": "admin.apisix.dev"
},
"key": "/apisix/ssl/1"
},
"action": "set"
}]]
)
ngx.status = code
ngx.say(body)
}
}
--- request
GET /t
--- response_body
passed
--- no_error_log
[error]
```
Note: You need to set the CA certificate and the certificate depth for
client certificate verification, i.e. `client.ca` and `client.depth`. Also
note: mtls_ca.crt is signed by the SNI `admin.apisix.dev`.
2. Set Route
for example:
```shell
curl http://127.0.0.1:9080/apisix/admin/routes/1 -H 'X-API-KEY:
edd1c9f034335f136f87ad84b625c8f1' -X PUT -i -d '
{
"uri": "/get",
"hosts": ["admin.apisix.dev"],
"upstream": {
"type": "roundrobin",
"nodes": {
"httpbin.org:80": 1
}
}
}'
```
On the route, the hosts attribute is specified as `admin.apisix.dev`. APISIX
will query the associated SNI CA certificate, server certificate and server key
according to the domain name by the request. This process is equivalent to
binding the route and the certificate.
3. Test
```shell
curl --cert /usr/local/apisix/t/certs/mtls_client.crt --key
/usr/local/apisix/t/certs/mtls_client.key --cacert
/usr/local/apisix/t/certs/mtls_ca.crt --resolve
'admin.apisix.dev:9443:127.0.0.1' https://admin.apisix.dev:9443/get -vvv
* Added admin.apisix.dev:9443:127.0.0.1 to DNS cache
* Hostname admin.apisix.dev was found in DNS cache
* Trying 127.0.0.1:9443...
* Connected to admin.apisix.dev (127.0.0.1) port 9443 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
* successfully set certificate verify locations:
* CAfile: /usr/local/apisix/t/certs/mtls_ca.crt
CApath: none
* 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, Request CERT (13):
* TLSv1.3 (IN), TLS handshake, Certificate (11):
* TLSv1.3 (IN), TLS handshake, CERT verify (15):
* TLSv1.3 (IN), TLS handshake, Finished (20):
* TLSv1.3 (OUT), TLS change cipher, Change cipher spec (1):
* TLSv1.3 (OUT), TLS handshake, Certificate (11):
* TLSv1.3 (OUT), TLS handshake, CERT verify (15):
* TLSv1.3 (OUT), TLS handshake, Finished (20):
* SSL connection using TLSv1.3 / TLS_AES_256_GCM_SHA384
* ALPN, server accepted to use h2
* Server certificate:
* subject: C=cn; ST=GuangDong; O=api7; L=ZhuHai; CN=admin.apisix.dev
* start date: Jun 20 13:14:34 2020 GMT
* expire date: Jun 18 13:14:34 2030 GMT
* common name: admin.apisix.dev (matched)
* issuer: C=cn; ST=GuangDong; L=ZhuHai; O=api7; OU=ops; CN=ca.apisix.dev
* SSL certificate verify ok.
* Using HTTP2, server supports multi-use
* Connection state changed (HTTP/2 confirmed)
* Copying HTTP/2 data in stream buffer to connection buffer after upgrade:
len=0
* Using Stream ID: 1 (easy handle 0xaaaad8ffadd0)
> GET /get HTTP/2
> Host: admin.apisix.dev:9443
> user-agent: curl/7.71.1
> accept: */*
>
* TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
* TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
* old SSL session ID is stale, removing
* Connection state changed (MAX_CONCURRENT_STREAMS == 128)!
< HTTP/2 200
< content-type: application/json
< content-length: 320
< date: Tue, 06 Jul 2021 15:40:14 GMT
< access-control-allow-origin: *
< access-control-allow-credentials: true
< server: APISIX/2.7
<
{
"args": {},
"headers": {
"Accept": "*/*",
"Host": "admin.apisix.dev",
"User-Agent": "curl/7.71.1",
"X-Amzn-Trace-Id": "Root=1-60e4795e-4dd03a271242afe233d53ef6",
"X-Forwarded-Host": "admin.apisix.dev"
},
"origin": "127.0.0.1, 49.70.187.161",
"url": "http://admin.apisix.dev/get"
}
* Connection #0 to host admin.apisix.dev left intact
```
The `curl` command specifies the CA certificate, client certificate, and
client key. Since this is a local test, the `--resolve` command is used so that
`admin.apisix.dev` is pointed to `127.0.0.1` and triggered the request
successfully.
From the TLS handshake process, we can see that a certificate verification
is performed between Client and APISIX to complete the process of mTLS protocol
processing. From the response, we can see that APISIX has completed the request
proxy forwarding.
How to configure the mTLS connection between Control Plane and APISIX,
between APISIX and Upstream, and between APISIX and etcd, respectively, can be
found in
[mtls](https://github.com/apache/apisix/blob/master/docs/zh/latest/mtls.md).
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]