Aller au contenu

Installation et configuration

Pre-requis

Composant Version minimum Note
Kubernetes 1.25+ Pour les PodSecurity admission
Kernel Linux 5.8+ Pour eBPF CO-RE (Falco)
Helm 3.12+ Gestionnaire de charts
kubectl 1.25+ Correspond a la version du cluster
# Verifier la version du kernel sur les noeuds
kubectl get nodes -o jsonpath='{range .items[*]}{.metadata.name}{"\t"}{.status.nodeInfo.kernelVersion}{"\n"}{end}'

# Verifier que eBPF est supporte
kubectl debug node/<node-name> -it --image=busybox -- ls /sys/kernel/btf/vmlinux

Déploiement de Falco

Ajout du dépôt Helm

helm repo add falcosecurity https://falcosecurity.github.io/charts
helm repo update

Valeurs de configuration

# falco-values.yaml
falco:
  # Utiliser eBPF moderne (pas le module kernel)
  driver:
    kind: modern_ebpf

  # Format de sortie JSON pour integration avec Loki
  json_output: true
  json_include_output_property: true
  json_include_tags_property: true

  # Canaux de sortie
  stdout_output:
    enabled: true
  http_output:
    enabled: false
  grpc_output:
    enabled: false

  # Regles personnalisees (en plus des regles par defaut)
  rules_files:
    - /etc/falco/falco_rules.yaml
    - /etc/falco/falco_rules.local.yaml
    - /etc/falco/rules.d

# Regles personnalisees
customRules:
  custom-rules.yaml: |-
    # Detecter la lecture de tokens ServiceAccount
    - rule: Read ServiceAccount Token
      desc: Detect reading of ServiceAccount token in a container
      condition: >
        open_read and container and
        fd.name startswith /var/run/secrets/kubernetes.io/serviceaccount and
        not proc.name in (coredns, kube-proxy, calico-node)
      output: >
        Lecture du token ServiceAccount
        (user=%user.name container=%container.name
         file=%fd.name image=%container.image.repository)
      priority: WARNING
      tags: [kubernetes, mitre_credential_access]

# Ressources
resources:
  requests:
    cpu: 200m
    memory: 256Mi
  limits:
    cpu: 1000m
    memory: 512Mi

# Tolerations pour s'executer sur tous les noeuds
tolerations:
  - effect: NoSchedule
    operator: Exists

Installation

# Creer le namespace dedie
kubectl create namespace falco-system

# Installer Falco
helm install falco falcosecurity/falco \
  --namespace falco-system \
  --values falco-values.yaml \
  --wait

# Verifier le deploiement
kubectl -n falco-system get pods -l app.kubernetes.io/name=falco
kubectl -n falco-system logs -l app.kubernetes.io/name=falco --tail=20

Vérification

# Declencher une alerte de test : shell dans un conteneur
kubectl run test-falco --image=busybox --restart=Never -- sleep 300
kubectl exec test-falco -- sh -c "cat /etc/shadow"

# Verifier que Falco a detecte l'evenement
kubectl -n falco-system logs -l app.kubernetes.io/name=falco | grep "test-falco" | tail -5

# Nettoyage
kubectl delete pod test-falco

Déploiement de OPA/Gatekeeper

Ajout du dépôt Helm

helm repo add gatekeeper https://open-policy-agent.github.io/gatekeeper/charts
helm repo update

Valeurs de configuration

# gatekeeper-values.yaml
replicas: 2

# Activer le mode audit
audit:
  # Frequence d'audit des ressources existantes
  auditInterval: 300       # 5 minutes
  # Nombre max de violations stockees par contrainte
  constraintViolationsLimit: 20

# Webhook
webhook:
  # Timeout du webhook (eviter les blocages)
  timeoutSeconds: 10

# Metriques Prometheus
metricsBackends: ["prometheus"]

# Exempter les namespaces systeme
exemptNamespaces:
  - kube-system
  - gatekeeper-system
  - falco-system
  - monitoring

resources:
  requests:
    cpu: 100m
    memory: 256Mi
  limits:
    cpu: 500m
    memory: 512Mi

Installation

# Installer Gatekeeper
helm install gatekeeper gatekeeper/gatekeeper \
  --namespace gatekeeper-system \
  --create-namespace \
  --values gatekeeper-values.yaml \
  --wait

