Ukratko

Najvažnije iz članka

  • Standardni Kubernetes Secret objekti nisu enkriptirani i pohranjuju se kao Base64 kodirani tekst u etcd-u, što predstavlja sigurnosni rizik.
  • Helm Secrets plugin koristi SOPS za enkripciju tajni unutar Helm chartova, omogućujući sigurno pohranjivanje tajni u Git repozitorijima s podrškom za PGP, AWS KMS, Google Cloud KMS, itd.
  • HashiCorp Vault pruža centralizirano i sigurno upravljanje tajnama s značajkama poput dinamičkih tajni, automatske rotacije, granularne kontrole pristupa i detaljnog auditiranja.
  • Integracija Vaulta s Kubernetesom kroz Vault Agent Injector omogućuje sigurno injektiranje tajni direktno u podove, osiguravajući end-to-end enkripciju i sprječavajući pohranu tajni u etcd-u u plaintext formatu.
Sadržaj članka
  1. Uvod u sigurnost tajni u Kubernetesu
  2. Zašto standardni Kubernetes Secrets nisu dovoljni?
  3. Helm Secrets: Enkripcija tajni u Git repozitorijima
  4. Što je Helm Secrets plugin?
  5. Instalacija Helm Secrets plugina
  6. Korištenje Helm Secrets s PGP ključem
  7. Prednosti Helm Secrets plugina
  8. Ograničenja Helm Secrets plugina
  9. HashiCorp Vault: Centralizirano upravljanje tajnama
  10. Ključne značajke Vaulta za Kubernetes
  11. Integracija Vaulta s Kubernetesom
  12. Arhitektura s Vault Agent Injectorom
  13. Koraci za implementaciju Vault Agent Injectora
  14. Prednosti integracije s Vault Agent Injectorom
  15. Ograničenja Vault Agent Injectora
  16. Zaključak i najbolje prakse
  17. Preporučene najbolje prakse:

Uvod u sigurnost tajni u Kubernetesu

U današnjem svijetu kontejneriziranih aplikacija i orkestracijskih platformi poput Kubernetesu, sigurnost je ključna, a posebno je osjetljiva na pitanje upravljanja tajnama. Tajne (secrets) su osjetljivi podaci poput lozinki za baze podataka, API ključeva, certifikata i drugih vjerodajnica koje aplikacije trebaju za ispravan rad. Nepravilno upravljanje tajnama može dovesti do ozbiljnih sigurnosnih propusta, ugrožavanja podataka i narušavanja integriteta sustava. Kubernetes ima ugrađen objekt Secret koji omogućuje pohranu i distribuciju tajni aplikacijama. Međutim, ovaj objekt, po svojoj zadanoj konfiguraciji, ne pruža end-to-end enkripciju za pohranjene vrijednosti. Tajne se unutar etcd baze, koja je temeljni repozitorij stanja Kubernetes klastera, pohranjuju kao Base64 kodirani tekst, što ih čini lako dekriptirajućima za svakoga tko ima pristup etcd-u ili Kubernetes API-ju. Ovo predstavlja značajan sigurnosni rizik i zahtijeva dodatne slojeve zaštite.

Zašto standardni Kubernetes Secrets nisu dovoljni?

Standardni Kubernetes Secret objekti su dizajnirani da omoguće jednostavnu distribuciju osjetljivih podataka unutar klastera. Međutim, oni imaju nekoliko nedostataka u smislu sigurnosti:

  • Base64 kodiranje, ne enkripcija: Kao što je spomenuto, vrijednosti se samo kodiraju, a ne kriptiraju. To znači da svatko tko ima pristup Kubernetes API-ju s odgovarajućim dopuštenjima može lako dekodirati i pročitati tajne.
  • Pohrana u etcd-u: etcd je kritična komponenta Kubernetes klastera. Ako etcd baza podataka nije adekvatno zaštićena (npr. enkripcija diska, ograničen pristup), napadač može doći do svih tajni.
  • Upravljanje u repozitorijima koda: Ako su Secret objekti definirani izravno u YAML manifestima i pohranjeni u sustavima za kontrolu verzija (npr. Git), dolazimo do situacije gdje su tajne pohranjene u plaintext formatu u repozitoriju, što je velika sigurnosna propast.
  • Rotacija tajni: Ručna rotacija tajni može biti složena i sklona pogreškama, posebno u velikim sustavima.

Kako bismo riješili ove probleme, potrebno je implementirati naprednija rješenja za upravljanje tajnama. U ovom tutorialu fokusirat ćemo se na dva popularna i moćna alata: Helm Secrets i HashiCorp Vault.

