19-bo‘lim

Xavfsizlik va zaxira nusxa

Autentifikatsiya yoqish, foydalanuvchi va rollar, eng kam huquq qoidasi, tarmoq cheklovi, mongodump va mongorestore hamda mongoimport.

🕑 14 daqiqa o‘qish 📄 1 007 so‘z 👁 0 marta ko‘rilgan
Ushbu bo‘lim mundarijasi
  1. Autentifikatsiya odatiy holda o'chirilgan
  2. Foydalanuvchi yaratish
  3. O'rnatilgan rollar
  4. O'z rolingizni yaratish
  5. Ulanish satri
  6. Foydalanuvchini o'chirish va parol almashtirish
  7. Zaxira nusxa - mongodump
  8. Tiklash - mongorestore
  9. mongoexport va mongoimport
  10. Yana uchta himoya qatlami
  11. Xulosa

Ma'lumotlar bazasi dasturning eng qimmatli qismini saqlaydi. Uni himoyalashning ikki tomoni bor: kim tegishi mumkin va yo'qolsa qanday qaytariladi.

JavaScript
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:

Natija
mongod --dbpath ~/mongodata --auth

Yoki sozlama faylida:

Natija
security:
  authorization: enabled
Internetga ochiq parolsiz MongoDB

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:

SozlamaXavfli holatTo'g'ri holat
bindIp0.0.0.0 - hamma tarmoqdan127.0.0.1 yoki ichki tarmoq
authorizationO'chirilganYoqilgan

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:

  1. Tarmoq: bazaga faqat dastur serveri ulana olsin.
  2. Autentifikatsiya: har ulanish parol talab qilsin.
  3. Huquq: har foydalanuvchida faqat kerakli ruxsat.

Birinchisi eng muhimi: baza umuman internetdan ko'rinmasa, qolgan ikkitasi ham buzilsa zarar bo'lmaydi.

Foydalanuvchi yaratish #

JavaScript
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 }))
Natija
1
[ { user: 'hisobot', roles: [ { role: 'read', db: 'dokon' } ] } ]
Parolni buyruqda yozmang

Yuqoridagi misolda parol ochiq yozilgan - bu faqat o'qish uchun. Amalda u ikkita joyda qoladi:

QayerdaMuammo
mongosh tarixiFayl sifatida diskda saqlanadi
EkranKim qarab tursa ko'radi

To'g'ri yo'l - passwordPrompt():

Natija
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 #

RolNima beradi
readFaqat o'qish
readWriteO'qish va yozish
dbAdminIndeks, statistika, sxema - lekin ma'lumot emas
userAdminShu bazada foydalanuvchi boshqarish
dbOwnerYuqoridagi uchtasi birga
clusterMonitorKlaster holatini kuzatish
backup / restoreZaxira olish va tiklash
rootHammasi - faqat administrator uchun
JavaScript
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()
Natija
[ 'dastur: readWrite', 'kuzatuvchi: read' ]

O'z rolingizni yaratish #

O'rnatilgan rollar juda keng bo'lishi mumkin. Aniq ruxsat uchun o'z roling yaratiladi:

JavaScript
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]
Natija
1
{ resource: { db: 'dokon', collection: 'kitob' }, actions: [ 'find' ] }

Bu rol faqat bitta to'plamdan o'qish huquqini beradi - qolgan to'plamlar ko'rinmaydi.

Har rol uchun eng kam huquq Veb-dastur readWrite faqat o'z bazasida indeks o'zgartira olmaydi Hisobot read faqat o'qish secondary dan Zaxira backup o'qish uchun yoza olmaydi Administrator root faqat qo'lda dasturda emas Nima uchun dastur root bilan ulanmasligi kerak Dasturdagi bitta zaiflik bazaning butun huquqiga aylanadi readWrite rolda zarar faqat shu baza bilan chegaralanadi Va u boshqa foydalanuvchi yarata olmaydi - ya'ni izini yashira olmaydi
Rolni vazifaga moslang, qulaylikka emas

Ulanish satri #

