DEV Community

Suleyman
Suleyman

Posted on • Edited on

HashiCorp Vault Nedir

HashiCorp Vault, temel olarak erişim bilgilerimizin (username-password, API token, SSL/TLS sertifikaları ) güvenli ve merkezi bir noktadan saklayıp yönetmemizi sağlayan bir uygulamadır.

Avantajları:

  • Merkezi noktadan yönetim: Birden fazla uygulama aynı vault sunucuna erişim sağlayıp istenilen bilgiye erişebilir.

  • Erişim ve Yetkilendirme: HashiCorp vault, birçok erişim metodunu destekler(token, username-password, güvenlik sertifikaları, LDAP) ve erişim sağlayan kişinin hangi bilgiye, hangi yetkilerle(read-write) sahip olacağını tanımlayabiliriz.

  • Şifreleme: HashiCorp Vault, client ile vault arasında ki veri akışını güvenli bir şifreleme ile yapar.

  • Restful API: Vault, RestAPI protokolünü desteklediği için secret oluşturma, silme, güncelleme gibi işlemleri HTTP/HTTPS protokolü üzerinden gerçekleştirebilir.

  • Dinamik Secret: Static bilgi saklayabileceğimiz gibi istersek periyodik olarak güncellenen dinamil secretlarda oluşturabiliriz. Bu durum güvenlik riskini de artırmaktadır.

  • Günlük ve İzleme: Vault kimin hangi bilgiye eriştiğini izler ve yazar bu sayede herhangi bir veri sızıntısında hangi kaynaktan gerçekleştiğini öğrenebiliriz.

  • Geniş Destek: Vault dünya genelinde birçok uygulamada ile entegrede çalışabilmektedir. Kubernetes, Ansible, Terraform, RabbitMQ ... Bu durum vault'un kullanımını da arttırmaktadır.

Vault Bileşenleri

Secret Engines: Vault'un gizli bilgileri (secrets) nasıl oluşturacağını, saklayacağını veya dinamik olarak üreteceğini tanımlayan modüllerdir.

1. Statik Gizemler: K/V (Key/Value) motoru, kullanıcı tarafından girilen statik şifreleri, API anahtarlarını veya TLS sertifikalarını depolar.
2. Dinamik Gizemler: Veritabanı (Database) veya AWS motorları, bir uygulama talep ettiğinde sadece o an için geçerli, kısa ömürlü (TTL) kimlik bilgileri (dinamik şifreler, geçici AWS anahtarları vb.) oluşturur.

Auth Methods: İstemcilerin vaulta erişimlerini denetler. Örneğin; token, username-password, güvenlik sertifikaları...

Politikalar: Auth Methods ile giriş yapabilen istemcinin hangi kaynaklara ve hangi yetkilerle erişeceğini belirler.

Audit Devices: Bilgilere erişim sağlayan kişilerin günlük kayıtlarının tutulduğu bileşendir.

Depolama Arka Ucu: Gizli verilerin, yapılandırma ayarlarının, politikaların ve kimlik doğrulama verilerinin kalıcı olarak depolanmasını sağlar. Veriler burada şifreli bir şekilde saklanmaktadır.

Vault Nasıl Çalışır

Master Key: Asıl amacı verileri şifreleyen "Data Encryption Key(DEK)" şifrelemektedir. Bu key sunucu ilk kurulduğunda veya başlatıldığında oluşturulur ve memory tutulur.

Data Encryption Key(DEK): Amacı vault üzerinde oluşturulan verileri şifrelemek ve çözmektir. Depolama arka ucunda tutulur. Ama master key olmadan bir anlamı yoktur çünkü verilere sadece bu key ile erişim sağlananamaktadır.

Seal ve Unseal Kavramları Nedir

Seal: Vault'un şifreli ve erişilemez olduğu durumdur. Bu durumda herhangi bir işlem yapılamaz. Vault ilk çalıştırıldığında ve restart olduğunda bu durumdadır(Auto-unseal yok ise)

Unseal: Vault'un kilidinin açılmasıdır. Bu işlem sırasında Master Key "Shamir’s Secret Sharing" isminde bir algoritma ile birkaç parçaya bölünür. key-shares = 5, key-threshold = 3 şeklinde bir tanım 5 tane unseal key'in oluşması ama 3 tanesinin yeterli olacağını belirtir. Bu key girildikten sonra master key oluşur ve vault'un kilidir açılır.

Auto-unseal, vault sunucu her yeniden başlatıldığında seal durumuna geçeceğini için production ortamda sıkıntı çıkarabilir. Bu durumda unseal işlemi otomotik gerçekleştilir. Bu işlem HSM cihazları ile yapılabilmektedir. Yaygın kullanılan servisler AWS KMS, Azure Key Vault, Google Cloud KMS

