當您需要對使用HTTP協議通信的服務進行細粒度的訪問控制時,可以使用自定義授權服務功能,根據特定業務需求定制授權機制,在服務間互相通信時加入鑒權流程,確保只有經過認證和授權的請求才能訪問相應的服務資源,提高服務間通信的安全性。本文以sleep與httpbin應用為例,介紹如何實現接入HTTP協議的自定義授權服務。
前提條件
步驟一:部署自定義授權服務
在ACK集群中部署自定義授權服務,該服務需遵循Istio自定義鑒權服務接口規范,支持HTTP和gRPC協議,用于實現自定義鑒權邏輯。本文使用的示例服務要求請求必須帶有x-ext-authz: allow
請求頭,才能通過鑒權訪問成功。
本文提供了自定義授權服務示例,您也可以參考本示例應用的代碼,創建自己的自定義授權服務。具體內容,請參見自定義授權。
通過kubectl連接集群,使用以下內容,創建ext-authz.yaml。
關于如何通過kubectl連接集群,請參見獲取集群KubeConfig并通過kubectl工具連接集群。
# Copyright Istio Authors # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # Example configurations for deploying ext-authz server separately in the mesh. apiVersion: v1 kind: Service metadata: name: ext-authz labels: app: ext-authz spec: ports: - name: http port: 8000 targetPort: 8000 - name: grpc port: 9000 targetPort: 9000 selector: app: ext-authz --- apiVersion: apps/v1 kind: Deployment metadata: name: ext-authz spec: replicas: 1 selector: matchLabels: app: ext-authz template: metadata: labels: app: ext-authz spec: containers: - image: registry-cn-hangzhou.ack.aliyuncs.com/ack-demo/asm-ext-authz-example:0.6 imagePullPolicy: IfNotPresent name: ext-authz ports: - containerPort: 8000 - containerPort: 9000 ---
執行以下命令,在集群中部署自定義授權服務。
kubectl apply -f ext-authz.yaml
執行以下命令,查看Pod部署情況。
kubectl get pod
預期輸出:
NAME READY STATUS RESTARTS AGE ext-authz-6b5db88f86-2m7c6 2/2 Running 0 79m
執行以下命令,驗證應用是否正常工作。
kubectl logs "$(kubectl get pod -l app=ext-authz -n default -o jsonpath={.items..metadata.name})" -n default -c ext-authz
預期輸出:
2023/12/20 08:15:39 Starting gRPC server at [::]:9000 2023/12/20 08:15:39 Starting HTTP server at [::]:8000
返回以上結果,說明應用正常工作,自定義授權服務部署成功。
獲取ext-authz授權服務的HTTP協議端口。
登錄容器服務管理控制臺,在左側導航欄選擇集群。
在集群列表頁面,單擊目標集群名稱,然后在左側導航欄,選擇 。
在服務頁面,單擊ext-authz。
在端點區域,可以看到HTTP協議的端口為8000。訪問該服務的HTTP地址為ext-authz.default.svc.cluster.local:8000。
步驟二:部署示例應用
使用以下內容,創建httpbin.yaml。
# Copyright Istio Authors # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. ################################################################################################## # httpbin service ################################################################################################## apiVersion: v1 kind: ServiceAccount metadata: name: httpbin --- apiVersion: v1 kind: Service metadata: name: httpbin labels: app: httpbin service: httpbin spec: ports: - name: http port: 8000 targetPort: 80 selector: app: httpbin --- apiVersion: apps/v1 kind: Deployment metadata: name: httpbin spec: replicas: 1 selector: matchLabels: app: httpbin version: v1 template: metadata: labels: app: httpbin version: v1 spec: serviceAccountName: httpbin containers: - image: docker.io/kennethreitz/httpbin imagePullPolicy: IfNotPresent name: httpbin ports: - containerPort: 80
執行以下命令,在集群中部署httpbin應用。
kubectl apply -f httpbin.yaml
使用以下內容,創建sleep.yaml。
# Copyright Istio Authors # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. ################################################################################################## # Sleep service ################################################################################################## apiVersion: v1 kind: ServiceAccount metadata: name: sleep --- apiVersion: v1 kind: Service metadata: name: sleep labels: app: sleep service: sleep spec: ports: - port: 80 name: http selector: app: sleep --- apiVersion: apps/v1 kind: Deployment metadata: name: sleep spec: replicas: 1 selector: matchLabels: app: sleep template: metadata: labels: app: sleep spec: terminationGracePeriodSeconds: 0 serviceAccountName: sleep containers: - name: sleep image: curlimages/curl command: ["/bin/sleep", "3650d"] imagePullPolicy: IfNotPresent volumeMounts: - mountPath: /etc/sleep/tls name: secret-volume volumes: - name: secret-volume secret: secretName: sleep-secret optional: true ---
執行以下命令,在集群中部署sleep應用。
kubectl apply -f sleep.yaml
步驟三:使用HTTP協議對接自定義授權服務
將步驟一部署的服務聲明到服務網格中,使服務網格可以使用該服務進行鑒權。
登錄ASM控制臺,在左側導航欄,選擇 。
在網格管理頁面,單擊目標實例名稱,然后在左側導航欄,選擇 ,然后單擊關聯自定義授權服務。
在關聯自定義授權服務頁面,單擊基于envoy.ext_authz實現的自定義授權服務(HTTP或gRPC協議)頁簽,進行相關配置,然后單擊創建。
類型
配置項
說明
必選參數
協議
選擇自定義授權應用的協議。本文選擇HTTP。
名稱
自定義授權服務名稱。本文設置為test4http。
服務地址
輸入自定義授權應用的服務地址<應用名稱>.<命名空間名稱>.svc.<集群域名>,此處必須為全稱。本文設置為ext-authz.default.svc.cluster.local。
服務端口
輸入自定義授權應用的服務端口。本文設置為8000。
超時時間
如果鑒權應用未在該時間內返回,則認為鑒權服務不可用,本文設置為10秒。
可選參數
鑒權服務不可用時放行請求
是否在鑒權服務不可用時放行請求。若啟用該選項,則鑒權服務不可用時請求被放行。本文設置為不開啟。
鑒權服務不可用自定義錯誤碼
該選項僅在關閉鑒權服務不可用時放行請求時可選。若啟用該選項,需填寫錯誤碼,在鑒權服務不可用時,該錯誤碼將被返回至調用端。本文設置為不開啟。
在鑒權請求中攜帶header
啟用該選項后,需填寫期望攜帶的Header Key,匹配的Header將被設置于傳送至自定義鑒權服務的請求中。本文設置為如在鑒權請求中攜帶Header所示。
說明僅設置協議為HTTP時,才可以設置該參數。
在鑒權請求中新增header
啟用該選項后,需填寫期望在鑒權請求中新增的Header Key和Header Value,這些Header將被增加到鑒權服務的鑒權請求中。
若Header在請求中已經存在,則覆蓋原Header。本文設置為不開啟。
說明僅設置協議為HTTP時,才可以設置該參數。
鑒權通過時覆蓋Header
啟用該選項后,需填寫期望覆蓋的Header Key,自定義鑒權通過時,使用鑒權請求Response中匹配的Header覆蓋目標服務請求中的Header。本文設置如鑒權通過時覆蓋Header所示。
說明僅設置協議為HTTP時,才可以設置該參數。
鑒權失敗時覆蓋Header
啟用該選項后,需填寫期望覆蓋的Header Key,自定義鑒權失敗時,使用鑒權請求Response中匹配的Header覆蓋返回至調用服務Response中的Header。本文設置如鑒權失敗時覆蓋Header所示。
說明僅設置協議為HTTP時,才可以設置該參數。
在鑒權請求中攜帶請求Body
啟用該選項后,需填寫鑒權請求攜帶Body的最大長度。若啟用允許將不完整消息發往鑒權服務,當被鑒權請求Body大于設置的最大長度時,從最大長度處截取,并將截取后的Body發往鑒權服務。
步驟四:為網格內的服務定義授權策略
您需要創建授權策略來配置需要鑒權的請求操作。
登錄ASM控制臺,在左側導航欄,選擇 。
在網格管理頁面,單擊目標實例名稱,然后在左側導航欄,選擇 ,然后單擊創建。
在創建頁面,進行相關配置,然后單擊創建。
配置項
說明
名稱
自定義授權策略名稱,本文設置為test1。
策略類型
選擇自定義授權服務。
自定義授權服務
選擇httpextauth-test4http(HTTP)。
命名空間
在工作負載生效頁簽,選擇default命名空間。
生效范圍
選擇Service。
工作負載
選擇httpbin。
請求匹配規則
在添加請求目標區域,打開HTTP路徑(Paths)開關,設置值為/headers。
步驟五:驗證服務間的自定義授權是否成功
執行以下命令,訪問
httpbin.default:8000/ip
。kubectl exec "$(kubectl get pod -l app=sleep -n default -o jsonpath={.items..metadata.name})" -c sleep -n default -- curl "http://httpbin.default:8000/ip" -s -o /dev/null -w "%{http_code}\n"
返回
200
,說明沒有觸發鑒權。因為訪問的路徑為/ip
,不是授權策略中定義的/headers
,所以不被授權策略約束。執行以下命令,帶有
x-ext-authz: deny
請求頭訪問httpbin.default:8000/headers
。kubectl exec "$(kubectl get pod -l app=sleep -n default -o jsonpath={.items..metadata.name})" -c sleep -ndefault -- curl "http://httpbin.default:8000/headers" -H "x-ext-authz: deny" -s -i
預期輸出:
HTTP/1.1 403 Forbidden x-ext-authz-check-result: denied content-length: 76 content-type: text/plain; charset=utf-8 date: Wed, 20 Dec 2023 09:53:28 GMT server: envoy x-envoy-upstream-service-time: 10 denied by ext_authz for not found header `x-ext-authz: allow` in the request
返回以上結果,說明觸發鑒權,但是鑒權未通過,返回的結果中存在新定義的響應頭
x-ext-authz-check-result: denied
。因為訪問的路徑是授權策略中定義的/headers
,所以會被授權策略約束。執行以下命令,帶有
x-ext-authz: allow
請求頭訪問httpbin.default:8000/headers
。kubectl exec "$(kubectl get pod -l app=sleep -n default -o jsonpath={.items..metadata.name})" -c sleep -n default -- curl "http://httpbin.default:8000/headers" -H "x-ext-authz: allow" -s
預期輸出:
{ "headers": { "Accept": "*/*", "Host": "httpbin.default:8000", "User-Agent": "curl/8.5.0", "X-Envoy-Attempt-Count": "1", "X-Ext-Authz": "allow", "X-Ext-Authz-Check-Result": "allowed", "X-Forwarded-Client-Cert": "By=spiffe://cluster.local/ns/default/sa/httpbin;Hash=c3e5364e87add0f4f69e6b0d029f5961b404c8f209bf9004b3d21a82cf67****;Subject=\"\";URI=spiffe://cluster.local/ns/default/sa/sleep" } }
返回以上結果,說明觸發鑒權,并且鑒權通過,返回的結果中存在新定義的響應頭
"X-Ext-Authz-Check-Result": "allowed"
。因為訪問的路徑是授權策略中定義的/headers
,所以會被授權策略約束。
相關操作
如果您需要了解如何開發基于HTTP協議的自定義授權服務,請參見開發基于HTTP協議的自定義授權服務。
如果您需要了解如何開發基于gRPC協議的自定義授權服務,請參見開發基于gRPC協議的自定義授權服務。
如果您需要對使用gRPC協議通信的服務進行細粒度的訪問控制,請參見接入gRPC協議的自定義授權服務。
如果您需要對網格外服務進行授權控制,請參見對網格內服務訪問外部網站進行授權控制和對網格內服務訪問外部數據庫進行授權控制。
您可以啟用網格審計功能,記錄或追溯不同用戶的日常操作,也可以為網格資源操作配置審計告警,在重要資源變動時及時發出告警通知到告警聯系人。具體操作,請參見使用KubeAPI操作審計和為網格資源操作配置審計告警。