MongoDB'de kullanıcı ve rol yönetimi, db.createUser() ile kullanıcı oluşturup ona rol vermek, gerektiğinde db.grantRolesToUser() ve db.revokeRolesFromUser() ile rolleri değiştirmek, yerleşik roller yetmediğinde de db.createRole() ile kendi rolünüzü tanımlamak demektir. Bir rol, belirli kaynaklar üzerinde belirli eylemleri yapma ayrıcalıkları taşır; kullanıcı yalnızca kendisine verilen rollerin izin verdiği işlemleri yapabilir, bunun dışında sisteme hiçbir erişimi yoktur.
Bu yazı, erişim denetimi açık bir MongoDB sunucusunda kimlerin ne yapabileceğini nasıl düzenleyeceğinizi anlatır: yerleşik rollerin ne işe yaradığını, kullanıcıları nasıl oluşturup güncelleyeceğinizi, rolleri nasıl ekleyip kaldıracağınızı, özel rolü nasıl yazacağınızı ve hangi rollerin aslında süper kullanıcı anlamına geldiğini. Erişim denetimini henüz açmadıysanız önce MongoDB authentication etkinleştirme yazısını uygulayın; buradaki işlemler bir kullanıcı yöneticisiyle doğrulanmış olmanızı varsayar.
Temel kavramlar: rol, ayrıcalık, kaynak ve eylem
MongoDB rol tabanlı erişim denetimi (RBAC) kullanır. Bir ayrıcalık (privilege), bir kaynak ile o kaynakta izin verilen eylemlerden oluşur. Kaynak bir veritabanı, bir koleksiyon, bir koleksiyon kümesi ya da kümenin kendisi (cluster) olabilir. Eylem ise find, insert, createIndex, serverStatus gibi izin verilen bir işlemdir. Bir rol bu ayrıcalıkları ya doğrudan listeler ya da başka rollerden miras alır.
Belgelerdeki kritik kurallardan biri şudur: roller ayrıcalıkları asla daraltmaz. Kullanıcının iki rolü varsa erişimi daha geniş olan geçerli olur. Örneğin readWriteAnyDatabase rolüne sahip bir kullanıcıya bir veritabanında ayrıca read vermek, o veritabanındaki yazma iznini kaldırmaz. Yetki kaldırmanın tek yolu ilgili rolü kullanıcıdan geri almaktır.
Bir rol tanımlandığı veritabanına bağlıdır. MongoDB rolü, veritabanı adı ile rol adının birleşimiyle benzersiz olarak tanımlar ve tüm rol bilgisini admin veritabanındaki system.roles koleksiyonunda saklar. Kullanıcı bilgileri de aynı şekilde admin.system.users içinde durur; belgeler bu koleksiyonları elle değiştirmemenizi, kullanıcı ve rol yönetimi yöntemlerini kullanmanızı ister.
Yerleşik roller

