在Istio中可以通过黑白名单功能来实现服务访问控制,能实现比Denier适配器更强的服务访问控制策略。
1.白名单
白名单规则是指,在默认情况下拒绝服务的所有请求,只允许符合条件的服务请求通过。使用示例如下:
1 apiVersion: config.istio.io/v1alpha2 2 kind: listchecker 3 metadata: 4 name: whitelist 5 spec: 6 overrides: 7 - "v1" 8 entryType: STRINGS 9 blacklist: false 10 --- 11 apiVersion: config.istio.io/v1alpha2 12 kind: listentry 13 metadata: 14 name: app-version 15 spec: 16 value: source.labels["version"] 17 --- 18 apiVersion: config.istio.io/v1alpha2 19 kind: rule 20 metadata: 21 name: check-version 22 spec: 23 match: destination.labels["app"] == "service-go" 24 actions: 25 - handler: whitelist.listchecker 26 instances: 27 - app-version.listentry
第1~9行定义了名为whitelist的listchecker适配器。overrides列出符合条件的字符串数组。blacklist表示是否为黑名单,设置为false表示这是一个白名单。entryType表示overrides列出的值的匹配类型,有4种类型可选:STRINGS表示普通的字符串,CASE_INSENSITIVE_STRINGS表示大小写敏感的字符串,IP_ADDRESSES表示值为IP地址或者IP地址段,REGEX表示使用正则匹配。
第11~16行定义了名为app-version的listentry实例,表示收集来源请求的version标签值。
第18~27行定义了名为check-version的rule,只有请求目标服务为service-go时才应用此规则。该规则表明,在请求服务service-go的请求中,只有来源版本为v1的请求才允许通过。
2.黑名单
黑名单规则是指,在默认情况下允许服务的所有请求,只拒绝符合条件的服务请求通过。使用示例如下:
1 apiVersion: config.istio.io/v1alpha2 2 kind: listchecker 3 metadata: 4 name: whitelist 5 spec: 6 overrides: 7 - "v2" 8 entryType: STRINGS 9 blacklist: true 10 --- 11 apiVersion: config.istio.io/v1alpha2 12 kind: listentry 13 metadata: 14 name: app-version 15 spec: 16 value: source.labels["version"] 17 --- 18 apiVersion: config.istio.io/v1alpha2 19 kind: rule 20 metadata: 21 name: check-version 22 spec: 23 match: destination.labels["app"] == "service-go" 24 actions: 25 - handler: whitelist.listchecker 26 instances: 27 - app-version.listentry
黑名单的定义与白名单几乎一致,只需要把blacklist设置为true即可。
第18~27行定义的规则表明,在请求服务service-go的请求中,来源版本为v2的请求会被拒绝。
【实验】
1)创建测试Pod:
$ kubectl apply -f kubernetes/dns-test.yaml
2)创建白名单规则:
$ kubectl apply -f istio/security/policy-rule-whitelist.yaml
3)访问service-node服务:
$ kubectl exec dns-test -c dns-test -- curl -s http://service-node/env {"message":"node v1","upstream":[{"message":"go v2","response_time":"0.06"}]} $ kubectl exec dns-test -c dns-test -- curl -s http://service-node/env {"message":"node v2","upstream":[]}
当访问服务service-node的v1版本时,可以得到服务service-go的正常响应;当访问服务service-node的v2版本时,无法得到服务service-go的正常响应。在这里,我们通过设置白名单达到了和Denier适配器规则同样的效果。
4)删除白名单规则:
$ kubectl delete -f istio/security/policy-rule-whitelist.yaml
5)创建黑名单规则:
$ kubectl apply -f istio/security/policy-rule-blacklist.yaml
6)访问service-node服务:
$ kubectl exec dns-test -c dns-test -- curl -s http://service-node/env {"message":"node v1","upstream":[{"message":"go v2","response_time":"0.06"}]} $ kubectl exec dns-test -c dns-test -- curl -s http://service-node/env {"message":"node v2","upstream":[]}
当访问服务service-node的v1版本时,可以得到服务service-go的正常响应;当访问服务service-node的v2版本时,无法得到服务service-go的正常响应。在这里,我们通过设置黑名单达到了和Denier适配器以及白名单规则同样的效果。
7)清理:
$ kubectl delete -f kubernetes/dns-test.yaml $ kubectl delete -f istio/security/policy-rule-blacklist.yaml