Análise RBAC de Kubernetes facilitada facilitada
Krane é uma ferramenta de análise estática simples do Kubernetes RBAC. Ele identifica possíveis riscos de segurança no design do K8S RBAC e faz sugestões sobre como mitigá -los. O painel Krane apresenta a postura atual de segurança do RBAC e permite navegar por sua definição.
Você pode começar com Krane instalando -o via gráfico de helm em seu cluster Kubernetes de destino ou executando -o localmente com o Docker.
Supõe -se que você tenha instalado a CLI da sua máquina.
$ helm repo add appvia https://appvia.github.io/krane
$ helm repo update
$ helm install krane appvia/krane --namespace krane --create-namespaceSiga a saída de instalação do gráfico do helmo em como o painel de Krane para a porta.
Supõe -se que você tenha o Docker em execução em sua máquina local. Instale o Docker-Compose, se você ainda não o fez.
Krane depende do RedisGraph. A pilha docker-compose define tudo o que é necessário para construir e executar o serviço Krane localmente. Também cuidará de sua dependência do RedisGraph.
docker-compose up -d
A imagem do Krane Docker será pré-construída automaticamente, se ainda não estiver presente na máquina local.
Observe que, ao executar docker-compose localmente, o Krane não iniciará o relatório e o painel do RBAC automaticamente. Em vez disso, o contêiner dormirá por 24h por padrão - esse valor pode ser ajustado no docker-compose.override.yml . Executão em um contêiner Krane em execução para executar comandos. docker-compose local também montará o Kube Config ( ~/.kube/config ) dentro do contêiner, permitindo que você execute relatórios contra quaisquer clusters Kubernetes aos quais você já tenha acesso.
Executivo em um contêiner Krane em execução.
docker-compose exec krane bash Uma vez no contêiner, você pode começar a usar comandos krane . Experimente krane -help .
krane -hPara inspecionar quais serviços estão em execução e as portas associadas:
docker-compose ps
Para parar Krane e seus serviços de dependência:
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>
kubectlPara executar um relatório contra um cluster em execução, você deve fornecer um contexto Kubectl
krane report -k <context>
Você também pode passar -c <cluster-name> Sinalizador se planeja executar a ferramenta contra vários clusters e o gráfico RBAC indexado separadamente para cada nome de cluster.
Para executar um relatório contra os arquivos locais do RBAC YAML/JSON, forneça um caminho de diretório
krane report -d </path/to/rbac-directory>
Nota: Krane espera que os seguintes arquivos (no formato YAML ou JSON) estejam presentes no caminho do diretório especificado:
Se as políticas de segurança do POD não estiverem em uso, você poderá ignorar a expectativa acima, criando um arquivo psp manualmente com o seguinte conteúdo:
{
"items" : []
} Nota, PodSecurityPolicy foi descontinuado em Kubernetes v1.21 e removido de Kubernetes em v1.25.
Para executar um relatório de um contêiner em cluster Kubernetes
krane report --incluster
NOTA: A conta de serviço usada por Krane exigirá acesso aos recursos do RBAC. Veja os pré -requisitos para obter detalhes.
Para validar a definição do RBAC como uma etapa no pipeline CI/CD
krane report --ci -d </path/to/rbac-directory>
Nota: Krane espera que certa convenção de nomenclatura seja seguida para arquivos de recursos RBAC armazenados localmente. Veja a seção acima. Para executar os comandos krane , é recomendável que o CI Executor referências quay.io/appvia/krane:latest Docker Image.
O modo CI é ativado pelo sinalizador --ci . Krane retornará o código de status não zero, juntamente com os detalhes das regras de risco quando um ou mais perigos forem detectados.
Para visualizar a árvore das facetas RBAC, o gráfico de rede e as descobertas mais recentes do relatório, você precisa iniciar o servidor do painel primeiro.
krane dashboard
Sinalizador de cluster -c <cluster-name> pode ser passado se você quiser executar o painel em relação ao nome específico do cluster. O painel procurará dados relacionados ao nome do cluster especificado, que é armazenado em cache no sistema de arquivos.
O comando acima iniciará o servidor Web local na porta 8000 padrão e exibirá o link do painel.
Krane Indexes RBAC entita no RedisGraph. Isso nos permite consultar a rede de dependências com eficiência e simplesmente usar o subconjunto de CypherQL suportado pelo RedisGraph.
Os seguintes nós são criados no gráfico para os objetos RBAC relevantes:
Psp - Um nó PSP que contém atributos em torno da Política de Segurança de Pod. Somente aplicável ao trabalhar com K8S <1,25.Rule - O nó da regra representa a regra de controle de acesso em torno dos recursos da Kubernetes.Role - O nó de função representa uma determinada função ou clusterRole. Atributo kind define tipo de função.Subject - Assunto representa todos os atores possíveis no cluster ( kind : usuário, grupo e serviceAccount)Namespace Kubernetes Kubernetes. :SECURITY - define um link entre a regra e os nós PSP. Somente aplicável ao trabalhar com K8S <1,25.:GRANT - define um vínculo entre a função e a regra associada a essa função.:ASSIGN - define um link entre um ator (sujeito) e dado função/clusterRole (nó de função).:RELATION - define um link entre dois nós de ator (sujeito) diferentes.:SCOPE - define um link entre os nós de função e namespace.:ACCESS - define um link entre os nós do assunto e do namespace.:AGGREGATE -define um vínculo entre clusterroles (um clusterrole agrega outro) A-(aggregates)->B:COMPOSITE -define um link entre clusterroles (um clusterRole pode ser agregado em outro) A<-(is a composite of)-B Todas as arestas são bidirecionais, o que significa que o gráfico pode ser consultado em qualquer direção. Somente exceções são :AGGREGATE e :COMPOSITE que são unidirecionais, embora preocupadas com os mesmos nós de borda.
Para consultar o gráfico diretamente, você pode executar um contêiner redisgraph em execução, inicie redis-cli e execute suas consultas arbitrárias. Siga as instruções oficiais para exemplos de comandos.
Você também pode consultar o gráfico do Krane Console. Primeiro executivo a executar o contêiner Krane , depois
# 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 |
+----------------+--------------------------------+-----------+------------------------------------------------+
Nota: Exemplo de consulta acima selecionará todos os sujeitos com funções atribuídas/clusterRoles que concedem acesso para update configmaps .
As regras de risco do RBAC são definidas no arquivo de regras. A estrutura de cada regra é amplamente auto-explicativa. O conjunto interno pode ser expandido / substituído adicionando regras personalizadas extras ao arquivo de regras do Cutom.
As macros são "contêineres" para um conjunto de atributos comuns/compartilhados e referenciados por uma ou mais regras de risco. Se você optar por usar a macro em uma determinada regra de risco, precisará fazer referência a ela pelo nome, por exemplo, macro: <macro-name> . Observe que os atributos definidos na macro referenciada terão precedência sobre os mesmos atributos definidos no nível da regra.
A macro pode conter qualquer um dos seguintes atributos:
query - Consulta Redisgraph. Tem precedência sobre template . Exige que writer seja definido.writer - Writer é uma expressão de rubi usada para formatar o conjunto de resultados query . O escritor tem precedência sobre template .template - Nome do modelo de consulta/escritor embutido. Se query & writer não for especificada, o gerador de consulta escolhido será usado junto com o escritor correspondente. A regra pode conter qualquer um dos seguintes atributos:
id [requerido] O ID da regra é um identificador de regra exclusivo.
group_title [requerido] Título aplicando a todos os itens que se enquadram nessa verificação de risco.
severity [necessária] Gravidade, como uma de: perigo ,: aviso ,: informações.
info [NECESSÁRIAS] Informações textuais sobre a verificação e sugestões sobre como mitigar o risco.
query [Conditonal] Redisgraph Consulta.
template . Exige que writer seja definido. O escritor do writer [conditonal] é uma expressão de rubi usada para formatar o conjunto de resultados da consulta.
template . Requer que query seja definida. template [Conditonal] Nome do modelo de consulta/escritor incorporado. Se query & writer não for especificada, o gerador de consulta escolhido será usado junto com o escritor correspondente.
Alguns modelos internos exigem que o atributo match_rules seja especificado no nível de regra individual para criar a consulta correta. Modelos atualmente exigindo:
match_rules . A consulta de gráfico gerada retorna as seguintes colunas: match_rules [conditonal] necessário quando template depende das regras de correspondência para criar uma consulta.
match_rules :
- resources : ['cronjobs']
verbs : ['update'] custom_params [Opcional] Lista de pares de valores-chave personalizados a serem avaliados e substituídos em uma query de regra e representação writer .
custom_params :
- attrA : valueA
- attrB : valueB{{attrA}} e {{attrB}} serão substituídos por valueA e valueB , respectivamente. threshold [opcional] valor numérico. Quando definido, isso ficará disponível como um espaço reservado para modelo {{threshold}} na expressão writer .
macro [opcional] Referência a parâmetros comuns definidos em uma macro nomeada.
disabled [Opcional] Quando definido como true , ele desativará a regra dada e a excluirá da avaliação. Por padrão, todas as regras estão ativadas.
- 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 O exemplo acima define explicitamente uma query de gráfico que é usada para avaliar o risco de RBAC e uma expressão writer usada para formatar o conjunto de resultados da consulta. A consulta simplesmente seleciona todos Subjects (excluindo a lista de permissões) e Namespaces aos quais eles têm acesso. Observe que o conjunto de resultados incluirá apenas Subjects com acesso a mais de 2 espaços de nome (valor threshold notado lá?). A expressão do último writer será capturada como saída formatada do item de resultado.
writer pode acessar o item de conjunto de resultados por meio do objeto result com métodos que correspondem a elementos retornados pela consulta, por exemplo, result.subject_kind , result.subject_name etc.
Observação:
{{threshold}} espaço reservado na expressão writer será substituído pelo valor da palavra -chave threshold da regra.{{whitelist_subject_names}} representa um campo personalizado que será interpolado com os valores da lista de permissões definidos para um determinado id da regra. Se um nome de campo de espaço reservado não for definido na lista de permissões, ele será substituído por uma matriz vazia [''] por padrão. Leia mais sobre a lista de permissões abaixo. Os modelos internos simplificam significativamente a definição de regra de risco, no entanto, eles são projetados para extrair tipos específicos de informações e podem não ser um bom ajuste para suas regras personalizadas. Se você se encontrar reutilizando as mesmas expressões de query ou writer em várias regras, considere extraí -las para uma macro e fazer referência a suas regras personalizadas para secá -las.
- 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 : ['*'] Exemplo acima mostra uma das regras internas. Ele faz referência ao modelo risky-role que, após o processamento, expandirá a regra ao injetar expressões de query e writer antes dos gatilhos da avaliação da regra. match_rules será usado para criar a consulta de correspondência apropriada.
A lista de permissões opcionais contém um conjunto de nomes de atributos definidos personalizados e valores respectivos (por permissões).
Os nomes de atributos e seus valores são arbitrários. Eles são definidos no arquivo da lista de permissões e divididos em três seções separadas:
global - Escopo de nível superior. Os atributos personalizados definidos aqui serão aplicados a todas as regras de risco, independentemente do nome do cluster.common - personalizados serão escoposos para id de regra de risco específica, independentemente do nome do cluster.cluster (com lista aninhada de nomes de cluster) - Atributos personalizados serão aplicados a id de regra de risco específica para um determinado nome de cluster. Cada regra de risco, após a avaliação, tentará interpolar todos os espaços reservados para parâmetros usados na query , por exemplo {{your_whitelist_attribute_name}} . Se um nome de parâmetro de espaço reservado (ou seja, um nome entre os colchetes dobrados) corresponder a qualquer um dos nomes de atributos da lista de permissões para esse id da regra de risco, ele será substituído por seu valor calculado. Se nenhum valores forem encontrados para um determinado espaço reservado, ele será substituído por [''] .
Exemplo Whitelist Abaixo produz o seguinte placeholder-key => value para uma regra de risco com o valor do atributo de id com o valor de "algum risco-regulamento-ID"
{{whitelist_role_names}} => ['acp:prometheus:operator']
{{whitelist_subject_names}} => ['privileged-psp-user', 'another-user']
As teclas de espaço reservado acima, quando usadas nas consultas de gráficos personalizadas, serão substituídas por seus respectivos valores após a avaliação de regras de risco.
Exemplo:
---
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 pode ser implantado em um clusters de Kubernetes locais ou remotos facilmente.
Kubernetes Namespace, conta de serviço junto com o RBAC apropriado deve estar presente no cluster. Veja os pré -requisitos para referência.
O padrão de entrada Krane padrão executa o bin/em cluster, que aguarda a instância do Redisgraph estar disponível antes de iniciar o REMERT RELATÓRIO RBAC e o servidor da web do painel .
Você pode controlar certos aspectos da execução em cluster com as seguintes variáveis de ambiente:
KRANE_REPORT_INTERVAL - define intervalo em segundos para o relatório de análise estática do RBAC. Padrão: 300 (em segundos, ou seja, 5 minutos).KRANE_REPORT_OUTPUT - define o formato de saída RBAC Relatório de risco. Valores possíveis :json , :yaml , :none . Padrão :: :json .Antes de começarmos, você precisará das seguintes ferramentas:
Instale o gráfico de leme:
$ helm repo add appvia https://appvia.github.io/krane
$ helm repo update
$ helm install krane appvia/krane --namespace krane --create-namespaceConsulte o arquivo valual.yaml para obter detalhes de outras opções e parâmetros assentáveis.
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.yamlObserve que o serviço de painel Krane não está exposto por padrão!
kubectl port-forward svc/krane 8000
--context= < docker-desktop >
--namespace=krane
# Open Krane dashboard at http://localhost:8000Você pode encontrar o exemplo de manifestos de implantação no diretório K8S.
Modificar os manifestos conforme necessário para suas implantações, certificando -se de fazer referência à versão correta da imagem Krane Docker em seu arquivo de implantação. Consulte Krane Docker Registry para obter tags disponíveis ou apenas use latest .
Se o seu cluster K8S vier com o suporte do controlador de Compose-on-Kubernetes embutido ( docker-desktop o suporta por padrão), você poderá implantar o Krane e suas dependências com um único comando de pilha de docker:
docker stack deploy
--orchestrator kubernetes
--namespace krane
--compose-file docker-compose.yml
--compose-file docker-compose.k8s.yml kraneNota: Verifique se o contexto atual do seu Kube está definido corretamente antes da execução do comando acima!
A pilha de aplicativos deve agora ser implantada para um cluster Kubernetes e todos os serviços prontos e expostos. Observe que a Krane iniciará automaticamente seu loop de relatório e servidor de painel.
docker stack services --orchestrator kubernetes --namespace krane kraneO comando acima produzirá a seguinte saída:
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
Verifique seu cluster Kubernetes RBAC Postura de segurança visitando http: // localhost: 8000.
Observe que , para implantações remotas de cluster, você provavelmente precisar
kubectl --context=my-remote-cluster --namespace=krane port-forward svc/krane 8000Para excluir a pilha
docker stack rm krane
--orchestrator kubernetes
--namespace kraneKrane o notificará sobre anomalias detectadas de média e alta gravidade por meio de sua integração frouxa.
Para ativar as notificações, especifique o Slack webhook_url & channel no arquivo config/config.yaml ou, alternativamente, defina as variáveis SLACK_WEBHOOK_URL e SLACK_CHANNEL . As variáveis de ambiente terão precedência sobre os valores de arquivo de configuração.
Esta seção descreve etapas para permitir o desenvolvimento local.
Instalar dependências de código Krane com
./bin/setup Krane depende do RedisGraph. docker-compose é a maneira mais rápida de fazer com que as dependências de Krane sejam executadas localmente.
docker-compose up -d redisgraphPara inspecionar o serviço Redisgraph, está em alta:
docker-compose psPara parar os serviços:
docker-compose downNesse ponto, você poderá modificar a base de código KRANE e os resultados de testes invocando comandos no shell local.
$ ./bin/krane --help # to get help
$ ./bin/krane report -k docker-desktop # to generate your first report for
# local docker-desktop k8s cluster
...Para ativar o modo de desenvolvimento local da interface do painel do painel
$ cd dashboard
$ npm install
$ npm startIsso iniciará automaticamente o servidor do painel, abrirá o navegador padrão e observará as alterações dos arquivos de origem.
Krane vem pré -configurado para melhorar a experiência do desenvolvedor com Skaffold. Iterando o projeto e validando o aplicativo executando toda a pilha no cluster Kubernetes local ou remoto, ficou mais fácil. O código de código Hot Hot permite que as alterações locais sejam propagadas automaticamente para o contêiner em execução para um ciclo de vida de desenvolvimento mais rápido.
skaffold dev --kube-context docker-desktop --namespace krane --port-forwardExecute testes localmente com
bundle exec rspecCongratulamo -nos com quaisquer contribuições da comunidade! Dê uma olhada no nosso guia de contribuição para obter mais informações sobre como começar. Se você usa Krane , ache útil ou geralmente está interessado em segurança Kubernetes, informe -nos estrelando e assistindo a este repositório. Obrigado!
Participe da discussão em nosso canal da comunidade.
Krane é um projeto comunitário e recebemos suas contribuições. Para relatar um bug, sugerir uma melhoria ou solicitar um novo recurso, abra um problema do GitHub. Consulte o nosso guia contribuinte para obter mais informações sobre como você pode ajudar.
Veja nosso roteiro para obter detalhes sobre nossos planos para o projeto.
Autor: Marcin Ciszak [email protected]
Copyright (c) 2019-2020 Appvia Ltd
Este projeto é distribuído sob a licença Apache, versão 2.0.