授权策略用于配置网格、namespace、服务/Workload 范围的访问管理规则。您可以通过 AuthorizationPolicy CRD 配置授权规则。AuthorizationPolicy 主要包含以下部分:
selector:指定策略的生效范围。
action:指定该策略是
ALLOW
策略还是 DENY
策略。rules:授权规则主体,由 from,to,where 3 部分构成。
from:指定请求的来源特征。
to:指定请求的操作特征。
when:指定授权规则的生效条件。
当有 AuthorizationPolicy 的
ALLOW
和 DENY
策略应用于同一范围时,DNEY
策略的优先级高于 ALLOW
策略,生效的规则如下:1. 如请求匹配任何一条
DENY
策略,则拒绝该请求的访问。2. 如该范围没有任何
ALLOW
策略,则允许该请求的访问。3. 如当前该范围存在
ALLOW
策略,且请求匹配到了任何一条 ALLOW
策略,则允许该请求的访问。4. 拒绝该请求的访问。
以下是两种特殊 AuthorizationPolicy 示例:
default namespace 的服务允许所有请求访问:
apiVersion: security.istio.io/v1beta1kind: AuthorizationPolicymetadata:name: allow-allnamespace: defaultspec:action: ALLOWrules:- {} # 规则可以匹配任何请求
default namespace 的服务拒绝所有请求访问:
apiVersion: security.istio.io/v1beta1kind: AuthorizationPolicymetadata:name: deny-allnamespace: defaultspec:{} # action 字段没有填写时默认是 ALLOW,此时请求无法匹配任何规则
AuthorizationPolicy 重要字段说明
以下是 AuthorizationPolicy 重要字段说明:
字段名称 | 字段类型 | 字段说明 |
metadata.name | string | AuthorizationPolicy 名称。 |
metadata.namespace | string | AuthorizationPolicy 命名空间。 |
spec.selector | map<string, string> | AuthorizationPolicy 使用填写的标签键值对,配合填写的 namespace,匹配配置下发的 Workload 范围: namespace 填写 istio-system,且 selector 字段不填写时,该策略生效范围为整个网格。 namespace 填写非 istio-system 的 namespace,且 selector 字段不填写时,策略生效范围为填写的 namespace。 namespace 填写非 istio-system 的 namespace,且 selector 字段填写了有效键值对时,策略的生效范围为在所填 namespace 下根据 selector 匹配到的 Workload。 |
spec.action | - | 指定该策略是 ALLOW 策略还是 DENY 策略。 |
spec.rules.from.source.principals | string[] | 源对等身份列表(即 service account),匹配 source.principal 字段 ,要求启用 mTLS,未填写时则允许任何 principal。 |
spec.rules.from.source.requestPrincipals | string[] | 请求身份列表(即 iss/sub claim),匹配 request.auth.principal 字段,未填写时则允许任何 requestPrincipals。 |
spec.rules.from.source.namespaces | string[] | 请求源的 namespace 列表,匹配 source.namespace 字段,要求启用 mTLS,未填写时允许来自任何 namespace 的请求。 |
spec.rules.from.source.ipBlocks | string[] | IP block 列表,匹配 source.ip 字段,支持单 IP 写法(如 1.2.3.4 )或 CIDR 写法(如 1.2.3.4/24 ),未填写时允许任何源 IP 的访问。 |
spec.rules.to.operation.hosts | string[] | 请求的域名列表,匹配 request.host 字段,未填写时允许任何域名,仅支持在 HTTP 协议请求中使用。 |
spec.rules.to.operation.ports | string[] | 请求的端口列表,匹配 destination.port 字段,未填写时允许任何端口。 |
spec.rules.to.operation.methods | string[] | 请求的方法列表,匹配 request.method 字段,使用 gRPC 协议时该值始终应为 POST 。未填写时允许任何方法 ,仅支持在 HTTP 协议请求中使用。 |
spec.rules.to.operation.paths | string[] | 请求的路径,匹配 request.url_path 字段,未填写时允许任何路径,仅支持在 HTTP 协议请求中使用。 |
spec.rules.when.condition.key | string | Istio 支持的条件字段名称,详见 Authorization Policy Conditions |
spec.rules.when.condition.values | string[] | 填写对应条件的值列表。 |
使用 AuthorizationPolicy 配置 namespace 的访问权限
为查看配置的 AuthorizationPolicy 策略效果,我们首先部署一套测试程序到网格管理的集群,部署完成后位于 test namespace 的 client 服务会自动发起对 base namespace user 服务的访问:
apiVersion: v1kind: Namespacemetadata:name: testlabels:istio.io/rev: 1-6-9 # sidecar 自动注入(istio 1.6.9)spec:finalizers:- kubernetes---apiVersion: apps/v1kind: Deploymentmetadata:name: clientnamespace: testlabels:app: clientspec:replicas: 10selector:matchLabels:app: clienttemplate:metadata:labels:app: clientspec:containers:- name: clientimage: ccr.ccs.tencentyun.com/zhulei/testclient:v1imagePullPolicy: Alwaysenv:- name: POD_NAMEvalueFrom:fieldRef:fieldPath: metadata.name- name: REGIONvalue: "guangzhou-zoneA"ports:- containerPort: 7000protocol: TCP---apiVersion: v1kind: Servicemetadata:name: clientnamespace: testlabels:app: clientspec:ports:- name: httpport: 7000protocol: TCPselector:app: clienttype: ClusterIP---apiVersion: v1kind: Namespacemetadata:name: baselabels:istio.io/rev: 1-6-9spec:finalizers:- kubernetes---apiVersion: apps/v1kind: Deploymentmetadata:name: usernamespace: baselabels:app: userspec:replicas: 1selector:matchLabels:app: usertemplate:metadata:labels:app: userspec:containers:- name: userimage: ccr.ccs.tencentyun.com/zhulei/testuser:v1imagePullPolicy: Alwaysenv:- name: POD_NAMEvalueFrom:fieldRef:fieldPath: metadata.name- name: REGIONvalue: "guangzhou-zoneB"ports:- containerPort: 7000---apiVersion: v1kind: Servicemetadata:name: usernamespace: baselabels:app: userspec:ports:- port: 7000name: httpselector:app: user
查看 client 容器的日志,会发现访问成功,正确返回了 user 信息:
接下来将配置 Authorization 策略,不允许 base namespace 的服务被 test namespace 的服务访问(需要开启 mTLS)。apiVersion: security.istio.io/v1beta1kind: AuthorizationPolicymetadata:name: base-authznamespace: basespec:action: DENYrules:- from:- source:namespaces:- test
配置完成后再次查看 client 的容器日志,发现所有访问均失败,没有返回 user 信息,AuthorizationPolicy 生效。
使用 AuthorizationPolicy 配置 Ingress Gateway 的 IP 黑白名单
您可以使用 AuthorizationPolicy 为边缘代理网关 Ingress Gateway 配置 IP 黑/白名单。
为验证黑白名单的配置效果,您首先需要部署一个测试程序
httpbin.foo
,并配置通过 Ingress Gateway 暴露此服务到公网:创建 foo namespace,开启 sidecar 自动注入,部署 httpbin 服务到 foo namespace:
apiVersion: v1kind: Namespacemetadata:name: foolabels:istio.io/rev: 1-6-9 # 开启 namespace 的 sidecar 自动注入(istio 版本 1.6.9)spec:finalizers:- kubernetes---apiVersion: v1kind: ServiceAccountmetadata:name: httpbinnamespace: foo---apiVersion: v1kind: Servicemetadata:name: httpbinnamespace: foolabels:app: httpbinservice: httpbinspec:ports:- name: httpport: 8000targetPort: 80selector:app: httpbin---apiVersion: apps/v1kind: Deploymentmetadata:name: httpbinnamespace: foospec:replicas: 1selector:matchLabels:app: httpbinversion: v1template:metadata:labels:app: httpbinversion: v1spec:serviceAccountName: httpbincontainers:- image: docker.io/kennethreitz/httpbinimagePullPolicy: IfNotPresentname: httpbinports:- containerPort: 80
配置通过 Ingress Gateway 暴露 httpbin 服务至公网访问:
apiVersion: networking.istio.io/v1alpha3kind: Gatewaymetadata:name: httpbin-gatewaynamespace: foospec:selector:app: istio-ingressgatewayistio: ingressgatewayservers:- port:number: 80name: httpprotocol: HTTPhosts:- "*"---apiVersion: networking.istio.io/v1alpha3kind: VirtualServicemetadata:name: httpbinnamespace: foospec:hosts:- "*"gateways:- httpbin-gatewayhttp:- route:- destination:port:number: 8000host: httpbin.foo.svc.cluster.local
通过 curl 语句
curl "$INGRESS_IP:80/headers" -s -o /dev/null -w "%{http_code}\\n"
测试服务的连通性,注意您需要将代码中的 $INGRESS_IP
替换为您的边缘代理网关 IP 地址,正常情况下会返回 200
返回码。为使 Ingress Gateway 能正确获取真实客户端源 IP,我们需要修改 Ingress Gateway Service 的 ExternalTrafficPolicy 为 Local,保证流量仅在本节点转发不做 SNAT。
下面将会使用 AuthorizationPolicy 把本机的 IP 地址列入 Ingress Gateway 的黑名单,并验证黑名单是否生效。
apiVersion: security.istio.io/v1beta1kind: AuthorizationPolicymetadata:name: black-listnamespace: istio-systemspec:selector:matchLabels:app: istio-ingressgatewayistio: ingressgatewayrules:- from:- source:ipBlocks:- $您的本机 IP 地址action: DENY
配置完成后再次通过 curl 语句
curl "$INGRESS_IP:80/headers" -s -o /dev/null -w "%{http_code}\\n"
测试服务的连通性,注意您需要将代码中的 $INGRESS_IP
替换为您的边缘代理网关 IP 地址,此时访问失败,返回 403
返回码,黑名单策略生效。