명시적 거부

명시적 거부 (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)

  1. 다음 명령은 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
  1. 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
  1. 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
  1. 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
  1. 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
  1. 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
  1. 다음 명령은 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
  1. /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
  1. /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
  1. /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 액션 비교는 인가 정책 개요를 확인하세요.