명시적 거부
명시적 거부 (Explicit Deny)
이 작업은 Istio 메시에서 트래픽을 명시적으로 거부하기 위해 DENY 액션의 Istio 인가 정책을 설정하는 방법을 보여드려요. DENY 액션은 우선순위가 더 높고 어떤 ALLOW 액션에도 우회되지 않는다는 점에서 ALLOW 액션과 달라요.
출처: Istio 문서
본문
이 작업은 Istio 메시에서 트래픽을 명시적으로 거부하도록 DENY 액션의 Istio 인가 정책을 설정하는 방법을 보여드려요. 이는 ALLOW 액션과 다른데, DENY 액션은 우선순위가 더 높아 어떤 ALLOW 액션도 우회할 수 없기 때문이에요.
시작하기 전에 (Before you begin)
이 작업을 시작하기 전에 다음을 수행하세요.
- Istio 인가 개념을 읽으세요.
- Istio 설치 가이드를 따라 Istio를 설치하세요.
- 워크로드 배포하기: 이 작업은
foo네임스페이스에 배포된httpbin과curl두 워크로드를 사용해요. 두 워크로드 모두 그 앞에 Envoy 프록시가 있어요. 다음 명령으로 예시 네임스페이스와 워크로드를 배포하세요.
$ kubectl create ns foo
$ kubectl apply -f <(istioctl kube-inject -f @samples/httpbin/httpbin.yaml@) -n foo
$ kubectl apply -f <(istioctl kube-inject -f @samples/curl/curl.yaml@) -n foo
- 다음 명령으로
curl이httpbin과 통신하는지 확인하세요.
$ kubectl exec "$(kubectl get pod -l app=curl -n foo -o jsonpath={.items..metadata.name})" -c curl -n foo -- curl http://httpbin.foo:8000/ip -sS -o /dev/null -w "%{http_code}\n"
200
[!note] 작업을 따르면서 예상 출력이 안 보이면 몇 초 후에 다시 시도하세요. 캐싱과 전파 오버헤드로 인해 지연이 발생할 수 있어요.
요청 명시적으로 거부하기 (Explicitly deny a request)
- 다음 명령은
foo네임스페이스의httpbin워크로드에 대한deny-method-get인가 정책을 만들어요. 정책은action을DENY로 설정해서rules섹션에 설정된 조건을 만족하는 요청을 거부해요. 이 유형의 정책은 거부 정책(deny policy)으로 잘 알려져 있어요. 이 경우 정책은 메서드가GET이면 요청을 거부해요.
$ kubectl apply -f - <<EOF
apiVersion: security.istio.io/v1
kind: AuthorizationPolicy
metadata:
name: deny-method-get
namespace: foo
spec:
selector:
matchLabels:
app: httpbin
action: DENY
rules:
- to:
- operation:
methods: ["GET"]
EOF
GET요청이 거부되는지 확인하세요.
$ kubectl exec "$(kubectl get pod -l app=curl -n foo -o jsonpath={.items..metadata.name})" -c curl -n foo -- curl "http://httpbin.foo:8000/get" -X GET -sS -o /dev/null -w "%{http_code}\n"
403
POST요청이 허용되는지 확인하세요.
$ kubectl exec "$(kubectl get pod -l app=curl -n foo -o jsonpath={.items..metadata.name})" -c curl -n foo -- curl "http://httpbin.foo:8000/post" -X POST -sS -o /dev/null -w "%{http_code}\n"
200
deny-method-get인가 정책을 업데이트해서 HTTP 헤더의x-token값이admin이 아닐 때만GET요청을 거부하세요. 다음 예시 정책은notValues필드 값을["admin"]으로 설정해서admin이 아닌 헤더 값이 있는 요청을 거부해요.
$ kubectl apply -f - <<EOF
apiVersion: security.istio.io/v1
kind: AuthorizationPolicy
metadata:
name: deny-method-get
namespace: foo
spec:
selector:
matchLabels:
app: httpbin
action: DENY
rules:
- to:
- operation:
methods: ["GET"]
when:
- key: request.headers[x-token]
notValues: ["admin"]
EOF
- HTTP 헤더
x-token: admin이 있는GET요청이 허용되는지 확인하세요.
$ kubectl exec "$(kubectl get pod -l app=curl -n foo -o jsonpath={.items..metadata.name})" -c curl -n foo -- curl "http://httpbin.foo:8000/get" -X GET -H "x-token: admin" -sS -o /dev/null -w "%{http_code}\n"
200
- HTTP 헤더
x-token: guest가 있는GET요청이 거부되는지 확인하세요.
$ kubectl exec "$(kubectl get pod -l app=curl -n foo -o jsonpath={.items..metadata.name})" -c curl -n foo -- curl "http://httpbin.foo:8000/get" -X GET -H "x-token: guest" -sS -o /dev/null -w "%{http_code}\n"
403
- 다음 명령은
httpbin워크로드의/ip경로에 대한 요청을 허용하는allow-path-ip인가 정책을 만들어요. 이 인가 정책은action필드를ALLOW로 설정해요. 이 유형의 정책은 허용 정책(allow policy)으로 잘 알려져 있어요.
$ kubectl apply -f - <<EOF
apiVersion: security.istio.io/v1
kind: AuthorizationPolicy
metadata:
name: allow-path-ip
namespace: foo
spec:
selector:
matchLabels:
app: httpbin
action: ALLOW
rules:
- to:
- operation:
paths: ["/ip"]
EOF
/ip경로에서 HTTP 헤더x-token: guest가 있는GET요청이deny-method-get정책에 의해 거부되는지 확인하세요. 거부 정책은 허용 정책보다 우선해요.
$ kubectl exec "$(kubectl get pod -l app=curl -n foo -o jsonpath={.items..metadata.name})" -c curl -n foo -- curl "http://httpbin.foo:8000/ip" -X GET -H "x-token: guest" -s -o /dev/null -w "%{http_code}\n"
403
/ip경로에서 HTTP 헤더x-token: admin이 있는GET요청이allow-path-ip정책에 의해 허용되는지 확인하세요.
$ kubectl exec "$(kubectl get pod -l app=curl -n foo -o jsonpath={.items..metadata.name})" -c curl -n foo -- curl "http://httpbin.foo:8000/ip" -X GET -H "x-token: admin" -s -o /dev/null -w "%{http_code}\n"
200
/get경로에서 HTTP 헤더x-token: admin이 있는GET요청이allow-path-ip정책과 일치하지 않아 거부되는지 확인하세요.
$ kubectl exec "$(kubectl get pod -l app=curl -n foo -o jsonpath={.items..metadata.name})" -c curl -n foo -- curl "http://httpbin.foo:8000/get" -X GET -H "x-token: admin" -s -o /dev/null -w "%{http_code}\n"
403
정리 (Clean up)
구성에서 foo 네임스페이스를 제거하세요.
$ kubectl delete namespace foo
더 알아보기 (Learn more)
- 인가 정책의 동작과 우선순위에 대한 자세한 내용은 인가 개념 문서를 참고하세요.
DENY/ALLOW/CUSTOM액션 비교는 인가 정책 개요를 확인하세요.