明确拒绝
此任务介绍如何设置 DENY
动作中的 Istio 授权策略,以明确拒绝 Istio 网格中的流量。
这与 ALLOW
动作不同,因为 DENY
动作具有更高的优先级,不会被任何 ALLOW
动作绕过。
开始之前
在您开始之前,请执行以下操作:
阅读 Istio 授权概念。
根据 Istio 安装指南安装 Istio.
部署工作负载:
该任务使用
httpbin
和sleep
这两个工作负载,部署在一个命名空间foo
。 这两个工作负载在每个工作负载前都有一个 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/sleep/sleep.yaml@) -n foo
使用以下命令校验
sleep
任务与httpbin
的对话。$ kubectl exec "$(kubectl get pod -l app=sleep -n foo -o jsonpath={.items..metadata.name})" -c sleep -n foo -- curl http://httpbin.foo:8000/ip -sS -o /dev/null -w "%{http_code}\n" 200
明确拒绝请求
以下命令为
foo
命名空间中的httpbin
工作负载创建deny-method-get
授权策略。 该授权将action
设置为DENY
,以拒绝满足rules
部分设置的条件的请求。 该类型策略被称为“拒绝策略”。在这种情况下,如果请求方式是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=sleep -n foo -o jsonpath={.items..metadata.name})" -c sleep -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=sleep -n foo -o jsonpath={.items..metadata.name})" -c sleep -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"]
,以拒绝 HTTP 头中x-token
值为非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=sleep -n foo -o jsonpath={.items..metadata.name})" -c sleep -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=sleep -n foo -o jsonpath={.items..metadata.name})" -c sleep -n foo -- curl "http://httpbin.foo:8000/get" -X GET -H "x-token: guest" -sS -o /dev/null -w "%{http_code}\n" 403
以下命令创建
allow-path-ip
授权策略,允许以/ip
路径向httpbin
工作负载发出请求。该授权策略设置action
字段为ALLOW
。该类型的策略被称为“允许策略”。$ 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=sleep -n foo -o jsonpath={.items..metadata.name})" -c sleep -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=sleep -n foo -o jsonpath={.items..metadata.name})" -c sleep -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=sleep -n foo -o jsonpath={.items..metadata.name})" -c sleep -n foo -- curl "http://httpbin.foo:8000/get" -X GET -H "x-token: admin" -s -o /dev/null -w "%{http_code}\n" 403
清理
从配置中删除命名空间 foo:
$ kubectl delete namespace foo