最近,我一直在为基于物联网的项目评估不同的 API 网关 (API GW) 选项。这样做的目的是找到一个足够好的解决方案来执行设备和 API GW 的相互 TLS (mTLS) 身份验证。
我尝试过的大多数解决方案似乎都在 TLS 握手期间执行 mTLS,如此处所示。所以这就是我所理解的OSI 第 4 层 (TCP/IP)身份验证方法。
但是,Kong API 网关似乎在OSI 第 7 层(应用程序)上执行此操作。基本上,在 TLS 握手阶段没有客户端身份验证,而是应用层验证对等证书。因此它能够发送带有 401 状态和一些有效负载的响应(如果 TLS 握手失败,这是不可能的)。例子
√ poc-mtls-local-env % make test-fail-wrong-cert master
curl -v --cacert certs/gen/ca-chain.crt \
--key certs/gen/device.key \
--cert certs/gen/device.crt \
https://mtls.auth.local.com/echo
* Trying 127.0.0.1...
* TCP_NODELAY set
* Connected to mtls.auth.local.com (127.0.0.1) port 443 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
* successfully set certificate verify locations:
* CAfile: certs/gen/ca.crt
CApath: none
* TLSv1.2 (OUT), TLS handshake, Client hello (1):
* TLSv1.2 (IN), TLS handshake, Server hello (2):
* TLSv1.2 (IN), TLS handshake, Certificate (11):
* TLSv1.2 (IN), TLS handshake, Server key exchange (12):
* TLSv1.2 (IN), TLS handshake, Request CERT (13):
* TLSv1.2 (IN), TLS handshake, Server finished (14):
* TLSv1.2 (OUT), TLS handshake, Certificate (11):
* TLSv1.2 (OUT), TLS handshake, Client key exchange (16):
* TLSv1.2 (OUT), TLS handshake, CERT verify (15):
* TLSv1.2 (OUT), TLS change cipher, Change cipher spec (1):
* TLSv1.2 (OUT), TLS handshake, Finished (20):
* TLSv1.2 (IN), TLS change cipher, Change cipher spec (1):
* TLSv1.2 (IN), TLS handshake, Finished (20):
* SSL connection using TLSv1.2 / ECDHE-RSA-AES256-GCM-SHA384
* ALPN, server accepted to use h2
* Server certificate:
* subject: C=US; ST=NY; L=NYC; O=Sample; OU=UDS; CN=local.com
* start date: Jul 29 12:10:25 2021 GMT
* expire date: Jul 29 12:10:25 2022 GMT
* subjectAltName: host "mtls.auth.local.com" matched cert's "mtls.auth.local.com"
* issuer: C=US; ST=NY; O=Sample; OU=UDS; CN=Sample Intermediate CA; emailAddress=it@sample.com
* 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 0x7fc0dd808200)
> GET /echo HTTP/2
> Host: mtls.auth.local.com
> User-Agent: curl/7.64.1
> Accept: */*
>
* Connection state changed (MAX_CONCURRENT_STREAMS == 128)!
< HTTP/2 401
< date: Tue, 10 Aug 2021 06:46:13 GMT
< content-type: application/json; charset=utf-8
< content-length: 49
< x-kong-response-latency: 4
< server: kong/2.4.1.1-enterprise-edition
<
* Connection #0 to host mtls.auth.local.com left intact
{"message":"TLS certificate failed verification"}* Closing connection 0
我们可以清楚地看到请求成功通过了 TLS 握手,应用层形成了 401 响应{"message": "TLS certificate failed verification"}
。
这让我想到了以下几个问题:
- 形式上来说,Kong在这里做的也可以叫mTLS吗?
- 这种方法有什么潜在的陷阱吗?