Istio 中的 IP 黑名单
IP Blacklisting in Istio
此处解释的 IP whitelisting/blacklisting 示例 https://kubernetes.io/docs/tutorials/services/source-ip/ 使用 source.ip 属性。但是,在 kubernetes 中(kubernetes 集群 运行 on docker-for-desktop)source.ip returns kube-proxy 的 IP。建议的解决方法是使用 request.headers["X-Real-IP"]
,但它似乎不起作用 returns kube-proxy IP in docker-for-desktop in mac.
https://github.com/istio/istio/issues/7328 提到了这个问题并指出:
With a proxy that terminates the client connection and opens a new connection to your nodes/endpoints. In such cases the source IP will always be that of the cloud LB, not that of the client.
With a packet forwarder, such that requests from the client sent to the loadbalancer VIP end up at the node with the source IP of the client, not an intermediate proxy.
Loadbalancers in the first category must use an agreed upon protocol between the loadbalancer and backend to communicate the true client IP such as the HTTP X-FORWARDED-FOR header, or the proxy protocol.
有人可以帮忙定义一个协议来从负载均衡器获取客户端 IP 吗?
也许你对 kube-proxy 和 istio 感到困惑,默认情况下 Kubernetes 使用 kube-proxy 但你可以安装 istio 为每个 pod 注入一个新的代理来控制内部服务的双向流量吊舱。
话虽如此,您可以在集群上安装 istio 并仅为您需要的服务启用它,并使用 istio 机制应用黑名单
https://istio.io/docs/tasks/policy-enforcement/denial-and-list/
要使用源 IP 创建黑名单,我们必须让 istio 管理如何获取源 IP 地址并使用从文档中获取的 som 配置:
apiVersion: config.istio.io/v1alpha2
kind: handler
metadata:
name: whitelistip
spec:
compiledAdapter: listchecker
params:
# providerUrl: ordinarily black and white lists are maintained
# externally and fetched asynchronously using the providerUrl.
overrides: ["10.57.0.0/16"] # overrides provide a static list
blacklist: false
entryType: IP_ADDRESSES
---
apiVersion: config.istio.io/v1alpha2
kind: instance
metadata:
name: sourceip
spec:
compiledTemplate: listentry
params:
value: source.ip | ip("0.0.0.0")
---
apiVersion: config.istio.io/v1alpha2
kind: rule
metadata:
name: checkip
spec:
match: source.labels["istio"] == "ingressgateway"
actions:
- handler: whitelistip
instances: [ sourceip ]
---
您可以使用参数 providerURL
来维护外部列表。
还要检查在 istio 的 ingress-gateway 服务上使用 externalTrafficPolicy: Local
。
根据评论,我最后的建议是使用不同的 ingress-controller 来避免使用 kube-proxy,我的建议是使用 nginx-controller
https://github.com/kubernetes/ingress-nginx
您可以将此入口配置为充当代理的常规 nginx
此处解释的 IP whitelisting/blacklisting 示例 https://kubernetes.io/docs/tutorials/services/source-ip/ 使用 source.ip 属性。但是,在 kubernetes 中(kubernetes 集群 运行 on docker-for-desktop)source.ip returns kube-proxy 的 IP。建议的解决方法是使用 request.headers["X-Real-IP"]
,但它似乎不起作用 returns kube-proxy IP in docker-for-desktop in mac.
https://github.com/istio/istio/issues/7328 提到了这个问题并指出:
With a proxy that terminates the client connection and opens a new connection to your nodes/endpoints. In such cases the source IP will always be that of the cloud LB, not that of the client.
With a packet forwarder, such that requests from the client sent to the loadbalancer VIP end up at the node with the source IP of the client, not an intermediate proxy.
Loadbalancers in the first category must use an agreed upon protocol between the loadbalancer and backend to communicate the true client IP such as the HTTP X-FORWARDED-FOR header, or the proxy protocol.
有人可以帮忙定义一个协议来从负载均衡器获取客户端 IP 吗?
也许你对 kube-proxy 和 istio 感到困惑,默认情况下 Kubernetes 使用 kube-proxy 但你可以安装 istio 为每个 pod 注入一个新的代理来控制内部服务的双向流量吊舱。
话虽如此,您可以在集群上安装 istio 并仅为您需要的服务启用它,并使用 istio 机制应用黑名单
https://istio.io/docs/tasks/policy-enforcement/denial-and-list/
要使用源 IP 创建黑名单,我们必须让 istio 管理如何获取源 IP 地址并使用从文档中获取的 som 配置:
apiVersion: config.istio.io/v1alpha2
kind: handler
metadata:
name: whitelistip
spec:
compiledAdapter: listchecker
params:
# providerUrl: ordinarily black and white lists are maintained
# externally and fetched asynchronously using the providerUrl.
overrides: ["10.57.0.0/16"] # overrides provide a static list
blacklist: false
entryType: IP_ADDRESSES
---
apiVersion: config.istio.io/v1alpha2
kind: instance
metadata:
name: sourceip
spec:
compiledTemplate: listentry
params:
value: source.ip | ip("0.0.0.0")
---
apiVersion: config.istio.io/v1alpha2
kind: rule
metadata:
name: checkip
spec:
match: source.labels["istio"] == "ingressgateway"
actions:
- handler: whitelistip
instances: [ sourceip ]
---
您可以使用参数 providerURL
来维护外部列表。
还要检查在 istio 的 ingress-gateway 服务上使用 externalTrafficPolicy: Local
。
根据评论,我最后的建议是使用不同的 ingress-controller 来避免使用 kube-proxy,我的建议是使用 nginx-controller
https://github.com/kubernetes/ingress-nginx
您可以将此入口配置为充当代理的常规 nginx