Prodüksiyonda korumasız bir MongoDB instance’ı bırakmak, evinizin kapısını açık bırakıp tatile gitmek gibidir. 2017 yılında binlerce MongoDB veritabanı fidye yazılımı saldırılarına maruz kaldı çünkü kimlik doğrulama aktif değildi ve sunucular internete açıktı. Bu yazıda MongoDB’nin güvenlik katmanlarını, kimlik doğrulama mekanizmalarını ve yetkilendirme sistemini gerçek dünya senaryolarıyla birlikte ele alacağız.
MongoDB Güvenlik Mimarisine Genel Bakış
MongoDB güvenliği birkaç katmandan oluşur. Ağ seviyesi güvenlik, kimlik doğrulama (authentication), yetkilendirme (authorization) ve denetim (auditing) bu katmanların başlıcalarıdır. Çoğu sysadmin sadece ağ güvenliğiyle yetinip MongoDB’nin kendi güvenlik özelliklerini aktif etmeyi unutur. Bu ciddi bir hata.
Önce temel kavramları netleştirelim:
- Authentication (Kimlik Doğrulama): “Sen kimsin?” sorusunun cevabı. Kullanıcının kim olduğunu doğrular.
- Authorization (Yetkilendirme): “Ne yapabilirsin?” sorusunun cevabı. Kullanıcının hangi işlemleri yapabileceğini belirler.
- RBAC (Role-Based Access Control): MongoDB’nin yetkilendirme için kullandığı rol tabanlı erişim kontrolü sistemi.
Kimlik Doğrulamayı Aktif Etmek
Yeni kurulu bir MongoDB instance’ında kimlik doğrulama varsayılan olarak kapalıdır. İlk yapmanız gereken şey bir admin kullanıcısı oluşturup ardından auth’u aktif etmek.
Adım 1: Auth olmadan bağlan ve admin kullanıcı oluştur
mongosh --port 27017
use admin
db.createUser({
user: "siteAdmin",
pwd: passwordPrompt(),
roles: [
{ role: "userAdminAnyDatabase", db: "admin" },
{ role: "readWriteAnyDatabase", db: "admin" }
]
})
passwordPrompt() kullanmak önemli, çünkü şifreyi komut geçmişine düşürmüyor. Shell history’de şifre görmek istemezsiniz.
Adım 2: MongoDB konfigürasyonunu güncelle
sudo nano /etc/mongod.conf
security:
authorization: enabled
Adım 3: Servisi yeniden başlat
sudo systemctl restart mongod
sudo systemctl status mongod
Artık kimlik doğrulama olmadan bağlanmaya çalışırsanız hata alırsınız:
# Bu artık çalışmaz
mongosh --port 27017
# Doğru kullanım
mongosh --port 27017 -u siteAdmin -p --authenticationDatabase admin
MongoDB Kimlik Doğrulama Mekanizmaları
MongoDB birden fazla auth mekanizması destekler.
SCRAM (Salted Challenge Response Authentication Mechanism)
Varsayılan ve en yaygın kullanılan mekanizma. MongoDB 4.0+ ile birlikte SCRAM-SHA-256 destekleniyor. Eski SCRAM-SHA-1’e göre çok daha güvenli.
# mongod.conf içinde mekanizma belirtmek
security:
authorization: enabled
javascriptEnabled: false
setParameter:
authenticationMechanisms: SCRAM-SHA-256
X.509 Sertifika Tabanlı Kimlik Doğrulama
Kurumsal ortamlarda ve replica set konfigürasyonlarında sıklıkla kullanılır. Client-server iletişiminde SSL/TLS sertifikaları kullanılır.
# X.509 ile bağlanma örneği
mongosh --tls
--tlsCertificateKeyFile /etc/ssl/mongodb/client.pem
--tlsCAFile /etc/ssl/mongodb/ca.pem
--authenticationMechanism MONGODB-X509
--authenticationDatabase '$external'
--host mongodb.sirketim.com
LDAP ile Harici Kimlik Doğrulama
Enterprise edition ile LDAP entegrasyonu mümkün. Active Directory veya OpenLDAP ile kullanıcı yönetimini merkezi hale getirebilirsiniz. Bu özellik özellikle büyük organizasyonlarda kullanıcı yönetimini kolaylaştırır çünkü MongoDB’de ayrıca kullanıcı oluşturmanıza gerek kalmaz.
Kullanıcı Yönetimi
Uygulama Kullanıcısı Oluşturma
Her uygulama için ayrı bir kullanıcı oluşturmak best practice’dir. “Herkese admin ver” yaklaşımı felakete davet etmektir.
use myapp_production
db.createUser({
user: "myapp_user",
pwd: passwordPrompt(),
roles: [
{ role: "readWrite", db: "myapp_production" }
],
mechanisms: ["SCRAM-SHA-256"],
passwordDigestor: "server"
})
Read-Only Kullanıcı Oluşturma
Raporlama ve analiz araçları için salt okunur kullanıcılar tanımlamak gerekir:
use myapp_production
db.createUser({
user: "reporting_user",
pwd: passwordPrompt(),
roles: [
{ role: "read", db: "myapp_production" }
]
})
Bir gerçek dünya senaryosu olarak düşünelim: E-ticaret platformunuzda ana uygulama kullanıcısı, Elasticsearch sync servisi kullanıcısı ve BI aracı kullanıcısı olmak üzere en az üç farklı kullanıcı tanımlamanız gerekir. Her birinin yetkisi sadece ihtiyaç duyduğu kadardır.
Kullanıcı Bilgilerini Görüntüleme ve Güncelleme
# Mevcut kullanıcıları listele
use admin
db.getUsers()
# Belirli bir kullanıcının detaylarını gör
db.getUser("myapp_user")
# Kullanıcının şifresini değiştir
db.changeUserPassword("myapp_user", passwordPrompt())
# Kullanıcıya yeni rol ekle
db.grantRolesToUser("myapp_user", [
{ role: "read", db: "analytics_db" }
])
# Kullanıcıdan rol al
db.revokeRolesFromUser("myapp_user", [
{ role: "read", db: "analytics_db" }
])
Role-Based Access Control (RBAC)
MongoDB’nin RBAC sistemi yerleşik (built-in) roller ve özel (custom) roller olmak üzere iki kategoride ele alınır.
Yerleşik Roller
Veritabanı Kullanıcı Rolleri:
- read: Belirtilen veritabanında okuma yetkisi
- readWrite: Belirtilen veritabanında okuma ve yazma yetkisi
Veritabanı Admin Rolleri:
- dbAdmin: Schema yönetimi, index oluşturma, istatistik görüntüleme
- dbOwner: dbAdmin, readWrite ve userAdmin kombinasyonu
- userAdmin: Kullanıcı ve rol yönetimi
Cluster Admin Rolleri:
- clusterAdmin: Cluster yönetiminin tamamı, dikkatli kullanın
- clusterMonitor: Monitoring araçları için salt okunur erişim
- hostManager: mongod ve mongos process yönetimi
Tüm Veritabanları Rolleri:
- readAnyDatabase: Tüm veritabanlarında okuma (admin db üzerinden)
- readWriteAnyDatabase: Tüm veritabanlarında okuma-yazma
- userAdminAnyDatabase: Tüm veritabanlarında kullanıcı yönetimi
- dbAdminAnyDatabase: Tüm veritabanlarında admin işlemleri
Süper Kullanıcı Rolleri:
- root: Her şey üzerinde tam yetki, sadece acil durumlarda kullanın
Özel Rol Oluşturma
Yerleşik roller çoğu zaman yeterli gelmiyor. Özellikle belirli koleksiyonlara veya işlemlere kısıtlı erişim gerektiğinde custom role oluşturmak şarttır.
use admin
db.createRole({
role: "orderReadWrite",
privileges: [
{
resource: { db: "myapp_production", collection: "orders" },
actions: ["find", "insert", "update"]
},
{
resource: { db: "myapp_production", collection: "customers" },
actions: ["find"]
}
],
roles: []
})
Bu örnekte orderReadWrite rolü sadece orders koleksiyonuna okuma-yazma, customers koleksiyonuna ise sadece okuma yetkisi veriyor. Delete yetkisi kasıtlı olarak dışarıda bırakıldı.
Şimdi bu rolü bir kullanıcıya atayalım:
use myapp_production
db.createUser({
user: "order_service_user",
pwd: passwordPrompt(),
roles: [
{ role: "orderReadWrite", db: "admin" }
]
})
Ağ Güvenliği ile Birlikte Kullanım
Kimlik doğrulama ve yetkilendirme tek başına yeterli değil. Ağ katmanında da kısıtlamalar uygulamak gerekir.
# /etc/mongod.conf
net:
port: 27017
bindIp: 127.0.0.1,10.0.1.50 # Sadece localhost ve uygulama sunucusu IP'si
tls:
mode: requireTLS
certificateKeyFile: /etc/ssl/mongodb/server.pem
CAFile: /etc/ssl/mongodb/ca.pem
security:
authorization: enabled
javascriptEnabled: false
operationProfiling:
slowOpThresholdMs: 100
mode: slowOp
Firewall Kuralları
# UFW ile MongoDB portunu sadece uygulama sunucusuna aç
sudo ufw deny 27017
sudo ufw allow from 10.0.1.50 to any port 27017
sudo ufw allow from 10.0.1.51 to any port 27017 # Replica set üyesi
# iptables ile aynı işlem
iptables -A INPUT -p tcp --dport 27017 -s 10.0.1.50 -j ACCEPT
iptables -A INPUT -p tcp --dport 27017 -j DROP
Replica Set Güvenliği: Keyfile Authentication
Replica set üyeleri arasındaki iletişimin güvenliği için keyfile veya X.509 kullanılır. Keyfile daha basit bir yöntemdir.
# Keyfile oluştur
openssl rand -base64 756 > /etc/mongodb/keyfile
chmod 400 /etc/mongodb/keyfile
chown mongodb:mongodb /etc/mongodb/keyfile
# /etc/mongod.conf
security:
authorization: enabled
keyFile: /etc/mongodb/keyfile
Bu keyfile’ı tüm replica set üyelerine aynı şekilde kopyalamanız gerekir. Aksi halde üyeler birbirini tanımaz.
# Keyfile'ı diğer sunuculara kopyala
scp /etc/mongodb/keyfile mongodb-replica2:/etc/mongodb/keyfile
scp /etc/mongodb/keyfile mongodb-replica3:/etc/mongodb/keyfile
Denetim (Auditing) ve Loglama
Kimin ne zaman ne yaptığını takip etmek güvenliğin önemli bir parçası. MongoDB Enterprise’da gelişmiş audit log özellikleri var, ama Community Edition’da da temel loglama yapılandırabilirsiniz.
# /etc/mongod.conf - Loglama ayarları
systemLog:
destination: file
path: /var/log/mongodb/mongod.log
logAppend: true
verbosity: 1
component:
accessControl:
verbosity: 2
command:
verbosity: 1
Log’ları düzenli olarak analiz etmek için basit bir bash scripti:
#!/bin/bash
# MongoDB auth hatalarını raporla
LOGFILE="/var/log/mongodb/mongod.log"
DATE=$(date +%Y-%m-%d)
OUTPUT="/var/log/mongodb/auth_report_${DATE}.txt"
echo "=== MongoDB Auth Hata Raporu - ${DATE} ===" > $OUTPUT
echo "" >> $OUTPUT
echo "Başarısız giriş denemeleri:" >> $OUTPUT
grep "Authentication failed" $LOGFILE |
grep "$DATE" |
awk '{print $NF}' |
sort | uniq -c | sort -rn >> $OUTPUT
echo "" >> $OUTPUT
echo "Yetkisiz erişim denemeleri:" >> $OUTPUT
grep "not authorized" $LOGFILE |
grep "$DATE" |
wc -l >> $OUTPUT
echo "" >> $OUTPUT
echo "Rapor tamamlandı: $OUTPUT"
# Belirli bir eşiği aşarsa mail at
FAILED_COUNT=$(grep "Authentication failed" $LOGFILE | grep "$DATE" | wc -l)
if [ $FAILED_COUNT -gt 10 ]; then
echo "UYARI: $DATE tarihinde $FAILED_COUNT başarısız giriş denemesi!" |
mail -s "MongoDB Güvenlik Alarmı" [email protected]
fi
Güvenlik Açıklarını Tespit Etme
MongoDB’nin kendi mongosh üzerinden güvenlik durumunu kontrol edebilirsiniz:
# Kimlik doğrulama durumunu kontrol et
db.adminCommand({ getCmdLineOpts: 1 })
# Tüm kullanıcıları listele (admin olarak)
use admin
db.system.users.find({}, { user: 1, db: 1, roles: 1 }).pretty()
# Mevcut bağlantıları ve oturumları görüntüle
db.currentOp()
# Gereksiz yere admin rolü olan kullanıcıları bul
db.system.users.find({
"roles.role": "root"
}, { user: 1, db: 1 })
Sık Yapılan Güvenlik Hataları
Gerçek ortamlarda tekrar tekrar gördüğüm hatalar:
- Connection string’e şifre gömmek:
mongodb://admin:sifre123@localhostşeklinde connection string’i kod içine yazmak ve bunu git’e push etmek. Environment variable kullanın.
- Tüm servislere aynı kullanıcıyı vermek: Her mikroservis, her araç için ayrı kullanıcı tanımlayın. Bir servis ele geçirildiğinde diğerleri etkilenmesin.
- JavaScript’i açık bırakmak:
javascriptEnabled: falseayarını mutlaka yapın. Server-side JavaScript’e ihtiyacınız yoksa kapatın.
- Şifre politikası uygulamamamak: MongoDB’nin built-in şifre politikası zayıf. Güçlü şifreler için organizasyonel politika oluşturun ve bunu CI/CD süreçlerinizde zorunlu kılın.
- Keyfile’ın yedeğini almamak: Replica set keyfile’ını kaybederseniz büyük sorun yaşarsınız. Vault veya başka bir secret management aracında saklayın.
- Test ortamı kullanıcılarını production’a taşımak: “Hızlıca” diye test ortamından kopyalanan zayıf şifreli kullanıcılar production’da yıllarca kalabiliyor.
Pratik Güvenlik Kontrol Listesi
Bir MongoDB sunucusunu devreye almadan önce şu adımları tamamlayın:
authorization: enabledayarının aktif olduğunu doğrulayınjavascriptEnabled: falseolduğunu kontrol edinbindIpayarının sadece gerekli IP’leri içerdiğini gözden geçirin- Her uygulama için ayrı, minimum yetkili kullanıcı oluşturun
- Admin şifresinin güçlü olduğunu (en az 20 karakter, karmaşık) doğrulayın
- TLS/SSL’in aktif olduğunu kontrol edin
- Firewall kurallarının MongoDB portunu kısıtladığını test edin
- Keyfile yedeğinin güvenli bir yerde saklandığını doğrulayın
- Log rotasyonunun konfigüre edildiğini kontrol edin
- Audit script veya monitoring’in çalıştığını doğrulayın
Sonuç
MongoDB güvenliği katmanlı bir yapıda ele alınmalı. Sadece bir şeye güvenmek, tek nokta başarısızlığı (single point of failure) yaratır. Kimlik doğrulama aktif, yetkilendirme en az ayrıcalık prensibine göre yapılandırılmış, ağ katmanı kısıtlı ve loglama çalışır durumda olmalı.
En önemli pratiği tekrar vurgulayalım: Her servis, her araç, her kullanıcı için ayrı MongoDB kullanıcısı oluşturun. Bu sizi olası bir güvenlik ihlalinin “blast radius”ini minimize eder. Bir mikroservisin credentials’ları ele geçirilse bile sadece o servisin erişebildiği verilere ulaşılabilir.
Güvenlik bir kez yapılıp unutulan bir şey değil. Düzenli olarak kullanıcı listesini gözden geçirin, kullanılmayan hesapları silin, log’ları analiz edin ve MongoDB güvenlik güncellemelerini takip edin. Sistem yöneticisinin işi asla bitmez, ama iyi yapılandırılmış bir güvenlik altyapısıyla en azından rahat uyursunuz.