IlmHamroh
Python kursi/Infratuzilma9/14-dars18 daqiqa
Mundarija (22)

28.9-dars: Muhit va sirlar boshqaruvi

28-QISM — INFRATUZILMA · 9-dars


1. Kirish va motivatsiya

Har ilova sozlamalarga muhtoj: ma'lumotlar bazasi manzili, API kalitlari, parollar, xususiyat bayroqlari, log darajasi. Bu sozlamalar muhitga qarab farq qiladi: dev'da lokal baza, prod'da haqiqiy baza; dev'da test API kaliti, prod'da haqiqiy. Agar sozlamalar kodda bo'lsa (masalan parol = "secret123") — ikki halokat: (1) har muhit uchun kodni o'zgartirish (bir kod, ko'p muhit imkonsiz), (2) sirlar git'da — xavfsizlik falokati (parol butun dunyoga ko'rinadi). Muhit va sirlar boshqaruvi — sozlamalarni koddan ajratish va sirlarni xavfsiz saqlash: muhit o'zgaruvchilari, .env fayllar, sir menejerlari. Sozlama koddan alohida — moslashuvchan va xavfsiz.

Muhit va sirlar boshqaruvi — sozlamalarni koddan ajratish va maxfiy ma'lumotlarni himoya qilish: muhit o'zgaruvchilari (environment variables — os.environ orqali), .env fayllar (lokal sozlamalar — git'da emas), sir menejerlari (Vault, AWS Secrets Manager, K8s Secret — 28.6), 12-faktor ilova (config koddan ajratish printsipi). Prinsip: bir kod, ko'p muhit (kod bir xil, sozlama muhitdan keladi), sirlar hech qachon git'da emas (xavfsizlik). Bu Docker 28.1-bob, Kubernetes 28.6-bob, CD 28.8-bob bilan bog'liq. Muhit va sirlar — konfiguratsiyani xavfsiz boshqarish. Sozlama muhitdan — kod universal.

Real vaziyat. Bir loyihada baza paroli kodda edi (DB_PASSWORD = "prod_secret") va git'ga kommit qilingan — parol butun jamoaga (va git tarixiga abadiy) ko'rindi. Yana dev/prod uchun kodni o'zgartirish kerak edi (baza manzili). Muhit o'zgaruvchilari qo'llanildi: sozlamalar os.environ dan (kod universal), .env (lokal, git'da emas — .gitignore), prod'da K8s Secret. Parol koddan chiqdi (xavfsiz), bir kod barcha muhitda ishladi. Muhit boshqaruvi — xavfsizlik va moslashuvchanlik.

Bu darsda muhit va sirlar boshqaruvini o'rganamiz.

Bu darsda:

  • Nega sozlamalarni ajratish
  • Muhit o'zgaruvchilari
  • .env fayllar
  • 12-faktor ilova (config)
  • Sirlarni xavfsiz saqlash
  • Sozlama qatlamlari (default, muhit)
  • Sir boshqaruv vositalari
  • Amaliy: config modeli

ℹ Misollar sof Python (os.environ, dict) bilan config mantiqini ko'rsatadi (deterministik).


2. Nazariya — chuqur tushuntirish

2.1. Nega sozlamalarni ajratish

Bir kod, ko'p muhit:

python
# YOMON: sozlama kodda (har muhit uchun o'zgartirish, sir git'da)
DB_URL = "postgres://prod-server/db"
PASSWORD = "secret123"          # xavfsizlik falokati!

# YAXSHI: sozlama muhitdan (kod universal)
DB_URL = os.environ["DB_URL"]
PASSWORD = os.environ["DB_PASSWORD"]

