您好,登錄后才能下訂單哦!
今天就跟大家聊聊有關如何深度解析Istio中的安全模塊,可能很多人都不太了解,為了讓大家更加了解,小編給大家總結了以下內容,希望大家根據這篇文章可以有所收獲。
單體應用拆分為微服務之后,提高了開發效率,增加系統系統穩定性,提高運維效率等等一系列的好處,但隨之也帶來了安全方面的風險,之前都是本地調用,現在都改為走網絡協議調用接口,今天著重介紹的是微服務架構中的新貴Istio中安全模塊分析,Istio安全的三大目標:
默認安全(Security by default):應用程序代碼和基礎結構無需更改。
深度防御(Defense in depth):與現有安全系統集成,提供多層防御。
零信任網絡(Zero-trust network):在不受信的網絡上,構建安全解決方案。
如上圖,Istio安全涉及到組件有:
Citadel 用于密鑰和證書的管理。
Proxy 實現客戶端與服務器端安全通信。
Pilot 將授權策略和安全命名信息分發給代理。
Mixer:校驗授權和審計。
身份信息
身份信息是安全基礎架構的基本概念,在服務和服務的通信開始前,雙方必須用其身份信息交換憑證,以達到相互認證的目的,根據安全信息達到鑒權的目的,同時根據身份信息可以進行審計,在kubernetes的環境下Istio身份標識使用Service Account。
PKI
PKI(Public Key Infrastructure)建立在Istio citadel 之上,Istio 使用 X.509 證書來攜帶 SPIFFE 格式的身份信息,PKI 還可以大規模自動化地進行密鑰和證書輪換。
證書生成流程
基于kubernetes環境下證書生成流程如下:
citadel同時也會監聽每個證書的生命周期,通過重寫 Kubernetes secret 自動輪換證書。Pilot生成安全信息即授權信息,Pilot將授權信息分發給envoy每個命名空間下有個default serviceaccount,citadel會為它創建一個名為istio.default的secret。
[root@kube01 ~]$ kubectl -n foo get secrets NAME TYPE DATA AGE default-token-bdpmg kubernetes.io/service-account-token 3 8d istio.default istio.io/key-and-cert 3 8d
默認在該命名空間下新建的istio應用都使用該secret。
istio-certs: Type: Secret (a volume populated by a Secret) SecretName: istio.default Optional: true
當為deployment指定了非默認serviceaccount,則秘鑰也將使用新的secret。
istio-certs: Type: Secret (a volume populated by a Secret) SecretName: istio.bookinfo-productpage Optional: true
Istio提供兩種類型的身份驗證:
傳輸身份驗證,也稱為服務到服務身份驗證:驗證直接客戶端進行連接。Istio提供相互TLS 作為傳輸身份驗證的完整堆棧解決方案。
源身份驗證,也稱為最終用戶身份驗證:驗證將請求作為最終用戶或設備的原始客戶端。
具體信息參見官網,本文章主要介紹第一種。
相互 TLS身份驗證(mTLS)
mTLS本身流程如下圖所示:
在Istio握手期間,客戶端envoy還進行安全命名檢查,驗證服務器證書中提供的服務賬戶是否有權限運行目標服務。
認證架構
通過yaml文件配置身份認證策略,部署后策略保存在Istio配置存儲中,Pilot監聽配置存儲,當發生變化后Pilot將策略轉變為適當的配置(envoy識別的配置等),再通知envoy如何執行身份認證機制,Pilot提供Istio系統管理的密鑰和證書的路徑,并將它們安裝到應用程序mesh以進行相互TLS。Istio通過異步發送配置到目標端點,代理收到消息后,新的身份認證立即生效。
認證架構如下圖所示:
部署影響
在部署Istio平臺時,通過yaml則是istio-demo-auth.yaml,該yaml安裝為所有控制面板中envoy添加了tls相關信息,在helm中則是global.controlPlaneSecuretyEnable: true,開啟后實質是為controlPlaneAuthPolicy: MUTUAL_TLS,分析添加該屬性后發生的變化如下:
控制面板
Istio-policy,istio-telemetry,istio-pilot,三個組件在istio-proxy中envoy進程啟動時會指定配置文件,依次為envoy_policy.yaml,envoy_telemetry.yaml,envoy_pilot.yaml,在這些文件中相同都增加如下:
"tls_context": { "common_tls_context": { "alpn_protocols": "h3", "tls_certificates": { "certificate_chain": { "filename": "/etc/certs/cert-chain.pem" }, "private_key": { "filename": "/etc/certs/key.pem" } }, "validation_context": { "trusted_ca": { "filename": "/etc/certs/root-cert.pem" }, "verify_subject_alt_name": [ "spiffe://cluster.local/ns/istio-system/sa/istio-pilot-service-account" ] } }
在模板文件地址 實質判斷controlPlaneAuthPolicy的值,如果這個值設置None,則當開啟網格策略mtls后,控制面板各個組件不支持tls,導致轉發失敗,必須設置到控制面板目標規則mode為DISABLE才可以,否則會導致握手失敗,報錯503,如下所示:
[2018-10-23 02:55:45.510][19][debug][connection] external/envoy/source/common/network/connection_impl.cc:466] [C127] connected [2018-10-23 02:55:45.510][19][debug][connection] external/envoy/source/common/ssl/ssl_socket.cc:113] [C127] handshake error: 2 [2018-10-23 02:55:45.510][19][debug][connection] external/envoy/source/common/ssl/ssl_socket.cc:113] [C127] handshake error: 5 [2018-10-23 02:55:45.510][19][debug][connection] external/envoy/source/common/network/connection_impl.cc:133] [C127] closing socket: 0
數據面板
數據面板中該值controlPlaneAuthPolicy:None不影響mtls功能使用(如果有誤請聯系更改)。
Istio可以在命名空間范圍或網格范圍中存儲身份認證策略,使用官網實例sleep訪問httpbin進行測試,訪問過程如下圖所示:
部署官網示例,步驟1:
$ kubectl create ns foo $ kubectl apply -f <(istioctl kube-inject -f samples/httpbin/httpbin.yaml) -n foo $ kubectl apply -f <(istioctl kube-inject -f samples/sleep/sleep.yaml) -n foo $ kubectl create ns bar $ kubectl apply -f <(istioctl kube-inject -f samples/httpbin/httpbin.yaml) -n bar $ kubectl apply -f <(istioctl kube-inject -f samples/sleep/sleep.yaml) -n bar $ kubectl create ns legacy $ kubectl apply -f samples/httpbin/httpbin.yaml -n legacy $ kubectl apply -f samples/sleep/sleep.yaml -n legacy
此時執行,步驟2:
for from in "foo" "bar"; do for to in "foo" "bar"; do kubectl exec $(kubectl get pod -l app=sleep -n ${from} -o jsonpath={.items..metadata.name}) -c sleep -n ${from} -- curl http://httpbin.${to}:8000/ip -s -o /dev/null -w "sleep.${from} to httpbin.${to}: %{http_code}\n"; done; done
返回結果皆為200,目前是未開啟mtls。
網格范圍策略
使用MeshPolicy,沒有目標選擇器部分。可以有最多一個網格范圍的策略在網格中,啟用mtls配置如下:
cat <<EOF | kubectl apply -f - apiVersion: "authentication.istio.io/v1alpha1" kind: "MeshPolicy" metadata: name: "default" spec: peers: - mtls: {} EOF
此時再次執行步驟2則結果都為503,需要增加目標規則配置,如下所示:
cat <<EOF | kubectl apply -f - apiVersion: "networking.istio.io/v1alpha3" kind: "DestinationRule" metadata: name: "default" namespace: "default" spec: host: "*.local" trafficPolicy: tls: mode: ISTIO_MUTUAL EOF
此時再次執行步驟2則結果為200正常。
分析開啟mtls后envoy發生的變化,在listeners的filter鏈中增加了tlsContext相關配置。
//使用istioctl proxy-config分析envoy istioctl proxy-config listeners -n foo httpbin-66dc4dd499-8fjgb --port 8000 -o json //輸出如下: ... "filterChains": [ { "tlsContext": { "commonTlsContext": { "tlsCertificates": [ { "certificateChain": { "filename": "/etc/certs/cert-chain.pem" }, "privateKey": { "filename": "/etc/certs/key.pem" } } ], "validationContext": { "trustedCa": { "filename": "/etc/certs/root-cert.pem" } }, "alpnProtocols": [ "h3", "http/1.1" ] }, "requireClientCertificate": true } ...
注意:當controlPanleAuth配置為None時,只是配置這兩個配置訪問依然為503,原因是控制面板不支持tls配置,如部署影響中有講到,如果為None時也想讓該示例生效,需要增加目標規則,目標規則中指定到控制面板的數據流不開啟mtls,使用明文訪問,如下所示:
cat <<EOF | kubectl apply -f - apiVersion: "networking.istio.io/v1alpha3" kind: "DestinationRule" metadata: name: "istio-system-manage-dr" namespace: "istio-system" spec: host: "*.istio-system.svc.cluster.local" trafficPolicy: tls: mode: DISABLE EOF
當擁有sidecar的應用開啟mtls后想要訪問非Istio服務,也是需要配置tls:DISABLE,如下所示:
cat <<EOF | kubectl apply -f - apiVersion: networking.istio.io/v1alpha3 kind: DestinationRule metadata: name: "httpbin-legacy" spec: host: "httpbin.legacy.svc.cluster.local" trafficPolicy: tls: mode: DISABLE EOF
命名空間范圍策略
具有名稱default且沒有目標選擇器部分。每個命名空間最多只能有一個名稱空間范圍的策略。它使用kind “Policy”,需要指定命名空間名稱,如下所示:
cat <<EOF | kubectl apply -f - apiVersion: "authentication.istio.io/v1alpha1" kind: "Policy" metadata: name: "default" namespace: "foo" spec: peers: - mtls: {} EOF
與網格范圍策略一樣,也需要指定目標規則,如下所示:
cat <<EOF | kubectl apply -f - apiVersion: "networking.istio.io/v1alpha3" kind: "DestinationRule" metadata: name: "default" namespace: "foo" spec: host: "*.foo.svc.cluster.local" trafficPolicy: tls: mode: ISTIO_MUTUAL EOF
開啟命名空間范圍策略只是針對當前命名空間,對于控制面板下的服務沒有任何影響,還是使用明文訪問。
Istio授權功能,基于角色的訪問控制(RBAC),為Istio中服務提供命名空間級別、服務級別、方法級別的訪問控制,特點是:
基于角色的語義,簡單易用。
服務到服務和最終用戶到服務授權。
通過自定義屬性支持(例如條件,角色和角色綁定)提供靈活性。
高性能,因為Istio授權在Envoy上本地執行。
授權架構
用戶使用.yaml配置Istio授權策略,部署完成后同樣存儲在Istio配置存儲,Pilot監聽Istio授權變化,如果發生變化Pilot獲取更新的授權策略,將Istio授權策略分發給與服務實例位于同一位置的Envoy代理,每個Envoy代理都運行一個授權引擎,該引擎在運行時授權請求。當請求到達代理時,授權引擎根據當前授權策略評估請求上下文,并返回授權結果,ALLOW或DENY。
啟用授權
使用RbacConfig對象啟用Istio授權,是一個單例,固定名稱為default,在RbacConfig中可以指定一個mode值,該值可以是:
OFF:禁用Istio授權。
ON:為網格中的所有服務啟用了Istio授權。
ON_WITH_INCLUSION:僅對inclusion字段中指定的服務和命名空間啟用Istio授權。
ON_WITH_EXCLUSION:對網格中的所有服務啟用Istio授權,但exclusion 字段中指定的服務和命名空間除外。
開啟授權,如下所示:
apiVersion: "rbac.istio.io/v1alpha1" kind: RbacConfig metadata: name: default spec: mode: 'ON_WITH_INCLUSION' inclusion: namespaces: ["default"]
當開啟rbacconfig后,正常的bookinfo示例已經不可以訪問,提示“RBAC: access denied“。
授權策略
使用bookinfo測試授權策略,配置策略,使用ServiceRole和ServiceRolebinding:
ServiceRole:定義一組訪問服務的權限。
ServiceRoleBinding:將權限授權給特定主體,例如用戶,組,服務。
ServiceRole
每條規則都以以下標準字段:
services:服務名稱列表。您可以將值設置*為包括指定命名空間中的所有服務。
methods:HTTP方法名稱列表,對于gRPC請求的權限,HTTP謂詞始終是POST。您可以將值設置*為包括所有HTTP方法。
paths:HTTP路徑或gRPC方法。gRPC方法必須采用以下形式/packageName.serviceName/methodName并且區分大小寫。
具體參考官網。
創建一個ServiceRole,如下所示:
apiVersion: "rbac.istio.io/v1alpha1" kind: ServiceRole metadata: name: service-viewer namespace: default spec: rules: - services: ["*"] methods: ["GET"] constraints: - key: "destination.labels[app]" values: ["productpage", "details", "reviews", "ratings"]
允許只讀訪問default命名空間下所有帶有指定標簽的服務。
ServiceRoleBinding
ServiceRoleBinding規范包括兩個部分:
roleRef指的是ServiceRole同一名稱空間中的資源。
subjects分配給該角色的列表。
如下所示:
apiVersion: "rbac.istio.io/v1alpha1" kind: ServiceRoleBinding metadata: name: bind-service-viewer namespace: default spec: subjects: - properties: source.namespace: "istio-system" - properties: source.namespace: "default" roleRef: kind: ServiceRole name: "service-viewer"
將ServiceRole授權給命名空間為“istio-system”和“default”。
看完上述內容,你們對如何深度解析Istio中的安全模塊有進一步的了解嗎?如果還想了解更多知識或者相關內容,請關注億速云行業資訊頻道,感謝大家的支持。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。