Helm Secrets: Enkripcija tajni u Git repozitorijima

Helm je de facto standard za pakiranje i implementaciju aplikacija unutar Kubernetes klastera. Dok Helm olakšava upravljanje konfiguracijom aplikacija, on sam po sebi ne pruža napredne mehanizme za sigurnu pohranu tajni. Ovdje na scenu stupa Helm Secrets plugin.

Što je Helm Secrets plugin?

Helm Secrets je dodatak za Helm CLI koji omogućuje enkripciju i dekripciju tajni izravno unutar Helm chartova. Koristi SOPS (Secrets OPerationS), alat razvijen od strane Mozille, za rukovanje enkripcijom. SOPS podržava razne backendove za ključeve, uključujući AWS KMS, Google Cloud KMS, Azure Key Vault i OpenPGP.

Instalacija Helm Secrets plugina

Prvo, osigurajte da imate instaliran Helm (v3 ili noviji). Zatim instalirajte Helm Secrets:

helm plugin install https://github.com/jkroepke/helm-secrets

Potom instalirajte SOPS CLI alat. Upute za instalaciju variraju ovisno o operativnom sustavu. Za macOS s Homebrew:

brew install sops

Za Linux s apt:

sudo apt update && sudo apt install sops

Korištenje Helm Secrets s PGP ključem

Jedan od najjednostavnijih načina za početak s Helm Secrets je korištenje OpenPGP ključeva. Pretpostavimo da imate generiran PGP ključ. Ako nemate, možete ga generirati s gpg --full-generate-key.

1. Kreiranje secrets.yaml datoteke

Unutar vašeg Helm charta (npr. my-app/charts/my-subchart/) ili na razini values datoteke, kreirajte datoteku secrets.yaml (ili bilo koji naziv, konvencija je secrets.yaml ili sensitive.yaml).

# my-app/secrets.yaml
db_password: "really_secret_password"
api_key: "super_secret_api_key_123"

2. Enkriptiranje tajni

Sada ćete enkriptirati ovu datoteku koristeći vaš PGP ključ. Morate znati ID ključa primatelja (recipient key ID), koji možete dobiti s gpg --list-secret-keys --keyid-format LONG.

sops --encrypt --pgp <VAŠ_PGP_KEY_ID> --in-place my-app/secrets.yaml

Nakon što izvršite ovu naredbu, my-app/secrets.yaml će biti zamijenjen svojom enkriptiranom verzijom. Izgledat će otprilike ovako:

apiVersion: v1
data:
  api_key: ENC[AES256_GCM,data:...,iv:...,tag:...,type:str]
  db_password: ENC[AES256_GCM,data:...,iv:...,tag:...,type:str]
kms:
  -
    arn: arn:aws:kms:...
    gcp_kms: []
    azure_kv: []
sops:
  kms: []
  gcp_kms: []
  azure_kv: []
  pgp:
    -
      fp: <VAŠ_PGP_FINGERPRINT>
      enc: |
        -----BEGIN PGP MESSAGE-----
        ...
        -----END PGP MESSAGE-----
  unencrypted_suffix: _unencrypted
  version: 3.7.3

Ovakva secrets.yaml datoteka sada se može sigurno pohraniti u Git repozitorij. Samo oni koji posjeduju odgovarajući PGP ključ moći će je dekriptirati.

3. Implementacija s Helm Secrets

