Asosiy kontentga o‘tish

Maqolalar

Darslik · 2026-08-16 · ~4 daqiqa o‘qiladi · o'rta

Token, parol, kalit: sirlar qayerda yashaydi va qayerda o'ladi

#security #devops #git #deploy

Mundarija

Kiberxavfsizlik darslarimda talabalarga bitta tajribani aytib beraman: GitHub'ga ochiq repo bilan tasodifan yuklangan token o'rtacha bir necha daqiqa ichida birinchi marta sinab ko'riladi. Buni maxsus botlar qiladi — ular GitHub'ning yangi commit oqimini tinimsiz skanerlashadi va token naqshlarini (Telegram, AWS, Stripe...) avtomatik ushlashadi. Ya'ni "kim ham mening kichkina repomni ko'rardi" degan umid ishlamaydi: ko'radigan tomon odam emas, mashina.

Seriya davomida sirlarga oid qoidalar bo'lak-bo'lak uchrab keldi — systemd'da EnvironmentFile, CI'da Secrets. Yakuniy qismda hammasini bitta tizimga yig'amiz.

Asosiy qoida: sir kodda emas, muhitda#

Sirning kodda yashashiga birinchi qadam doim beg'ubor ko'rinadi: "hozircha shu yerga yozib turay, keyin olib tashlayman". Keyin u commit bo'ladi — va bo'ldi, endi u tarixda. Shuning uchun qoida murosasiz: token, parol, kalit — faqat muhit o'zgaruvchisida. Kod ularni nomi bilan so'raydi, qiymatini qayerdan kelishi bilan ishi yo'q:

# config/settings.py
import os

SECRET_KEY = os.environ["DJANGO_SECRET_KEY"]  # yo'q bo'lsa — ataylab yiqilsin
BOT_TOKEN = os.environ.get("BOT_TOKEN", "")  # ixtiyoriy bo'lsa — bo'sh default

os.environ["..."] bilan os.environ.get("...") orasidagi tanlov ham ongli: ilova ishlashi uchun majburiy sir yo'q bo'lsa, start paytida baland ovozda yiqilgani yaxshi — jimgina bo'sh qiymat bilan ishlab, qayeridadir g'alati xato berganidan ko'ra.

.env fayl va uning egizagi#

Muhit o'zgaruvchilarini qo'lda eksport qilib yurish noqulay, shuning uchun ular .env faylga yig'iladi. Bu faylning ikkita temir qoidasi bor:

# .gitignore ichida BIRINCHI kunda turishi kerak:
.env

Ikkinchisi — .envning "egizagi": qiymatlarsiz, lekin to'liq ro'yxatli .env.example fayli repo'da turadi:

# .env.example — bu fayl repo'da ochiq turadi, sirlar YO'Q
DJANGO_SECRET_KEY=
BOT_TOKEN=
DATABASE_URL=postgresql://user:password@127.0.0.1/dbname
TELEGRAM_ADMIN_CHAT_ID=

Bu kichik fayl ikki katta muammoni yechadi. Yangi muhit ko'targan odam (yoki olti oydan keyingi siz) qaysi o'zgaruvchilar kerakligini kod ichini titkilamasdan biladi. Va CI/CD qismida aytilgan env drift — kodga yangi o'zgaruvchi qo'shilib, serverdagi .env unutilishi — ushlanadigan bo'ladi: .env.example bilan serverdagi faylni solishtirish kifoya.

Serverda esa .env fayli o'z uy tartibiga ega:

sudo chown deploy:deploy /opt/mysite/.env
sudo chmod 600 /opt/mysite/.env    # faqat egasi o'qiydi — boshqa hech kim

Sizib chiqdi: birinchi soat rejasi#

Ehtiyotkorlikka qaramay sir oshkor bo'lishi mumkin: commit'da ketdi, skrinshotda ko'rindi, chatga tashlab yuborildi. Bu vaziyatda ketma-ketlik oldindan ma'lum bo'lishi kerak, chunki o'ylab o'tirishga vaqt yo'q:

  1. Avval almashtiring, keyin tozalang. Birinchi harakat — sirni bekor qilish: bot tokenini @BotFather'da /revoke, API kalitni provayder panelida yangilash, parolni almashtirish. Repo'ni tozalash ikkinchi o'rinda — chunki sizdan oldin allaqachon nusxa olishgan deb hisoblang;
  2. Yangi sirni joylang — serverdagi .env, GitHub Secrets;
  3. Tarixni tozalang — lekin illyuziyasiz.

git'da o'chirish — o'chirish emas

Keyingi commit'da sirni olib tashlash uni yashirmaydi: u tarixda, har klonda, har fork'da qolgan. Tarixni git filter-repo yoki BFG bilan qayta yozish mumkin, lekin bu ham faqat sizning repoingizni tozalaydi — allaqachon tortib olingan nusxalarni emas. Shuning uchun tartib qat'iy: sizib chiqqan sir — o'lgan sir, uni tozalash emas, almashtirish qutqaradi.

Commit'dan oldingi himoya#

Eng yaxshi sizish — bo'lmagan sizish. Ikki bepul qatlamni yoqib qo'ying:

# gitleaks: commit'lardagi sir naqshlarini topadi
# lokalda bir martalik tekshiruv:
gitleaks detect --source .

# yoki CI'ga qadam sifatida (checks job'iga):
# - run: gitleaks detect --source . --no-banner

GitHub'ning o'zida ham push protection bor (Settings → Code security): tanigan naqshdagi sir push qilinsa, uni qabul qilmay qaytaradi. Ochiq repolarda bepul, yoqmaslikka sabab yo'q.

Nima .env'da, nima unda emas#

Oxirida bitta chegara masalasi. Hamma narsani ham sir deb yurmang — aksincha, konfiguratsiya bilan sirni ajratish tartib beradi:

.env'da (sir) Kodda/repo'da (konfiguratsiya)
SECRET_KEY, tokenlar, parollar Port raqamlari, timeout'lar
Baza ulanish satri (paroli bilan) ALLOWED_HOSTS ro'yxati
Tashqi API kalitlari Kesh muddatlari, sahifa o'lchamlari

Sir bo'lmagan narsani .envga olib o'tish teskari muammo tug'diradi: konfiguratsiya ko'zdan yo'qoladi, muhitlar orasidagi farq esa hujjatsiz qoladi.

Seriya yakuni#

To'qqiz qismlik yo'l shu yerda tugaydi. Yalang'och VPS'dan boshlagan edik — endi qo'lingizda to'liq tizim bor: SSH kalitli kirish va firewall, systemd ostidagi xizmatlar, nginx va TLS, timer'li zaxira, reboot'ga chidamlilik, o'zi deploy bo'ladigan pipeline, o'qiladigan loglar va joyida turgan sirlar. Bularning har biri alohida mayda ko'rinadi, birga esa "kechasi xotirjam uxlaydigan server" degan natijani beradi.

Savollar bo'lsa — bog'laning, qaysidir qadam o'z serveringizda boshqacha chiqqan bo'lsa, yozing: seriya jonli, real savollar asosida to'ldirilib boradi.