
Análise de riscos de segurança para recursos Kubernetes
Para mais exemplos, visite Kubesec.io, que usa a API hospedada da ControlPlane em v2.kubesec.io/scan.
Crie um arquivo de recurso Kubernetes (ex.: kubesec-test.yaml) para analisar. Para um teste rápido, você pode salvar o seguinte manifesto de Pod:
$ cat <<EOF > kubesec-test.yaml
apiVersion: v1
kind: Pod
metadata:
name: kubesec-demo
spec:
containers:
- name: kubesec-demo
image: gcr.io/google-samples/node-hello:1.0
securityContext:
readOnlyRootFilesystem: true
EOF
Execute uma análise no seu arquivo de manifesto:
# Usando o binário local
kubesec scan kubesec-test.yaml
# Ou usando Docker
docker run -i kubesec/kubesec:v2 scan /dev/stdin < kubesec-test.yaml
# Usando o binário local com um formato de saída de tabela legível por humanos
kubesec scan kubesec-test.yaml --format table
[!TIP] Para visualizar os resultados em uma tabela legível em vez do formato JSON padrão, use o sinalizador
--format table
O kubesec exibirá uma pontuação de segurança e uma análise detalhada do seu recurso.
O Kubesec está disponível como:
docker.io/kubesec/kubesec:v2Ou instale o commit mais recente do GitHub com:
$ go install github.com/controlplaneio/kubesec/v2@latest
$ GO111MODULE="on" go get github.com/controlplaneio/kubesec/v2
Analise recursos Kubernetes a partir de arquivos locais ou entrada padrão.
O Kubesec pode analisar vários documentos YAML em um único arquivo de entrada, ou analisar documentos de vários arquivos de uma só vez, desde que estejam formatados corretamente como múltiplos documentos separados por ---.
# Analisar um arquivo YAML local específico
kubesec scan ./deployment.yaml
# Analisar a partir da entrada padrão (JSON ou YAML)
cat file.json | kubesec scan -
# Analisar um chart Helm renderizado
helm template -f values.yaml ./chart | kubesec scan /dev/stdin
# Analisar vários documentos YAML separados por '---'
{ cat test/asset/multi.yml; echo "---"; cat test/asset/critical.yml; } | kubesec scan -
Você pode executar os mesmos comandos de análise usando a imagem oficial do Docker:
# Analisar um arquivo via Docker usando entrada padrão
docker run -i kubesec/kubesec:v2 scan /dev/stdin < kubesec-test.yaml
O Kubesec suporta três formatos de saída diferentes, especificados pelo sinalizador --format / -f: json (padrão), table e template, e pode analisar vários documentos YAML em um único arquivo de entrada.
# Saída em array JSON (comportamento padrão)
kubesec scan ./deployment.yaml --format json
# Saída em tabela legível por humanos
kubesec scan ./deployment.yaml --format table
# Usar um template personalizado para a saída
kubesec scan ./deployment.yaml --format template --template report-template.tmpl
# Uma regra
kubesec scan --rules CapSysAdmin kubesec-test.yaml
# Várias regras
kubesec scan --rules RunAsNonRoot,SeccompAny,ApparmorAny kubesec-test.yaml
[
{
"object": "Pod/security-context-demo.default",
"valid": true,
"message": "Failed with a score of -30 points",
"score": -30,
"scoring": {
"critical": [
{
"selector": "containers[] .securityContext .capabilities .add == SYS_ADMIN",
"reason": "CAP_SYS_ADMIN is the most privileged capability and should always be avoided",
"points": -30
}
],
"advise": [
{
"selector": "containers[] .securityContext .runAsNonRoot == true",
"reason": "Force the running image to run as a non-root user to ensure least privilege",
"points": 1
},
{
// ...
}
]
}
}
]

