通过 Istio 入口网关的 TLS 握手失败 (tlsMode=passthrough)

2024-03-17

从外部客户端到 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"

logs

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网关和虚拟服务配置的问题。

Gatway:

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

库伯内特服务:

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

UPDATE:实际上,来自客户端的 TLS 流量确实到达了服务器 Pod,我已经通过这样做确认了这一点tcpdump port 443在服务器 Pod 上运行 openssl s_client 命令时看到数据包。不清楚为什么 pod 上的 istio-proxy 没有显示这一点,这并不能解释握手失败的原因。

我注意到了别的事情。通过-msg标记为openssl s_client,我没有看到任何返回,在“>>>”之后没有“


我的配置中有 2 个错误:

  • 在我的 Kubernetes 服务的配置中。不幸的是我的 TCP 端口 443 的名称是grpc-svc这会破坏 TLS 直通。将此端口重命名为tcp-svc解决问题。

  • 我不应该使用入口端口 15443,该端口似乎是为其他用途保留的。在入口网关上打开另一个端口 9444,然后在网关上配置端口 9444,就像我在问题中配置端口 15443 一样(即 TLS 直通的配置),然后将虚拟服务配置为路由 9444,就像我配置虚拟服务一样我的问题中 15433 的路线。

执行这两项操作可以让openssl s_client从外部客户端通过入口成功与 kubernetes 服务进行 TLS 握手。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

通过 Istio 入口网关的 TLS 握手失败 (tlsMode=passthrough) 的相关文章

随机推荐