# ===========================================================================
# 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
