# =========================================================================== # mTLS path — sleep@mesh-test ==(outer Istio mTLS)==> egw-mtls@egress-mtls --> www.wikipedia.org:443 # outer (sidecar<->egw-mtls): Istio mTLS(ISTIO_MUTUAL). egw-mtls가 client cert를 강제하고 # mesh CA로 검증(SPIFFE 신원). in-cluster 구간 암호화·신원. # inner (app<->wikipedia) : 앱 HTTPS. egw-mtls는 outer 메시 TLS만 풀고 inner 앱 TLS는 # 복호화하지 않은 채 tcp_proxy로 외부에 전달(=inner는 여전히 passthrough). # 즉 "TLS-in-TLS": gateway에서 outer는 종료, inner는 통과. 동작 구조의 실측 근거는 # gw__report-2026-06-08_egress-mtls (단일 gateway 버전) — 본 랩은 그것을 별도 pod로 분리한 것. # =========================================================================== apiVersion: networking.istio.io/v1beta1 kind: ServiceEntry metadata: name: wiki-ext namespace: mesh-test spec: exportTo: - "." - "egress-mtls" hosts: - www.wikipedia.org ports: - number: 443 name: tls protocol: TLS resolution: DNS --- apiVersion: networking.istio.io/v1beta1 kind: Gateway metadata: name: egw-mtls-gateway namespace: egress-mtls spec: selector: istio: egw-mtls servers: - port: number: 443 # egw-pt와 동일 포트(다른 pod라 충돌 없음). Service가 443->8443 remap, # Envoy는 8443에 listener bind. DR portLevelSettings와 일치해야 함. name: tls protocol: TLS hosts: - www.wikipedia.org tls: mode: ISTIO_MUTUAL # outer 메시 mTLS 종료 — client cert 강제(SPIFFE), mesh CA 검증 --- apiVersion: networking.istio.io/v1beta1 kind: DestinationRule metadata: name: egw-mtls-dr namespace: mesh-test spec: exportTo: - "." host: egw-mtls.egress-mtls.svc.cluster.local subsets: - name: mtls trafficPolicy: loadBalancer: simple: ROUND_ROBIN portLevelSettings: - port: number: 443 # sidecar가 dial하는 gateway Service 포트(=Gateway server port) tls: mode: ISTIO_MUTUAL # sidecar가 gateway로 갈 때 메시 mTLS로 감쌈(outer) sni: www.wikipedia.org # 그 mTLS handshake SNI = gateway server hosts 매칭 키. # 이 sni가 어긋나면 gateway listener 매칭 실패로 연결 끊김. --- # (1) client sidecar -> egress-mtls gateway (outer mTLS wrap) apiVersion: networking.istio.io/v1beta1 kind: VirtualService metadata: name: wiki-client namespace: mesh-test spec: exportTo: - "." hosts: - www.wikipedia.org gateways: - mesh tls: - match: - gateways: - mesh port: 443 # 앱은 443으로 나가지만 sniHosts: - www.wikipedia.org route: - destination: host: egw-mtls.egress-mtls.svc.cluster.local subset: mtls port: number: 443 # gateway Service 443(->8443 listener)로 보냄 weight: 100 --- # (2) egress-mtls gateway -> external host (inner 앱 TLS passthrough) # ⚠️ 종단(ISTIO_MUTUAL) listener는 tcp route로 받아야 한다. tls/sniHosts route를 걸면 # network filter가 안 생겨 "0 chains"로 listener가 통째 omit된다(istiod: "listener missed # network filter"). 외부 메시 mTLS는 이미 listener가 종단했으므로 SNI는 소비됨 → 포트 # 매칭만으로 충분하고, 내부 앱 TLS 바이트는 tcp_proxy로 wikipedia:443까지 그대로 흘린다. apiVersion: networking.istio.io/v1beta1 kind: VirtualService metadata: name: wiki-gateway namespace: egress-mtls spec: exportTo: - "." hosts: - www.wikipedia.org gateways: - egw-mtls-gateway tcp: - match: - gateways: - egw-mtls-gateway port: 443 # Gateway server port와 일치(listener는 8443에 bind됨) route: - destination: host: www.wikipedia.org port: number: 443 weight: 100