簡體   English   中英

通過 Istio 入口網關的 TLS 握手失敗(tlsMode=passthrough)

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM