Pushing From PERMISSIVE Up to STRICT
한국어 원문으로 표시합니다.
목표
mTLS 정책의 세 가지 범위와 우선순위를 손으로 다뤄 보고, 운영 중인 메시를 끊지 않고 STRICT 로 올리는 절차를 계획으로 남깁니다.
왜 중요한가
STRICT 전환은 기술적으로는 필드 하나를 바꾸는 일이지만, 운영에서는 가장 사고가 잦은 작업 중 하나입니다. 이유는 단순합니다 — 평문으로 들어오던 경로가 예고 없이 전부 끊기기 때문입니다. 사이드카 없는 크론, 메시 밖 배치, 커스텀 프로브는 대시보드에 잘 드러나지 않다가 STRICT 를 켠 순간 장애로 나타납니다. 그래서 정석은 PERMISSIVE 로 두고 평문 트래픽의 출발지를 전수 조사한 뒤, 좁은 범위부터 올리는 것입니다.
또 하나 반드시 익혀야 할 것은 방향의 구분입니다. PeerAuthentication 은 받는 쪽(인바운드), DestinationRule 의 trafficPolicy.tls 는 보내는 쪽(아웃바운드)을 다룹니다. 이 둘이 어긋나면 연결이 실패하는데, 애플리케이션 로그에는 그냥 503 으로만 보입니다. 게다가 이 조합은 istioctl analyze 가 잡아 주지 않습니다 — 예전에는 전용 분석기가 있었지만 지금 버전의 분석기 목록에는 없습니다. 그래서 두 리소스를 짝으로 놓고 사람이 직접 대조하는 습관이 그대로 안전장치가 됩니다.
이 환경에서는 실제 핸드셰이크가 일어나지 않으므로, 채점은 정책의 이름·범위·필드와 정적 분석 결과를 봅니다.
단계
시작 전 준비. 실습 파드는 실습마다 새로 뜨므로 앞 실습의 메시 설정은 남아 있지 않습니다. kubectl get crd peerauthentications.security.istio.io 가 비어 있으면 istioctl manifest generate --set profile=minimal > /root/istio/manifest.yaml 후 kubectl apply -f /root/istio/manifest.yaml 을 두 번 실행하세요. 이 매니페스트가 istio-system 네임스페이스도 함께 만드는데, 2번에서 메시 전역 정책을 둘 곳이라 반드시 있어야 합니다. 그다음 kubectl create ns mesh-lab && kubectl label ns mesh-lab istio-injection=enabled 로 작업 네임스페이스를 준비하세요.
/root/istio/mtls/pa-permissive.yaml을 만드세요 — 문서 하나짜리 PeerAuthentication 이며metadata.name은default,metadata.namespace는mesh-lab,spec.mtls.mode는PERMISSIVE이고selector는 두지 마세요(네임스페이스 전체 정책입니다). 만든 뒤 적용하세요.istio-system네임스페이스에 이름이default인 PeerAuthentication 을spec.mtls.mode: STRICT로, selector 없이 적용하세요. 그리고/root/istio/mtls/out/scope-note.txt에 메시 전역 / 네임스페이스 / 워크로드 세 층 중 더 좁고 구체적인 범위가 우선한다는 규칙을 적으세요.mesh-lab에 payments 워크로드를 만드세요 — ServiceAccountpayments, Servicepayments(포트 이름http8080,http-metrics9090), Deploymentpayments(파드 라벨app: payments,serviceAccountName: payments). 그다음 PeerAuthenticationlegacy-metrics를mesh-lab에 만드세요:selector.matchLabels.app은payments,spec.mtls.mode는STRICT,portLevelMtls에는 포트9090하나만mode: DISABLE로 두세요.mesh-lab에 DestinationRulepayments-mtls를 만드세요.spec.host는payments,spec.trafficPolicy.tls.mode는ISTIO_MUTUAL입니다. 그리고/root/istio/mtls/out/direction-note.txt에 PeerAuthentication 이 받는 쪽(인바운드), DestinationRule 이 보내는 쪽(클라이언트/아웃바운드)을 다룬다는 차이를 적으세요./root/istio/mtls/identity.txt에 payments 워크로드의 SPIFFE 아이덴티티를 정확히 한 줄로 적으세요:spiffe://cluster.local/ns/mesh-lab/sa/payments. 그리고/root/istio/mtls/out/identity-note.txt에 메시의 신원이 IP 주소가 아니라 서비스 어카운트라는 요지를 적으세요.mesh-lab에 RequestAuthenticationjwt-payments를 만드세요.selector.matchLabels.app은payments,jwtRules[0].issuer는https://idp.labhub.example/,jwtRules[0].jwksUri는https://idp.labhub.example/.well-known/jwks.json입니다. 그리고/root/istio/mtls/out/jwt-note.txt에 이 리소스만으로는 토큰 없는 요청을 막지 못하며 AuthorizationPolicy 가 함께 필요하다는 사실을 적으세요.mesh-lab의defaultPeerAuthentication 을STRICT로 바꿔 적용하세요. 그 상태에서spec.trafficPolicy.tls.mode: DISABLE인 DestinationRule(예:payments-plaintext)을 적용하고istioctl analyze -n mesh-lab결과를/root/istio/mtls/out/analyze-conflict.txt에 저장하세요. 이 버전의 분석기 목록에는 mTLS 조합 충돌을 보는 분석기가 없어 출력에 그 충돌이 나타나지 않습니다 — 무엇과 무엇이 어긋났는지 한 줄로 덧붙여 기록에 남기세요. 그다음 그 DestinationRule 을 삭제하거나ISTIO_MUTUAL로 고쳐 충돌을 없애고, 다시 분석해/root/istio/mtls/out/analyze-fixed.txt에 저장하세요.mesh-lab에tls.mode: DISABLE인 DestinationRule 이 하나도 남으면 안 됩니다./root/istio/mtls/migration.md를 400바이트 이상으로 쓰세요. 문서 안에서PERMISSIVE와 관측(메트릭/모니터링) 이야기가STRICT라는 단어보다 먼저(윗줄에) 나와야 하고, 네임스페이스 단위 단계 적용과 롤백(되돌리는) 방법이 들어가야 합니다. 마지막으로mesh-lab의defaultPeerAuthentication 이STRICT인 상태로 마무리하세요.
참고
- 실습 파드는 실습마다 새로 뜨므로 앞 실습의 클러스터 상태는 남아 있지 않습니다. 그래서 메시 설정을 매니페스트로 남겨 두는 것이 곧 재현 가능성입니다. 보안 정책은 특히 그렇습니다 — 손으로 켠 STRICT 는 클러스터가 사라지면 함께 사라지지만, 저장소에 든 정책은 다음 클러스터에서도 그대로 재현됩니다.
- 8번에서 문서 제목에
STRICT를 먼저 쓰면 순서 검사가 걸립니다. 제목은 "mTLS 전환 계획" 처럼 두고, 본문을 단계 0(관측, PERMISSIVE 유지) → 단계 1(평문 출발지 제거) → 단계 2(네임스페이스 단위 STRICT) → 단계 3(메시 전역 STRICT) → 롤백 순으로 쓰세요. - 실제 운영에서 평문 비율은
istio_requests_total의connection_security_policy라벨로 봅니다. 이 환경에는 메트릭이 없지만, 계획서에는 그 판단 근거를 적어 두는 것이 맞습니다. - 3번의 Deployment 는
/opt/lab/fixtures/istio/inject-target.yaml을 복사해serviceAccountName만 추가하면 편합니다. - 흔한 실수 1: 네임스페이스 전체 정책에 selector 를 붙이는 것. selector 가 붙는 순간 워크로드 단위 정책이 되어 나머지 워크로드에는 적용되지 않습니다.
- 흔한 실수 2: 메시 전역 정책을 아무 네임스페이스에나 두는 것. 루트 네임스페이스(
istio-system)에 이름default로 두어야 전역이 됩니다.
네임스페이스 기본 정책을 PERMISSIVE 로 두기
/root/istio/mtls/pa-permissive.yaml 을 만드세요 — 문서 하나짜리 PeerAuthentication 이며 metadata.name 은 default, metadata.namespace 는 mesh-lab, spec.mtls.mode 는 PERMISSIVE 이고 selector 는 두지 마세요(네임스페이스 전체 정책입니다). 만든 뒤 적용하세요.
네임스페이스 전체에 걸리는 정책은 이름이 정해져 있고 selector 를 두지 않습니다. 전환은 평문과 암호문을 함께 받는 상태에서 시작합니다.
메시 전역 기본값을 STRICT 로 올리기
istio-system 네임스페이스에 이름이 default 인 PeerAuthentication 을 spec.mtls.mode: STRICT 로, selector 없이 적용하세요. 그리고 /root/istio/mtls/out/scope-note.txt 에 메시 전역 / 네임스페이스 / 워크로드 세 층 중 더 좁고 구체적인 범위가 우선한다는 규칙을 적으세요.
메시 전역 정책은 루트 네임스페이스에 둡니다. 그리고 세 층의 범위 중 무엇이 이기는지 메모로 정리하세요.
워크로드 하나의 포트 하나만 예외로 열기
mesh-lab 에 payments 워크로드를 만드세요 — ServiceAccount payments, Service payments(포트 이름 http 8080, http-metrics 9090), Deployment payments(파드 라벨 app: payments, serviceAccountName: payments). 그다음 PeerAuthentication legacy-metrics 를 mesh-lab 에 만드세요: selector.matchLabels.app 은 payments, spec.mtls.mode 는 STRICT, portLevelMtls 에는 포트 9090 하나만 mode: DISABLE 로 두세요.
예외는 최대한 좁게. 워크로드는 selector 로 고르고, 기본은 여전히 STRICT 로 둔 채 문제되는 포트만 따로 지정합니다.
보내는 쪽 mTLS 선언하기
mesh-lab 에 DestinationRule payments-mtls 를 만드세요. spec.host 는 payments, spec.trafficPolicy.tls.mode 는 ISTIO_MUTUAL 입니다. 그리고 /root/istio/mtls/out/direction-note.txt 에 PeerAuthentication 이 받는 쪽(인바운드), DestinationRule 이 보내는 쪽(클라이언트/아웃바운드)을 다룬다는 차이를 적으세요.
받는 쪽과 보내는 쪽은 다른 리소스가 다룹니다. 인증서를 직접 지정하지 않고 메시가 발급한 것을 쓰겠다는 모드가 따로 있습니다.
워크로드의 신원을 적어 보기
/root/istio/mtls/identity.txt 에 payments 워크로드의 SPIFFE 아이덴티티를 정확히 한 줄로 적으세요: spiffe://cluster.local/ns/mesh-lab/sa/payments. 그리고 /root/istio/mtls/out/identity-note.txt 에 메시의 신원이 IP 주소가 아니라 서비스 어카운트라는 요지를 적으세요.
세 조각이 순서대로 들어갑니다. 그리고 그 신원의 근거가 되는 오브젝트가 클러스터에 실제로 있어야 합니다.
최종 사용자 JWT 검증 정책 만들기
mesh-lab 에 RequestAuthentication jwt-payments 를 만드세요. selector.matchLabels.app 은 payments, jwtRules[0].issuer 는 https://idp.labhub.example/, jwtRules[0].jwksUri 는 https://idp.labhub.example/.well-known/jwks.json 입니다. 그리고 /root/istio/mtls/out/jwt-note.txt 에 이 리소스만으로는 토큰 없는 요청을 막지 못하며 AuthorizationPolicy 가 함께 필요하다는 사실을 적으세요.
서명을 검증하려면 발급자와 공개키 위치가 모두 필요합니다. 그리고 이 리소스만으로 무엇을 못 막는지 메모에 적으세요.
STRICT 와 DISABLE 의 충돌 만들고 해소하기
mesh-lab 의 default PeerAuthentication 을 STRICT 로 바꿔 적용하세요. 그 상태에서 spec.trafficPolicy.tls.mode: DISABLE 인 DestinationRule(예: payments-plaintext)을 적용하고 istioctl analyze -n mesh-lab 결과를 /root/istio/mtls/out/analyze-conflict.txt 에 저장하세요. 이 버전의 분석기 목록에는 mTLS 조합 충돌을 보는 분석기가 없어 출력에 그 충돌이 나타나지 않습니다 — 무엇과 무엇이 어긋났는지 한 줄로 덧붙여 기록에 남기세요. 그다음 그 DestinationRule 을 삭제하거나 ISTIO_MUTUAL 로 고쳐 충돌을 없애고, 다시 분석해 /root/istio/mtls/out/analyze-fixed.txt 에 저장하세요. mesh-lab 에 tls.mode: DISABLE 인 DestinationRule 이 하나도 남으면 안 됩니다.
받는 쪽은 암호화를 요구하는데 보내는 쪽이 평문을 고집하면 연결이 실패합니다. 분석 결과를 고치기 전과 후로 나눠 남기고, 어긋난 설정은 하나도 남겨 두지 마세요.
단계적 전환 계획 쓰고 전환 끝내기
/root/istio/mtls/migration.md 를 400바이트 이상으로 쓰세요. 문서 안에서 PERMISSIVE 와 관측(메트릭/모니터링) 이야기가 STRICT 라는 단어보다 먼저(윗줄에) 나와야 하고, 네임스페이스 단위 단계 적용과 롤백(되돌리는) 방법이 들어가야 합니다. 마지막으로 mesh-lab 의 default PeerAuthentication 이 STRICT 인 상태로 마무리하세요.
문서에서 단어가 나오는 순서가 곧 단계 순서입니다. 관측과 PERMISSIVE 를 먼저, STRICT 를 뒤에 적고, 되돌리는 방법도 넣으세요.