Vault Çalışma Modları
Vault 2 farklı çalışma modu ile çalıştırabiliriz.
1- Developer Mode
2- Production Mode

1- Developer Mode: Test/Dev ortamları için kullanılabilen ve verilerin memory üzerinde tutulduğu modtur. Auto-unseal özelliği bulunmaktadır. Amaç vaultu test etmek ve öğrenmek için tasarlanmıştır.

2- Production Mode: Amacı production ortamda kullanmaktır. Veriler arka depoloma sunucunda saklanır ve her başlatıldığında veriler silinmez ve sunucu her başlatıldığında seal(mühürlenmiş) olur. Standby node olarak kurulabileceği yüksek erişilebilirlik için birkaç node kurulabilir.

Docker ile Vault Kurulumu ve Kullanımı

Ben test etmek amaçlı docker üzerinde hızlıca bir vault contaıneri ayağa kaldıracağım ve kullanacağım. Bizim ki production mode çalışacak.

version: '3.7'

services:
  vault:
    image: hashicorp/vault:latest
    container_name: vault
    ports:
      - "8200:8200" 
    volumes:
      - ./config/vault.hcl:/vault/config/config.hcl:ro 
      - vault_data:/vault/file # 
    environment:   
      VAULT_CONFIG_FILE: /vault/config/config.hcl
      VAULT_ADDR: 'http://0.0.0.0:8200'
      VAULT_SKIP_CHOWN: true
    cap_add:
    command: "server"
volumes:
  vault_data:
Enter fullscreen mode Exit fullscreen mode

./config/vault.hcl

ui = true
listener "tcp" {
  address     = "0.0.0.0:8200"
  tls_disable = 1 # Test/Geliştirme için TLS devre dışı
}
storage "file" {
  path = "/vault/file" # Veri kalıcı volume'e yazılacak
}
Enter fullscreen mode Exit fullscreen mode

Aşağıdaki komutla ayağa kaldırabiliriz.

docker compose up -d

Temel Vault Komutları

vault --help, Kullanabileceğimiz komutları görüntüleyebiliriz.
vault login, Vault'a login olmamızı sağlar. Bizden token isteyecektir.

vault status, Vault'un durumunu öğrenebiliriz.

vault operator unseal
vault operator unseal
vault operator unseal , vault kilidini açmamızı sağlar

vault operator seal, vault'u kilitlemizi sağlar.

vault secrets enable -path=secret kv-v2, kv tipinde secret engine enable eder.

vault kv put secret/mysql username="root" password="12345", secret oluşturmamızı sağlar. kv put secret/mysql altındaki tüm verileri silip yeni verileri yazar yani override eder.

vault kv patch secret/mysql username="root" password="12345", bu üzerine yazar.

vault kv get secret/mysql, secret okumamızı sağlar.

vault kv get --format=json secret/mysql, secretlerı json formatında görüntülememizi sağlar.

Komut,İşlem Türü,Geri Alınabilir mi?,GUI Durumu
vault kv delete secret/mysql, Soft Delete , Veriler geri alınabilir.
vault kv destroy --versions=1 secret/mysql, Soft Delete (Version),Veri gider, metadata kalır.)
vault kv metadata delete secret/mysql ,Hard Delete, Veriler silinir.

Policy Olusturma

path "secret/data/mysql {
  capabilities = ["read", "list"]
}

Enter fullscreen mode Exit fullscreen mode

Bu policy ile kullanıcı sadece bu pathe erişim sağlayabilir ve
Eğer mysql path'nin altında da secretlar var ise "secret/data/mysql/*" şeklinde tanımlama yapılabilir. Bu policy admin-policy.hcl dosyasına yazıp aşağıdaki komutla oluşturabiliriz.

vault policy write mysql-policy admin-policy.hcl

Oluşturulan policy ' yi aşağıdaki komutla bir token ile eşleştiririz. Bu komuttan sonra bize bir token verecektir not almayı unutmayalım.

vault token create -policy=mysql-policy

vault write auth/userpass/users/ahmet \
    password="cok-gizli-sifre" \
    policies="admin-policy"
Enter fullscreen mode Exit fullscreen mode

Kubernetes ExternalSecret olarak Vault Kullanımı

Şimdi de yaygın olarak kullanılan kubernetes ve vaultu beraber kullanacağız. Burada kubernetes secretlarını vault üzerinden alacaktır.

