19-bo‘lim
Xavfsizlik va zaxira nusxa
Autentifikatsiya yoqish, foydalanuvchi va rollar, eng kam huquq qoidasi, tarmoq cheklovi, mongodump va mongorestore hamda mongoimport.
Ushbu bo‘lim mundarijasi
Ma'lumotlar bazasi dasturning eng qimmatli qismini saqlaydi. Uni himoyalashning ikki tomoni bor: kim tegishi mumkin va yo'qolsa qanday qaytariladi.
db.getUsers().users.forEach(u => db.dropUser(u.user))
db.getRoles().roles.forEach(r => db.dropRole(r.role))
db.kitob.insertMany([
{ _id: 1, nom: "Otkan kunlar", narx: 85000 },
{ _id: 2, nom: "Navoiy", narx: 95000 },
{ _id: 3, nom: "Ufq", narx: 64000 }
])
Autentifikatsiya odatiy holda o'chirilgan #
MongoDB ni yangi o'rnatganingizda u parolsiz ishlaydi. Bu qulay, lekin faqat o'z kompyuteringizda.
Uni yoqish uchun server --auth bayrog'i bilan ishga
tushiriladi:
mongod --dbpath ~/mongodata --auth
Yoki sozlama faylida:
security:
authorization: enabled
Bu tarixdagi eng katta ma'lumot sizib chiqishlarining sababi bo'lgan. 2017-yilda o'n minglab MongoDB serveri internetga parolsiz ochiq holda topilgan va ularning ma'lumotlari o'chirilib, evaziga to'lov talab qilingan.
Muammo ikkita sozlamada edi:
| Sozlama | Xavfli holat | To'g'ri holat |
|---|---|---|
bindIp | 0.0.0.0 - hamma tarmoqdan | 127.0.0.1 yoki ichki tarmoq |
authorization | O'chirilgan | Yoqilgan |
Zamonaviy versiyalarda bindIp odatiy holda
127.0.0.1 - ya'ni faqat o'z kompyuteringizdan. Lekin ko'p
qo'llanma "ishlamayapti" muammosini hal qilish uchun uni
0.0.0.0 ga o'zgartirishni maslahat beradi - va aynan shu
yerda xavf tug'iladi.
Uch qavatli himoya:
- Tarmoq: bazaga faqat dastur serveri ulana olsin.
- Autentifikatsiya: har ulanish parol talab qilsin.
- Huquq: har foydalanuvchida faqat kerakli ruxsat.
Birinchisi eng muhimi: baza umuman internetdan ko'rinmasa, qolgan ikkitasi ham buzilsa zarar bo'lmaydi.
Foydalanuvchi yaratish #
const r = db.createUser({
user: "hisobot",
pwd: "kuchli-parol-almashtiring",
roles: [ { role: "read", db: "dokon" } ]
})
r.ok
db.getUsers().users.map(u => ({ user: u.user, roles: u.roles }))
1
[ { user: 'hisobot', roles: [ { role: 'read', db: 'dokon' } ] } ]
Yuqoridagi misolda parol ochiq yozilgan - bu faqat o'qish uchun. Amalda u ikkita joyda qoladi:
| Qayerda | Muammo |
|---|---|
mongosh tarixi | Fayl sifatida diskda saqlanadi |
| Ekran | Kim qarab tursa ko'radi |
To'g'ri yo'l - passwordPrompt():
db.createUser({
user: "hisobot",
pwd: passwordPrompt(),
roles: [ { role: "read", db: "dokon" } ]
})
Buyruq bajarilganda mongosh parolni so'raydi va uni ekranga chiqarmaydi.
Dasturlarda esa parol muhit o'zgaruvchisida (env) yoki
sirlarni boshqarish tizimida saqlanadi - hech qachon kodda
emas.
O'rnatilgan rollar #
| Rol | Nima beradi |
|---|---|
read | Faqat o'qish |
readWrite | O'qish va yozish |
dbAdmin | Indeks, statistika, sxema - lekin ma'lumot emas |
userAdmin | Shu bazada foydalanuvchi boshqarish |
dbOwner | Yuqoridagi uchtasi birga |
clusterMonitor | Klaster holatini kuzatish |
backup / restore | Zaxira olish va tiklash |
root | Hammasi - faqat administrator uchun |
const a = db.createUser({
user: "dastur", pwd: "parol-1",
roles: [ { role: "readWrite", db: "dokon" } ]
})
const b = db.createUser({
user: "kuzatuvchi", pwd: "parol-2",
roles: [ { role: "read", db: "dokon" } ]
})
db.getUsers().users.map(u => u.user + ": " + u.roles[0].role).sort()
[ 'dastur: readWrite', 'kuzatuvchi: read' ]
O'z rolingizni yaratish #
O'rnatilgan rollar juda keng bo'lishi mumkin. Aniq ruxsat uchun o'z roling yaratiladi:
const r = db.createRole({
role: "kitob_oquvchi",
privileges: [ {
resource: { db: "dokon", collection: "kitob" },
actions: [ "find" ]
} ],
roles: []
})
r.ok
db.getRole("kitob_oquvchi", { showPrivileges: true }).privileges[0]
1
{ resource: { db: 'dokon', collection: 'kitob' }, actions: [ 'find' ] }
Bu rol faqat bitta to'plamdan o'qish huquqini beradi - qolgan to'plamlar ko'rinmaydi.
Ulanish satri #
Autentifikatsiya yoqilgandan keyin ulanish shunday ko'rinadi:
mongosh "mongodb://dastur:[email protected]:27017/dokon?authSource=dokon"
| Qism | Ma'nosi |
|---|---|
dastur:parol | Foydalanuvchi va parol |
/dokon | Qaysi bazaga ulanish |
authSource | Foydalanuvchi qaysi bazada yaratilgan |
authSource ko'pincha unutiladi: foydalanuvchi admin
bazasida yaratilgan bo'lsa, authSource=admin yozilishi
kerak - aks holda "Authentication failed" xatosi chiqadi.
Foydalanuvchini o'chirish va parol almashtirish #
const r = db.createUser({ user: "vaqtinchalik", pwd: "p1",
roles: [ { role: "read", db: "dokon" } ] })
db.changeUserPassword("vaqtinchalik", "yangi-parol").ok
db.getUsers().users.length
db.dropUser("vaqtinchalik").ok
db.getUsers().users.length
1
1
1
0
Zaxira nusxa - mongodump #
mongodump butun bazani fayllarga yozadi:
mongodump --port 27017 --db dokon --out ~/zaxira
writing dokon.kitob to /home/husanboy/zaxira/dokon/kitob.bson
writing dokon.mijoz to /home/husanboy/zaxira/dokon/mijoz.bson
done dumping dokon.kitob (2 documents)
done dumping dokon.mijoz (1 document)
Har to'plam uchun ikkita fayl yaratiladi:
kitob.bson - hujjatlar (ikkilik BSON)
kitob.metadata.json - indekslar va sozlamalar
| Bayroq | Ma'nosi |
|---|---|
--db | Faqat bitta baza |
--collection | Faqat bitta to'plam |
--query | Faqat shartga mos hujjatlar |
--gzip | Siqilgan holda saqlash |
--archive=fayl | Bitta faylga yozish |
--oplog | Nusxa olish paytidagi o'zgarishlarni ham qamrash |
Tiklash - mongorestore #
mongorestore --port 27017 \
--nsFrom "dokon.*" \
--nsTo "dokon_tiklandi.*" ~/zaxira
restoring dokon_tiklandi.kitob from /home/husanboy/zaxira/dokon/kitob.bson
finished restoring dokon_tiklandi.kitob (2 documents, 0 failures)
restoring dokon_tiklandi.mijoz from /home/husanboy/zaxira/dokon/mijoz.bson
finished restoring dokon_tiklandi.mijoz (1 document, 0 failures)
3 document(s) restored successfully. 0 document(s) failed to restore.
--nsFrom va --nsTo juftligi nusxani boshqa nom
bilan tiklash imkonini beradi. Bu zaxirani tekshirishning
eng xavfsiz usuli: asl baza o'z joyida qoladi.
Eng ko'p uchraydigan fojia: zaxira har kecha olinib kelingan, lekin kerak bo'lganda tiklanmagan.
Sabablari odatda oddiy:
| Sabab | Qanday sezilmay qoladi |
|---|---|
| Disk to'lgan | Fayl yarim yozilgan |
| Huquq yetmagan | Bir nechta to'plam tushmagan |
| Skript xato bergan | Chiqish hech kim o'qimaydigan jurnalga ketgan |
| Foydalanuvchilar tushmagan | Tiklangan bazaga hech kim ulana olmaydi |
Minimal talab - har oyda bir marta:
- Zaxirani boshqa bazaga tiklang (
--nsTo). - To'plamlardagi hujjatlar sonini asl baza bilan solishtiring.
- Bir nechta so'rovni ikkala bazada bajarib, natijani solishtiring.
- Tiklash qancha vaqt olganini yozib qo'ying.
Oxirgi band ko'pincha unutiladi. "Zaxiramiz bor" degan javob yetarli emas - "necha soatda tiklanadi?" degan savolga ham javob bo'lishi kerak.
mongoexport va mongoimport #
mongodump ikkilik format bilan ishlaydi. Boshqa tizim
bilan ma'lumot almashish uchun JSON yoki CSV kerak:
mongoexport --port 27017 --db dokon --collection kitob \
--type csv --fields _id,nom,narx --out kitob.csv
mongoimport --port 27017 --db dokon --collection kitob \
--type csv --headerline --file kitob.csv
| Vosita | Format | Qachon |
|---|---|---|
mongodump / mongorestore | BSON | Zaxira uchun |
mongoexport / mongoimport | JSON, CSV | Almashish uchun |
mongoexport ni zaxira uchun ishlatmangJSON hamma BSON turini saqlay olmaydi. Decimal128,
Date, ObjectId va Long matnga aylanadi va qaytarib
tiklanganda turi yo'qoladi.
Natijada narx maydoni Decimal128 o'rniga matn bo'lib
qoladi va hamma hisob-kitob buziladi.
--jsonFormat=canonical bayrog'i turlarni saqlab qoladi,
lekin baribir mongodump ishonchliroq: u bitta bayt ham
o'zgartirmaydi.
Qoida: zaxira uchun mongodump, boshqa tizimga
berish uchun mongoexport.
Yana uchta himoya qatlami #
| Qatlam | Nima qiladi |
|---|---|
| TLS | Tarmoqdagi ma'lumotni shifrlaydi |
| Diskda shifrlash | Disk o'g'irlansa ham fayl o'qilmaydi |
| Maydon darajasida shifrlash | Alohida maydonlar serverda ham shifrlangan |
Oxirgisi eng kuchli: Queryable Encryption bilan pasport
raqami yoki tibbiy ma'lumot shifrlangan holda saqlanadi va
shu holatda qidirilishi ham mumkin. Hatto baza
administratori ham asl qiymatni ko'ra olmaydi.
- Autentifikatsiyani qanday yoqish kerakligini yozing.
bindIpsozlamasi nega muhimligini tushuntiring.readroli bilan foydalanuvchi yarating.- Parolni buyruqda yozish nega xavfli - yozing.
passwordPrompt()ning farqini ayting.- O'z rolingizni yarating va uning huquqlarini ko'ring.
- Dastur nega
rootbilan ulanmasligi kerakligini tushuntiring. mongodumpbilan nusxa oling.- Uni
--nsTobilan boshqa bazaga tiklang va sonlarni solishtiring. mongoexportnega zaxira uchun yaramasligini yozing.
Xulosa #
- MongoDB odatiy holda parolsiz ishga tushadi -
--authbilan yoqiladi. - Eng muhim himoya - tarmoq: baza internetdan ko'rinmasin (
bindIp). - Rollar:
read,readWrite,dbAdmin,backup,rootva boshqalar. - Dastur hech qachon
rootbilan ulanmasin -readWriteyetarli. - Aniq ruxsat uchun
createRolebilan o'z roling yaratiladi. - Parolni buyruqda yozmang -
passwordPrompt()yoki muhit o'zgaruvchisi. authSourceunutilsa "Authentication failed" xatosi chiqadi.mongodump- zaxira uchun,mongoexport- almashish uchun.mongoexportBSON turlarini yo'qotadi - zaxira sifatida yaramaydi.- Tiklab ko'rilmagan zaxira - zaxira emas: uni
--nsTobilan muntazam sinang.
Keyingi bo'limda o'rgangan hamma narsani bitta amaliy loyihada birlashtiramiz.
O‘qish tarixini saqlamoqchimisiz?
Tizimga kirsangiz, tugatgan bo‘limlaringiz saqlanadi va qoldirgan joyingizdan davom etasiz.
Xatolik topdingizmi?
Imlo xatosi, ishlamaydigan kod yoki noto‘g‘ri ma‘lumotni ko‘rsangiz - bizga xabar bering. Har bir xabar administrator tomonidan ko‘rib chiqiladi.