MongoDB, sık ihtiyaç duyulan erişim düzeyleri için hazır roller sunar. Her yerleşik rol, kendi veritabanındaki sistem dışı koleksiyonlar için veritabanı düzeyinde, sistem koleksiyonları için koleksiyon düzeyinde erişim tanımlar. Sistem koleksiyonları <veritabanı>.system.* ad alanındakiler ile local.replset.* koleksiyonlarıdır.
| Rol | Nerede | Ne sağlar |
|---|---|---|
| read | Her veritabanı | Sistem dışı koleksiyonlarda ve system.js içinde okuma |
| readWrite | Her veritabanı | read yetkilerine ek olarak veri değiştirme, koleksiyon ve indeks oluşturma |
| dbAdmin | Her veritabanı | Şema işleri, indeksleme, istatistik; kullanıcı ve rol yönetimi yok, tam okuma da yok |
| userAdmin | Her veritabanı | O veritabanında kullanıcı ve rol oluşturma ve değiştirme |
| dbOwner | Her veritabanı | readWrite, dbAdmin ve userAdmin birleşimi |
| clusterMonitor | admin | İzleme araçları için salt okunur erişim |
| hostManager | admin | Sunucuları izleme ve yönetme |
| clusterManager | admin | Küme yönetimi ve izleme; config ve local veritabanlarına erişim |
| clusterAdmin | admin | clusterManager, clusterMonitor ve hostManager birleşimi ve dropDatabase |
| backup | admin | Yedek almak için gereken en az ayrıcalık |
| restore | admin | Yedekten geri yükleme ayrıcalıkları |
| readAnyDatabase | admin | local ve config dışında tüm veritabanlarında read ve listDatabases |
| readWriteAnyDatabase | admin | local ve config dışında tüm veritabanlarında readWrite |
| dbAdminAnyDatabase | admin | local ve config dışında tüm veritabanlarında dbAdmin |
| userAdminAnyDatabase | admin | local ve config dışında tüm veritabanlarında userAdmin |
| root | admin | Tüm kaynaklarda tam yetki |
Tablodaki bazı satırlar ilk bakışta yanıltıcı olabilir. dbAdmin adına rağmen veritabanındaki sıradan koleksiyonlarda find gibi tam okuma yetkisi içermez; indeks oluşturma, collMod, compact, profiler açma gibi yönetim eylemleri verir. root rolü ise readWriteAnyDatabase, dbAdminAnyDatabase, userAdminAnyDatabase, clusterAdmin, restore ve backup rollerinin toplamıdır; belgelere göre MongoDB 8.0 ve sonrasında bu rol bypassDefaultMaxTimeMS eylemini de içerir, yani bu kullanıcının sorguları defaultMaxTimeMS değerini yok sayar.
Ayrıca MongoDB küme üyelerini temsil eden nesnelere __system adında iç bir rol atar. Belgeler bu rolün uygulamalara veya insan yöneticilere verilmemesini açıkça söyler; tüm eylemlere gerçekten ihtiyaç varsa bunun yerine özel bir rol tanımlanmasını önerir.
Kullanıcı oluşturma: db.createUser() alanları
db.createUser() kullanıcıyı çalıştırıldığı veritabanında oluşturur; o veritabanı kullanıcının kimlik doğrulama veritabanı olur. Yöntemin aldığı kullanıcı belgesindeki alanlar şunlardır:
| Alan | Zorunlu mu | Açıklama |
|---|---|---|
| user | Evet | Yeni kullanıcının adı |
| pwd | $external dışında evet | Düz metin parola veya passwordPrompt() |
| roles | Evet | Rol listesi; rolsüz kullanıcı için boş dizi verilebilir |
| customData | Hayır | Ad soyad, personel numarası gibi serbest bilgi |
| authenticationRestrictions | Hayır | İzin verilen istemci ve sunucu IP adresleri veya CIDR aralıkları |
| mechanisms | Hayır | SCRAM-SHA-1, SCRAM-SHA-256 ya da ikisi (varsayılan ikisi) |
| passwordDigestor | Hayır | server (varsayılan) veya client; client, SCRAM-SHA-256 ile uyumsuz |
roles dizisinde, kullanıcıyla aynı veritabanındaki bir rolü yalnızca adıyla ("readWrite") yazabilirsiniz. Başka bir veritabanındaki rol için ise belge biçimi zorunludur: { role: "read", db: "raporlar" }. Aşağıdaki örnekte kullanıcı magaza veritabanında oluşturuluyor, kendi veritabanında okuma ve yazma, raporlar veritabanında yalnızca okuma yetkisi alıyor:
use magaza
db.createUser(
{
user: "siparisServisi",
pwd: passwordPrompt(),
customData: { ekip: "backend" },
roles: [
"readWrite",
{ role: "read", db: "raporlar" }
]
}
)Belgelerde dikkat edilmesi gereken birkaç davranış daha var. local veritabanında kullanıcı oluşturamazsınız. Aynı veritabanında aynı adla ikinci bir kullanıcı oluşturmaya çalışırsanız yöntem yinelenen kullanıcı hatası döndürür. Replica set üzerinde çalıştırıldığında bu yöntem varsayılan olarak "majority" yazma onayıyla yürütülür. MongoDB her kullanıcıya oluşturulurken benzersiz bir userId atar.
Kullanıcıları ve rollerini görüntüleme
Tek bir kullanıcının bilgisini görmek için kullanıcının kimlik doğrulama veritabanına geçip db.getUser() çağırırsınız. Dönen belgedeki roles alanı kullanıcının tüm rollerini listeler. Bir veritabanındaki tüm kullanıcılar için db.getUsers() kullanılır; bu yöntem usersInfo: 1 komutunu sarar.
use magaza
db.getUser("siparisServisi")
db.getUsers( { showCredentials: false, filter: { "customData.ekip": "backend" } } )db.getUsers() seçeneklerinde showCredentials varsayılan olarak false'tur ve true yapıldığında parola özetini gösterir. showCustomData varsayılan olarak true'dur. filter ise $match aşaması koşullarıyla kullanıcıları süzmenizi sağlar.
Rol verme ve geri alma
Var olan bir kullanıcıya rol eklemek için db.grantRolesToUser(), rol kaldırmak için db.revokeRolesFromUser() kullanılır. İkisini de kullanıcının oluşturulduğu veritabanında çalıştırırsınız. Rol vermek için o rolün veritabanında grantRole, geri almak için revokeRole eylemine sahip olmanız gerekir; userAdmin ve userAdminAnyDatabase bu eylemleri sağlar.
use magaza
db.grantRolesToUser(
"siparisServisi",
[ { role: "read", db: "arsiv" } ]
)
db.revokeRolesFromUser(
"siparisServisi",
[ { role: "read", db: "raporlar" } ]
)Bir rolün sağladığı ayrıcalıkların yalnızca bir kısmını geri almak istiyorsanız belgelerin önerdiği yol, rolün tamamını geri alıp yalnızca gereken ayrıcalıkları içeren başka bir rol vermektir. Böyle bir rol yoksa özel rol oluşturmanız gerekir. Sharded cluster'da yapılan değişiklik komutun çalıştığı mongos'ta hemen geçerli olur, diğer mongos örneklerinde ise kullanıcı önbelleğinin yenilenmesi 10 dakikaya kadar sürebilir (userCacheInvalidationIntervalSecs parametresi).
Parola değiştirme ve kullanıcı silme
Bir kullanıcının parolasını değiştirmek için db.changeUserPassword() yeterlidir. Başka bir kullanıcının parolasını değiştirebilmek için o veritabanında changePassword eylemine sahip olmanız gerekir. Yeni parolayı ekrana yazmamak için burada da passwordPrompt() kullanabilirsiniz:
use magaza
db.changeUserPassword("siparisServisi", passwordPrompt())
db.dropUser("eskiRaporcu")db.dropUser() kullanıcıyı çalıştırıldığı veritabanından siler. Belgeler önemli bir uyarı yapar: userAdminAnyDatabase rolüne sahip bir kullanıcıyı silmeden önce kullanıcı yönetimi yetkisi olan en az bir başka kullanıcınız olduğundan emin olun. Aksi halde kullanıcı ekleyip yönetebilecek kimse kalmayabilir. Güvenlik kontrol listesi de kullanıcıları düzenli aralıklarla gözden geçirmenizi ve yenilemenizi önerir.
Özel rol tanımlama: db.createRole()

