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: notifications-unsubscr...@apisix.apache.org

For queries about this service, please contact Infrastructure at:
us...@infra.apache.org


Reply via email to