Öncelikle externalSecrets operatörünü kurmamız gerekiyor. ExternalSecret, hassas verilerinizi Kubernetes'in kendi iç Secret nesnesinde depolamak yerine, bunları harici bir sır yönetim sisteminde (Secret Store) saklamanıza olanak tanır ve bu harici sırları otomatik olarak Kubernetes Secret nesnelerine senkronize eder.

helm repo add external-secrets https://charts.external-secrets.io
helm install external-secrets external-secrets/external-secrets --namespace external-secrets --create-namespace
Enter fullscreen mode Exit fullscreen mode

Şimdi aşağıdaki şekilde bir policy oluşturalım. Bu policy'nin aşağıdaki şekilde sadece read yetkisi olsun.

path "secret/data/mysql {
  capabilities = ["read"]
}
Enter fullscreen mode Exit fullscreen mode

Bir token oluşturalım ve bu policy ile ilişkilendirelim

vault token create -policy=k8s-read

Aşağdaki şekilde bir secret oluşturalım ve bir önceki komutta aldığımız tokenı yapıştıralım. Bu token bizim vaulta login olmamızı sağlayacak.

kubectl create secret generic vault-token-secret \
    --from-literal=token=<TOKEN> \
    -n vault-ns
Enter fullscreen mode Exit fullscreen mode

Aşağıdaki YAML ile bir SecretStore oluşturuyoruz. SecretStore bizim hangi sisteme bağlanacağımı ve hangi verilere ulaşacağımızı belirler.

cat <<EOF | kubectl apply -f -
apiVersion: external-secrets.io/v1
kind: SecretStore
metadata:
  name: vault-backend
  namespace: vault-ns
spec:
  provider:
    vault:
      server: "http://172.35.28.80:8200" # Vault IP Adresi
      path: "secret"  # Bu policy de belirttiğim secret engine ismidir.
      version: v2
      auth:
        tokenSecretRef:
          name: vault-token-secret #Bir önceki adımda oluşturulan secret 
          key: token              #Secret içindeki key adı
EOF

Enter fullscreen mode Exit fullscreen mode

Aşağıdaki komutla kontrol ettiğimizde STATUS=Valid ise erişim sağlanmıştır.

root@master:~/vault# kubectl get secretstore -n vault-ns
NAME            AGE   STATUS   CAPABILITIES   READY
vault-backend   35s   Valid    ReadWrite      True
Enter fullscreen mode Exit fullscreen mode

Sıra artık bu secretları kullanmakta. Aşağıdaki YAML manifesti ile ExternalSecret oluşturuyoruz ve hangi değerleri kullanacaksak belirliyoruz.

cat <<EOF | kubectl apply -f -
apiVersion: external-secrets.io/v1
kind: ExternalSecret
metadata:
  name: mysql-secret-vault
  namespace: vault-ns
spec:
  refreshInterval: 1m
  secretStoreRef:
    name: vault-backend #SecretStore ismi
    kind: SecretStore
  target:
    name: mysql-secret # Kubernetes'te oluşacak secret adı
  data:
  - secretKey: MYSQL_ROOT_PASSWORD
    remoteRef:
      key: secret/data/mysql # Vault'taki tam yol
      property: mysql_root_pass  #Bu değerler vault üzerinde tanımlı olanlar
  - secretKey: MYSQL_USERNAME
    remoteRef:
      key: secret/data/mysql
      property: mysql_user
  - secretKey: MYSQL_PASSWORD
    remoteRef:
      key: secret/data/mysql 
      property: mysql_pass
  - secretKey: MYSQL_DATABASE
    remoteRef:
      key: secret/data/mysql
      property: mysql_db
EOF
Enter fullscreen mode Exit fullscreen mode

Aşağıdaki komutlarla doğrulama işlemlerini yaptığımızda secretların oluştuğunu görüntüleyebiliriz.

root@master:~/vault# kubectl get externalsecret -n vault-ns
NAME                 STORETYPE     STORE           REFRESH INTERVAL   STATUS         READY
mysql-secret-vault   SecretStore   vault-backend   1m0s               SecretSynced   True
root@master:~/vault# kubectl get secret -n vault-ns
NAME                 TYPE     DATA   AGE
mysql-secret         Opaque   4      14s
vault-token-secret   Opaque   1      10m
root@master:~/vault# kubectl get secret mysql-secret -n vault-ns -oyaml
apiVersion: v1
data:
  MYSQL_DATABASE: c3VsZXltYW5EYXRhYmFzZQ==
  MYSQL_PASSWORD: YWhtZXQ=
  MYSQL_ROOT_PASSWORD: U3VsZXltYW4yMDI1ISE=
  MYSQL_USERNAME: c3VsZXltYW4=
Enter fullscreen mode Exit fullscreen mode

Bir sonraki makalede görüşmek üzere iyi günler.

Top comments (0)