驗證和授權是安全工作 PUZZLE 的重要部分,需要雲架構師和 DevOps 工程師來解決。在本文中,我們將特別查看如何實現授權/訪問控制;即是认证实体可以在 Istio 服務网格中执行哪些操作。它通過防止具有恶意意图的操作來保護基礎設施。
在服務网格中,授权可以通過 OPA 策略來定義。OPA 是一種機制,幫助 DevOps 同仁為 Kubernetes 工作負載定義和強制執行授權策略。在本文中,我們將看到:
- 什么是 OPA
- 为什么您應該將 OPA 整合到 Istio 服務网格中
- Istio 和 OPA 是如何授權請求的
- 您可以跟進哪些精確步驟將 OPA 整合到 Istio 中
OPA 是什么?
OPA(Open Policy Agent 的缩寫)是一個開源的通用策略執行引擎,它讓 DevOps 可以使用一種高层次的声明式語言 Rego,將策略定義為代码。OPA 幫助中心化地定義和強制执行跨堆栈的策略,同時解放開發者不需要在應用程序代碼中寫入授權策略。以下是 OPA 的工作方式(請参见圖 1):
- 应用程序/服务接收到请求。
- 服务將 JSON 授权請求發送到 OPA。
- OPA將請求與定義的授權策略進行對比。
- OPA 做出決策,并以 JSON 格式將授權响应(ALLOW/DENY)返回給服務。
圖 1: 使用 OPA 的授權請求流程
注意,不需要是 Developer 编写的应用程序发送授权请求:可以是 Argo CD、Kubernetes Gateway API 资源、Terraform、Prometheus 或任何其他东西,因为 OPA 是通用目的的。 (我在这里提到了并在图中绘制了一个在 Kubernetes 集群中的应用程序,以便方便更好地理解。)
為什麼要将 OPA 整合到 Istio 中?
Istio 有一个健壮的授权机制。然而,拥有像 OPA 这样的专用策略执行引擎与 Istio 服务网路相结合也有其好处:
- 集中的管理系统来定义和执行策略:OPA 使 DevOps 能够更容易地集中管理整个堆栈的授权策略。这包括网格化工作负载、非网格化堆栈,以及授权检查(例如,防止在周五部署的政策)。
- 在定义策略时更具灵活性和细粒度:如果你看下面的表格(图 2),很明显 Istio 授权可以做很多事情,并根据来自不同数据源的各种字段的请求进行匹配。然而,Istio AuthorizationPolicy CRD 在配置 HTTP 请求体或任何字段中的上下文数据方面可能会有所限制,这时可以使用 OPA。与 Istio 不同,OPA 可以使用任何数据进行策略评估。
- 简化的 AuthZ 配置:在 Istio 中配置复杂的授权规则可能会让 DevOps 感到繁琐。OPA 使用 Rego 进行配置,这更接近一种编程语言。使用 Rego 相对容易设置从基本到复杂的策略规则。
圖表 2: Istio 与 OPA 授權比較(來源)
Istio 与 OPA 是如何授權請求的
DevOps 可以將 OPA 部署為完全独立的服務,或者作為 Envoy 代理和應用程序容器的 sidecar 容器在 pod 中一起部署。後者方法有助於減少延遲。
OPA sidecar 容器需要像 Istio 的 Envoy 代理 sidecar 容器一樣注入到應用程序 pod 中。我們可以設定注入的 OPA 容器挂載包含授權規則的 ConfigMaps;然後在 namespace 中的每個 OPA sidecar 容器都将挂載在 ConfigMap 中定義的相同配置和 AuthZ 規則。
一旦注入了 OPA sidecar,當服務接收到請求時,Envoy 代理將向 OPA 發送授權請求以進行授權決定:
圖表 3:Istio-OPA 授權 workflow
假設 DevOps 人员不希望同一个 namespace 中的每個注入 OPA 容器都遵循相同的配置,並希望強制不同的規則。這種情況下,他們可以執行以下任何行為:
- 移除硬編碼,讓當前注入政策使用特定的 ConfigMap
- 配置篡改 webhook 並者在 pod 層面禁用 sidecar 注入
- 從遠程HTTP伺服器不上載政策束
- 在不同的命名空間中部署應用程序和伴生器,並使用不同的ConfigMap
將Opa與Istio整合的步驟:示例
這裡的念頭是讓OPA成為外部授權者,而不是Envoy代理伴生器 — 來進行存取控制決策。
我將使用Istio文件中的經典Bookinfo應用程序作為示例。我將為OPA配置Istio以進行存取控制,並檢查是否通過發送請求到bookinfo/productpage來執行:
圖4:Istio-OPA整合教學圖
請注意/productpage是UI,它對內呼叫其他服務,例如評論和評分服務(圖表)。我將將OPA注入bookinfo
命名空間中的每個容器的每個容器;所有OPA容器掛载相同的ConfigMap,因此具有相同的授權政策。Bookinfo
應用程序的預設行為不會转发任何HTTP认证,所以內部呼叫將無法通過认证和授權。
我們將按照給定的步驟進行:
- 配置OPA伴生器注入
- 啟用Istio代理與OPA之間的通信
- 部署OPA配置
- 應用Istio配置
- 部署應用並測試Istio-OPA授權設置
示範的前提是您的叢集已安裝Istio v1.19+。我在這裡使用的是Istio v1.21.0。
OPA提供了一個quickstart.yaml以便於安裝。我已將yaml拆分為三部分以便更容易理解:IMESH GitHub庫。
步驟1:配置OPA Sidecar注入
kubectl apply -f opa_controller.yaml
opa_controller.yaml
部署所有內容 — TLS證書、包含注入策略的ConfigMap、入站控制器部署以及變更Webhook配置 — 到opa-istio
命名空間(參見圖5):
- 變更Webhook控制器(
opa-istio-admission-controller
)將監聽特定標籤(opa-istio-injection
)並將其值設置為啟用。 - 網頁挂钩控制器呼叫
admission-controller
,該控制器具有注入策略。 - 注入策略告訴
admission-controller
如何將OPA旁邊集装箱注入到 Pod 中。
圖 5: OPA 旁邊集装箱注入配置
現在,在部署 Bookinfo 應用程序之前,我們將創建bookinfo
命名空間,並按照以下步驟進行:
通過應用bookinfo-ns.yaml創建bookinfo
命名空間:
kubectl apply -f bookinfo-ns.yaml
opa-istio-injection: enabled
, to auto-inject OPA sidecars.
步驟 2: 允許 Istio 代理和 OPA 之間的通信
在istio-system
命名空間中編輯 Istio ConfigMap 並添加extensionProviders
(opa-ext-authz-grpc
),以便在网格中啟用外部授權:
- 從 opa_controller.yaml 中的註釋複製
extensionProviders
。 - 编辑 Istio ConfigMap 并在网格字段中添加
extensionProviders
。 - 確保缩進正確。
- 保存配置。
此步驟使istio-proxy
能夠與 Pod 中的opa-istio
集装箱進行授權請求。
如果您查看extensionProviders
,它是在 Envoy 中的ExtAuthzGrpc
過濾器類型,具有指定的服務条目和端口:
...
extensionProviders:
- name: opa-ext-authz-grpc
envoyExtAuthzGrpc:
service: opa-ext-authz-grpc.local
port: "9191"
...
`extensionProviders` 的名稱、服務地址和埠應該在 `opa_authz.yaml` 和 `opa_config.yaml` 之中相同。
步驟 3: 部署 OPA 配置
`opa_config.yaml` 定義了開放策略相關的配置。它有 `opa-istio-config` 和 `opa-policy ConfigMaps` — 它們分別定義了 gRPC 服務實現 (`envoy_ext_authz_grpc`) 和實際的授權策略。
授權策略可以分為兩部分:第一部分定義了允許或拒絕授權的條件;第二部分定義了用戶角色和每個角色的權限。
由於 Rego 這裡沒有使用很多關鍵詞,所以授权策略可能需要一些時間來適應。启用 Rego 的新版本以獲得關鍵詞(例如允許條件關鍵詞)。
在 `bookinfo` 命名空間中應用 OPA 配置,因為它與應用程序一同使用:
kubectl apply -f opa_config.yaml -n bookinfo
步驟 4: 應用 Istio 配置
opa_authz.yaml 文件包含 Istio 配置。它有一個 AuthorizationPolicy
和一個 ServiceEntry
。請注意,授权策略提供者是 opa-ext-authz-grpc
,這是我們在步驟 2 中在 ConfigMap 中配置的 extensionProvider
。
同樣地,ServiceEntry
中定義的主機名與 extensionProvider
中給出的服務地址(opa-ext-authz-grpc.local
)相同。gRPC 服務將在 127.0.0.1 的 localhost 端口 9191 上運行,這使得 ServiceEntry
通過 istio-proxy
容器讓 opa-istio
側邊車在 Pod 內可达。
部署配置:
kubectl apply -f opa_authz.yaml -n bookinfo
步驟 5:部署應用程序並測試 Istio-OPA 授權設定
部署 Bookinfo 應用程序和网关:
kubectl apply -f /your_Istio_directory/samples/bookinfo/platform/kube/bookinfo.yaml -n bookinfo
kubectl apply -f /your_Istio_directory/samples/bookinfo/networking/bookinfo-gateway.yaml -n bookinfo
查看 bookinfo
命名空间中的 Pod:
kubectl get pods -n bookinfo
您可以看到每個 Pod 中有 3 个容器的運行:應用程序、Envoy 代理(istio-proxy
)和 OPA(opa-istio
)容器。
獲取 Istio 网关的 IP 以訪問服務:
kubectl get svc -n istio-system

