该任务演示如何去构建Istio授权策略,拒绝在istio网格中的HTTP流量。
1. 准备工作
- 该任务使用两个工作负载,httpbin和sleep,部署在一个名称空间foo上。这两个工作负载都在前面有一个特使代理。使用以下命令部署示例名称空间和工作负载
$ 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 -s -o /dev/null -w "%{http_code}\n"
2. 明确的拒绝一个请求
- 下面的命令为foo名称空间中的httpbin工作负载创建deny-method-get授权策略。策略设置拒绝的操作,以拒绝满足规则部分中设置的条件的请求。这种类型的策略称为deny策略。在这种情况下,如果请求的方法是GET,策略就会拒绝请求。
$ kubectl apply -f - <<EOF
apiVersion: security.istio.io/v1beta1
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 -s -o /dev/null -w "%{http_code}\n"
- 校验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 -s -o /dev/null -w "%{http_code}\n"
- 更新deny-method- GET授权策略,只有当HTTP头x-token值不是admin时才拒绝GET请求。下面的示例策略将notValues字段的值设置为[“admin”],以拒绝具有非admin标题值的请求
$ kubectl apply -f - <<EOF
apiVersion: security.istio.io/v1beta1
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获取请求
$ 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"
- 验证使用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" -s -o /dev/null -w "%{http_code}\n"
- 下面的命令创建allow-path-ip授权策略,以允许在/ip路径上请求httpbin工作负载。此授权策略将操作字段设置为允许。这种类型的策略称为allow策略。
$ kubectl apply -f - <<EOF
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
name: allow-path-ip
namespace: foo
spec:
selector:
matchLabels:
app: httpbin
action: ALLOW
rules:
- to:
- operation:
paths: ["/ip"]
EOF
- 验证使用HTTP头x-token: guest at path /ip的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: admin" -s -o /dev/null -w "%{http_code}\n"
- 验证path- path-ip策略是否允许使用HTTP头x-token: admin at path /ip的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: admin" -s -o /dev/null -w "%{http_code}\n"
- 验证使用HTTP头x-token: admin at path / GET的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"
3. 移除配置的名称空间
$ kubectl delete namespace foo