LabHub

Istio 서비스 메시 · 보안 — mTLS 와 AuthorizationPolicy · 실습

전면 거부에서 최소 권한까지 좁혀 가기

LabHub 에서 이어서 보기

목표

기본 거부에서 출발해 호출 그래프대로만 권한을 여는 최소 권한 인가를 만들고, 각 호출의 결과를 매트릭스로 설명할 수 있게 됩니다.

왜 중요한가

인가 설계에서 가장 많이 하는 실수는 필요한 것을 하나씩 막는 방향으로 접근하는 것입니다. 그러면 빠뜨린 경로가 영원히 열려 있고, 그 사실을 아무도 모릅니다. 반대로 전면 거부에서 출발하면 빠뜨린 경로는 즉시 403 으로 드러나므로 설계가 완결됩니다. Istio 는 이 뒤집기를 spec: {} 한 줄로 표현합니다 — ALLOW 정책은 존재하는데 매칭 규칙이 없으니 아무도 통과하지 못합니다.

평가 순서도 반드시 몸에 익혀야 합니다. CUSTOM → DENY → ALLOW 순이고, ALLOW 는 "정책이 하나라도 있으면 매칭돼야 통과"입니다. 즉 ALLOW 정책을 처음 추가하는 순간 그 워크로드가 화이트리스트 모드로 바뀝니다. 이 사실을 모르고 정책 하나를 추가했다가 기존 트래픽이 전부 막히는 사고가 흔합니다. DENY 가 ALLOW 보다 먼저 평가된다는 성질은 반대로 안전망이 됩니다 — 관리 경로처럼 "무슨 일이 있어도 막아야 하는 것"은 DENY 로 한 겹 더 깔아 둡니다.

마지막으로, 인가 정책의 principals 는 mTLS 인증서의 신원에서 나옵니다. 평문으로 들어온 요청은 principal 이 비어 있어 절대 매칭되지 않으므로, STRICT 전환이 인가의 전제 조건입니다.

단계

시작 전 준비. 실습 파드는 실습마다 새로 뜨므로 앞 실습의 메시 설정은 남아 있지 않습니다. kubectl get crd authorizationpolicies.security.istio.io 가 비어 있으면 istioctl manifest generate --set profile=minimal > /root/istio/manifest.yamlkubectl apply -f /root/istio/manifest.yaml두 번 실행하고, kubectl create ns mesh-lab && kubectl label ns mesh-lab istio-injection=enabled 로 네임스페이스를 준비하세요. 2번과 4번에서 selector 가 가리킬 payments·ratings 워크로드도 이 실습 안에서 새로 만들어야 합니다.

1. mesh-lab 에 AuthorizationPolicy deny-all 을 만드세요 — spec: {} 만 두어 selector 도 rules 도 없이(action 은 생략해 기본값 ALLOW) 적용합니다. 그리고 /root/istio/authz/out/denyall-note.txt 에 규칙이 없으면 아무도 통과하지 못하는 이유를 적으세요.
2. mesh-lab 에 ServiceAccount frontend 를 만들고(앞 실습의 payments 워크로드가 없다면 함께 만드세요), AuthorizationPolicy allow-frontend 를 만드세요: selector.matchLabels.apppayments, actionALLOW, rules[0].from[0].source.principals 에는 cluster.local/ns/mesh-lab/sa/frontend 를 적으세요. spiffe:// 접두어를 붙이면 안 됩니다.
3. 같은 allow-frontend 정책에 rules[0].to[0].operation 을 추가하세요. methods["GET"] 하나만, paths 에는 /api/* 를 포함하세요. 그리고 /root/istio/authz/out/path-note.txt 에 경로 매칭이 정규식이 아니라 접두어/접미어 와일드카드만 지원한다는 점을 적으세요.
4. mesh-lab 에 ratings 워크로드(Service ratings, Deployment ratings-v1, 파드 라벨 app: ratings)를 만들고, AuthorizationPolicy allow-mesh-lab 을 만드세요: selector.matchLabels.appratings, rules[0].from[0].source.namespaces["mesh-lab"] 입니다. 그리고 /root/istio/authz/out/ns-note.txt 에 네임스페이스 단위가 서비스 어카운트(principal) 단위보다 거친 통제라는 점을 적으세요.
5. mesh-lab 에 AuthorizationPolicy deny-admin 을 만드세요: actionDENY, rules[0].to[0].operation.paths/admin/* 을 포함합니다. 그리고 /root/istio/authz/order.txt 에 평가 순서를 한 줄에 하나씩, 세 줄로 적으세요 — 첫 줄에 CUSTOM, 둘째 줄에 DENY, 셋째 줄에 ALLOW 가 들어가야 합니다(한 줄에 몰아 쓰면 안 됩니다).
6. mesh-lab 에 AuthorizationPolicy allow-v2-clients 를 만드세요. rules[0].when 에 조건을 두 개 두되, 하나는 key: request.headers[x-api-version]values: ["v2"] 로, 다른 하나는 key: source.namespacenotValues: ["legacy"] 로 적으세요. notValues 를 쓰는 조건의 key 에는 request.headers 가 들어가면 안 됩니다.
7. mesh-lab 에 AuthorizationPolicy audit-sensitive 를 만드세요: actionAUDIT, rules[0].to[0].operation.paths 에 감사할 경로(예: /internal/*)를 지정합니다. 그리고 /root/istio/authz/out/audit-note.txt 에 AUDIT 이 트래픽을 막지 않고 기록만 한다는 점과, 정책을 실제로 켜기 전에 영향을 미리 보는 용도라는 점을 함께 적으세요.
8. /root/istio/authz/out/authz-matrix.json 을 만드세요. cases 배열에 6건 이상을 담되 각 항목에는 expected("allow" 또는 "deny" 둘 중 하나)와 policy(그 결과를 만든 정책 이름 — mesh-lab 에 실제로 존재해야 하고 공백 없는 한 단어)가 있어야 합니다. 허용 예상 2건 이상, 거부 예상 2건 이상이 필요합니다. mesh-lab 의 AuthorizationPolicy 는 5개 이상이어야 하고, istioctl analyze -n mesh-lab 결과를 /root/istio/authz/out/analyze.txt 에 저장하되 Error [ 가 없어야 합니다.

참고

단계 8개

  1. 빈 규칙으로 전면 거부 깔기
  2. 호출자 신원으로 한 경로만 열기
  3. 메서드와 경로까지 좁히기
  4. 네임스페이스 단위로 허용하기
  5. 거부 안전망 깔고 평가 순서 적기
  6. 조건으로 더 세밀하게 좁히기
  7. 막지 않고 기록만 하는 정책 만들기
  8. 호출별 허용·거부 매트릭스 만들기