現在一切就绪,我們準備好測試授權策略了。我們在 opa_config.yaml 中定義的策略如下:
...
user_roles = {
"alice": ["guest"],
"bob": ["admin"]
}
role_perms = {
"guest": [
{"method": "GET", "path": "/productpage"},
],
"admin": [
{"method": "GET", "path": "/productpage"},
{"method": "GET", "path": "/api/v1/products"},
],
...
Alice 是一個只能訪問 /productpage
的訪客用戶;Bob 是一個管理員,可以訪問路徑 /productpage
和 /api/v1/products
。讓我們來核實一下策略。
嘗試從 Alice 访问 /api/v1/products
:
curl -vvv your_istio_gateway_ip/api/v1/products -u alice:password
您可以看到 Alice 沒有訪問路徑的權限,所以返回了 403 禁止
的响应。讓我們试著像 Bob 一樣走同样的路徑:
curl -vvv your_istio_gateway_ip/api/v1/products -u bob:password
响应显示了 HTTP 状态 200 OK
,以及响应内容最后的部分。
使用 OPA 的访问控制示例场景
您可以使用 Istio 的 AuthorizationPolicy CRD 来强制执行上述演示中的策略。您不需要 OPA。然而,如开头表格中提到的,Istio 授权在某些情况下可能会受到限制。让我举一个简单的例子。
假设有一个名为 BookReviews 的应用程序,它是一个 GraphQL 服务,其中评论者提交评论,编辑编辑并发布这些评论,用户阅读已发布的评论。
当评论者将书评添加到服务时,请求将包括评论者的 JWT,其中包含评论者所属的组和角色(评论者或编辑)。请求体还将包含包含新创建评论数据的 GraphQL 突变查询。
假设您想要确保以下条件:
- 只有评论者可以提交评论。
- 编辑只能编辑由属于他们管理的同一组的评论者撰写的评论。
- 只有编辑才能将评论标记为“准备发布”。
以下是包括上述策略的图表:
Istio 的 AuthorizationPolicy 将难以强制执行上述条件。原因是 Istio 无法使用 GraphQL 请求体进行授权检查,这是政策评估所需的 JWT 旁边的 JSON 对象。
OPA並無此限制。它可以 loads any data for policy checks,並且 DevOps 可以 以更符合人体工學的方式使用 Rego 寫這些規則。
影片:实际行动演示
如果您更偏好观看实际行动演示,請查看以下的影片:S
对企业整合 Istio 的支持
大多数企业使用 OPA 来定义和强制执行整个堆栈的授权策略。拥有一个访问控制的中央机制可以提高整体安全性和 IT 团队的灵活性。否则,开发者将会浪费时间将授权策略开发到用特定语言编写的应用程序代码中,这阻碍了可伸缩性和更快地推出业务逻辑。
Source:
https://dzone.com/articles/5-steps-to-integrate-istio-with-opa