Kubernetes RBAC分析變得容易
Krane是一個簡單的Kubernetes RBAC靜態分析工具。它確定了K8S RBAC設計中的潛在安全風險,並就如何減輕它們提出了建議。 Krane儀表板呈現當前的RBAC安全姿勢,並讓您瀏覽其定義。
您可以通過在目標Kubernetes群集中安裝Helm Chart或使用Docker在本地運行它來開始使用Krane。
假設您在計算機上安裝了Helm CLI。
$ helm repo add appvia https://appvia.github.io/krane
$ helm repo update
$ helm install krane appvia/krane --namespace krane --create-namespace遵循有關如何向前方的Krane儀表板的Helm圖表安裝輸出。
假設您的碼頭機在本地計算機上運行。如果還沒有安裝Docker-Compose。
Krane取決於Redisgraph。 docker-compose堆棧定義了在本地構建和運行Krane服務所需的所有內容。它也將照顧其重新依賴。
docker-compose up -d
如果在本地機器上尚未存在, Krane Docker映像將自動進行預構建。
請注意,在本地運行docker-compose時, Krane不會自動啟動RBAC報告和儀表板。取而代之的是,默認情況下,容器將睡覺24小時 - 可以在docker-compose.override.yml中調整此值。執行到運行的Krane容器中以運行命令。本地docker-compose還將在容器內安裝Kube Config( ~/.kube/config ),使您能夠針對您已經可以訪問的任何Kubernetes群集運行報告。
執行運行的Krane容器。
docker-compose exec krane bash進入容器後,您可以開始使用krane命令。嘗試krane -help 。
krane -h檢查正在運行哪些服務和相關端口:
docker-compose ps
阻止Krane及其依賴服務:
docker-compose down
$ krane --help
NAME:
krane
DESCRIPTION:
Kubernetes RBAC static analysis & visualisation tool
COMMANDS:
dashboard Start K8s RBAC dashboard server
help Display global or [command] help documentation
report Run K8s RBAC report
GLOBAL OPTIONS:
-h, --help
Display help documentation
-v, --version
Display version information
-t, --trace
Display backtrace when an error occurs
AUTHOR:
Marcin Ciszak <[email protected]> - Appvia Ltd <appvia.io>
kubectl上下文要針對運行群集運行報告,您必須提供kubectl上下文
krane report -k <context>
如果您計劃針對多個群集運行該工具,並且為每個群集名稱分別使用-c <cluster-name> RBAC圖。
要針對本地RBAC YAML/JSON文件運行報告,請提供目錄路徑
krane report -d </path/to/rbac-directory>
注意: Krane期望在指定目錄路徑中存在以下文件(YAML或JSON格式):
如果不使用POD安全策略,則可以通過手動創建一個使用以下內容的psp文件來繞過上述期望:
{
"items" : []
}請注意,在Kubernetes v1.21中棄用了PodSecurityPolicy ,並從v1.25中的Kubernetes中刪除。
從Kubernetes群集中運行的容器運行報告
krane report --incluster
注意: Krane使用的服務帳戶將需要訪問RBAC資源。有關詳細信息,請參見先決條件。
驗證RBAC定義是CI/CD管道中的一步
krane report --ci -d </path/to/rbac-directory>
注意: Krane希望在本地存儲的RBAC資源文件中遵循某些命名約定。請參見上面的部分。為了運行krane命令,建議CI執行者參考quay.io/appvia/krane:latest docker image。
CI模式由--ci標誌啟用。當檢測到一個或多個危險時, Krane將返回非零狀態代碼以及破壞風險規則的詳細信息。
要查看RBAC Facets樹,網絡圖和最新報告發現,您需要首先啟動儀表板服務器。
krane dashboard
群集標誌-c <cluster-name>如果要使用特定群集名稱運行儀表板,則可以傳遞。儀表板將查找與文件系統中被緩存的指定群集名稱相關的數據。
上面的命令將在默認端口8000上啟動本地Web服務器,並顯示儀表板鏈接。
Krane Indexes RBAC在Redisgraph中引起了影響。這使我們能夠有效地查詢依賴關係網絡,並簡單地使用Redisgraph支持的Cypherql的子集。
相關RBAC對象的圖中創建了以下節點:
Psp圍繞POD安全策略圍繞屬性的PSP節點。僅在使用K8 <1.25時適用。Rule - 規則節點代表圍繞Kubernetes資源的訪問控制規則。Role - 角色節點代表給定的角色或聚類。 kind屬性定義角色類型。Subject - 主題代表集群中的所有可能的參與者( kind :用戶,組和serviceaccount)Namespace -Kubernetes名稱空間節點。 :SECURITY - 定義規則和PSP節點之間的鏈接。僅在使用K8 <1.25時適用。:GRANT - 定義與該角色相關的角色和規則之間的聯繫。:ASSIGN - 定義Actor(主題)和給定的角色/簇(角色節點)之間的鏈接。:RELATION - 定義兩個不同的參與者(主題)節點之間的聯繫。:SCOPE - 定義角色和名稱空間節點之間的鏈接。:ACCESS - 定義主題和名稱空間節點之間的鏈接。:AGGREGATE - 定義簇共簇(一個聚合另一個A-(aggregates)->B另一個)之間的鏈接:COMPOSITE - 定義聚類之間的鏈接(一個聚集在另一個簇中) A<-(is a composite of)-B所有邊緣都是雙向的,這意味著可以在任一方向上查詢圖。唯一的例外是:AGGREGATE和:COMPOSITE關係,儘管與相同的邊緣節點有關。
為了直接查詢圖形,您可以將其執行到運行的redisgraph容器中,啟動redis-cli並運行任意查詢。遵循官方說明以獲取命令的示例。
您也可以從Krane Console查詢該圖。首先執行運行Krane容器,然後
# Start Krane console - this will open interactive ruby shell with Krane code preloaded
console
# Instantiate Graph client
graph = Krane :: Clients :: RedisGraph . client cluster : 'default'
# Run arbitrary CypherQL query against indexed RBAC Graph
res = graph . query ( %Q(
MATCH (r:Rule {resource: "configmaps", verb: "update"})<-[:GRANT]-(ro:Role)<-[:ASSIGN]-(s:Subject)
RETURN s.kind as subject_kind, s.name as subject_name, ro.kind as role_kind, ro.name as role_name) )
# Print the results
res . print_resultset # Results...
+----------------+--------------------------------+-----------+------------------------------------------------+
| subject_kind | subject_name | role_kind | role_name |
+----------------+--------------------------------+-----------+------------------------------------------------+
| ServiceAccount | bootstrap-signer | Role | system:controller:bootstrap-signer |
| User | system:kube-controller-manager | Role | system::leader-locking-kube-controller-manager |
| ServiceAccount | kube-controller-manager | Role | system::leader-locking-kube-controller-manager |
| User | system:kube-scheduler | Role | system::leader-locking-kube-scheduler |
| ServiceAccount | kube-scheduler | Role | system::leader-locking-kube-scheduler |
+----------------+--------------------------------+-----------+------------------------------------------------+
注意:上面的示例查詢將選擇具有分配的角色/群集授予訪問update configmaps所有主題。
RBAC風險規則在規則文件中定義。每個規則的結構在很大程度上是自我解釋的。可以通過在Custom規則文件中添加額外的自定義規則來擴展內置集 /覆蓋。
宏是一組常見/共享屬性的“容器”,並由一個或多個風險規則引用。如果您選擇在給定的風險規則中使用宏,則需要按名稱引用它,例如macro: <macro-name> 。請注意,引用macro定義的屬性將優先於規則級別上定義的相同屬性。
宏可以包含以下任何屬性:
query - 重新查詢。比template優先。需要定義writer 。writer - 作者是用於格式query結果集的紅寶石表達式。作者優先於template 。template - 內置查詢/作者模板名稱。如果未指定query和writer ,則選擇的查詢生成器將與匹配的作者一起使用。 規則可以包含以下任何屬性:
id [必需]規則ID是唯一的規則標識符。
group_title [必需]標題適用於屬於此風險檢查的所有項目。
severity [必需]的嚴重性,作為:危險,警告,:信息之一。
info [必需]有關如何減輕風險的檢查和建議的文本信息。
query [conditonal] redisgraph查詢。
template優先。需要定義writer 。 writer [conditonal]作者是用於格式查詢結果集的紅寶石表達式。
template 。需要定義query 。 template [conditonal]內置查詢/作者模板名稱。如果未指定query和writer ,則選擇的查詢生成器將與匹配的作者一起使用。
某些內置模板需要在單個規則級別上指定match_rules屬性,以構建正確的查詢。當前需要它的模板:
match_rules指定的訪問規則構建多匹配圖查詢。生成的圖形查詢返回以下列: match_rules [conditonal] template依賴匹配規則以構建查詢時需要。
match_rules :
- resources : ['cronjobs']
verbs : ['update'] custom_params [可選]要在規則query和writer表示中評估和替換的自定義鍵值對列表。
custom_params :
- attrA : valueA
- attrB : valueB{{attrA}}和{{attrB}}鍵的模板佔位符分別將分別用valueA和valueB替換。 threshold [可選]數值。當定義時,此功能將作為模板佔位符{{threshold}}在writer表達式中可用。
macro [可選]引用指定宏定義的常見參數。
disabled [可選]設置為true時,它將禁用給定規則並將其排除在評估之外。默認情況下,所有規則均已啟用。
- id : verbose-rule-example
group_title : Example rule
severity : :danger
info : Risk description and instructions on how to mitigate it goes here
query : |
MATCH
(s:Subject)-[:ACCESS]->(ns:Namespace)
WHERE
NOT s.name IN {{whitelist_subject_names}}
RETURN
s.kind as subject_kind,
s.name as subject_name,
COLLECT(ns.name) as namespace_names
ORDER BY
subject_kind,
subject_name,
namespace_names DESC
threshold : 2
writer : |
if result.namespace_names.count > {{threshold}}
"#{result.subject_kind} #{result.subject_name} can access namespaces: #{result.namespace_names.join(', ')}"
end
disabled : true上面的示例明確定義了用於評估RBAC風險的圖形query ,以及用於格式查詢結果集的writer表達式。查詢只需選擇所有Subjects (不包括白名單)和他們可以訪問的Namespaces 。請注意,結果集將僅包括具有訪問2以上名稱空間的Subjects (在那裡註意到threshold值值?)。最後writer的表達式將被捕獲為格式化結果項目輸出。
writer可以通過result對象訪問結果設置的項目, result.subject_name result.subject_kind方法匹配查詢返回的元素。
筆記:
{{threshold}} writer表達式中的佔位符將被規則的threshold關鍵字值代替。{{whitelist_subject_names}}表示一個自定義字段,該字段將與給定規則id定義的白色列表值插值。如果未在白名單中定義佔位符字段名稱,則默認情況下將用空數組['']代替。在下面了解有關白名單的更多信息。 內置模板可顯著簡化風險規則的定義,但是,它們旨在提取特定的信息,並且可能不適合您的自定義規則。如果您發現自己在多個規則中重複使用相同的query或writer表達式,則應考慮將其提取到macro ,並在自定義規則中引用以使其乾燥。
- id : risky-any-verb-secrets
group_title : Risky Roles/ClustersRoles allowing all actions on secrets
severity : :danger
info : Roles/ClusterRoles allowing all actions on secrets. This might be dangerous. Review listed Roles!
template : risky-role
match_rules :
- resources : ['secrets']
verbs : ['*']上面的示例顯示了內置規則之一。它引用了risky-role模板,該模板將在處理後通過在規則評估觸發前註入query和writer表達方式來擴展規則。 match_rules將用於構建適當的匹配查詢。
可選的白名單包含一組自定義定義的屬性名稱和相應的(白名單)值。
屬性名稱及其值是任意的。它們在白名單文件中定義,並分為三個單獨的部分:
global - 頂級範圍。此處定義的自定義屬性將適用於所有風險規則,而不論群集名稱如何。common - 自定義屬性將範圍為特定的風險規則id而不管群集名稱如何。cluster (帶有群集名稱的嵌套列表) - 定制屬性將適用於給定群集名稱的特定風險規則id 。每個風險規則在評估後,都將嘗試插入query中使用的所有參數佔位持有人,例如{{your_whitelist_attribute_name}} 。如果占位符參數名稱(即雙捲髮支架之間的名稱)匹配該風險規則id的任何白名單屬性名稱,則將其替換為其計算值。如果找不到給定佔位持有人的值,它將用['']代替。
下面的白名單示例為具有id屬性值匹配的“ Some-strik-Rule-id”的風險規則產生以下placeholder-key => value映射
{{whitelist_role_names}} => ['acp:prometheus:operator']
{{whitelist_subject_names}} => ['privileged-psp-user', 'another-user']
在自定義圖查詢中使用時,上面的佔位符鍵將在風險規則評估時被各自的值所取代。
例子:
---
rules :
global : # global scope - applies to all risk rule and cluster names
whitelist_role_names : # custom attribute name
- acp:prometheus:operator # custom attribute values
common : # common scope - applies to specific risk rule id regardless of cluster name
some-risk-rule-id : # this corresponds to risk rule id defined in config/rules.yaml
whitelist_subject_names : # custom attribute name
- privileged-psp-user # custom attribute values
cluster : # cluster scope - applies to speciifc risk rule id and cluster name
default : # example cluster name
some-risk-rule-id : # risk rule id
whitelist_subject_names : # custom attribute nane
- another-user # custom attribute values Krane可以輕鬆地部署到本地或遠程Kubernetes群集。
Kubernetes名稱空間,服務帳戶以及適當的RBAC必須存在於集群中。請參閱參考的先決條件。
默認情況下, Krane Entrypoint執行bin/cluster-run,該bin/clustruster-run等待redisgraph實例在啟動RBAC報告循環和儀表板Web服務器之前就可以使用。
您可以通過以下環境變量控制集群內執行的某些方面:
KRANE_REPORT_INTERVAL在RBAC靜態分析報告運行中以秒為單位定義間隔。默認值: 300 (以秒為單位,即5分鐘)。KRANE_REPORT_OUTPUT定義RBAC風險報告輸出格式。可能的值:json , :yaml ,: :none 。默認值:: :json 。在開始之前,您需要以下工具:
安裝頭盔圖:
$ helm repo add appvia https://appvia.github.io/krane
$ helm repo update
$ helm install krane appvia/krane --namespace krane --create-namespace有關其他可設置的選項和參數的詳細信息,請參見values.yaml文件。
kubectl create
--context < docker-desktop >
--namespace krane
-f k8s/redisgraph-service.yaml
-f k8s/redisgraph-deployment.yaml
-f k8s/krane-service.yaml
-f k8s/krane-deployment.yaml請注意,默認情況下, Krane儀表板服務不會公開!
kubectl port-forward svc/krane 8000
--context= < docker-desktop >
--namespace=krane
# Open Krane dashboard at http://localhost:8000您可以在K8S目錄中找到示例部署清單。
修改您的部署所需的清單,確保您在其部署文件中引用Krane Docker映像的正確版本。有關可用標籤,請參見Krane Docker註冊表,或者只使用latest 。
如果您的K8S群集隨附內置的Kubernetes Controller支持( docker-desktop默認支持它),則您可以將Krane及其依賴項用單個Docker stack命令:
docker stack deploy
--orchestrator kubernetes
--namespace krane
--compose-file docker-compose.yml
--compose-file docker-compose.k8s.yml krane注意:在運行上面的命令之前,請確保正確設置當前的kube上下文!
現在,應用程序堆棧應部署到Kubernetes群集,並準備好所有服務。請注意, Krane將自動啟動其報告循環和儀表板服務器。
docker stack services --orchestrator kubernetes --namespace krane krane上面的命令將產生以下輸出:
ID NAME MODE REPLICAS IMAGE PORTS
0de30651-dd5 krane_redisgraph replicated 1/1 redislabs/redisgraph:1.99.7 *:6379->6379/tcp
aa377a5f-62b krane_krane replicated 1/1 quay.io/appvia/krane:latest *:8000->8000/tcp
通過訪問http:// localhost:8000檢查您的Kubernetes群集RBAC安全姿勢。
請注意,對於遠程群集部署
kubectl --context=my-remote-cluster --namespace=krane port-forward svc/krane 8000刪除堆棧
docker stack rm krane
--orchestrator kubernetes
--namespace krane克蘭(Krane)將通過其鬆弛整合通知您有關中和高嚴重性的異常。
要啟用通知在config/config.yaml文件中指定Slack webhook_url & channel ,或者可以設置SLACK_WEBHOOK_URL和SLACK_CHANNEL環境變量。環境變量將優先於配置文件值。
本節介紹了實現本地發展的步驟。
使用
./bin/setupKrane取決於Redisgraph。 docker-compose是使Krane在本地運行的依賴關係的最快方法。
docker-compose up -d redisgraph檢查Redisgraph服務已升起:
docker-compose ps停止服務:
docker-compose down此時,您應該能夠通過在本地殼中調用命令來修改Krane代碼庫和測試結果。
$ ./bin/krane --help # to get help
$ ./bin/krane report -k docker-desktop # to generate your first report for
# local docker-desktop k8s cluster
...啟用儀表板UI本地開發模式
$ cd dashboard
$ npm install
$ npm start這將自動啟動儀表板服務器,打開默認瀏覽器並註意源文件更改。
Krane獲得了改善Skaffold的開發人員經驗的預先配置。通過在本地或遠程Kubernetes群集中運行整個堆棧來迭代項目並驗證應用程序,這變得更加容易。代碼熱填充使本地更改自動傳播到運行的容器,以更快地開發生命週期。
skaffold dev --kube-context docker-desktop --namespace krane --port-forward與本地進行測試
bundle exec rspec我們歡迎社區的任何貢獻!請查看我們的貢獻指南,以獲取有關如何入門的更多信息。如果您使用Krane ,發現它有用或對Kubernetes安全性感興趣,請通過主演和觀看此倉庫來告知我們。謝謝!
加入我們社區渠道的討論。
克蘭(Krane)是一個社區項目,我們歡迎您的貢獻。要報告錯誤,建議改進或請求新功能,請打開GitHub問題。有關如何提供幫助的更多信息,請參閱我們的貢獻指南。
有關我們的項目計劃的詳細信息,請參見我們的路線圖。
作者:Marcin Ciszak [email protected]
版權(C)2019-2020 Appvia Ltd
該項目是根據Apache許可證(版本2.0)分發的。