# Verifier
kubectl -n gatekeeper-system get pods

Déployer les contraintes essentielles

Contrainte : interdire les conteneurs privilegies

# template-privileged-container.yaml
apiVersion: templates.gatekeeper.sh/v1
kind: ConstraintTemplate
metadata:
  name: k8sdisallowprivileged
spec:
  crd:
    spec:
      names:
        kind: K8sDisallowPrivileged
  targets:
    - target: admission.k8s.gatekeeper.sh
      rego: |
        package k8sdisallowprivileged
        violation[{"msg": msg}] {
          containers := array.concat(
            object.get(input.review.object.spec, "containers", []),
            object.get(input.review.object.spec, "initContainers", []))
          container := containers[_]
          container.securityContext.privileged == true
          msg := sprintf("Conteneur privilegie interdit : %s", [container.name])
        }
# constraint-no-privileged.yaml
apiVersion: constraints.gatekeeper.sh/v1beta1
kind: K8sDisallowPrivileged
metadata:
  name: no-privileged-containers
spec:
  enforcementAction: deny
  match:
    kinds:
      - apiGroups: [""]
        kinds: ["Pod"]
    excludedNamespaces:
      - kube-system

Autres contraintes recommandees

Suivez le même pattern (ConstraintTemplate + Constraint) pour ces cas courants :

Contrainte Objectif
K8sAllowedRepos Limiter les registres d'images autorises
K8sRequireRunAsNonRoot Exiger runAsNonRoot sur tous les conteneurs
K8sDisallowHostNetwork Interdire hostNetwork: true
K8sRequireResourceLimits Exiger des resources.limits sur chaque conteneur

La Gatekeeper Library fournit des templates pre-écrits pour ces cas.

# Deployer les contraintes
kubectl apply -f template-privileged-container.yaml
kubectl apply -f constraint-no-privileged.yaml

# Verifier le status
kubectl get constrainttemplates
kubectl get constraints

Déploiement de Trivy Operator

Ajout du dépôt Helm

helm repo add aqua https://aquasecurity.github.io/helm-charts/
helm repo update

Valeurs de configuration

# trivy-operator-values.yaml
operator:
  targetNamespaces: ""       # vide = tous les namespaces
  excludeNamespaces: "kube-system,gatekeeper-system,falco-system"
  scanJobTTL: 300s
  concurrentScanJobsLimit: 3

trivy:
  mode: Standalone
  severity: "CRITICAL,HIGH,MEDIUM"
  ignoreUnfixed: false

vulnerabilityReportsPlugin: "Trivy"
configAuditReportsPlugin: "Trivy"
exposedSecretsScannerEnabled: true
serviceMonitor:
  enabled: true

Installation

# Installer Trivy Operator
helm install trivy-operator aqua/trivy-operator \
  --namespace trivy-system \
  --create-namespace \
  --values trivy-operator-values.yaml \
  --wait

# Verifier
kubectl -n trivy-system get pods

Vérification

# Attendre que les premiers scans se terminent (quelques minutes)
kubectl get vulnerabilityreports -A --no-headers | head -10

# Voir le detail d'un rapport
kubectl get vulnerabilityreport -n default -o yaml | head -40

# Compter les CVE critiques
kubectl get vulnerabilityreports -A -o json | \
  jq '[.items[].report.summary.criticalCount] | add'

Routage des alertes vers Loki/Grafana

Collecte des alertes Falco avec Alloy

Configurez Alloy pour collecter les logs Falco (stdout JSON) et les pousser vers Loki avec un tenant dedie security :

# Extrait de la configuration Alloy
discovery.kubernetes "falco_pods" {
  role = "pod"
  namespaces { names = ["falco-system"] }
  selectors {
    role  = "pod"
    label = "app.kubernetes.io/name=falco"
  }
}

loki.source.kubernetes "falco_logs" {
  targets    = discovery.kubernetes.falco_pods.targets
  forward_to = [loki.write.default.receiver]
}

loki.write "default" {
  endpoint {
    url       = "http://loki-gateway.monitoring.svc:3100/loki/api/v1/push"
    tenant_id = "security"
  }
}

Dashboard pre-construit

Falco fournit un dashboard Grafana officiel (ID 11914). Importez-le depuis grafana.com/dashboards. Pour les dashboards et requêtes LogQL détaillés, voir le chapitre Integration.