=== CMD 1: apply manifest + wait === + kubectl apply -f manifest.yaml pod/client created deployment.apps/echo created service/echo created serviceaccount/httpsmtls-gw created deployment.apps/httpsmtls-gw created service/httpsmtls-gw created gateway.networking.istio.io/httpsmtls-gw created destinationrule.networking.istio.io/httpsmtls-gw-dr created virtualservice.networking.istio.io/httpsmtls-leg2-tcp created + kubectl -n istio-vt-t07 wait --for=condition=Ready pod/client --timeout=90s pod/client condition met + kubectl -n istio-vt-t07 rollout status deploy/httpsmtls-gw --timeout=90s Waiting for deployment "httpsmtls-gw" rollout to finish: 0 of 1 updated replicas are available... deployment "httpsmtls-gw" successfully rolled out === CMD 2: leg2_tcp_baseline (client -> httpsmtls-gw:8443 tcp route -> mock:443) === + kubectl -n istio-vt-t07 exec client -c curl -- curl -sk -o /dev/null -w 'leg2_tcp_baseline=%{http_code} ' --connect-to mock.istio-verify-ext.svc.homelab.local:443:httpsmtls-gw.istio-vt-t07.svc.homelab.local:8443 https://mock.istio-verify-ext.svc.homelab.local/ leg2_tcp_baseline=000 command terminated with exit code 35 === ENVIRONMENT DEVIATION NOTE === CMD2 (baseline) initially FAILED: leg2_tcp_baseline=000, curl exit 35. Root cause (confirmed via istioctl/pilot-agent): Istio's internal ServiceRegistry registers ALL k8s Services under suffix *.svc.cluster.local (istio-proxy env TRUST_DOMAIN=cluster.local, and 'istioctl proxy-config cluster --fqdn mock.istio-verify-ext.svc.homelab.local' returns EMPTY while '...svc.cluster.local' returns the real cluster). Actual kubeadm/CoreDNS clusterDomain IS homelab.local (confirmed: kubeadm-config cm clusterDomain: homelab.local), so plain DNS lookups need homelab.local, but Istio VirtualService route destination.host / DestinationRule host fields (which must match Istio's registry hostname, NOT real DNS) need cluster.local. harness-notes.md's blanket guidance 'all test manifests/commands must use *.svc.homelab.local FQDNs' is therefore INCOMPLETE: it holds for actual DNS names (curl URL host, --connect-to target) but NOT for VS route destination.host / DR host, which are Istio-internal registry lookups keyed to cluster.local in this install (global.proxy.clusterDomain was left at default cluster.local instead of being aligned to the cluster's real homelab.local domain). Gateway 'hosts'/VS 'hosts' fields are literal SNI-match strings (not registry lookups) so they correctly stay on homelab.local (matching curl's actual SNI). FIX APPLIED: changed VirtualService tcp/tls route destination.host and DestinationRule.spec.host from *.svc.homelab.local to *.svc.cluster.local (manifest.yaml updated in place). Re-applying and re-running CMD1+CMD2 below. === CMD 1 RETRY: apply corrected manifest + wait === + kubectl apply -f manifest.yaml pod/client configured deployment.apps/echo unchanged service/echo unchanged serviceaccount/httpsmtls-gw unchanged deployment.apps/httpsmtls-gw unchanged service/httpsmtls-gw unchanged gateway.networking.istio.io/httpsmtls-gw unchanged destinationrule.networking.istio.io/httpsmtls-gw-dr configured virtualservice.networking.istio.io/httpsmtls-leg2-tcp configured + kubectl -n istio-vt-t07 wait --for=condition=Ready pod/client --timeout=90s pod/client condition met + kubectl -n istio-vt-t07 rollout status deploy/httpsmtls-gw --timeout=90s deployment "httpsmtls-gw" successfully rolled out === CMD 2 RETRY: leg2_tcp_baseline === + kubectl -n istio-vt-t07 exec client -c curl -- curl -sk -o /dev/null -w 'leg2_tcp_baseline=%{http_code} ' --connect-to mock.istio-verify-ext.svc.homelab.local:443:httpsmtls-gw.istio-vt-t07.svc.homelab.local:8443 https://mock.istio-verify-ext.svc.homelab.local/ leg2_tcp_baseline=000 command terminated with exit code 35 === SECOND DEVIATION (found after 1st fix) === After fixing destination.host suffix, baseline STILL failed differently: curl -v showed a TLS handshake completing against a cert issued by 'O=cluster.local' (Istio's own CA), including a 'Request CERT' step, then after curl sent its GET the server sent TLS alert 'certificate_required' -> curl exit 56. This meant curl's OWN https session was landing directly on the httpsmtls-gw Gateway's ISTIO_MUTUAL listener UNWRAPPED (no outer mTLS tunnel at all), because the client-side DestinationRule (host mismatched to homelab.local) was NOT actually being applied - client envoy was doing a bare opaque TCP passthrough of curl's raw bytes, not ISTIO_MUTUAL origination. Fixing DR.host to the correct registry name (cluster.local, same fix as VS) then produced a THIRD, different failure: gateway log 'filter_chain_not_found' (NR). Diagnosis via 'istioctl proxy-config cluster pod/client.istio-vt-t07 --fqdn httpsmtls-gw...svc.cluster.local -o json': the DR's ISTIO_MUTUAL transportSocket sets sni='outbound_.8443_._.httpsmtls-gw.istio-vt-t07.svc.cluster.local' by DEFAULT (Istio's standard auto-generated SNI for ISTIO_MUTUAL client TLS origination, meant for AUTO_PASSTHROUGH-style east-west gateway routing). This auto-SNI does NOT match our Gateway CR's declared 'hosts: [mock.istio-verify-ext.svc.homelab.local]', so the Gateway's listener filter chain (which matches literally on SNI) rejected the connection with filter_chain_not_found. FIX: added explicit 'trafficPolicy.tls.sni: mock.istio-verify-ext.svc.homelab.local' to the DestinationRule (this is the standard, documented Istio practice for egress-gateway TLS-origination patterns - pinning SNI to the value the receiving Gateway resource actually matches on). RESULT: leg2_tcp_baseline=200, exit=0. Manifest.yaml now reflects this final corrected form (3 deviations from the ISTIO_VT_NS-substituted-only spec: DR host + VS route destination host both changed from .svc.homelab.local to .svc.cluster.local, and DR gained an explicit tls.sni field). This is an important, generalizable environment finding: in THIS cluster, Istio's control plane was installed with global.proxy.clusterDomain left at the default 'cluster.local', which differs from the cluster's real kubeadm/CoreDNS domain 'homelab.local'. harness-notes.md's blanket 'use *.svc.homelab.local everywhere' guidance is correct ONLY for literal DNS names actually resolved by CoreDNS (curl URL host, --connect-to target); it is WRONG for Istio VirtualService route destination.host / DestinationRule host, which must match Istio's internal ServiceRegistry hostname (cluster.local here), not real DNS. This likely affects any other test using cross-namespace/cross-service FQDNs in VS/DR host fields. === CMD 2 FINAL (with corrected manifest): leg2_tcp_baseline === + kubectl -n istio-vt-t07 exec client -c curl -- curl -sk -o /dev/null -w 'leg2_tcp_baseline=%{http_code} ' --connect-to mock.istio-verify-ext.svc.homelab.local:443:httpsmtls-gw.istio-vt-t07.svc.homelab.local:8443 https://mock.istio-verify-ext.svc.homelab.local/ leg2_tcp_baseline=200 === CMD 3: filterChains baseline count on gateway 8443 listener === + istioctl proxy-config listener deploy/httpsmtls-gw.istio-vt-t07 --port 8443 -o json | jq '.[0].filterChains | length' 1 === CMD 4: switch leg-2 VS route to tls/sniHosts === + kubectl -n istio-vt-t07 apply -f - <0) === + istioctl proxy-config listener deploy/httpsmtls-gw.istio-vt-t07 --port 8443 -o json | jq '.[0].filterChains | length' 1