Routing mesh traffic for application internally using public DNS

There are a few similar questions already but none with any answers that I can see…

I have a number of services running within our mesh. They use an ingress-gateway to allow traffic in via an AWS Network Load Balancer.

Some of the services need to call one another but use the public DNS name rather than the internal svc.cluster.local address.

I’ve tried the following but this actually stops all access to the pods from internal and external endpoints.

apiVersion: networking.istio.io/v1beta1
kind: ServiceEntry
metadata:
  name: service
spec:
  hosts:
  - service.example.com
  location: MESH_INTERNAL
  ports:
  - number: 443
    name: https
    protocol: HTTPS
  resolution: DNS
  workloadSelector:
    labels:
      istio: ingress

The VirtualService currently in place for the ingress gateway is:

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: service
spec:
  gateways:
    - istio-ingress/gateway
  hosts:
    - service.example.com
  http:
    - match:
        - uri:
            prefix: /
      route:
        - destination:
            host: service.namespace.svc.cluster.local
            port:
              number: 80

From my tests, trying to solve another problem, I believe you need to rewrite the authority in the virtualservice before redirecting the requests to your internal service.

Try this:

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: service
spec:
  gateways:
    - istio-ingress/gateway
  hosts:
    - service.example.com
  http:
    - match:
        - uri:
            prefix: /
      rewrite:
        authority: service.namespace.svc.cluster.local
      route:
        - destination:
            host: service.namespace.svc.cluster.local
            port:
              number: 80

This will change the Host header used by the proxy, so when the request reaches the service, it will match the internal name, not the external one.