Autentifikatsiya yoqilgandan keyin ulanish shunday ko'rinadi:

Natija
mongosh "mongodb://dastur:[email protected]:27017/dokon?authSource=dokon"
QismMa'nosi
dastur:parolFoydalanuvchi va parol
/dokonQaysi bazaga ulanish
authSourceFoydalanuvchi 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 #

JavaScript
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
Natija
1
1
1
0

Zaxira nusxa - mongodump #

mongodump butun bazani fayllarga yozadi:

Natija
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:

Natija
kitob.bson            - hujjatlar (ikkilik BSON)
kitob.metadata.json   - indekslar va sozlamalar
BayroqMa'nosi
--dbFaqat bitta baza
--collectionFaqat bitta to'plam
--queryFaqat shartga mos hujjatlar
--gzipSiqilgan holda saqlash
--archive=faylBitta faylga yozish
--oplogNusxa olish paytidagi o'zgarishlarni ham qamrash

Tiklash - mongorestore #

Natija
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.

Tekshirilmagan zaxira - zaxira emas

Eng ko'p uchraydigan fojia: zaxira har kecha olinib kelingan, lekin kerak bo'lganda tiklanmagan.

Sabablari odatda oddiy:

SababQanday sezilmay qoladi
Disk to'lganFayl yarim yozilgan
Huquq yetmaganBir nechta to'plam tushmagan
Skript xato berganChiqish hech kim o'qimaydigan jurnalga ketgan
Foydalanuvchilar tushmaganTiklangan bazaga hech kim ulana olmaydi

Minimal talab - har oyda bir marta:

  1. Zaxirani boshqa bazaga tiklang (--nsTo).
  2. To'plamlardagi hujjatlar sonini asl baza bilan solishtiring.
  3. Bir nechta so'rovni ikkala bazada bajarib, natijani solishtiring.
  4. 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:

Natija
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
VositaFormatQachon
mongodump / mongorestoreBSONZaxira uchun
mongoexport / mongoimportJSON, CSVAlmashish uchun
mongoexport ni zaxira uchun ishlatmang

JSON 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 #

QatlamNima qiladi
TLSTarmoqdagi ma'lumotni shifrlaydi
Diskda shifrlashDisk o'g'irlansa ham fayl o'qilmaydi
Maydon darajasida shifrlashAlohida 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.

Amaliy topshiriq
  1. Autentifikatsiyani qanday yoqish kerakligini yozing.
  2. bindIp sozlamasi nega muhimligini tushuntiring.
  3. read roli bilan foydalanuvchi yarating.
  4. Parolni buyruqda yozish nega xavfli - yozing.
  5. passwordPrompt() ning farqini ayting.
  6. O'z rolingizni yarating va uning huquqlarini ko'ring.
  7. Dastur nega root bilan ulanmasligi kerakligini tushuntiring.
  8. mongodump bilan nusxa oling.
  9. Uni --nsTo bilan boshqa bazaga tiklang va sonlarni solishtiring.
  10. mongoexport nega zaxira uchun yaramasligini yozing.

Xulosa #

  • MongoDB odatiy holda parolsiz ishga tushadi - --auth bilan yoqiladi.
  • Eng muhim himoya - tarmoq: baza internetdan ko'rinmasin (bindIp).
  • Rollar: read, readWrite, dbAdmin, backup, root va boshqalar.
  • Dastur hech qachon root bilan ulanmasin - readWrite yetarli.
  • Aniq ruxsat uchun createRole bilan o'z roling yaratiladi.
  • Parolni buyruqda yozmang - passwordPrompt() yoki muhit o'zgaruvchisi.
  • authSource unutilsa "Authentication failed" xatosi chiqadi.
  • mongodump - zaxira uchun, mongoexport - almashish uchun.
  • mongoexport BSON turlarini yo'qotadi - zaxira sifatida yaramaydi.
  • Tiklab ko'rilmagan zaxira - zaxira emas: uni --nsTo bilan muntazam sinang.

Keyingi bo'limda o'rgangan hamma narsani bitta amaliy loyihada birlashtiramiz.

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.