Mundarija (22)
- 1. Kirish va motivatsiya
- 2. Nazariya — chuqur tushuntirish
- 2.1. Nega sozlamalarni ajratish
- 2.2. Muhit o'zgaruvchilari
- 2.3. .env fayllar
- 2.4. 12-faktor ilova (config)
- 2.5. Sirlarni xavfsiz saqlash
- 2.6. Sozlama qatlamlari (default, muhit)
- 2.7. Sir boshqaruv vositalari
- 2.8. Config — koddan ajratilgan, xavfsiz
- 3. Tez ma'lumotnoma
- 4. Batafsil misollar
- Misol 1 — Muhit o'zgaruvchilari (o'qish)
- Misol 2 — Sozlama qatlamlari (ustuvorlik)
- Misol 3 — Sirlarni tekshirish (git'da bo'lmasligi)
- Misol 4 — Muhitga qarab config (dev/prod)
- 5. To'g'ri va noto'g'ri tushunishlar
- 6. Keng tarqalgan xatolar va yechimlari
- 7. Integratsiya — bu bilim qayerda kerak bo'ladi
- 8. Eng yaxshi amaliyotlar
- 9. Amaliy topshiriq
- Xulosa
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
.envfayllar- 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:
# 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:
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:
# .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:
# 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
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)
"""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:
=== 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 sozlamaNima ko'rsatdi: 2.2-bo'lim.
Misol 2 — Sozlama qatlamlari (ustuvorlik)
"""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:
=== 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 qiladiNima ko'rsatdi: 2.6-bo'lim.
Misol 3 — Sirlarni tekshirish (git'da bo'lmasligi)
"""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:
=== 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'daNima ko'rsatdi: 2.5-bo'lim.
Misol 4 — Muhitga qarab config (dev/prod)
"""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:
=== 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
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"
git rm secret; git commit # tarixda qoladi # ⚠️
# sirni almashtir (rotate) + tarixdan tozalash # ✅4. Majburiy sozlama get bilan (jim standart)
db = os.environ.get("DATABASE_URL", "") # bo'sh? # ⚠️
db = os.environ["DATABASE_URL"] # yo'q → xato # ✅5. Config validatsiyasiz
port = os.environ["PORT"] # "abc"? (matn) # ⚠️
port = int(os.environ["PORT"]) # tur + validatsiya # ✅6. Har muhit uchun alohida kod
if PROD: db = "..." else: db = "..." # kodda # ⚠️
db = os.environ["DATABASE_URL"] # muhit beradi # ✅7. Sirni logga yozish
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
Config koddan ajrat (muhit o'zgaruvchisi).
Sirlar hech qachon git'da (
.gitignore)..envlokal +.env.example(namuna).Sir menejeri (katta loyiha — Vault, K8s Secret).
Config validatsiya (tur, majburiy).
Qatlamlar (default → muhit).
Sirni logga yozma (maskala).
Sir sizsa — almashtir (o'chirish yetmaydi).
9. Amaliy topshiriq
Vazifa 1: Bashorat qiling
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
- Moslashuvchanlik + xavfsizlik
- Har muhit uchun o'zgartirish, sir git'da
- OS darajasidagi sozlama (os.environ)
["x"]majburiy (xato),.getixtiyoriy (standart)- Lokal sozlamalar fayli
- Yo'q (
.gitignore) - Config muhitda (kod ochiq bo'lsa ham xavfsiz)
- Kodda, git'dagi
.env - Buzilgan (almashtirish kerak)
- Sozlama manbalari (default, fayl, muhit)
- Muhit (yuqori pastini bekor qiladi)
- Sirlarni markazlashgan himoya (Vault)
Vazifa 2: Xatolarni tuzating
1. PASSWORD = "secret123"
2. git add .env
3. port = os.environ["PORT"] # matn
4. if PROD: db=... else: db=...
5. logging.info(config) # sirJavoblar
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:
- Majburiy
- Ixtiyoriy
- Standart
- Tur
Vazifa 4: Qatlamlar
Modellang:
- Default
- Fayl
- Muhit
- Ustuvorlik
Vazifa 5: Sir tekshiruvi
Modellang:
- Config
- Sir kalitlari
- Topish
- Xavfsizlik
Vazifa 6: Muhit config
Modellang:
- Dev
- Prod
- Bir kod
- 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
- Git tarixi abadiy (sir tushsa — abadiy)
- Sir sizsa — almashtir (o'chirish — yolg'on xotirjamlik)
- Bir sir — zanjirli zarar (kirish nuqtasi)
- Ehtiyot mutanosib (qiymat vs xavf)
6. Xulosa
- Git tarix abadiy → o'chirish yetmaydi (almashtir)
- Sir sizishi zanjirli (to'g'ridan, lateral, ishonch)
- Bir sir — butun tizim kirish nuqtasi
- Paranoyya emas — mutanosib ehtiyot
Nimani mustahkamlaydi: 2.5-bo'lim.
Xulosa
Bu darsda muhit va sirlar boshqaruvini o'rgandik.
Eng muhim uch fikr:
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 (terminalexport, Docker-e, K8s env)..envfayllar — lokal sozlamalar (load_dotenv()); git'da EMAS (.gitignore— sirlar sizmasin),.env.example(namuna — git'da, yo'riqnoma); faqat lokal/dev.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).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.
Izohlar (0)
Izoh yozish uchun kiring.
- Hozircha izoh yo'q. Birinchi bo'ling!