Kada koristite Helm za implementaciju charta koji sadrži enkriptiranu secrets.yaml datoteku, Helm Secrets plugin će automatski detektirati i dekriptirati datoteku prije nego što je proslijedi Helm rendereru. To znači da možete koristiti tajne u vašim templates/*.yaml datotekama kao i bilo koje druge vrijednosti.

Primjer deployment.yaml dijela koji koristi tajnu:

# my-app/templates/deployment.yaml
...
env:
  - name: DB_PASSWORD
    value: {{ .Values.db_password }}
  - name: API_KEY
    value: {{ .Values.api_key }}
...

Kada pokrenete helm install ili helm upgrade:

helm upgrade --install my-app ./my-app -f my-app/secrets.yaml

Hem Secrets će presresti poziv, dekriptirati secrets.yaml i injektirati vrijednosti u Helm renderiranje. Važno je napomenuti da Helm Secrets dekriptira datoteke na klijentskoj strani, prije nego što se podaci pošalju Kubernetes API-ju. To znači da tajne i dalje dolaze do Kubernetes API-ja u plaintext formatu unutar pozvanog objekta, ali su zaštićene tijekom tranzita i pohrane u Git repozitoriju.

Prednosti Helm Secrets plugina

  • Enkripcija u mirovanju (encryption at rest): Tajne su enkriptirane u Git repozitorijima.
  • Automatizacija: Integrira se fluidno s Helm procesom implementacije.
  • Fleksibilnost: Podržava različite mehanizme za upravljanje ključevima (PGP, KMS).
  • Auditabilnost: Promjene tajni se prate u Gitu.

Ograničenja Helm Secrets plugina

  • Klijentska enkripcija/dekripcija: Tajne se dekriptiraju na klijentskom stroju i šalju u Kubernetes u plaintext formatu (unutar Secret objekta), što znači da i dalje ostaju Base64 kodirane u etcd-u.
  • Ručna rotacija ključeva: Rotacija PGP ključeva ili KMS ključeva zahtijeva ažuriranje svih enkriptiranih datoteka.

Za aplikacije koje zahtijevaju najvišu razinu sigurnosti i dinamičku rotaciju tajni, potrebna je naprednija integracija s rješenjima poput HashiCorp Vaulta.

HashiCorp Vault: Centralizirano upravljanje tajnama

HashiCorp Vault je alat za centralizirano upravljanje tajnama i zaštitu osjetljivih podataka. Vault ne samo da pohranjuje tajne, već pruža i dinamičko generiranje tajni, automatsku rotaciju, strogu kontrolu pristupa (ACL), detaljno auditiranje i enkripciju podataka u mirovanju i tranzitu.

Ključne značajke Vaulta za Kubernetes

  • Centralizirana pohrana: Sve tajne su na jednom sigurnom mjestu.
  • Dinamičke tajne: Vault može generirati kratkotrajne tajne (npr. privremene lozinke za baze podataka) koje istječu nakon određenog vremena, smanjujući rizik od kompromitacije.
  • Automatska rotacija: Tajne se mogu automatski rotirati bez ljudske intervencije.
  • Precizna kontrola pristupa: Detaljna kontrola tko može pristupiti kojim tajnama, koristeći politike i autentičnu integraciju s Kubernetesom.
  • Enkripcija u mirovanju i tranzitu: Sve tajne su kriptirane i u bazi podataka Vaulta i tijekom komunikacije s klijentima.
  • Auditabilnost: Svaki pristup tajni se bilježi, omogućujući detaljno auditiranje.

Integracija Vaulta s Kubernetesom

Postoji nekoliko načina za integraciju HashiCorp Vaulta s Kubernetesom. Dva najčešća i preporučena pristupa su:

  1. Vault Agent Injector: Sidecar kontejner koji injektira tajne u podove.
  2. External Secrets Operator: Operator koji sinkronizira tajne iz Vaulta (ili drugih vanjskih izvora) u nativne Kubernetes Secret objekte.

U ovom tutorialu fokusirat ćemo se na Vault Agent Injector zbog njegove elegancije i mogućnosti dinamičkog generiranja tajni.

Arhitektura s Vault Agent Injectorom

Vault Agent Injector je Mutating Admission Webhook controller koji automatski modificira podove prije nego što se stvore u klasteru. Kada kreirate pod, injektor detektira određene anotacije u definiciji poda. Ako su prisutne, injektor dodaje vault-agent sidecar kontejner podu. Ovaj sidecar kontejner je odgovoran za:

  • Autentikaciju na Vault (koristeći Kubernetes Service Account).
  • Dohvaćanje tajni iz Vaulta.
  • Pisanje tajni u shared volume (npr. emptyDir) unutar poda.
  • Opcijski, održavanje tajni ažuriranima i njihovu rotaciju.

Aplikacijski kontejner tada pristupa tajnama iz tog shared volumea, obično preko mountanih datoteka.

Koraci za implementaciju Vault Agent Injectora

1. Postavljanje Vaulta

Prvo, morate imati funkcionalan Vault klaster. Možete ga postaviti unutar Kubernetes klastera (u proizvodnom okruženju preporučuje se HA setup) ili izvan njega. Za potrebe ovog tutoriala, pretpostavit ćemo da je Vault dostupan i da imate pristup njegovom API-ju.

2. Omogućavanje Kubernetes Auth metode u Vaultu

Vault mora biti konfiguriran da vjeruje Kubernetesu i da dopusti podovima da se autenticiraju koristeći njihove Service Account tokene.

# Prijavite se u Vault CLI
vault login <ROOT_TOKEN_ILI_DR_AUTENTIKACIJA>

# Omogućite Kubernetes Auth metoduvault auth enable kubernetes

# Konfigurirajte Kubernetes Auth metodu
vault write auth/kubernetes/config \
    token_reviewer_jwt="$(cat /var/run/secrets/kubernetes.io/serviceaccount/token)" \
    kubernetes_host="https://$KUBERNETES_PORT_443_TCP_ADDR" \
    kubernetes_ca_cert="$(cat /var/run/secrets/kubernetes.io/serviceaccount/ca.crt)" \
    issuer="https://kubernetes.default.svc.cluster.local"

# Kreirajte politiku koja definira pristup tajnama
vault policy write my-app-policy - <<EOF
path "secret/data/my-app/*" {
  capabilities = ["read"]
}
EOF

# Konfigurirajte rolu za Service Account
vault write auth/kubernetes/role/my-app-role \
    bound_service_account_names="my-app-sa" \
    bound_service_account_namespaces="default" \
    policies="my-app-policy" \
    ttl="1h"

Ovdje my-app-sa je Service Account vaših aplikacija, a my-app-policy definira koje tajne mogu čitati. secret/data/my-app/* odnosi se na putanju u Vaultu gdje su tajne pohranjene (npr. KV v2 engine).

3. Instalacija Vault Agent Injectora

Najlakši način je putem Helm charta HashiCorp Vaulta.

helm repo add hashicorp https://helm.releases.hashicorp.com
helm repo update

helm install vault hashicorp/vault \
    --set "server.enabled=false" \
    --set "injector.enabled=true" \
    --set "global.externalVaultAddr=http://<VAULT_SERVER_IP_ILI_HOSTNAME>:8200"

Prilagodite global.externalVaultAddr na vašu Vault instancu.

4. Kreiranje Service Accounta i Deployanja aplikacije

Kreirajte Service Account koji će koristiti vaša aplikacija i na koju ste vezali Vault rolu.

# sa.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
  name: my-app-sa
  namespace: default

Sada, u definiciji vašeg deploymenta, dodajte anotacije koje instruiraju Vault Agent Injector da injektira sidecar i dohvati tajne.

# deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-app-deployment
  namespace: default
spec:
  selector:
    matchLabels:
      app: my-app
  template:
    metadata:
      labels:
        app: my-app
      annotations:
        # Omogućite injektor
        vault.hashicorp.com/agent-inject: "true"
        # Putanja do tajne u Vaultu
        vault.hashicorp.com/agent-inject-secret-config: "secret/data/my-app/credentials"
        # Predložak za rendering tajne (Go template)
        vault.hashicorp.com/agent-inject-template-config: |
          {{- with secret "secret/data/my-app/credentials" -}}
          DB_PASSWORD={{ .Data.data.db_password }}
          API_KEY={{ .Data.data.api_key }}
          {{- end -}}
        # Odredišna putanja unutar poda
        vault.hashicorp.com/agent-inject-file-config: "/vault/secrets/app-config.txt"
        # Service Account za autentikaciju na Vault
        vault.hashicorp.com/service-account-name: "my-app-sa"
    spec:
      serviceAccountName: my-app-sa
      containers:
        - name: my-app-container
          image: my-app-image:latest
          # Aplikacija čita tajne iz mountane datoteke
          command: ["sh", "-c", "source /vault/secrets/app-config.txt && echo \"DB_Password: $DB_PASSWORD, API_Key: $API_KEY\" && sleep infinity"]

Objašnjenje anotacija:

  • vault.hashicorp.com/agent-inject: "true": Omogućuje injekciju Vault Agenta.
  • vault.hashicorp.com/agent-inject-secret-config: Navodi putanju do tajne koju želimo dohvatiti.
  • vault.hashicorp.com/agent-inject-template-config: Koristi Go template sintaksu za formatiranje tajne. Ovo je moćna značajka koja omogućuje mapiranje specifičnih polja iz Vault tajne u datoteku unutar poda.
  • vault.hashicorp.com/agent-inject-file-config: Definira putanju unutar poda gdje će generirana datoteka s tajnama biti spremljena.
  • vault.hashicorp.com/service-account-name: Specificira Service Account koji će se koristiti za autentikaciju na Vault.

Pohranjivanje tajni u Vault:

Prije pokretanja deploymenta, osigurajte da su tajne pohranjene u Vaultu na putanji secret/data/my-app/credentials.

vault kv put secret/my-app/credentials db_password="myStrongDbPass" api_key="mySuperSecureApiKey"

Nakon što se my-app-deployment pokrene, Vault Agent sidecar će se autenticirati na Vault koristeći my-app-sa, dohvatiti tajne, i spremiti ih u app-config.txt unutar zajedničkog volumena. Vaša aplikacija tada može čitati te tajne iz datoteke.

Prednosti integracije s Vault Agent Injectorom

  • End-to-End sigurnost: Tajne nikada nisu pohranjene u etcd-u u plaintext formatu. One se dohvaćaju iz Vaulta i direktno injektiraju u memoriju poda ili privremeni filesystem.
  • Dinamičke tajne i rotacija: Mogućnost korištenja dinamičkih tajni (npr. privremene lozinke za baze podataka) i automatska rotacija, smanjujući površinu napada.
  • Centralizirano upravljanje: Sve tajne su na jednom sigurnom, auditabilnom mjestu.
  • Manje izmjene koda aplikacije: Aplikacija samo čita iz datoteke, ne mora direktno komunicirati s Vaultom.
  • Precizna kontrola pristupa: Vault politike omogućuju vrlo granularnu kontrolu pristupa.

Ograničenja Vault Agent Injectora

  • Kompleksnost implementacije: Postavljanje i konfiguriranje Vaulta i integracije zahtijeva značajno znanje i trud.
  • Dodatni resursi: Svaki pod dobiva dodatni sidecar kontejner, što povećava potrošnju resursa (CPU/Memorija).
  • Latency: Dodatni korak za dohvaćanje tajni pri pokretanju poda može neznatno produljiti vrijeme pokretanja.

Zaključak i najbolje prakse

Upravljanje tajnama u Kubernetesu je kompleksan zadatak koji zahtijeva pažljivo planiranje i implementaciju robustnih rješenja. Korištenje standardnih Kubernetes Secret objekata bez dodatne zaštite nije preporučljivo za osjetljive podatke.

Kombinacija Helm Secrets plugina i HashiCorp Vaulta nudi sveobuhvatno rješenje:

  • Helm Secrets osigurava da su tajne enkriptirane u Git repozitorijima, rješavajući problem "secrets-in-git". Idealan je za statičke tajne koje se ne rotiraju često i za manje osjetljive podatke.
  • HashiCorp Vault s Vault Agent Injectorom pruža najvišu razinu sigurnosti za dinamičke, visoko osjetljive tajne. Omogućuje end-to-end enkripciju, dinamičku rotaciju, detaljno auditiranje i preciznu kontrolu pristupa, osiguravajući da tajne nikada nisu u plaintextu unutar klastera.

Preporučene najbolje prakse:

  1. Nikada ne pohranjujte tajne u plaintextu u Git: Koristite Helm Secrets, SOPS ili slične alate za enkripciju.
  2. Koristite HashiCorp Vault za visoko osjetljive i dinamičke tajne: Za baze podataka, API ključeve i certifikate gdje je potrebna rotacija i najviša razina sigurnosti.
  3. Implementirajte least privilege princip: Dajte aplikacijama samo minimalna dopuštenja potrebna za pristup tajnama.
  4. Redovito rotirajte tajne: Automatizirajte rotaciju gdje god je to moguće. Vault to čini jednostavnim.
  5. Auditirajte pristup tajnama: Koristite Vaultov audit log za praćenje tko je i kada pristupio tajnama.
  6. Enkriptirajte etcd: Iako Vault rješava problem pohrane tajni, općenito je dobra praksa enkriptirati etcd kako bi se osigurala još jedna razina zaštite za sve podatke klastera.
  7. Koristite Kubernetes Service Accounts za autentikaciju na Vault: Ne koristite dugotrajne tokene ili statičke vjerodajnice unutar podova.
  8. Izbjegavajte environment varijable za tajne: Tajne u environment varijablama mogu procuriti putem logova, ps naredbi, i nisu adekvatno zaštićene. Koristite mountane datoteke.

Primjenom ovih strategija i alata, možete značajno poboljšati sigurnosni položaj vaših aplikacija i podataka unutar Kubernetes okruženja, gradeći otporne i sigurne sustave.

Izvori i dodatno čitanje

  1. HashiCorp Vault Agent Injector Overview
  2. Helm Secrets GitHub Repository
  3. Kubernetes Secrets Documentation
  4. Mozilla SOPS Documentation
B
Uredništvo portala

BAJT

Službeni autorski profil redakcije portala BAJT. Sadržaj priprema i provjerava uredništvo portala.