[英]TLS handshake through Istio ingress gateway fails (tlsMode=passthrough)
從外部客戶端到 Kubernetes 集群內的服務器的 TLS 握手失敗。 這是關於理解為什么。
我已經配置了一個 Istio 入口網關來傳遞在端口 15433 上接收到的 TLS,並將其路由到端口 433 上的服務器。
當客戶端嘗試 TLS 握手時,入口網關日志會顯示活動,但不會顯示服務器日志,也不會顯示 istio-proxy 日志。
TLS客戶端:
openssl s_client \
-connect [redacted]-[redacted].us-west-2.elb.amazonaws.com:15443 \
-servername myservice.mynamespace \
-CAfile /path/to/ca.cert \
-cert /path/to/cert.pem \
-key /path/to/cert.key <<< "Q"
日志
CONNECTED(00000006)
140090868934296:error:140790E5:SSL routines:ssl23_write:ssl handshake failure:s23_lib.c:177:
---
no peer certificate available
---
No client certificate CA names sent
---
SSL handshake has read 0 bytes and written 298 bytes
---
New, (NONE), Cipher is (NONE)
Secure Renegotiation IS NOT supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
SSL-Session:
Protocol : TLSv1.2
Cipher : 0000
Session-ID:
Session-ID-ctx:
Master-Key:
Key-Arg : None
PSK identity: None
PSK identity hint: None
SRP username: None
Start Time: 1600987862
Timeout : 300 (sec)
Verify return code: 0 (ok)
Istio 入口網關日志:
"- - -" 0 - "-" "-" 298 0 1069 - "-" "-" "-" "-" "192.168.101.136:443" outbound|443||myservice.mynamespace.svc.cluster.local 192.168.115.141:42350 192.168.115.141:15443 192.168.125.206:23298 myservice.mynamespace -
其中 192.168.101.136 是 myservice pod 的 IP,192.168.115.141 是 ingressgateway pod 的 IP。
根據 IP,這意味着客戶端連接到達了網關,網關似乎已經應用了虛擬服務路由並記錄了它正在將其轉發到 pod。 看起來很正常,除了 pod 上的 istio-proxy 沒有顯示任何活動和服務器日志(盡管服務器沒有記錄傳輸層發生的事情)。
AFAIK 服務器已為 TLS 正確配置,因為以下端口轉發的 TLS 握手成功:
kubectl port-forward -n mynamespace service/myservice 4430:443 &
openssl s_client \
-connect localhost:4430 \
-CAfile /path/to/ca.cert \
-cert /path/to/cert.pem \
-key /path/to/cert.key <<< "Q"
# I get back a TLS session ID, looks good.
所以這說明istio的網關或者virtualservice配置有問題。
網關:
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: mygateway
namespace: mynamespace
spec:
selector:
istio: ingressgateway
servers:
- port:
number: 15443
name: tls-passthrough
protocol: TLS
tls:
mode: PASSTHROUGH
hosts:
- "*"
虛擬服務:
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: myservice
namespace: mynamespace
spec:
hosts:
- "*"
gateways:
- mygateway
tls:
- match:
- port: 15443
sniHosts:
- myservice.mynamespace
route:
- destination:
host: myservice
port:
number: 443
Kubernetes 服務:
apiVersion: v1
kind: Service
metadata:
name: myservice
namespace: mynamespace
labels:
app: myservice
spec:
selector:
app: myservice
ports:
- protocol: TCP
port: 443
targetPort: 443
name: grpc-svc
更新:實際上,來自客戶端的 TLS 流量確實到達了服務器 pod,我已經通過在服務器 pod 上執行tcpdump port 443
並在運行 openssl s_client 命令時查看數據包來確認這一點。 不清楚為什么 pod 上的 istio-proxy 沒有顯示這一點,這並不能解釋握手失敗的原因。
我注意到了別的東西。 將-msg
標志傳遞給openssl s_client
,我看不到任何返回,在“>>>”之后沒有“<<<”,但 tcpdump 顯示服務器 pod 將數據包發送回網關。
我的配置中有兩個錯誤:
在我的 Kubernetes 服務的配置中。 不幸的是,我的 TCP 端口 443 的名稱是grpc-svc
,它破壞了 TLS 直通。 將此端口重命名為tcp-svc
可解決此問題。
我不應該使用入口端口 15443,它似乎是為別的東西保留的。 在 ingressgateway 上打開另一個端口 9444,然后完全按照我在我的問題中配置端口 15443(即 TLS passthrough 的配置)在網關上配置端口 9444,然后像配置虛擬服務一樣配置虛擬服務以路由 9444在我的問題中 15433 的路線。
執行這兩項操作允許來自外部客戶端的openssl s_client
通過入口成功與 kubernetes 服務進行 TLS 握手。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.