승인 정책 개요
한 곳에서 실행될 수 있는 모놀리식 애플리케이션과 달리 글로벌 분산 마이크로서비스 앱은 네트워크 경계를 넘어 호출합니다. 즉, 애플리케이션에 더 많은 진입점이 있으며 악의적인 공격에 대한 기회가 많아집니다. Kubernetes 포드에는 일시적 IP가 있기 때문에 워크로드 간 액세스를 보호하려면 기존 IP 기반 방화벽 규칙은 적합하지 않습니다. 마이크로서비스 아키텍처에서는 새로운 보안 방식이 필요합니다. Kubernetes 서비스 계정 및 Istio 보안 정책, Cloud Service Mesh와 같은 보안 기능을 구축하면 애플리케이션을 보호할 수 있는 훨씬 더 많은 기능을 제공합니다.
이 페이지에서는 애플리케이션 작업자에게 AuthorizationPolicy
맞춤 리소스(CR)를 간략히 설명합니다. 승인 정책을 사용하면 애플리케이션(L7) 및 전송(L3/4) 레이어에서 워크로드의 액세스 제어를 사용 설정할 수 있습니다. 권한을 지정하려면 승인 정책을 구성합니다. 이 서비스 또는 사용자가 수행할 수 있는 작업은 무엇인가요?
승인 정책
메시의 서비스 간 요청 및 최종 사용자와 서비스 간 요청은 기본적으로 허용됩니다. AuthorizationPolicy
CR을 사용하여 워크로드의 세분화된 정책을 정의합니다. 승인 정책을 적용하면 Cloud Service Mesh가 사이드카 프록시에 이를 배포합니다. 요청이 워크로드에 도달하면 사이드카 프록시는 승인 정책을 확인하여 요청 허용 또는 거부 여부를 결정합니다.
정책 범위
전체 서비스 메시, 네임스페이스 또는 개별 워크로드에 정책을 적용할 수 있습니다.
메시 전체에 정책을 적용하려면
metadata:namespace
필드에 루트 네임스페이스istio-system
을 지정합니다.apiVersion: "security.istio.io/v1beta1" kind: "AuthorizationPolicy" metadata: name: "mesh-wide" namespace: istio-system spec: ...
네임스페이스에 정책을 적용하려면
metadata:namespace
필드에 네임스페이스를 지정합니다.apiVersion: "security.istio.io/v1beta1" kind: "AuthorizationPolicy" metadata: name: "currencyservice" namespace: currencyservice spec: ...
정책을 특정 워크로드로 제한하려면
selector
필드를 포함합니다.apiVersion: "security.istio.io/v1beta1" kind: "AuthorizationPolicy" metadata: name: "frontend" namespace: demo spec: selector: matchLabels: app: frontend ...
기본 구조
승인 정책에는 정책 범위, action
및 rules
의 목록이 포함됩니다.
이전 섹션에서 설명한 대로 정책 범위는 전체 메시, 네임스페이스 또는 특정 워크로드일 수 있습니다. 이를 포함하는 경우
selector
필드는 정책 대상을 지정합니다.action
필드는 요청의ALLOW
또는DENY
여부를 지정합니다. 작업을 지정하지 않으면 기본적으로 작업이ALLOW
로 설정됩니다. 명확성을 위해 항상 작업을 지정하는 것이 좋습니다. (승인 정책은AUDIT
및CUSTOM
작업도 지원합니다.)rules
는 작업을 트리거할 시간을 지정합니다.
아래 예시를 참조하세요.
정책은
demo
네임스페이스의frontend
서비스 요청에 적용됩니다.'hello:world'가 요청 헤더에 있으면 요청이 허용되며, 그렇지 않은 경우 요청이 거부됩니다.
apiVersion: "security.istio.io/v1beta1"
kind: "AuthorizationPolicy"
metadata:
name: "hello-world"
namespace: demo
spec:
selector:
matchLabels:
app: frontend
action: ALLOW
rules:
- when:
- key: request.headers[hello]
values: ["world"]
요청 작업에 대한 액세스 제어
rules
아래에 to
섹션을 추가하여 HTTP 메서드 또는 TCP 포트와 같은 특정 요청 작업에 대한 액세스를 제어할 수 있습니다.
다음 예시에서는 GET
및 POST
HTTP 메서드만 demo
네임스페이스의 currencyservice
에 허용됩니다.
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
name: currencyservice
namespace: demo
spec:
selector:
matchLabels:
app: currencyservice
action: ALLOW
rules:
- to:
- operation:
methods: ["GET", "POST"]
인증된 ID에 대한 액세스 제어
앞의 예시에서 정책은 인증되지 않은 워크로드의 요청을 허용합니다. STRICT
상호 TLS(mTLS)를 사용 설정한 경우 source
섹션에서 요청을 보낸 워크로드 또는 네임스페이스의 ID를 기반으로 액세스를 제한할 수 있습니다.
principals
또는notPrincipal
필드를 사용하여 워크로드 수준에서 액세스를 제어할 수 있습니다.namespaces
또는notNamespaces
필드를 사용하여 네임스페이스 수준에서 액세스를 제어할 수 있습니다.
위의 모든 필드에 STRICT
mTLS가 사용 설정되어 있어야 합니다. STRICT
mTLS를 설정할 수 없는 경우 대체 솔루션은 일반 텍스트 요청 거부를 참조하세요.
식별된 워크로드
다음 예시에서 currencyservice
에 대한 요청은 frontend
서비스의 요청만 허용됩니다. 다른 워크로드의 currencyservice
에 대한 요청이 거부됩니다.
apiVersion: "security.istio.io/v1beta1"
kind: "AuthorizationPolicy"
metadata:
name: "currencyservice"
namespace: demo
spec:
selector:
matchLabels:
app: currencyservice
action: ALLOW
rules:
- from:
- source:
principals: ["example-project-1234.svc.id.goog/ns/demo/sa/frontend-sa"]
서비스 계정을 지정하려면 Cloud Service Mesh 인증 기관(Mesh CA) 및 Certificate Authority Service(CA 서비스)의 principals
가 다음 형식이어야 합니다.
principals: ["PROJECT_ID.svc.id.goog/ns/NAMESPACE/sa/SERVICE_ACCOUNT_NAME"]
PROJECT_ID.svc.id.goog
는 Mesh CA의 트러스트 도메인입니다. Istio CA(이전 명칭: Citadel)를 사용하는 경우 기본 트러스트 도메인은 cluster.local
입니다.
식별된 네임스페이스
다음 예시는 소스가 foo
네임스페이스가 아니면 요청을 거부하는 정책을 보여줍니다.
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
name: httpbin-deny
namespace: foo
spec:
selector:
matchLabels:
app: httpbin
version: v1
action: DENY
rules:
- from:
- source:
notNamespaces: ["foo"]
값 일치
승인 정책의 필드 대부분은 다음과 같이 일치하는 스키마를 모두 지원합니다.
- 완전 일치: 문자열이 완전히 일치합니다.
"*"
와일드 카드 문자를 사용한 와일드 카드 일치:- 프리픽스 일치: 끝이
"*"
인 문자열입니다. 예를 들어"test.example.*"
는"test.example.com"
또는"test.example.com.cn"
과 일치합니다. - 서픽스 일치:
"*"
로 시작하는 문자열입니다. 예를 들어"*.example.com"
은"eng.example.com"
또는"test.eng.example.com"
과 일치합니다.
- 프리픽스 일치: 끝이
- 존재 일치: 필드가 존재하고 비어 있지 않아야 한다고 지정하려면
fieldname: ["*"]
형식을 사용합니다. 이는 필드를 지정하지 않는 것과 다릅니다. 즉, 빈 필드를 포함하여 모든 항목이 일치합니다.
몇 가지 예외가 있습니다. 예를 들어 다음 필드는 완전 일치만 지원합니다.
when
섹션 아래의key
필드source
섹션 아래의ipBlocks
to
섹션 아래의ports
필드
다음 정책 예시에서는 프리픽스가 /test/*
또는 서픽스가 */info
인 경로에서 액세스를 허용합니다.
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
name: tester
namespace: default
spec:
selector:
matchLabels:
app: products
action: ALLOW
rules:
- to:
- operation:
paths: ["/test/*", "*/info"]
제외 일치
when
필드의 notValues
, source
필드의 notIpBlocks
, to
필드의 notPorts
와 같은 부정 조건을 일치시키기 위해 Cloud Service Mesh는 제외 일치를 지원합니다. 다음 예시에서는 요청 경로가 /healthz
가 아닌 경우 JWT 인증에서 파생된 유효한 요청 principals
가 필요합니다. 따라서 정책은 JWT 인증에서 /healthz
경로에 대한 요청을 제외합니다.
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
name: disable-jwt-for-healthz
namespace: default
spec:
selector:
matchLabels:
app: products
action: ALLOW
rules:
- to:
- operation:
notPaths: ["/healthz"]
from:
- source:
requestPrincipals: ["*"]
일반 텍스트 요청 거부
Cloud Service Mesh 1.5 이상에서는 기본적으로 자동 mTLS가 사용 설정됩니다. 자동 mTLS를 사용하면 클라이언트 사이드카 프록시가 서버에 사이드카가 있는지 자동으로 감지합니다. 클라이언트 사이드카는 사이드카가 있는 워크로드에는 mTLS를 전송하고, 사이드카 없는 워크로드에는 일반 텍스트를 전송합니다. 최상의 보안을 위해 STRICT mTLS를 사용 설정하는 것이 좋습니다.
워크로드 또는 네임스페이스에 대해 STRICT
모드로 mTLS를 사용 설정할 수 없는 경우 다음을 수행할 수 있습니다.
namespaces
또는principals
가 비어 있지 않은 트래픽을 명시적으로 허용하는 승인 정책 만들기, 또는namespaces
또는principals
가 비어 있는 트래픽 거부하기
namespaces
및 principals
는 mTLS 요청으로만 추출될 수 있으므로 이러한 정책은 모든 일반 텍스트 트래픽을 효과적으로 거부합니다.
다음 정책은 요청의 주 구성원이 비어 있는 경우 요청을 거부합니다(일반 텍스트 요청의 경우). 주 구성원이 비어 있지 않으면 정책이 요청을 허용합니다. ["*"]
는 비어 있지 않은 일치를 의미하고, notPrincipals
와 함께 사용한다는 것은 빈 주 구성원에 대한 일치를 의미합니다.
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
name: require-mtls
namespace: NAMESPACE
spec:
action: DENY
rules:
- from:
- source:
notPrincipals: ["*"]
승인 정책 우선순위
별도의 ALLOW
및 DENY
승인 정책을 구성할 수 있지만 정책이 원하는 대로 작동하는지 확인하려면 정책 우선순위 및 기본 동작을 이해해야 합니다. 다음 다이어그램은 정책 우선순위를 설명합니다.
다음 섹션의 정책 예시에서는 여러 기본 동작과 이러한 동작이 유용할 수 있는 상황을 보여줍니다.
허용 안함
다음 예시에서는 일치하는 항목이 없는 ALLOW
정책을 보여줍니다. 기본적으로 다른 ALLOW
정책이 없으면 요청이 항상 거부됩니다.
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
name: allow-nothing
spec:
action: ALLOW
allow-nopolicy 정책으로 시작하고 워크로드에 더 많은 액세스를 추가할 수 있도록 ALLOW
정책을 점진적으로 추가하는 것이 좋습니다.
모든 액세스 거부
다음 예시는 모든 항목과 일치하는 DENY
정책을 보여줍니다. DENY
정책은 ALLOW
정책보다 먼저 평가되므로 요청과 일치하는 ALLOW
정책이 있더라도 모든 요청이 거부됩니다.
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
name: deny-all
spec:
action: DENY
rules:
- {}
모두 거부 정책은 워크로드에 대한 모든 액세스를 일시적으로 중지하려는 경우에 유용합니다.
모든 액세스 허용
다음 예시에서는 모든 항목과 일치하고 워크로드에 대한 전체 액세스를 허용하는 ALLOW
정책을 보여줍니다. allow-all 정책은 요청을 항상 허용하므로 다른 ALLOW
정책은 쓸모가 없습니다.
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
name: allow-all
spec:
action: ALLOW
rules:
- {}
allow-all 정책은 워크로드에 일시적으로 전체 액세스 권한을 노출하려는 경우에 유용합니다. DENY
정책이 있으면 DENY
정책이 ALLOW
정책 이전에 평가되므로 요청이 계속 거부될 수 있습니다.
권장사항
각 서비스에 대해 Kubernetes 서비스 계정을 만들고 배포에서 서비스 계정을 지정합니다. 예를 들면 다음과 같습니다.
apiVersion: v1 kind: ServiceAccount metadata: name: frontend-sa namespace: demo --- apiVersion: apps/v1 kind: Deployment metadata: name: frontend namespace:demo spec: selector: matchLabels: app: frontend template: metadata: labels: app: frontend spec: serviceAccountName: frontend-sa ...
allow-nothing 정책으로 시작하고 점진적으로
ALLOW
정책을 추가하여 워크로드에 대한 액세스 권한을 늘립니다.서비스에 JWT를 사용하는 경우:
DENY
정책을 만들어 인증되지 않은 요청을 차단합니다. 예를 들면 다음과 같습니다.apiVersion: security.istio.io/v1beta1 kind: AuthorizationPolicy metadata: name: requireJWT namespace: admin spec: action: DENY rules: - from: - source: notRequestPrincipals: ["*"]
allow-nothing 정책을 적용합니다.
각 워크로드의
ALLOW
정책을 정의합니다. 예시는 JWT 토큰을 참조하세요.
다음 단계
Cloud Service Mesh 보안 기능에 대해 자세히 알아보세요.
- Cloud Service Mesh 사용자 인증 구성
- 서비스의 감사 정책 구성
- 전송 보안 구성
- IAP(Identity-Aware Proxy)와 Cloud Service Mesh 통합
- GKE 클러스터에서 Cloud Service Mesh 이그레스 게이트웨이 사용 시 권장사항
Istio 문서의 승인 정책에 대해 자세히 알아보세요.