Destination rule to set mTLS ignores specific host

Hi All,

I’ve applied 2 ‘ServiceEntry’ in the test namespace

apiVersion: networking.istio.io/v1alpha3
kind: ServiceEntry
metadata:
  name: external-svc-http
spec:
  hosts:
  - "*.test.com" 
  location: MESH_EXTERNAL
  ports:
  - number: 80
    name: http
    protocol: HTTP
  resolution: NONE
apiVersion: networking.istio.io/v1alpha3
kind: ServiceEntry
metadata:
  name: specific-external-svc-http
spec:
  hosts:
  - test.test.com 
  location: MESH_EXTERNAL
  ports:
  - number: 80
    name: http
    protocol: HTTP
  resolution: NONE

I wanted to apply a destination rule to encrypt traffic only to the “test.test.com” host with the following DestinationRule:

apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
  name: test-test-istio-mtls
  namespace: test
spec:
  host: "test.test.com"
  trafficPolicy:
    tls:
      mode: ISTIO_MUTUAL

From the config dump I can see that the DestinationRule also applied to the “*.test.com” host

{
 "version_info": "2019-11-26T12:50:00Z/42",
 "cluster": {
  "name": "outbound|80||*.test.com",
  "type": "ORIGINAL_DST",
  "connect_timeout": "10s",
  "lb_policy": "CLUSTER_PROVIDED",
  "circuit_breakers": {
   "thresholds": [
    {
     "max_retries": 1024
    }
   ]
  },
  "tls_context": {
   "common_tls_context": {
    "tls_certificates": [
     {
      "certificate_chain": {
       "filename": "/etc/certs/cert-chain.pem"
      },
      "private_key": {
       "filename": "/etc/certs/key.pem"
      }
     }
    ],
    "validation_context": {
     "trusted_ca": {
      "filename": "/etc/certs/root-cert.pem"
     }
    },
    "alpn_protocols": [
     "istio"
    ]
   },
   "sni": "outbound_.80_._.*.test.com"
  },
  "metadata": {
   "filter_metadata": {
    "istio": {
     "config": "/apis/networking/v1alpha3/namespaces/test/destination-rule/test-test-istio-mtls"
    }
   }
  }
 },
 "last_updated": "2019-11-26T12:50:00.192Z"
},

I found this code

// Matches returns true if this hostname overlaps with the other hostname. Names overlap if:
// - they're fully resolved (i.e. not wildcarded) and match exactly (i.e. an exact string match)
// - one or both are wildcarded (e.g. "*.foo.com"), in which case we use wildcard resolution rules
// to determine if h is covered by o or o is covered by h.
// e.g.:
//  Name("foo.com").Matches("foo.com")   = true
//  Name("foo.com").Matches("bar.com")   = false
//  Name("*.com").Matches("foo.com")     = true
//  Name("bar.com").Matches("*.com")     = true
//  Name("*.foo.com").Matches("foo.com") = false
//  Name("*").Matches("foo.com")         = true
//  Name("*").Matches("*.com")           = true
func (n Name) Matches(o Name) bool {

Name("*.com").Matches(“foo.com”) = true
I’m not sure that in my case this is a match.

Is this the expected behavior?

@incfly could you please take a look?

@hzxuzhonghu @howardjohn thoughts?

this is a general destination rule host resolutoin issue. Unless your mesh has *.cluster.local DestinationRule, with ISTIO_MUTUAL otherwise, I think it’s a bug based on my understanding…

@incfly thanks for your response. I do not have such DestinationRule.

From the description:
// one or both are wildcarded (e.g. ".foo.com"), in which case we use wildcard resolution rules*
// to determine if h is covered by o or o is covered by h.

I’m assuming that for DestinationRule host match, this logic is wrong.

I agree with you. Please file a bug against networking area, and provide minimal reproducible yaml/steps.