Kubernetes RBAC 분석이 쉽게 만들어졌습니다
Krane 은 간단한 Kubernetes RBAC 정적 분석 도구입니다. K8S RBAC 설계의 잠재적 보안 위험을 식별하고이를 완화하는 방법에 대한 제안을합니다. Krane Dashboard는 현재 RBAC 보안 자세를 제공하고 정의를 탐색 할 수 있습니다.
대상 Kubernetes 클러스터의 Helm 차트를 통해 설치하거나 Docker와 함께 로컬로 실행하여 Krane을 시작할 수 있습니다.
컴퓨터에 Helm CLI를 설치 한 것으로 가정합니다.
$ helm repo add appvia https://appvia.github.io/krane
$ helm repo update
$ helm install krane appvia/krane --namespace krane --create-namespaceKrane 대시 보드 포트를 포트하는 방법에 대한 Helm 차트 설치 출력을 따르십시오.
로컬 컴퓨터에서 Docker를 실행한다고 가정합니다. 아직하지 않은 경우 Docker-Compose를 설치하십시오.
크레인은 redisgraph에 의존합니다. docker-compose Stack은 로컬에서 Krane 서비스를 구축하고 실행하는 데 필요한 모든 것을 정의합니다. 또한 RedisGraph 의존성을 처리합니다.
docker-compose up -d
로컬 컴퓨터에 아직 존재하지 않으면 Krane Docker 이미지는 자동으로 사전 구축됩니다.
docker-compose 로컬로 실행할 때 Krane은 RBAC 보고서 와 대시 보드를 자동으로 시작하지 않습니다. 대신, 컨테이너는 기본적으로 24 시간 동안 잠을 자게됩니다.이 값은 docker-compose.override.yml 에서 조정할 수 있습니다. 실행되는 크레인 컨테이너로 실행하여 명령을 실행합니다. 로컬 docker-compose 컨테이너 내부에 Kube Config ( ~/.kube/config )를 마운트하여 이미 액세스 할 수있는 Kubernetes 클러스터에 대한 보고서를 실행할 수 있습니다.
실행중인 크레인 컨테이너로 실행하십시오.
docker-compose exec krane bash 컨테이너에 들어가면 krane 명령을 사용하여 시작할 수 있습니다. krane -help 사용해보십시오.
krane -h실행중인 서비스와 관련 포트를 검사하기 위해 :
docker-compose ps
크레인 과 의존성 서비스를 중지하려면 :
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>
도구를 여러 클러스터에 대해 도구를 실행하고 각 클러스터 이름에 대해 RBAC 그래프를 별도로 인덱싱하려는 경우 -c <cluster-name> 플래그를 통과 할 수도 있습니다.
로컬 RBAC YAML/JSON 파일에 대한 보고서를 실행하려면 디렉토리 경로 제공
krane report -d </path/to/rbac-directory>
참고 : Krane은 다음 파일 (Yaml 또는 JSON 형식)이 지정된 디렉토리 경로에 참석할 것으로 기대합니다.
POD 보안 정책이 사용되지 않으면 다음 내용으로 psp 파일을 수동으로 작성하여 위의 기대치를 우회 할 수 있습니다.
{
"items" : []
} PodSecurityPolicy Kubernetes v1.21에서 더 이상 사용되지 않았으며 v1.25의 Kubernetes에서 제거되었습니다.
Kubernetes 클러스터에서 실행되는 컨테이너에서 보고서를 실행하려면
krane report --incluster
참고 : Krane 이 사용하는 서비스 계정은 RBAC 자원에 대한 액세스가 필요합니다. 자세한 내용은 전제 조건을 참조하십시오.
CI/CD 파이프 라인의 단계로서 RBAC 정의를 검증하려면
krane report --ci -d </path/to/rbac-directory>
참고 : Krane은 로컬로 저장된 RBAC 리소스 파일에 대한 특정 명명 규칙을 준수 할 것으로 예상합니다. 위의 섹션을 참조하십시오. krane 명령을 실행하려면 CI Executor가 quay.io/appvia/krane:latest Docker Image를 참조하는 것이 좋습니다.
CI 모드는 --ci 플래그에 의해 활성화됩니다. Krane은 하나 이상의 위험이 감지 될 때 비 위험 규칙에 대한 세부 사항과 함께 비 지위 코드를 반환합니다.
RBAC 측면 트리, 네트워크 그래프 및 최신 보고서 결과를 보려면 먼저 대시 보드 서버를 시작해야합니다.
krane dashboard
클러스터 플래그 -c <cluster-name> 특정 클러스터 이름에 대해 대시 보드를 실행하려면 전달 될 수 있습니다. 대시 보드는 파일 시스템에 캐시 된 지정된 클러스터 이름과 관련된 데이터를 찾습니다.
위의 명령은 기본 포트 8000 에서 로컬 웹 서버를 시작하고 대시 보드 링크를 표시합니다.
크레인은 redisgraph의 rbac endites를 색인합니다. 이를 통해 RedisGraph에서 지원하는 CypherQL의 하위 세트를 효율적으로 사용하여 종속성 네트워크를 쿼리 할 수 있습니다.
다음 노드는 관련 RBAC 객체의 그래프에서 생성됩니다.
Psp POD 보안 정책 주변의 속성을 포함하는 PSP 노드. K8S <1.25로 작업 할 때만 적용됩니다.Rule - 규칙 노드는 Kubernetes 리소스에 대한 액세스 제어 규칙을 나타냅니다.Role - 역할 노드는 주어진 역할 또는 클러스터 롤을 나타냅니다. kind 속성은 역할 유형을 정의합니다.Subject - 피험자는 클러스터의 가능한 모든 행위자를 나타냅니다 ( kind : 사용자, 그룹 및 ServiceAccount)Namespace -Kubernetes 네임 스페이스 노드. :SECURITY - 규칙과 PSP 노드 사이의 링크를 정의합니다. K8S <1.25로 작업 할 때만 적용됩니다.:GRANT 해당 역할과 관련된 역할과 규칙 사이의 연결을 정의합니다.:ASSIGN - 액터 (주제)와 주어진 역할/클러스터 롤 (역할 노드) 사이의 링크를 정의합니다.:RELATION - 두 개의 다른 액터 (주제) 노드 사이의 링크를 정의합니다.:SCOPE 역할과 네임 스페이스 노드 사이의 링크를 정의합니다.:ACCESS 제목과 네임 스페이스 노드 사이의 링크를 정의합니다.:AGGREGATE -클러스터 론 (하나의 클러스터 롤 응집체) 사이의 링크를 정의합니다 A-(aggregates)->B:COMPOSITE 클러스터 론 사이의 링크를 정의합니다 (하나의 클러스터 롤은 다른 하나에서 집계 될 수 있음) A<-(is a composite of)-B 모든 가장자리는 양방향이므로 그래프는 어느 방향 으로든 쿼리 될 수 있습니다. 예외는 다음과 같습니다 :AGGREGATE 및 :COMPOSITE 관계.
그래프를 직접 쿼리하려면 실행중인 redisgraph 컨테이너로 실행할 수 있고 redis-cli 시작하고 임의의 쿼리를 실행할 수 있습니다. 명령의 예에 대한 공식 지침을 따르십시오.
크레인 콘솔에서 그래프를 쿼리 할 수도 있습니다. 그런 다음 먼저 크레인 컨테이너를 실행합니다
# 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 위험 규칙은 규칙 파일에 정의되어 있습니다. 각 규칙의 구조는 대체로 자기 설명 적입니다. Cutom 규칙 파일에 추가 사용자 정의 규칙을 추가하여 내장 세트를 확장 / 재정의 할 수 있습니다.
매크로는 일련의 공통/공유 속성 세트의 "컨테이너"이며 하나 이상의 위험 규칙에 의해 참조됩니다. 주어진 위험 규칙에서 매크로 macro: <macro-name> 사용하기로 선택한 경우, 이름으로 참조해야합니다. 참조 macro 에 정의 된 속성은 규칙 수준에 정의 된 동일한 속성보다 우선합니다.
매크로는 다음 속성 중 하나를 포함 할 수 있습니다.
query - redisgraph 쿼리. template 보다 우선합니다. writer 정의해야합니다.writer -Writer는 query 결과 세트를 포맷하는 데 사용되는 루비 표현입니다. 작가는 template 보다 우선합니다.template - 내장 쿼리/라이터 템플릿 이름. query & writer 지정되지 않으면 선택한 쿼리 생성기가 일치하는 작가와 함께 사용됩니다. 규칙은 다음 속성 중 하나를 포함 할 수 있습니다.
id [필수] 규칙 ID는 고유 한 규칙 식별자입니다.
group_title [필수] 제목이 위험 점검에 해당하는 모든 품목에 적용됩니다.
severity [필수] 심각도는 : 위험, : 경고, : 정보.
info [필수] 확인에 대한 텍스트 정보 및 위험을 완화하는 방법에 대한 제안.
query [Conditonal] redisgraph 쿼리.
template 보다 우선합니다. writer 정의해야합니다. writer [Conditonal] Writer는 쿼리 결과 세트를 형식화하는 데 사용되는 루비 표현입니다.
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 [선택 사항] 숫자 값. 정의되면 이것은 writer 표현식에서 템플릿 자리 표시 자 {{threshold}} 로 사용할 수있게됩니다.
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 값이 나타나셨습니까?). Last writer 의 표현식은 형식화 된 결과 항목 출력으로 캡처됩니다.
writer result 객체를 통해 결과 세트 항목 result.subject_name 액세스 할 수 있습니다 result.subject_kind
메모:
{{threshold}} writer Expression의 자리 표시자는 규칙의 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 : ['*'] 위의 예는 내장 규칙 중 하나를 보여줍니다. 그것은 규칙 평가 트리거 전에 query 와 writer 표현을 주입하여 처리시 규칙을 확장 할 risky-role 템플릿을 참조합니다. match_rules 적절한 일치 쿼리를 빌드하는 데 사용됩니다.
옵션 화이트리스트에는 정의 된 속성 이름 세트와 각각의 (화이트리스트) 값이 포함되어 있습니다.
속성 이름과 그 값은 임의적입니다. 그것들은 화이트리스트 파일에 정의되어 있으며 세 가지 별도 섹션으로 나뉩니다.
global - 최상위 범위. 여기에 정의 된 사용자 정의 속성은 클러스터 이름에 관계없이 모든 위험 규칙에 적용됩니다.common - 사용자 정의 속성은 클러스터 이름에 관계없이 특정 위험 규칙 id 에 스코핑됩니다.cluster (중첩 클러스터 이름 목록 포함) - 사용자 정의 속성은 주어진 클러스터 이름의 특정 위험 규칙 id 에 적용됩니다. 평가시 각 위험 규칙은 query 에 사용되는 모든 매개 변수 자리 표시 자 (예 {{your_whitelist_attribute_name}} 보간하려고 시도합니다. 자리 표시 자 매개 변수 이름 (예 : 이중 곱슬 괄호 사이의 이름)이 해당 위험 규칙 id 의 화이트리스트 속성 이름과 일치하면 계산 된 값으로 대체됩니다. 주어진 자리 표시 자에 대한 값이 발견되지 않으면 [''] 로 대체됩니다.
아래의 Whitelist 아래의 Whitelist는 다음 placeholder-key => value id 속성 값이 "일부 위험-규칙 ID" 와 일치하는 위험 규칙에 대한 값 매핑을 생성합니다.
{{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 크레인은 로컬 또는 원격 Kubernetes 클러스터에 쉽게 배치 할 수 있습니다.
Kubernetes 네임 스페이스, 적절한 RBAC와 함께 서비스 계정이 클러스터에 있어야합니다. 참조는 전제 조건을 참조하십시오.
Default Krane Entrypoint는 Bin/In-Cluster-Run을 실행하여 RBAC 보고서 루프 및 대시 보드 웹 서버를 시작하기 전에 RedisGraph 인스턴스를 사용할 수 있도록 기다립니다.
다음 환경 변수로 클러스터 내 실행의 특정 측면을 제어 할 수 있습니다.
KRANE_REPORT_INTERVAL RBAC 정적 분석 보고서 실행의 경우 간격을 몇 초 만에 정의합니다. 기본값 : 300 (몇 초, 즉 5 분).KRANE_REPORT_OUTPUT RBAC 위험 보고서 출력 형식을 정의합니다. 가능한 값 :json , :yaml , :none . 기본값 : :json .시작하기 전에 다음 도구가 필요합니다.
Helm 차트 설치 :
$ 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.yamlKrane Dashboard Service는 기본적으로 노출되지 않습니다!
kubectl port-forward svc/krane 8000
--context= < docker-desktop >
--namespace=krane
# Open Krane dashboard at http://localhost:8000K8S 디렉토리에서 예제 배포 매니페스트를 찾을 수 있습니다.
배포에 필요한대로 매니페스트를 수정하여 배포 파일에서 올바른 버전의 Krane Docker Image를 참조하십시오. 사용 가능한 태그는 Krane Docker Registry를 참조하거나 latest 사용하십시오.
K8S 클러스터가 내장 Compose-on-Kubernetes 컨트롤러 지원 ( docker-desktop 기본적으로 지원)이 제공되면 단일 Docker 스택 명령으로 Krane 및 해당 종속성을 배포 할 수 있습니다.
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 보안 자세를 확인하십시오.
원격 클러스터 배포의 경우 먼저 Krane Service를 포트로 포트해야 할 것입니다.
kubectl --context=my-remote-cluster --namespace=krane port-forward svc/krane 8000스택을 삭제합니다
docker stack rm krane
--orchestrator kubernetes
--namespace krane크레인은 느슨한 통합을 통해 중간 및 높은 심각도의 감지 된 이상에 대해 알려줍니다.
알림을 활성화하려면 config/config.yaml 파일에 slack webhook_url & channel 지정하거나 SLACK_WEBHOOK_URL 및 SLACK_CHANNEL 환경 변수를 모두 설정하십시오. 환경 변수는 구성 파일 값보다 우선합니다.
이 섹션에서는 지역 개발을 가능하게하는 단계를 설명합니다.
크레인 코드 종속성을 설치하십시오
./bin/setup 크레인은 redisgraph에 의존합니다. docker-compose Krane 의 종속성을 로컬로 실행하는 가장 빠른 방법입니다.
docker-compose up -d redisgraphRedisGraph 서비스를 검사하려면 다음과 같습니다.
docker-compose ps서비스 중지 :
docker-compose down이 시점에서 로컬 쉘에서 명령을 호출하여 크레인 코드베이스 및 테스트 결과를 수정할 수 있어야합니다.
$ ./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 클러스터에서 전체 스택을 실행하여 프로젝트를 반복하고 응용 프로그램을 검증하는 것이 쉬워졌습니다. Code Hot Reload를 사용하면 로컬 변경이 더 빠른 개발 수명주기를 위해 러닝 컨테이너로 자동 전파 될 수 있습니다.
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에 따라 배포됩니다.