首页 > 解决方案 > Istio:无法使用出口网关、自定义 CA 证书设置双向 TLS 发起

问题描述

我在使用出口网关配置双向 TLS 发起时遇到问题。我正在使用文档中提供的配置:https ://istio.io/latest/docs/tasks/traffic-management/egress/egress-gateway-tls-origination-sds/#perform-mutual-tls-origination-with -一个出口网关

我收到以下 curl 错误消息:

kubectl exec "$(kubectl get pod -l app=sleep -o jsonpath={.items..metadata.name})" -c sleep -- curl -s -v 'http://ADDRESS_HERE/Service/something'

[2021-02-05T08:14:26.529Z] "GET /Service/something HTTP/1.1" 503 UF,URX "TLS error: 100663398:public key routines:OPENSSL_internal:DECODE_ERROR 184549501:X.509 certificate routines:OPENSSL_internal:PUBLIC_KEY_DECODE_ERROR 268435581:SSL routines:OPENSSL_internal:CERTIFICATE_VERIFY_FAILED" 0 333 41 - "10.240.0.214" "Apache-HttpClient/4.5.3 (Java/11.0.10)" "3a4b121d-e232-4a89-8798-f7251e74e601" "<ADDRESS_HERE>" "<IP_ADDRESS_HERE>:9443" outbound|9443||<ADDRESS_HERE> - 10.240.0.42:9443 10.240.0.214:60150 <ADDRESS_HERE> -

看起来存在与证书相关的问题,但我可以使用 curl 访问外部服务,并且提供的证书与 curl 命令的参数相同。我认为问题可能与自定义证书不受各方信任的事实有关。有什么办法可以解决吗?

这是我的配置:

Istio 1.8.0:

apiVersion: networking.istio.io/v1beta1
kind: ServiceEntry
metadata:
  name: externalservice-egress
spec:
  hosts:
  - api.externalservice.com
  ports:
  - number: 9443
    name: https
    protocol: HTTPS
  resolution: DNS
  location: MESH_EXTERNAL
---
apiVersion: networking.istio.io/v1beta1
kind: Gateway
metadata:
  name: externalservice-egress
spec:
  selector:
    istio: egressgateway
  servers:
  - port:
      number: 9443
      name: https
      protocol: HTTPS
    hosts:
    - api.externalservice.com
    tls:
      mode: ISTIO_MUTUAL
---
apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
metadata:
  name: externalservice-egress
spec:
  host: istio-egressgateway.istio-system.svc.cluster.local
  subsets:
  - name: externalservice-egress
    trafficPolicy:
      loadBalancer:
        simple: ROUND_ROBIN
      portLevelSettings:
      - port:
          number: 9443
        tls:
          mode: ISTIO_MUTUAL
          sni: api.externalservice.com
---
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
  name: externalservice
spec:
  hosts:
    - api.externalservice.com
  gateways:
    - externalservice-egress
    - mesh
  http:
  - match:
    - gateways:
      - mesh
      port: 80
    route:
    - destination:
        host: istio-egressgateway.istio-system.svc.cluster.local
        subset: externalservice-egress
        port:
          number: 9443
      weight: 100
  - match:
    - gateways:
      - externalservice-egress
      port: 9443
    route:
    - destination:
        host: api.externalservice.com
        port:
          number: 9443
      weight: 100
---
apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
metadata:
  name: externalservice-egress-tls-origination
  namespace: istio-system # namespace other than for other configuration items - like for example from documentation
spec:
  host: api.externalservice.com
  trafficPolicy:
    loadBalancer:
      simple: ROUND_ROBIN
    portLevelSettings:
    - port:
        number: 9443
      tls:
        mode: MUTUAL
        credentialName: client-credential
        sni: api.externalservice.com

Kubernetes 秘密:

kubectl describe secret -n istio-system client-credential 

Name:         client-credential
Namespace:    istio-system
Labels:       <none>
Annotations:  <none>

Type:  Opaque

Data
====
tls.key:  1679 bytes
ca.crt:   1525 bytes
tls.crt:  1956 bytes

api.externalservice.com 是仅在 https/9443 上侦听的外部服务。

我相信用于创建此密钥的 client.crt、client.key 和 ca.crt 是正确的,因为我可以从网格外部连接到 api.externalservice.com:

curl -k --cert client.crt --key client.key -v https://ADDRESS_HERE:9443/Service/something

谢谢你帮我解决这个问题。我很欣赏如何解决这个问题的任何想法。

编辑:好的,看来我需要在某处提供 ca carificate:

Error [IST0129] (DestinationRule rule) DestinationRule namespace/rule in namespace namespace has TLS mode set to MUTUAL but no caCertificates are set to validate server identity for host: <ADDRESS_HERE> at port number:9443

我正在使用 Egress Gateway,所以我应该将此证书挂载到 Egress GW pod 吗?

EDIT2:另外,我的印象是证书管理是由客户端凭据秘密处理的。是否真的需要添加 caCertificates 参数?

标签: sslistio

解决方案


推荐阅读