Yerleşik roller ihtiyacınızı tam karşılamıyorsa kendi rolünüzü tanımlarsınız. db.createRole(), privileges dizisinde açık ayrıcalıkları, roles dizisinde miras alınacak rolleri alır. Rol oluşturmak için ilgili veritabanında createRole ve grantRole eylemleri gerekir. Ayrıcalıklardaki kaynak belgesi şu biçimlerden biridir:
| Kaynak belgesi | Anlamı |
|---|---|
| { db: "magaza", collection: "urunler" } | Belirli veritabanındaki belirli koleksiyon |
| { db: "magaza", collection: "" } | Veritabanındaki tüm sistem dışı koleksiyonlar |
| { db: "", collection: "urunler" } | Tüm veritabanlarında bu adı taşıyan koleksiyonlar |
| { db: "", collection: "" } | local ve config dışında tüm veritabanlarındaki sistem dışı koleksiyonlar |
| { cluster: true } | Kümenin kendisi (shutdown, serverStatus gibi sistem eylemleri) |
Kapsam kuralı önemlidir: admin dışındaki bir veritabanında oluşturulan rol yalnızca kendi veritabanına ait ayrıcalıkları içerebilir ve yalnızca aynı veritabanındaki rollerden miras alabilir. Başka veritabanlarını, tüm veritabanlarını ya da { cluster: true } kaynağını kullanan bir rolün admin veritabanında oluşturulması gerekir. Aşağıdaki örnek, yalnızca magaza.urunler koleksiyonunu okuyup güncelleyebilen bir rol tanımlar ve onu bir kullanıcıya verir:
use magaza
db.createRole(
{
role: "urunEditoru",
privileges: [
{ resource: { db: "magaza", collection: "urunler" }, actions: [ "find", "update" ] }
],
roles: []
}
)
db.grantRolesToUser( "siparisServisi", [ "urunEditoru" ] )Küme kaynağı gerektiren bir rol örneği olarak belgeler, yalnızca mongostat çalıştırmaya yetecek kadar ayrıcalık veren bir rolü admin veritabanında tanımlar. Aynı yaklaşımla bir izleme hesabına yalnızca serverStatus eylemini verebilirsiniz:
use admin
db.createRole(
{
role: "izlemeRolu",
privileges: [
{ resource: { cluster: true }, actions: [ "serverStatus" ] }
],
roles: []
}
)Bir rolün gerçekte ne verdiğini görmek için db.getRole() yöntemini showPrivileges: true ile çağırın. Dönen belgede privileges yalnızca rolde doğrudan yazılan ayrıcalıkları, inheritedPrivileges ise miras alınanlar dahil tüm ayrıcalıkları listeler; rol başka rollerden miras almıyorsa iki alan aynıdır. Kullanılmayan özel bir rolü db.dropRole() ile silebilirsiniz.
use magaza
db.getRole( "urunEditoru", { showPrivileges: true } )IP kısıtlaması: authenticationRestrictions
Kullanıcıya (veya role) authenticationRestrictions ekleyerek kimlik doğrulamanın yalnızca belirli adreslerden yapılmasını sağlayabilirsiniz. Bu belge yalnızca iki alan içerebilir; tanınmayan bir alan olursa sunucu hata verir. clientSource, istemcinin IP adresinin listede veya listedeki bir CIDR aralığında olmasını ister. serverAddress ise bağlantının sunucunun hangi IP adresi üzerinden kabul edildiğini denetler.
use admin
db.createUser(
{
user: "raporPaneli",
pwd: passwordPrompt(),
roles: [ { role: "read", db: "raporlar" } ],
authenticationRestrictions: [ {
clientSource: [ "192.0.2.0" ],
serverAddress: [ "198.51.100.0" ]
} ]
}
)Belgelerin uyarısına göre bir kullanıcı birbiriyle uyumsuz kısıtlamalar taşıyan birden çok rolü miras alırsa kullanılamaz hale gelir; örneğin bir rol clientSource için bir adres, diğeri başka bir adres istiyorsa sunucu bu kullanıcıyı doğrulayamaz. Kısıtlamalı rol oluşturmak için ayrıca setAuthenticationRestriction eylemi gerekir. Bu özellik ağ düzeyindeki güvenlik duvarının yerine geçmez, onu tamamlar; ağ katmanı için güvenlik kontrol listesine bakın.
Örnek senaryo: tek sunucuda dört hesap
Kendi VPS'inizde bir mağaza uygulaması çalıştırdığınızı düşünün. Belgelerdeki en az ayrıcalık ve erişim yalıtımı ilkesine göre makul bir düzen şöyle olur: admin veritabanında userAdminAnyDatabase rolüne sahip bir yönetici; magaza veritabanında yalnızca readWrite alan uygulama kullanıcısı; raporlama için yalnızca read alan ayrı bir kullanıcı; yedekleme betikleri için de admin veritabanında backup rolüne sahip bir hesap. Belgelere göre backup rolü mongodump ile tüm bir mongod örneğini yedeklemeye yeterlidir, geri yükleme için ise restore rolü kullanılır.
use admin
db.createUser(
{
user: "yedekci",
pwd: passwordPrompt(),
roles: [ { role: "backup", db: "admin" } ]
}
)Böylece uygulama kodu ele geçirilse bile saldırgan kullanıcı oluşturamaz ya da başka veritabanlarına yazamaz; yedek hesabının parolası sızsa bile veri değiştirilemez. Yedekleme araçlarının ayrıntısı mongodump ve mongorestore yazısında anlatılıyor.
Sık yapılan hatalar