# Imprimir todas as regras de análise com suas pontuações associadas
kubesec print-rules
# Imprimir todas as regras de análise com suas pontuações associadas como tabela
kubesec print-rules --format table
[
{
"id": "AllowPrivilegeEscalation",
"selector": "containers[] .securityContext .allowPrivilegeEscalation == true",
"reason": "Ensure a non-root process can not gain more privileges",
"kinds": [
"Pod",
"Deployment",
"StatefulSet",
"DaemonSet"
],
"points": -7,
"advise": 0
},
...
]
O Kubesec utiliza o kubeconform (obrigado @yannh) para validar os manifestos a serem analisados. Isso implica que especificar diferentes locais de schema segue as regras descritas no README do kubeconform.
# Usa o schema mais recente do upstream
# O schema será obtido de: https://raw.githubusercontent.com/yannh/kubernetes-json-schema/master/master-standalone-strict/pod-v1.json
kubesec scan ./pod.yaml
# Usa uma versão de schema específica do upstream (formato x.y.z sem o prefixo v)
# O schema será obtido de: https://raw.githubusercontent.com/yannh/kubernetes-json-schema/master/v1.25.3-standalone-strict/pod-v1.json
kubesec scan ./pod.yaml --kubernetes-version 1.25.3
# Usa uma versão de schema específica em um ambiente isolado via HTTP
# O schema será obtido de: `https://host.server/v<version>-standalone-strict/pod-v1.json`
kubesec scan ./deployment.yaml --kubernetes-version <version> --schema-location https://host.server
# Usa uma versão de schema específica em um ambiente isolado com arquivos locais
# O schema será lido de: `/opt/schemas/v<version>-standalone-strict/pod-v1.json`
kubesec scan ./deployment.yaml --kubernetes-version <version> --schema-location /opt/schemas
Nota: para limitar chamadas de rede externas e permitir o uso em ambientes isolados (airgap), a imagem kubesec incorpora schemas. Se você pretende alterar o local do schema, será necessário alterar as variáveis de ambiente K8S_SCHEMA_VER e SCHEMA_LOCATION em tempo de execução.
O Kubesec inclui um servidor HTTP integrado que você pode executar localmente ou em um contêiner para aceitar solicitações de análise pela rede.
# Iniciar o servidor HTTP em segundo plano na porta 8080
kubesec http 8080 &
# Enviar um arquivo ao servidor em execução via POST
curl -sSX POST --data-binary @deployment.yaml http://localhost:8080/scan
# Parar o servidor local em segundo plano quando terminar
kill %
# Iniciar o servidor HTTP via Docker
docker run -d -p 8080:8080 kubesec/kubesec:v2 http 8080
# Enviar um arquivo ao servidor em execução via POST
curl -sSX POST --data-binary @deployment.yaml http://localhost:8080/scan
Não se esqueça de parar o servidor.
O Kubesec também está disponível via HTTPS em v2.kubesec.io/scan.
Não envie YAML sensível para este serviço público.
O serviço é executado com base na melhor boa vontade/estrita possibilidade (best effort).
# Enviar um manifesto diretamente para a API v2 hospedada
curl -sSX POST --data-binary @"deployment.yaml" https://v2.kubesec.io/scan
# Analisar a saída da API usando jq para retornar um código de saída diferente de zero se a pontuação for <= 10
curl -sSX POST --data-binary @"deployment.yaml" https://v2.kubesec.io/scan | jq --exit-status '.score > 10'
# Usar o parâmetro de consulta "rule" para analisar apenas regras específicas (várias são suportadas)
curl -sSX POST --data-binary @test/asset/score-0-cap-sys-admin.yml "http://localhost:8080/scan?rule=SeccompAny&rule=ApparmorAny"
Você também pode definir uma função Bash, por exemplo:
# Definir uma função BASH
$ kubesec ()
{
local FILE="${1:-}";
[[ ! -e "${FILE}" ]] && {
echo "kubesec: ${FILE}: No such file" >&2;
return 1
};
curl --silent \
--compressed \
--connect-timeout 5 \
-sSX POST \
--data-binary=@"${FILE}" \
https://v2.kubesec.io/scan
}
# Enviar um recurso Kubernetes para v2.kubesec.io/scan
$ kubesec ./deployment.yml
# Retornar código de status diferente de zero se a pontuação não for maior que 10
$ kubesec ./score-9-deployment.yml | jq --exit-status '.score > 10' >/dev/null
# código de status 1
Consulte CONTRIBUTING.md para mais informações.
Se você tiver alguma dúvida sobre Kubesec e segurança Kubernetes:
Seu feedback é sempre bem-vindo!
Feito com ❤ por ControlPlane