Istio数据面配置解析18:使用RBAC对Http请求进行授权
Posted UpInTheVir
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Istio数据面配置解析18:使用RBAC对Http请求进行授权相关的知识,希望对你有一定的参考价值。
Istio数据面配置解析18:使用RBAC对Http请求进行授权
Istio数据面配置解析18:使用RBAC对Http请求进行授权概述相关拓扑准备相关配置RbacConfigServiceRole和ServiceRoleBindingDestinationRule测试结果
概述
本文介绍了在Isito中使用RBAC对Http请求进行授权:
1.0版本针对Http的RBAC授权的配置会被加到Server端inbound listener的envoy.http_connection_manager这个filter的envoy.filters.http.rbac中。
1.0版本只支持针对Http的RBAC授权。
针对source.principal的授权,需要为Client端挂载证书和密钥。
相关拓扑
在destinationrule中启用针对server端的istio_mutual的配置。
为server端配置rbacconfig,开启rbac授权。
为server端配置servicerole,为角色授权。
为server端配置servicerolebinding,将角色与被授权对象关联。
在本文中,将基于source.principal进行授权,也就是针对client端的证书信息进行授权。
使用istio rbacconfig定义nginx.default.svc.cluster.local启用rbac授权。
使用istio servicerole定义到nginx.default.svc.cluster.local服务的带有version: v1标签的端点的角色权限。
使用istio servicerole定义到nginx.default.svc.cluster.local服务的带有version: v2标签的端点的角色权限。
使用istio servicerolebinding定义将cluster.local/ns/default/sa/sleep-v1与v1角色绑定。
使用istio servicerolebinding定义将cluster.local/ns/default/sa/sleep-v2与v2角色绑定。
使用istio destinationrule为到nginx.default.svc.cluster.local服务的请求挂载证书。
准备
apiVersion: v1
kind: ServiceAccount
metadata:
name: sleep-v1
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: sleep-v2
---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: sleep-v1
spec:
replicas: 1
template:
metadata:
labels:
app: sleep
version: v1
spec:
serviceAccountName: sleep-v1
containers:
- name: sleep
image: 192.168.0.61/istio-example/alpine-curl
command: ["/bin/sleep","7200"]
imagePullPolicy: IfNotPresent
---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: sleep-v2
spec:
replicas: 1
template:
metadata:
labels:
app: sleep
version: v2
spec:
serviceAccountName: sleep-v2
containers:
- name: sleep
image: 192.168.0.61/istio-example/alpine-curl
command: ["/bin/sleep","7200"]
imagePullPolicy: IfNotPresent
准备sleep-v1和sleep-v2用于client端。
为sleep-v1和sleep-v2准备相应的serviceaccount。
apiVersion: v1
kind: Service
metadata:
name: nginx
spec:
type: ClusterIP
ports:
- port: 80
name: http
selector:
app: nginx
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: nginx
---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: nginx-v1
spec:
replicas: 1
template:
metadata:
labels:
app: nginx
version: v1
spec:
serviceAccountName: nginx
containers:
- name: nginx
image: 192.168.0.61/istio-example/nginx
ports:
- containerPort: 80
volumeMounts:
- mountPath: /etc/nginx/conf.d/
readOnly: true
name: conf
- mountPath: /etc/nginx/html/
readOnly: true
name: index
volumes:
- name: conf
configMap:
name: nginx-v1
items:
- key: default.conf
path: default.conf
- name: index
configMap:
name: nginx-v1
items:
- key: index.html
path: index.html
---
apiVersion: v1
kind: ConfigMap
metadata:
name: nginx-v1
data:
default.conf: |
server {
listen 80;
server_name loalhost;
location / {
root /etc/nginx/html/;
index index.html index.htm;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
}
index.html: |
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
body {
width: 35em;
margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif;
}
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<h1>v1!</h1>
<p>If you see this page, the nginx web server is successfully installed and working. Further configuration is required.</p>
<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>
<p><em>Thank you for using nginx.</em></p>
</body>
</html>
---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: nginx-v2
spec:
replicas: 1
template:
metadata:
labels:
app: nginx
version: v2
spec:
serviceAccountName: nginx
containers:
- name: nginx
image: 192.168.0.61/istio-example/nginx
ports:
- containerPort: 80
volumeMounts:
- mountPath: /etc/nginx/conf.d/
readOnly: true
name: conf
- mountPath: /etc/nginx/html/
readOnly: true
name: index
volumes:
- name: conf
configMap:
name: nginx-v2
items:
- key: default.conf
path: default.conf
- name: index
configMap:
name: nginx-v2
items:
- key: index.html
path: index.html
---
apiVersion: v1
kind: ConfigMap
metadata:
name: nginx-v2
data:
default.conf: |
server {
listen 80;
server_name loalhost;
location / {
root /etc/nginx/html/;
index index.html index.htm;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
}
index.html: |
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
body {
width: 35em;
margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif;
}
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<h1>v2!</h1>
<p>If you see this page, the nginx web server is successfully installed and working. Further configuration is required.</p>
<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>
<p><em>Thank you for using nginx.</em></p>
</body>
</html>
准备nginx-v1和nginx-v2用于server端。
为nginx-v1和nginx-v2准备相应的service以及serviceaccount。
相关配置
RbacConfig
apiVersion: "rbac.istio.io/v1alpha1"
kind: RbacConfig
metadata:
name: default
namespace: istio-system
spec:
mode: 'ON_WITH_INCLUSION'
inclusion:
services: ["nginx.default.svc.cluster.local"]
rbacconfig相关配置。
目前istio的rbaconfig为全局配置,每个mesh中只能配置一个。
rbacconfig的name需要配置为default。
rbacconfig的namespace需要配置为istio-system。
rbacconfig的模式配置为ON_WITH_INCLUSION,即只针对inclusion中定义的服务启用rbac。
在inclusion中,配置针对nginx.default.svc.cluster.local启用rbac授权。
ServiceRole和ServiceRoleBinding
apiVersion: rbac.istio.io/v1alpha1
kind: ServiceRole
metadata:
name: sr-v1
namespace: default
spec:
rules:
- services: ["nginx.default.svc.cluster.local"]
methods: ["GET"]
constraints:
- key: "destination.labels[version]"
values: ["v1"]
---
apiVersion: rbac.istio.io/v1alpha1
kind: ServiceRole
metadata:
name: sr-v2
namespace: default
spec:
rules:
- services: ["nginx.default.svc.cluster.local"]
methods: ["GET"]
constraints:
- key: "destination.labels[version]"
values: ["v2"]
servicerole相关配置。
在servicerole sr-v1中,针对nginx.default.svc.cluster.local的destination.labels[version]包含v1的pod,授予http get的权限。
在servicerole sr-v2中,针对nginx.default.svc.cluster.local的destination.labels[version]包含v2的pod,授予http get的权限。
apiVersion: rbac.istio.io/v1alpha1
kind: ServiceRoleBinding
metadata:
name: srb-v1
namespace: default
spec:
subjects:
- user: "cluster.local/ns/default/sa/sleep-v1"
roleRef:
kind: ServiceRole
name: "sr-v1"
---
apiVersion: rbac.istio.io/v1alpha1
kind: ServiceRoleBinding
metadata:
name: srb-v2
namespace: default
spec:
subjects:
- user: "cluster.local/ns/default/sa/sleep-v2"
roleRef:
kind: ServiceRole
name: "sr-v2"
servicerolebinding相关配置。
将user,也就是source.principal,为cluster.local/ns/default/sa/sleep-v1,也就是sleep-v1应用,授予sr-v1的角色,也就是可以以http get的方式,访问nginx-v1。
将user,也就是source.principal,为cluster.local/ns/default/sa/sleep-v2,也就是sleep-v2应用,授予sr-v2的角色,也就是可以以http get的方式,访问nginx-v2。
{
"name": "10.234.1.48_80",
"address": {
"socketAddress": {
"address": "10.234.1.48",
"portValue": 80
}
},
"filterChains": [
{
"filterChainMatch": {
"transportProtocol": "raw_buffer"
},
"filters": [
{
"name": "envoy.http_connection_manager",
…
"http_filters": [
{
"config": {
"policy": {
"peers": [
{
"mtls": {
"mode": "PERMISSIVE"
}
}
]
}
},
"name": "istio_authn"
},
{
"config": {
"rules": {
"policies": {
"sr-v1": {
"permissions": [
{
"and_rules": {
"rules": [
{
"or_rules": {
"rules": [
{
"header": {
"exact_match": "GET",
"name": ":method"
…
"principals": [
{
"and_ids": {
"ids": [
{
"metadata": {
"filter": "istio_authn",
"path": [
{
"key": "source.principal"
}
],
"value": {
"string_match": {
"exact": "cluster.local/ns/default/sa/sleep-v1"
在nginx-v1的inbound listener中,会增加相应的filter,针对source.principal为cluster.local/ns/default/sa/sleep-v1的角色,授予get的权限。
{
"name": "10.234.0.70_80",
"address": {
"socketAddress": {
"address": "10.234.0.70”,
"portValue": 80
}
},
"filterChains": [
{
"filterChainMatch": {
"transportProtocol": "raw_buffer"
},
"filters": [
{
"name": "envoy.http_connection_manager",
…
"http_filters": [
{
"config": {
"policy": {
"peers": [
{
"mtls": {
"mode": "PERMISSIVE"
}
}
]
}
},
"name": "istio_authn"
},
{
"config": {
"rules": {
"policies": {
"sr-v1": {
"permissions": [
{
"and_rules": {
"rules": [
{
"or_rules": {
"rules": [
{
"header": {
"exact_match": "GET",
"name": ":method"
…
"principals": [
{
"and_ids": {
"ids": [
{
"metadata": {
"filter": "istio_authn",
"path": [
{
"key": "source.principal"
}
],
"value": {
"string_match": {
"exact": "cluster.local/ns/default/sa/sleep-v2”
在nginx-v2的inbound listener中,会增加相应的filter,针对source.principal为cluster.local/ns/default/sa/sleep-v2的角色,授予get的权限。
DestinationRule
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: dr
spec:
host: nginx.default.svc.cluster.local
trafficPolicy:
tls:
mode: ISTIO_MUTUAL
destinationrule相关配置。
因为是针对source.principal进行授权,所以要在client端挂载相应证书。
针对到server端的请求,启用ISTIO_MUTUAL,挂载相应证书和密钥。
{
"name": "outbound|80||nginx.default.svc.cluster.local",
"type": "EDS",
"edsClusterConfig": {
"edsConfig": {
"ads": {}
},
"serviceName": "outbound|80||nginx.default.svc.cluster.local"
},
"connectTimeout": "1.000s",
"circuitBreakers": {
"thresholds": [
{}
]
},
"tlsContext": {
"commonTlsContext": {
"tlsCertificates": [
{
"certificateChain": {
"filename": "/etc/certs/cert-chain.pem"
},
"privateKey": {
"filename": "/etc/certs/key.pem"
}
}
],
"validationContext": {
"trustedCa": {
"filename": "/etc/certs/root-cert.pem"
},
"verifySubjectAltName": [
"spiffe://cluster.local/ns/default/sa/nginx"
]
},
"alpnProtocols": [
"istio"
]
},
"sni": "outbound|80||nginx.default.svc.cluster.local"
}
}
在sleep-v1和sleep-v2的和服务nginx.default.svc.cluster.local相关的outbound cluster中,会挂载相应的证书和密钥。
测试结果
/ # curl http://nginx
RBAC: access denied/ #
/ #
/ # curl http://nginx
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
body {
width: 35em;
margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif;
}
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<h1>v1!</h1>
<p>If you see this page, the nginx web server is successfully installed and working. Further configuration is required.</p>
<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>
<p><em>Thank you for using nginx.</em></p>
</body>
</html>
/ #
sleep-v1可以正常访问nginx-v1的服务,但在访问nginx-v2时,会发生RBAC: access denied。
/ # curl http://nginx
RBAC: access denied/ #
/ #
/ # curl http://nginx
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
body {
width: 35em;
margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif;
}
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<h1>v2!</h1>
<p>If you see this page, the nginx web server is successfully installed and working. Further configuration is required.</p>
<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>
<p><em>Thank you for using nginx.</em></p>
</body>
</html>
/ #
sleep-v2可以正常访问nginx-v2的服务,但在访问nginx-v1时,会发生RBAC: access denied。
以上是关于Istio数据面配置解析18:使用RBAC对Http请求进行授权的主要内容,如果未能解决你的问题,请参考以下文章
为啥我使用 Istio AuthorizationPolicy 和 JWT 收到 403“RBAC: access denied”