gRPC+mTLS through Egress GW

Hi,

I am trying to configure some rules in Istio for accessing external gRPC services through the Egress GW.

First approach was to setup all communications as plain (so no mtls) between Client Service (in mesh) and Egress GW and then from Egress to External Service. Everything worked fine.

Then, I wanted to set all as mTLS, but I started to have problems when setting mTLS between Client Service and Egress GW. I have no problem between Egress GW and final destination, so I could either use plain or mtls in this part.

I was able to run a similar scenario with simple REST services… but I am facing problems when moving to gRPC.

Has anybody tried accessing a grpc service through the Egress GW with mtls between these two?

I have included two descriptors, one for plain and the other one for mtls (only between client and egress gw). Could anybody clarify if I am doing something wrong?

client --> grpc (plain) --> egress gw —> grpc (plain) --> external service

apiVersion: networking.istio.io/v1alpha3
kind: ServiceEntry
metadata:
  name: gcd-external
  namespace: ${APPS_NAMESPACE}
spec:
  hosts:
  - gcd.${EXTERNAL_NAMESPACE}.svc.cluster.local
  ports:
  - number: 3000
    name: grpc
    protocol: GRPC
  resolution: DNS
  location: MESH_EXTERNAL
---
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
  name: gcd-egressgateway
  namespace: ${APPS_NAMESPACE}
spec:
  selector:
    istio: egressgateway
  servers:
  - port:
      number: 80
      name: http2
      protocol: HTTP2
    hosts:
    - gcd.${EXTERNAL_NAMESPACE}.svc.cluster.local
---
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
  name: egressgateway-for-gcd
  namespace: ${APPS_NAMESPACE}
spec:
  host: istio-egressgateway.istio-system.svc.cluster.local
  subsets:
  - name: gcd
    trafficPolicy:
      tls:
        mode: DISABLE
---
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
  name: gcd
  namespace: ${APPS_NAMESPACE}
spec:
  host: gcd.${EXTERNAL_NAMESPACE}.svc.cluster.local
  trafficPolicy:
    tls:
      mode: DISABLE
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: direct-gcd-through-egress-gateway
  namespace: ${APPS_NAMESPACE}
spec:
  hosts:
  - gcd.${EXTERNAL_NAMESPACE}.svc.cluster.local
  gateways:
  - gcd-egressgateway
  - mesh
  http:
  - match:
    - gateways:
      - mesh
      port: 3000
    rewrite:
      authority: gcd.${EXTERNAL_NAMESPACE}.svc.cluster.local
    route:
    - destination:
        host: istio-egressgateway.istio-system.svc.cluster.local
        subset: gcd
        port:
          number: 80
      weight: 100
  - match:
    - gateways:
      - gcd-egressgateway
      port: 80
    route:
    - destination:
        host: gcd.${EXTERNAL_NAMESPACE}.svc.cluster.local
        port:
          number: 3000
      weight: 100

Then, the one that I cannot make it work…

client --> grpc (mTLS) --> egress gw —> grpc (plain) --> external service

apiVersion: networking.istio.io/v1alpha3
kind: ServiceEntry
metadata:
  name: gcd-external
  namespace: ${APPS_NAMESPACE}
spec:
  hosts:
  - gcd.${EXTERNAL_NAMESPACE}.svc.cluster.local
  ports:
  - number: 3000
    name: grpc
    protocol: GRPC
  resolution: DNS
  location: MESH_EXTERNAL
---    
apiVersion: networking.istio.io/v1alpha3
    kind: Gateway
metadata:
  name: gcd-egressgateway
  namespace: ${APPS_NAMESPACE}
spec:
  selector:
    istio: egressgateway
  servers:
  - port:
      number: 443
      name: https
      protocol: HTTPS
    hosts:
    - gcd.${EXTERNAL_NAMESPACE}.svc.cluster.local
    tls:
      mode: MUTUAL
      serverCertificate: /etc/certs/cert-chain.pem
      privateKey: /etc/certs/key.pem
      caCertificates: /etc/certs/root-cert.pem
---
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
  name: egressgateway-for-gcd
  namespace: ${APPS_NAMESPACE}
spec:
  host: istio-egressgateway.istio-system.svc.cluster.local
  subsets:
  - name: gcd
    trafficPolicy:
      tls:
        mode: ISTIO_MUTUAL
        sni: gcd.${EXTERNAL_NAMESPACE}.svc.cluster.local
---
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
  name: gcd
  namespace: ${APPS_NAMESPACE}
spec:
  host: gcd.${EXTERNAL_NAMESPACE}.svc.cluster.local
  trafficPolicy:
    tls:
      mode: DISABLE
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: direct-gcd-through-egress-gateway
  namespace: ${APPS_NAMESPACE}
spec:
  hosts:
  - gcd.${EXTERNAL_NAMESPACE}.svc.cluster.local
  gateways:
  - gcd-egressgateway
  - mesh
  http:
  - match:
    - gateways:
      - mesh
      port: 3000
    rewrite:
      authority: gcd.${EXTERNAL_NAMESPACE}.svc.cluster.local
    route:
    - destination:
        host: istio-egressgateway.istio-system.svc.cluster.local
        subset: gcd
        port:
          number: 443
      weight: 100
  - match:
    - gateways:
      - gcd-egressgateway
      port: 443
    route:
    - destination:
        host:  gcd.${EXTERNAL_NAMESPACE}.svc.cluster.local
        port:
          number: 3000
      weight: 100

Thanks a lot!!!