kubernetes - 通过源 IP 地址保护 Kiali(在 Istio 中)
问题描述
我通过使用this在 Istio 1.10.2 中应用了 kiali 。现在我正在尝试通过过滤源 IP 地址来保护它。我尝试使用授权策略,但没有奏效。当它应该拒绝任何不在 ALLOW 策略中的请求时,它会继续允许每个人
授权政策:
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
name: kiali-ingress-policy-allow
namespace: istio-system
spec:
selector:
matchLabels:
app: kiali
action: ALLOW
rules:
- from:
- source:
remoteIpBlocks: ["10.43.212.247/32","10.43.212.242/32"]
虚拟服务:
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: kiali
namespace: istio-system
spec:
hosts:
- "kiali.myinternaldomain.local"
gateways:
- istio-system/my-internal-gateway
http:
- match:
- uri:
prefix: /
route:
- destination:
host: kiali
port:
number: 20001
使用默认配置文件和这些额外参数安装 ISTIO:
apiVersion: install.istio.io/v1alpha1
kind: IstioOperator
spec:
meshConfig:
accessLogFile: /dev/stdout
components:
ingressGateways:
- name: istio-ingressgateway
enabled: true
k8s:
overlays:
- apiVersion: apps/v1
kind: Deployment
name: istio-ingressgateway
patches:
- path: kind
value: DaemonSet
- path: spec.strategy
- path: spec.updateStrategy
value:
rollingUpdate:
maxUnavailable: 50%
type: RollingUpdate
egressGateways:
- name: istio-egressgateway
enabled: true
k8s:
hpaSpec:
minReplicas: 2
pilot:
k8s:
hpaSpec:
minReplicas: 2
values:
gateways:
istio-ingressgateway:
autoscaleEnabled: false
env:
ISTIO_META_HTTP10: '1'
pilot:
env:
PILOT_HTTP10: '1'
解决方案
我设法在GCP VMALLOW
上的 Istio 1.10.2 中设置工作策略,集群是使用带有 Calico CNI 插件的 kubeadm 设置的。我使用了这个文档 - Ingress Gateway。
注意:我将istio-ingressgateway
服务类型更改为NodePort
service 而不是LoadBalancer
,但这在这种情况下无关紧要。
我的网络设计如下:
- 第一个 VM - Kubernetes 节点 - 10.xxx.0.2 地址
- 第二个虚拟机 - 10.xxx.0.3 地址
- 第三个 VM - 10.xxx.0.4 地址 - 此地址将在 ALLOW 策略中
我部署了以下 NGINX 服务和部署...
apiVersion: v1
kind: Service
metadata:
name: nginx-svc
labels:
app: nginx
spec:
ports:
- name: http
port: 80
targetPort: 80
selector:
app: nginx
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deply
spec:
replicas: 1
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
version: v1
spec:
containers:
- image: nginx
imagePullPolicy: IfNotPresent
name: nginx
ports:
- containerPort: 80
...以及以下网关和虚拟服务定义:
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: gateway
spec:
selector:
istio: ingressgateway
servers:
- port:
number: 80
name: http
protocol: HTTP
hosts:
- "*"
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: nginx-vs
spec:
hosts:
- "my-test.com"
gateways:
- gateway
http:
- route:
- destination:
host: nginx-svc
port:
number: 80
查看nginx-svc
虚拟服务定义中的服务名称(您应该使用要配置的名称)。
我可以从网络中的每个虚拟机运行以下命令:
user@vm-istio:~$ curl 10.xxx.0.2:31756 -H "Host: my-test.com"
<!DOCTYPE html>
...
<title>Welcome to nginx!</title>
所以它工作正常。
kubectl get pods -n istio-system -o name -l istio=ingressgateway | sed 's|pod/||' | while read -r pod; do istioctl proxy-config log "$pod" -n istio-system --level rbac:debug; done
...并且我设置externalTrafficPolicy
为Local
服务istio-ingressgateway
以保留原始客户端的 IP 地址:
kubectl patch svc istio-ingressgateway -n istio-system -p '{"spec":{"externalTrafficPolicy":"Local"}}
在 istio 入口网关控制器的日志中,我可以看到请求即将到来并且它们正在继续:
kubectl logs istio-ingressgateway-5d57955454-9mz4b -n istio-system -f
...
[2021-11-24T13:39:47.220Z] "GET / HTTP/1.1" 200 - via_upstream - "-" 0 615 1 0 "10.xxx.0.3" "curl/7.64.0" "69953f69-8a46-9e2a-a5a7-36861bae4a77" "my-test.com" "192.168.98.74:80" outbound|80||nginx-svc.default.svc.cluster.local 192.168.98.72:60168 192.168.98.72:8080 10.xxx.0.3:55160 - -
[2021-11-24T13:39:48.980Z] "GET / HTTP/1.1" 200 - via_upstream - "-" 0 615 1 0 "10.xxx.0.4" "curl/7.64.0" "89284e11-42f9-9e84-b256-d3ea37311e92" "my-test.com" "192.168.98.74:80" outbound|80||nginx-svc.default.svc.cluster.local 192.168.98.72:60192 192.168.98.72:8080 10.xxx.0.4:35800 - -
现在,我将应用基于 IP 的允许列表以仅允许第二个 VM 地址托管my-test.com
:
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
name: ingress-policy
namespace: istio-system
spec:
selector:
matchLabels:
app: istio-ingressgateway
action: ALLOW
rules:
- from:
- source:
ipBlocks: ["10.xxx.0.4"]
to:
- operation:
hosts:
- "my-test.com"
在地址为 10.xxx.0.4 的 VM 上 curl 像以前一样工作,但在地址为 10.xxx.0.3 的 VM 上,我们可以注意到以下内容:
user@vm-istio:~$ curl 10.xxx.0.2:31756 -H "Host: my-test.com"
RBAC: access denied
所以它按预期工作。
在 istio 入口网关控制器的日志中,我们可以注意到请求被拒绝(查找与 RBAC 相关的日志):
kubectl logs istio-ingressgateway-5d57955454-9mz4b -n istio-system -f
2021-11-24T14:05:11.382613Z debug envoy rbac checking request: requestedServerName: , sourceIP: 10.xxx.0.3:55194, directRemoteIP: 10.xxx.0.3:55194, remoteIP: 10.xxx.0.3:55194,localAddress: 192.168.98.72:8080, ssl: none, headers: ':authority', 'my-test.com'
':path', '/'
':method', 'GET'
':scheme', 'http'
'user-agent', 'curl/7.64.0'
'accept', '*/*'
'x-forwarded-for', '10.xxx.0.3'
'x-forwarded-proto', 'http'
'x-envoy-internal', 'true'
'x-request-id', '63c0f55c-5545-92a0-80fc-aa2a5a63bf04'
'x-envoy-decorator-operation', 'nginx-svc.default.svc.cluster.local:80/*'
'x-envoy-peer-metadata', '...'
'x-envoy-peer-metadata-id', 'router~192.168.98.72~istio-ingressgateway-5d57955454-9mz4b.istio-system~istio-system.svc.cluster.local'
, dynamicMetadata:
2021-11-24T14:05:11.382662Z debug envoy rbac enforced denied, matched policy none
[2021-11-24T14:05:11.382Z] "GET / HTTP/1.1" 403 - rbac_access_denied_matched_policy[none] - "-" 0 19 0 - "10.xxx.0.3" "curl/7.64.0" "63c0f55c-5545-92a0-80fc-aa2a5a63bf04" "my-test.com" "-" outbound|80||nginx-svc.default.svc.cluster.local - 192.168.98.72:8080 10.xxx.0.3:55194 - -
特别是这部分:
[2021-11-24T14:05:11.382Z] "GET / HTTP/1.1" 403 - rbac_access_denied_matched_policy[none]
这清楚地表明我们的政策正在发挥作用。
允许我们请求的日志示例:
2021-11-25T10:58:34.717495Z debug envoy rbac enforced allowed, matched policy ns[istio-system]-policy[ingress-policy]-rule[0]
[2021-11-25T10:58:34.717Z] "GET / HTTP/1.1" 200 - via_upstream - "-" 0 615 25 23 "10.xxx.0.4" "curl/7.64.0" "889e3326-093c-94b1-b856-777c06cbe2b7" "my-test.com" "192.168.98.75:80" outbound|80||nginx-svc.default.svc.cluster.local 192.168.98.72:46190 192.168.98.72:8080 10.xxx.0.4:37148 - -
重要的是:
- 确保在 pod 的日志中
istio-ingressgateway-{..}
您可以注意到其他 VM 的源 IP 地址,以便策略可以允许/阻止 - 我的建议是在服务网格边缘为外部流量设置 AuthorizationPolicy - 这是 istio 入口网关,这就是我的 AuthorizationPolicy 使用“选择器”匹配标签
app: ingress-istio-ingressgateway
(而不是 kiali)的原因 - 使用正确类型的 IP -
ipBlocks
与remoteIpBlocks
. 根据您的设置,它应该是ipBlocks
:
何时使用
ipBlocks
vs.remoteIpBlocks
:如果您使用 X-Forwarded-For HTTP 标头或代理协议来确定原始客户端 IP 地址,那么您应该remoteIpBlocks
在您的AuthorizationPolicy
. 如果你正在使用externalTrafficPolicy: Local
,那么你应该ipBlocks
在你的AuthorizationPolicy
.
推荐阅读
- angular - Angular 和 Laravel 错误 - 应用程序已被 CORS 策略阻止
- python - 遍历具有多个句柄的 Pandas DataFrame,并迭代地追加编辑的行?
- c# - 如何从 BuckarooSdk 获取付款状态?
- node.js - NodeJs 未在端口 4000 中运行
- php - 使用 Laradock 主管运行队列
- c# - 在命名管道上读写
- android - 如何在 AAR 文件中构建具有依赖关系的模块
- java - 如何在两个不同的功能分支中提交类和接口(git flow eclipse)
- sql - 创建 MS SQL Server 查询以确定排名
- r - 如何在R中舍入一个整数