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:
./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
}
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"]
}
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"
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
Ş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"]
}
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
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
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
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
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=
Bir sonraki makalede görüşmek üzere iyi günler.
Top comments (0)