- Aynı kişiyi her veritabanında ayrı kullanıcı olarak oluşturmak: Belgeler tek kullanıcı oluşturup her veritabanı için ayrı rol vermeyi önerir.
- Rol eklemek için db.updateUser() kullanmak:
rolesdizisi tamamen değişir ve mevcut roller kaybolur. - Daha dar bir rol vererek yetki kısmaya çalışmak: Roller yetkiyi daraltmaz; geniş rolü geri almanız gerekir.
- Küme kaynağı kullanan rolü sıradan bir veritabanında oluşturmak: Böyle roller
adminveritabanında tanımlanmalıdır. - Son kullanıcı yöneticisini silmek: Önce yönetici yetkisi olan başka bir kullanıcı bulunduğundan emin olun.
- system.users koleksiyonunu elle düzenlemek: Kullanıcı yönetimi yöntemleri dışında bu koleksiyona dokunmayın.
Sık Sorulan Sorular
Kullanıcıyı hangi veritabanında oluşturmalıyım?
Teknik olarak her veritabanında olabilir; kullanıcının yetkileri kimlik doğrulama veritabanıyla sınırlı değildir. Yönetici ve küme çapında rol taşıyan hesapları admin'de, tek bir uygulamaya ait hesabı o uygulamanın veritabanında tutmak düzeni kolaylaştırır. Hangi veritabanını seçerseniz bağlantı dizesindeki authSource değeri de o olmalıdır.
Bir kullanıcıya root vermek pratik değil mi?
Pratiktir ama root tüm kaynaklarda tam yetki verir. Uygulama hesabına root vermek, en az ayrıcalık ilkesine aykırıdır ve uygulamadaki tek bir açığın tüm sunucuyu etkilemesine yol açar.
Rol değişikliği bağlı oturumlarda hemen geçerli olur mu?
Tek sunucuda ve komutun çalıştığı mongos'ta değişiklik hemen uygulanır. Sharded cluster'daki diğer mongos örneklerinde ise belgeler önbelleğin yenilenmesinin 10 dakikaya kadar sürebileceğini belirtir.
Rolsüz bir kullanıcı oluşturmanın anlamı var mı?
roles: [] ile kullanıcı oluşturup rolleri daha sonra db.grantRolesToUser() ile vermek mümkündür. Rolü olmayan kullanıcı kimlik doğrulayabilir ama erişim denetimi açıkken neredeyse hiçbir işlem yapamaz.
Marka adları sahiplerine aittir. Bu yazı bağımsız bir teknik rehberdir; adı geçen kuruluşlarla bayilik veya ortaklık ilişkisi bulunduğu anlamına gelmez.
İlgili içerikler: MongoDB öğrenme rehberi · MongoDB authentication etkinleştirme · MongoDB güvenlik kontrol listesi · mongodump ve mongorestore · MongoDB production notları · VPS güvenlik sertleştirme