Nega ajratish — sozlamalarni koddan ajratish ikki muammoni hal qiladi: (1) moslashuvchanlik (bir kod, ko'p muhit — sozlama muhitdan keladi, kodni o'zgartirmasdan dev/prod); (2) xavfsizlik (sirlar kodda/git'da emas — parol, kalit sizib chiqmaydi). Kodda sozlama: har muhit uchun kodni o'zgartirish (imkonsiz — bir kod), sirlar git tarixida (abadiy ko'rinadi). Ajratilgan: kod universal, sirlar himoyalangan. Bu 12-faktor ilova printsipi (28.9.4). Ajratish — moslashuvchan va xavfsiz. Sozlama muhitda, kod bir xil.

2.2. Muhit o'zgaruvchilari

Operatsion tizim orqali sozlama:

python
import os

# o'qish (muhitdan)
db_url = os.environ["DATABASE_URL"]        # bo'lmasa xato
log_level = os.environ.get("LOG_LEVEL", "info")   # standart bilan

# o'rnatish (tashqarida — terminal, Docker, K8s)
# export DATABASE_URL=postgres://...
# docker run -e DATABASE_URL=... 

Muhit o'zgaruvchilari (environment variables) — operatsion tizim darajasidagi kalit-qiymat sozlamalar, dastur ularni o'qiydi (os.environ): os.environ["KEY"] (majburiy — bo'lmasa xato), os.environ.get("KEY", default) (ixtiyoriy — standart bilan). Ular tashqarida o'rnatiladi (terminal export, Docker -e, K8s env — 28.6) — kodda emas. Sabab: universal (har OS, til qo'llaydi), koddan ajratilgan (muhit beradi), Docker/K8s bilan tabiiy. Bu sozlamani koddan chiqarishning eng oddiy usuli. Muhit o'zgaruvchilari — koddan tashqari sozlama. Kod o'qiydi, muhit beradi.

2.3. .env fayllar

Lokal sozlamalar:

python
# .env fayl (lokal rivojlanish — git'da EMAS)
DATABASE_URL=postgres://localhost/dev
LOG_LEVEL=debug
API_KEY=test_key

# Python (python-dotenv):
from dotenv import load_dotenv
load_dotenv()   # .env ni muhitga yuklaydi
db = os.environ["DATABASE_URL"]

.env fayllar — lokal rivojlanish sozlamalarini saqlaydigan fayl (kalit=qiymat): load_dotenv() (python-dotenv) uni muhit o'zgaruvchilariga yuklaydi. Sabab: har export ni qo'lda yozish noqulay — .env bir joyda (lokal sozlamalar). Muhim: .env git'da EMAS (.gitignorega qo'shiladi — sirlar sizib chiqmaydi); .env.example (namuna — kalitlar ro'yxati, qiymatsiz — git'da, jamoaga yo'riqnoma). .env faqat lokal/dev (prod'da — muhit o'zgaruvchilari yoki sir menejeri). .env — lokal sozlama qulayligi (git'da emas). Lokal .env, prod boshqacha.

2.4. 12-faktor ilova (config)

Config koddan ajratish printsipi:

12-faktor ilova (config faktori):
   config koddan qat'iy ajratilgan
   config muhit o'zgaruvchilarida (kodda/faylda emas)
   bir kod → har muhitda (config bilan)
   test: kodni ochiq qilsam, sir sizadimi?

12-faktor ilova (twelve-factor app) — zamonaviy, bulut-mahalliy ilovalar uchun 12 printsip; config faktori: konfiguratsiya (muhitga qarab o'zgaradigan — baza, kalit) koddan qat'iy ajratilgan bo'lishi kerak, muhit o'zgaruvchilarida saqlanadi. Sinov: "kodni hozir ochiq (open source) qilsam — sirlar sizadimi?" (agar ha — config kodda, yomon). Sabab: bir kod (build) har muhitda ishlashi kerak (config bilan — 28.1 Docker image bir xil), sirlar himoyalangan. Bu bulut, konteyner, CD bilan tabiiy. 12-faktor config — sozlamani muhitga qo'yish. Kod ochiq bo'lsa ham — xavfsiz.

2.5. Sirlarni xavfsiz saqlash

Maxfiy ma'lumot himoyasi:

Sirlar (parol, API kalit, sertifikat):
   ❌ kodda (git tarixida abadiy)
   ❌ .env git'da (sizib chiqadi)
   ✅ muhit o'zgaruvchisi (run vaqtida)
   ✅ sir menejeri (Vault, AWS Secrets, K8s Secret)
   ✅ shifrlangan saqlash

Sirlarni xavfsiz saqlash — maxfiy ma'lumot (parol, API kalit, sertifikat) qat'iy himoyalanishi kerak: hech qachon kodda (git tarixida abadiy — o'chirsangiz ham tarixda qoladi), hech qachon git'dagi .env. To'g'ri: muhit o'zgaruvchisi (run vaqtida beriladi), sir menejeri (Vault, AWS Secrets Manager, K8s Secret — markazlashgan, shifrlangan, kirish nazorati, aylantirish). Agar sir git'ga tushsa — u buzilgan (rotate — almashtirish kerak, o'chirish yetmaydi). Sirlar — ilovaning eng nozik qismi. Sir menejeri — sirlarni professional boshqarish. Sir git'da — abadiy buzilgan.

2.6. Sozlama qatlamlari (default, muhit)

Ustuvorlik tartibi:

python
# sozlama qatlamlari (past → yuqori ustuvorlik):
# 1. Kod ichidagi standart (default)
# 2. Config fayl
# 3. Muhit o'zgaruvchilari
# 4. Buyruq argumentlari
# yuqori qatlam pastini bekor qiladi
config = {**defaults, **fayl, **muhit}   # muhit ustun

Sozlama qatlamlari — sozlamalar bir necha manbadan keladi, ustuvorlik tartibi bilan: standart (default — kodda, eng past), config fayl, muhit o'zgaruvchilari, buyruq argumentlari (eng yuqori). Yuqori qatlam pastini bekor qiladi (masalan muhit o'zgaruvchisi standartni almashtiradi). Sabab: standart (ko'p holatda ishlaydi), lekin muhit/foydalanuvchi almashtira olishi kerak (moslashuvchanlik). Bu 12-faktor bilan mos (muhit ustun). Kutubxonalar (pydantic-settings, dynaconf) qatlamlarni boshqaradi. Qatlamlar — moslashuvchan sozlama (standart + almashtirish). Yuqori bekor qiladi.

2.7. Sir boshqaruv vositalari

Sir boshqaruv vositalari: muhit o'zgaruvchilari (oddiy — kichik loyiha, K8s); K8s Secret (28.6 — Kubernetes'da, base64, RBAC bilan); HashiCorp Vault (markazlashgan sir menejeri — shifrlash, kirish nazorati, dinamik sirlar, audit); bulut menejerlari (AWS Secrets Manager, GCP Secret Manager, Azure Key Vault — bulut integratsiyasi, aylantirish); .env + .gitignore (faqat lokal dev). Xususiyatlar: shifrlash (dam olayotgan, uzatilayotgan), kirish nazorati (kim ko'radi), aylantirish (rotation — sirlarni davriy almashtirish), audit (kim, qachon kirdi). Katta loyiha — sir menejeri (professional). Vosita — sirlar hajmi/xavfiga qarab. Sir menejeri — markazlashgan himoya.

2.8. Config — koddan ajratilgan, xavfsiz

Muhit va sirlar boshqaruvi asosiy g'oyasi — config koddan ajratilgan va sirlar himoyalangan: kod universal (bir build, har muhit — 28.1), sozlama muhitdan (moslashuvchan), sirlar xavfsiz (git'da emas, sir menejerida). Bu 12-faktor ilova printsipi, Docker (28.1 — bir image), Kubernetes (28.6 — ConfigMap/Secret), CD (28.8 — muhitlar) bilan chuqur bog'liq. Xavfsizlik nuqtai nazaridan — sirlar eng nozik (parol sizsa — falokat), shuning uchun qat'iy intizom (hech qachon kodda/git'da). "Config koddan ajratilgan" — professional ilova belgisi. Config — kod emas (muhit, sir). Kod universal, config muhitda, sir himoyalangan.


3. Tez ma'lumotnoma

python
import os

# MUHIT O'ZGARUVCHILARI
db = os.environ["DATABASE_URL"]              # majburiy (bo'lmasa xato)
level = os.environ.get("LOG_LEVEL", "info")  # ixtiyoriy (standart)

# .env (lokal — git'da EMAS)
from dotenv import load_dotenv
load_dotenv()

# QATLAMLAR (past → yuqori ustuvorlik)
config = {**defaults, **fayl_config, **os.environ}

# pydantic-settings (tipli config):
# class Settings(BaseSettings):
#     database_url: str
#     log_level: str = "info"

# SIRLAR:
# ❌ kodda, ❌ git'dagi .env
# ✅ muhit o'zgaruvchisi, ✅ sir menejeri (Vault, K8s Secret)

# .gitignore: .env  (sirlarni saqla!)
# .env.example: kalitlar (qiymatsiz — git'da, yo'riqnoma)

Muhit va sirlar xulosasi

Config koddan ajratilgan (bir kod, ko'p muhit)
Muhit o'zgaruvchilari (os.environ) · .env (lokal, git'da emas)
12-faktor: config muhitda (kod ochiq bo'lsa ham xavfsiz)
Sirlar: hech qachon git'da → sir menejeri (Vault, K8s Secret)
Qatlamlar (default → fayl → muhit — yuqori bekor qiladi)

4. Batafsil misollar

Misollar sof Python (os.environ, dict) bilan config mantiqini ko'rsatadi.

Misol 1 — Muhit o'zgaruvchilari (o'qish)

python
"""Muhit o'zgaruvchilari: majburiy va ixtiyoriy (standart bilan) o'qish."""
import os


def config_ol() -> dict:
    return {
        # ixtiyoriy (standart bilan — get)
        "log_level": os.environ.get("LOG_LEVEL", "info"),
        "max_conn": int(os.environ.get("MAX_CONN", "10")),
        "debug": os.environ.get("DEBUG", "false") == "true",
    }


def main() -> None:
    # test uchun muhit o'zgaruvchilarini o'rnatamiz (deterministik)
    os.environ["LOG_LEVEL"] = "debug"
    os.environ["MAX_CONN"] = "50"

    config = config_ol()

    print("=== 1. Muhitdan o'qilgan sozlamalar ===")
    print(f"  log_level: {config['log_level']}")
    print(f"  max_conn: {config['max_conn']}")

    print("\n=== 2. Standart qiymat (o'rnatilmagan) ===")
    print(f"  debug (o'rnatilmagan): {config['debug']}")
    print("  DEBUG yo'q → standart 'false'")

    print("\n=== 3. Tur konversiyasi ===")
    print(f"  max_conn turi: {type(config['max_conn']).__name__}")
    print("  muhit o'zgaruvchisi matn → int ga o'girish")

    print("\n=== 4. Majburiy (get emas — bo'lmasa xato) ===")
    try:
        _ = os.environ["MAVJUD_EMAS"]
    except KeyError:
        print("  MAVJUD_EMAS: KeyError (majburiy o'zgaruvchi yo'q)")
    print("  ⭐ Muhit o'zgaruvchilari — koddan tashqari sozlama")


if __name__ == "__main__":
    main()

Natijaning muhim qismi:

text
=== 1. Muhitdan o'qilgan sozlamalar ===
  log_level: debug
  max_conn: 50

=== 2. Standart qiymat (o'rnatilmagan) ===
  debug (o'rnatilmagan): False
  DEBUG yo'q → standart 'false'

=== 3. Tur konversiyasi ===
  max_conn turi: int
  muhit o'zgaruvchisi matn → int ga o'girish

=== 4. Majburiy (get emas — bo'lmasa xato) ===
  MAVJUD_EMAS: KeyError (majburiy o'zgaruvchi yo'q)
  ⭐ Muhit o'zgaruvchilari — koddan tashqari sozlama

Nima ko'rsatdi: 2.2-bo'lim.

Misol 2 — Sozlama qatlamlari (ustuvorlik)

python
"""Qatlamlar: standart → fayl → muhit (yuqori qatlam pastini bekor qiladi)."""


def config_qur(defaults: dict, fayl: dict, muhit: dict) -> dict:
    # ustuvorlik: muhit > fayl > default
    return {**defaults, **fayl, **muhit}


def main() -> None:
    # 1-qatlam: kod standartlari (eng past)
    defaults = {"log_level": "info", "max_conn": 10, "timeout": 30}
    # 2-qatlam: config fayl
    fayl = {"max_conn": 50}
    # 3-qatlam: muhit o'zgaruvchilari (eng yuqori)
    muhit = {"log_level": "debug"}

    config = config_qur(defaults, fayl, muhit)

    print("=== 1. Standart qatlam ===")
    print(f"  {defaults}")

    print("\n=== 2. Fayl qatlami (max_conn'ni bekor qiladi) ===")
    print(f"  {fayl}")

    print("\n=== 3. Muhit qatlami (log_level'ni bekor qiladi) ===")
    print(f"  {muhit}")

    print("\n=== 4. Yakuniy config (birlashgan) ===")
    print(f"  log_level: {config['log_level']} (muhitdan)")
    print(f"  max_conn: {config['max_conn']} (fayldan)")
    print(f"  timeout: {config['timeout']} (standartdan)")
    print("  ⭐ Qatlamlar — yuqori pastini bekor qiladi")


if __name__ == "__main__":
    main()

Natijaning muhim qismi:

text
=== 1. Standart qatlam ===
  {'log_level': 'info', 'max_conn': 10, 'timeout': 30}

=== 2. Fayl qatlami (max_conn'ni bekor qiladi) ===
  {'max_conn': 50}

=== 3. Muhit qatlami (log_level'ni bekor qiladi) ===
  {'log_level': 'debug'}

=== 4. Yakuniy config (birlashgan) ===
  log_level: debug (muhitdan)
  max_conn: 50 (fayldan)
  timeout: 30 (standartdan)
  ⭐ Qatlamlar — yuqori pastini bekor qiladi

Nima ko'rsatdi: 2.6-bo'lim.

Misol 3 — Sirlarni tekshirish (git'da bo'lmasligi)

python
"""Sir tekshiruvi: config'da sir bormi (git'ga tushmasligi kerak)."""


SIR_KALITLARI = ["password", "secret", "api_key", "token", "private_key"]


def sir_tekshir(config: dict) -> dict:
    topilgan_sirlar = []
    for kalit, qiymat in config.items():
        # kalit sir so'zini o'z ichiga oladimi
        if any(sir in kalit.lower() for sir in SIR_KALITLARI):
            topilgan_sirlar.append(kalit)
    return {"sirlar": topilgan_sirlar, "xavfsizmi": len(topilgan_sirlar) == 0}


def main() -> None:
    print("=== 1. Xavfsiz config (sir yo'q) ===")
    xavfsiz = {"log_level": "info", "max_conn": 50, "timeout": 30}
    r = sir_tekshir(xavfsiz)
    print(f"  sirlar: {r['sirlar']}")
    print(f"  git'ga xavfsizmi: {r['xavfsizmi']}")

    print("\n=== 2. Xavfli config (sirlar bor) ===")
    xavfli = {"db_url": "postgres://...", "db_password": "secret123", "api_key": "xyz"}
    r = sir_tekshir(xavfli)
    print(f"  topilgan sirlar: {r['sirlar']}")
    print(f"  git'ga xavfsizmi: {r['xavfsizmi']}")

    print("\n=== 3. Sirlar qayerda bo'lishi kerak ===")
    print("  db_password, api_key → muhit o'zgaruvchisi/sir menejeri")
    print("  git'da EMAS (abadiy ko'rinadi)")

    print("\n=== 4. Qoida ===")
    print("  sir git'ga tushsa → buzilgan (almashtirish kerak)")
    print("  o'chirish yetmaydi (tarixda qoladi)")
    print("  ⭐ Sirlar — hech qachon git'da")


if __name__ == "__main__":
    main()

Natijaning muhim qismi:

text
=== 1. Xavfsiz config (sir yo'q) ===
  sirlar: []
  git'ga xavfsizmi: True

=== 2. Xavfli config (sirlar bor) ===
  topilgan sirlar: ['db_password', 'api_key']
  git'ga xavfsizmi: False

=== 3. Sirlar qayerda bo'lishi kerak ===
  db_password, api_key → muhit o'zgaruvchisi/sir menejeri
  git'da EMAS (abadiy ko'rinadi)

=== 4. Qoida ===
  sir git'ga tushsa → buzilgan (almashtirish kerak)
  o'chirish yetmaydi (tarixda qoladi)
  ⭐ Sirlar — hech qachon git'da

Nima ko'rsatdi: 2.5-bo'lim.

Misol 4 — Muhitga qarab config (dev/prod)

python
"""Muhitga qarab: bir kod, turli muhit (dev/prod) turli sozlama."""


def muhit_config(muhit: str) -> dict:
    # umumiy standartlar
    umumiy = {"app_name": "myapp", "versiya": "1.0"}

    # muhitga xos (muhit o'zgaruvchisidan kelishi kerak — bu yerda model)
    muhitga_xos = {
        "dev": {"db": "localhost/dev", "debug": True, "log": "debug"},
        "staging": {"db": "staging-server/db", "debug": False, "log": "info"},
        "prod": {"db": "prod-server/db", "debug": False, "log": "warning"},
    }

    if muhit not in muhitga_xos:
        raise ValueError(f"Noma'lum muhit: {muhit}")
    return {**umumiy, **muhitga_xos[muhit]}


def main() -> None:
    print("=== 1. Dev muhiti ===")
    dev = muhit_config("dev")
    print(f"  db: {dev['db']}, debug: {dev['debug']}, log: {dev['log']}")

    print("\n=== 2. Prod muhiti ===")
    prod = muhit_config("prod")
    print(f"  db: {prod['db']}, debug: {prod['debug']}, log: {prod['log']}")

    print("\n=== 3. Bir kod, turli sozlama ===")
    print(f"  app_name bir xil: {dev['app_name']} = {prod['app_name']}")
    print(f"  db farqli: dev={dev['db']}, prod={prod['db']}")

    print("\n=== 4. Kod o'zgarmaydi ===")
    print("  muhit o'zgaruvchisi (ENV=prod) sozlamani tanlaydi")
    print("  bir build, har muhit (12-faktor)")
    print("  ⭐ Muhitga qarab config (kod universal)")


if __name__ == "__main__":
    main()

Natijaning muhim qismi:

text
=== 1. Dev muhiti ===
  db: localhost/dev, debug: True, log: debug

=== 2. Prod muhiti ===
  db: prod-server/db, debug: False, log: warning

=== 3. Bir kod, turli sozlama ===
  app_name bir xil: myapp = myapp
  db farqli: dev=localhost/dev, prod=prod-server/db

=== 4. Kod o'zgarmaydi ===
  muhit o'zgaruvchisi (ENV=prod) sozlamani tanlaydi
  bir build, har muhit (12-faktor)
  ⭐ Muhitga qarab config (kod universal)

Nima ko'rsatdi: 2.1, 2.4-bo'limlar.


5. To'g'ri va noto'g'ri tushunishlar

Noto'g'ri fikr To'g'risi
"Sozlama kodda" Muhitda (bir kod, ko'p muhit)
"Parol kodda mayli" Hech qachon (git tarixida abadiy)
".env git'da" .gitignore (sizib chiqadi)
"Sirni o'chirsam yetadi" Almashtirish (tarixda qoladi)
"Bir muhit uchun kod" Universal (config bilan)
"Config bir manba" Qatlamlar (default, muhit)
"base64 = shifrlash" Kodlangan (shifrlash emas)
"Sir menejeri ortiqcha" Katta loyihaga zarur

6. Keng tarqalgan xatolar va yechimlari

1. Sir kodda

python
PASSWORD = "secret123"   # git tarixida             # ⚠️
PASSWORD = os.environ["DB_PASSWORD"]                # ✅

2. .env git'da

git add .env   # sirlar sizadi                       # ⚠️
# .gitignore'ga .env + .env.example (namuna)          # ✅

3. Sirni o'chirib "tuzatish"

bash
git rm secret; git commit   # tarixda qoladi          # ⚠️
# sirni almashtir (rotate) + tarixdan tozalash         # ✅

4. Majburiy sozlama get bilan (jim standart)

python
db = os.environ.get("DATABASE_URL", "")   # bo'sh?    # ⚠️
db = os.environ["DATABASE_URL"]   # yo'q → xato        # ✅

5. Config validatsiyasiz

python
port = os.environ["PORT"]   # "abc"? (matn)           # ⚠️
port = int(os.environ["PORT"])   # tur + validatsiya   # ✅

6. Har muhit uchun alohida kod

python
if PROD: db = "..."  else: db = "..."   # kodda        # ⚠️
db = os.environ["DATABASE_URL"]   # muhit beradi        # ✅

7. Sirni logga yozish

python
logging.info(f"config: {config}")   # sir logda!      # ⚠️
# sirlarni maskalash (***), logga yozmaslik            # ✅

7. Integratsiya — bu bilim qayerda kerak bo'ladi

  • 28.1-dars (o'tilgan): Docker — -e, bir image
  • 28.6-dars (o'tilgan): K8s — ConfigMap/Secret
  • 28.8-dars (o'tilgan): CD — muhitlar
  • 20-qism (o'tilgan): FastAPI — pydantic settings
  • 31-qism: Loyihalar — config boshqaruv

8. Eng yaxshi amaliyotlar

  1. Config koddan ajrat (muhit o'zgaruvchisi).

  2. Sirlar hech qachon git'da (.gitignore).

  3. .env lokal + .env.example (namuna).

  4. Sir menejeri (katta loyiha — Vault, K8s Secret).

  5. Config validatsiya (tur, majburiy).

  6. Qatlamlar (default → muhit).

  7. Sirni logga yozma (maskala).

  8. Sir sizsa — almashtir (o'chirish yetmaydi).


9. Amaliy topshiriq

Vazifa 1: Bashorat qiling

python
1.  # nega config ajratish?
2.  # ikki muammo (kodda config)?
3.  # muhit o'zgaruvchisi nima?
4.  # os.environ["x"] vs .get?
5.  # .env nima?
6.  # .env git'dami?
7.  # 12-faktor config nima?
8.  # sirlar qayerda emas?
9.  # sir git'ga tushsa?
10. # qatlamlar nima?
11. # qaysi qatlam ustun?
12. # sir menejeri nima?
Javoblar
  1. Moslashuvchanlik + xavfsizlik
  2. Har muhit uchun o'zgartirish, sir git'da
  3. OS darajasidagi sozlama (os.environ)
  4. ["x"] majburiy (xato), .get ixtiyoriy (standart)
  5. Lokal sozlamalar fayli
  6. Yo'q (.gitignore)
  7. Config muhitda (kod ochiq bo'lsa ham xavfsiz)
  8. Kodda, git'dagi .env
  9. Buzilgan (almashtirish kerak)
  10. Sozlama manbalari (default, fayl, muhit)
  11. Muhit (yuqori pastini bekor qiladi)
  12. Sirlarni markazlashgan himoya (Vault)

Vazifa 2: Xatolarni tuzating

python
1.  PASSWORD = "secret123"

2.  git add .env

3.  port = os.environ["PORT"]  # matn

4.  if PROD: db=... else: db=...

5.  logging.info(config)  # sir
Javoblar
python
1.  os.environ["DB_PASSWORD"]

2.  .gitignore + .env.example

3.  int(os.environ["PORT"])

4.  os.environ["DATABASE_URL"]

5.  sirlarni maskala (logga yozma)

Vazifa 3: Muhit o'zgaruvchisi

Modellang:

  1. Majburiy
  2. Ixtiyoriy
  3. Standart
  4. Tur

Vazifa 4: Qatlamlar

Modellang:

  1. Default
  2. Fayl
  3. Muhit
  4. Ustuvorlik

Vazifa 5: Sir tekshiruvi

Modellang:

  1. Config
  2. Sir kalitlari
  3. Topish
  4. Xavfsizlik

Vazifa 6: Muhit config

Modellang:

  1. Dev
  2. Prod
  3. Bir kod
  4. Turli sozlama

Vazifa 7: O'ylash

"Config koddan ajratish" va "sirlar hech qachon kodda" — texnik qoidalardan tashqari, xavfsizlik madaniyati masalasi. Nima uchun sir git'ga tushsa "o'chirish yetmaydi, almashtirish kerak" (bu ko'plarni hayron qoldiradi), va nega "sirlar bilan ehtiyot" (paranoyya darajasida) oqlangan — bir sir sizishi qanday zanjirli oqibatlarga olib kelishi mumkin?

Javob

Qisqa javob: Sir git'ga tushsa "o'chirish yetmaydi", chunki: git — tarix tizimi (05-qism) — har commit abadiy saqlanadi; sirni o'chirib yangi commit qilsangiz, sir oldingi commit'da qoladi (git tarixini ochgan har kim ko'radi — git log, git show). Undan tashqari: sir allaqachon tarqalgan bo'lishi mumkin (repo public bo'lsa — botlar git'ni skanerlaydi, sirlarni yig'adi soniyalar ichida; jamoa a'zolari, fork'lar ko'rgan). Shuning uchun yagona xavfsiz yo'l — sirni almashtirish (rotate — eski sirni bekor qilish, yangisini yaratish): eski sir buzilgan deb hisoblanadi (kim ko'rgani noma'lum). "Sirlar bilan paranoyya" oqlangan, chunki bir sir sizishi zanjirli oqibatlar beradi: (1) to'g'ridan zarar (baza paroli sizsa — ma'lumot o'g'irlanadi/o'chiriladi; API kalit — xizmatdan suiiste'mol, hisobingizga katta hisob); (2) lateral harakat (bir sir — boshqasiga kirish: server kaliti → serverga kirish → boshqa sirlar → butun tizim); (3) ishonch buzilishi (foydalanuvchi ma'lumotlari sizsa — obro', huquqiy javobgarlik, jarima — GDPR); (4) aniqlash qiyin (sir bilan kirgan hujumchi "qonuniy" ko'rinadi — uzoq sezilmaydi). Bir sir — kirish nuqtasi (butun tizimga). Xavfsizlik eng zaif halqa bilan belgilanadi (bir sizgan sir — barcha himoyani aylanib o'tadi). Shuning uchun "ishonma, tekshir" (zero-trust), "eng kam imtiyoz" (least privilege), "sirni hech qachon ochiq qoldirma". Paranoyya emas — mutanosib ehtiyot (sir qiymati yuqori, sizish oson, oqibat og'ir). Muhandislik saboqlari: git tarixi abadiy (sir tushsa — abadiy); sir sizsa — almashtir (o'chirish yolg'on xotirjamlik); bir sir — zanjirli zarar (kirish nuqtasi); xavfsizlik — eng zaif halqa (intizom har joyda); ehtiyot mutanosib (qiymat vs xavf).

1. Nega o'chirish yetmaydi

Git tarix abadiy (sir oldingi commit'da qoladi). Sir allaqachon tarqalgan bo'lishi mumkin (botlar, jamoa). Yagona yo'l — almashtirish.

2. Zanjirli oqibatlar

  • To'g'ridan zarar (ma'lumot, suiiste'mol)
  • Lateral harakat (bir sir → boshqasi → tizim)
  • Ishonch buzilishi (obro', huquqiy)
  • Aniqlash qiyin (qonuniy ko'rinadi)

3. Nega paranoyya oqlangan

Omil Sabab
Sir qiymati Yuqori (kirish nuqtasi)
Sizish osonligi Botlar skanerlaydi (soniyalar)
Oqibat Og'ir (zanjirli zarar)

4. Xavfsizlik — eng zaif halqa

Bir sizgan sir barcha himoyani aylanib o'tadi. Intizom har joyda (zero-trust, least privilege).

5. Muhandislik saboqlari

  1. Git tarixi abadiy (sir tushsa — abadiy)
  2. Sir sizsa — almashtir (o'chirish — yolg'on xotirjamlik)
  3. Bir sir — zanjirli zarar (kirish nuqtasi)
  4. Ehtiyot mutanosib (qiymat vs xavf)

6. Xulosa

  1. Git tarix abadiy → o'chirish yetmaydi (almashtir)
  2. Sir sizishi zanjirli (to'g'ridan, lateral, ishonch)
  3. Bir sir — butun tizim kirish nuqtasi
  4. Paranoyya emas — mutanosib ehtiyot

Nimani mustahkamlaydi: 2.5-bo'lim.


Xulosa

Bu darsda muhit va sirlar boshqaruvini o'rgandik.

Eng muhim uch fikr:

  1. Config ajratish va muhit o'zgaruvchilari. Sozlamalarni koddan ajratish ikki muammoni hal qiladi: moslashuvchanlik (bir kod, ko'p muhit — sozlama muhitdan) va xavfsizlik (sirlar kodda/git'da emas). Muhit o'zgaruvchilari (environment variables) — OS darajasidagi sozlamalar, dastur o'qiydi (os.environ["KEY"] — majburiy, .get("KEY", default) — ixtiyoriy); ular tashqarida o'rnatiladi (terminal export, Docker -e, K8s env). .env fayllar — lokal sozlamalar (load_dotenv()); git'da EMAS (.gitignore — sirlar sizmasin), .env.example (namuna — git'da, yo'riqnoma); faqat lokal/dev.

  2. 12-faktor va sirlarni saqlash. 12-faktor ilova (config faktori) — konfiguratsiya koddan qat'iy ajratilgan, muhit o'zgaruvchilarida; sinov: "kodni ochiq qilsam — sirlar sizadimi?"; bir build har muhitda (Docker image bir xil). Sirlarni xavfsiz saqlash — parol/kalit hech qachon kodda (git tarixida abadiy) yoki git'dagi .env; to'g'ri: muhit o'zgaruvchisi, sir menejeri (Vault, AWS Secrets, K8s Secret — shifrlangan, kirish nazorati, aylantirish, audit). Sir git'ga tushsa — buzilgan (almashtirish kerak — o'chirish yetmaydi, tarixda qoladi).

  3. Qatlamlar va xavfsizlik madaniyati. Sozlama qatlamlari — bir necha manba, ustuvorlik bilan: standart (default — eng past) → config fayl → muhit o'zgaruvchilari → argumentlar (eng yuqori); yuqori qatlam pastini bekor qiladi (moslashuvchanlik). Sir boshqaruv vositalari: muhit o'zgaruvchilari (oddiy), K8s Secret, Vault (markazlashgan — shifrlash, RBAC, aylantirish, audit). Config koddan ajratilgan va sirlar himoyalangan — professional ilova belgisi (12-faktor, Docker, K8s, CD bilan bog'liq). Sir sizishi zanjirli oqibatlar beradi (to'g'ridan zarar, lateral harakat, ishonch buzilishi) — bir sir butun tizimga kirish nuqtasi; xavfsizlik eng zaif halqa bilan belgilanadi, shuning uchun sirlar bilan mutanosib ehtiyot (qat'iy intizom).

Keyingi darsda monitoring va metrikalarni o'rganamiz: ishlab chiqarishdagi tizimni kuzatish — metrikalar (so'rovlar soni, javob vaqti, xatolik), Prometheus/Grafana kabi vositalar va "kuzatiluvchanlik" (observability) tushunchasi.

Ulashish:Telegram'da

Izohlar (0)

Izoh yozish uchun kiring.

  • Hozircha izoh yo'q. Birinchi bo'ling!
28.9-dars: Muhit va sirlar boshqaruvi — IlmHamroh