Xavfsizlik — root siz, maxfiy ma'lumotlar, image skanerlash
Muammodan boshlaylik
Hujumchi ilovangizdagi zaiflik orqali konteyner ichida buyruq bajarishga muvaffaq bo'ldi. Keyin nima bo'ladi?
- Konteyner root sifatida ishlayapti → tizim fayllarini o'zgartirishi mumkin
envbuyrug'i → baza paroli, JWT kaliti, AWS kalitlari ko'rinib turibdi- Image da
curl,bash,aptbor → qo'shimcha vositalarni yuklab oladi - Konteyner baza bilan bitta tarmoqda → bazaga to'g'ridan-to'g'ri ulanadi
docker.sockulangan → butun server uning qo'lida
Konteyner — xavfsizlik chegarasi, lekin mutlaq emas. Bu dars — himoya qatlamlari haqida: bittasi o'tib ketilsa, keyingisi to'xtatadi.
1. Root siz ishlash
RUN addgroup -S ilova && adduser -S ilova -G ilova
COPY --chown=ilova:ilova . .
USER ilova
Yoki tayyor foydalanuvchi: node (node image), www-data (php), nginx (nginxinc/nginx-unprivileged).
Tekshirish:
docker exec api whoami # root bo'lmasligi kerak
docker exec api id
1024 dan kichik portlar root talab qiladi — shuning uchun root siz konteynerda 8080 ni tinglang va tashqarida 80:8080 bilan bog'lang.
2. Imtiyozlarni cheklash
services:
api:
image: dokon-api:1.4.2
read_only: true # fayl tizimi faqat o'qish uchun
tmpfs:
- /tmp # yozish kerak bo'lgan joy — xotirada
cap_drop:
- ALL # barcha Linux imtiyozlarini olib tashlash
security_opt:
- no-new-privileges:true # setuid orqali imtiyoz oshirish taqiqlangan
read_only— hujumchi fayllarni o'zgartira olmaydi, zararli dastur yozolmaydicap_drop: ALL— root bo'lsa ham ko'p narsa qila olmaydi (tarmoq sozlash, fayl egasini o'zgartirish...). Kerak bo'lsa bittasini qaytarish:cap_add: [NET_BIND_SERVICE]no-new-privileges—sudo/ setuid fayllar orqali root ga ko'tarilish yo'q
[!WARNING]
privileged: true— barcha himoyalarni o'chiradi: konteyner amalda server ustidan root. Faqat aniq bilganingizda (masalan, Docker-in-Docker CI runner) va hech qachon veb-ilova uchun emas.
docker.sock
volumes:
- /var/run/docker.sock:/var/run/docker.sock # ⚠️
Docker socket ga kirish = serverda root (yangi privileged konteyner yaratib, butun diskni ulash mumkin). Faqat zarur vositalarga (Traefik, monitoring) va iloji bo'lsa socket proxy orqali (37-dars).
3. Maxfiy ma'lumotlar (secrets)
Qayerda saqlamaslik kerak
# ❌ Image ichida — har kim docker history yoki qatlamdan o'qiydi
ENV DB_PASSWORD=Sir123
COPY .env .
ARG NPM_TOKEN
RUN echo "//registry.npmjs.org/:_authToken=$NPM_TOKEN" > .npmrc && npm ci
Oxirgi misolda .npmrc keyingi qatorda o'chirilsa ham — u oldingi qatlamda qoladi (14-dars). ARG qiymatlari esa docker history da ko'rinadi.
docker history --no-trunc dokon-api:1.0 # ARG va ENV lar shu yerda
Build vaqtidagi sirlar — --mount=type=secret
RUN --mount=type=secret,id=npmrc,target=/root/.npmrc npm ci
docker build --secret id=npmrc,src=$HOME/.npmrc -t dokon-api .
Fayl faqat shu RUN vaqtida mavjud — hech bir qatlamga yozilmaydi.
Ishga tushirish vaqtidagi sirlar
| Usul | Xavfsizlik | Izoh |
|---|---|---|
environment: da qiymat (compose fayl Git da) |
❌ | Kodda parol |
.env fayl (Git dan tashqari) |
⚠️ Asosiy | env va docker inspect da ko'rinadi |
Compose secrets: |
✅ Yaxshiroq | Fayl sifatida /run/secrets/ da |
| Vault, AWS Secrets Manager, Doppler | ✅✅ | Katta loyihalar |
Compose secrets:
services:
baza:
image: postgres:17-alpine
environment:
POSTGRES_PASSWORD_FILE: /run/secrets/db_parol
secrets:
- db_parol
secrets:
db_parol:
file: ./secrets/db_parol.txt # Git da emas!
Ko'p rasmiy image lar *_FILE o'zgaruvchilarini qo'llab-quvvatlaydi — parol muhit o'zgaruvchisida emas, faylda. O'z ilovangizda: fs.readFileSync('/run/secrets/db_parol', 'utf8').trim().
4. Image skanerlash
Image dagi har bir paket — potentsial zaiflik (CVE). Skanerlar ma'lum zaifliklar bazasi bilan solishtiradi:
# Docker Scout (Docker Desktop bilan)
docker scout quickview dokon-api:1.4.2
docker scout cves dokon-api:1.4.2
# Trivy (bepul, ochiq kodli, CI da eng ommabop)
docker run --rm -v /var/run/docker.sock:/var/run/docker.sock \
aquasec/trivy image dokon-api:1.4.2
trivy image --severity HIGH,CRITICAL --exit-code 1 dokon-api:1.4.2
--exit-code 1 — jiddiy zaiflik topilsa CI ni to'xtatish (41-dars).
Natijada odatda:
Total: 23 (HIGH: 4, CRITICAL: 1)
│ openssl │ CVE-2024-XXXX │ CRITICAL │ 3.1.4-r0 │ 3.1.4-r5 │
Ko'pincha yechim oddiy: asos image ni yangilash (node:22-alpine ning yangi versiyasi) va qayta build.
5. Image ni kichik va toza saqlash
Image da qancha kam narsa bo'lsa — shuncha kam zaiflik va hujumchi uchun kamroq vosita (17-dars):
- Multi-stage — kompilyator va dev bog'liqliklar yakuniy image da yo'q
-alpine,-slim, distroless — shell ham yo'q- Asos image — rasmiy yoki "Docker Official / Verified Publisher"; noma'lum muallif image lari — yo'q
- Versiya qotirilgan (
node:22.11-alpine), yoki digest (38-dars)
6. Tarmoq va host
- Faqat proxy tashqariga ochiq; baza —
internal: truetarmoqda (25-dars) 127.0.0.1:bilan bog'lash — faqat lokal xizmatlar uchun- Docker portlari UFW ni chetlab o'tadi — 25-darsdagi ogohlantirish
- Docker va server tizimini yangilab turing
Tekshiruv ro'yxati
[ ] USER — root emas
[ ] Image da sirlar yo'q (docker history ni tekshiring)
[ ] .dockerignore da .env, .git
[ ] Asos image versiyasi qotirilgan va yangi
[ ] Trivy/Scout — CRITICAL yo'q
[ ] read_only, cap_drop: ALL, no-new-privileges
[ ] privileged yo'q, docker.sock faqat zarur joyda
[ ] Baza tashqariga ochiq emas
[ ] Sirlar — secrets yoki tashqi menejerda
[ ] Resurs chegaralari (40-dars)
Nima uchun shunday?
Nima uchun bu choralarning hammasi kerak — bittasi yetmaydimi?
Chunki xavfsizlik — chuqur himoya (defense in depth): har bir qatlam boshqasi muvaffaqiyatsiz bo'lishini nazarda tutadi. Ilovada zaiflik bo'ladi — bu muqarrar. Savol — undan keyin hujumchi qancha narsa qila oladi. Root siz foydalanuvchi — tizimni o'zgartira olmaydi; read_only — hech narsa yozolmaydi; minimal image — vositalari yo'q; izolyatsiyalangan tarmoq — bazaga yetolmaydi; sirlar faylda — env bo'sh. Har bir qatlam zararni kichraytiradi, va birgalikda "konteyner buzildi" hodisasi "butun kompaniya ma'lumotlari sizdi" ga aylanmaydi.
Xulosa
Eslab qoling:
USER— root emas; portlar 1024 dan yuqoriread_only,cap_drop: ALL,no-new-privileges;privileged— yo'qdocker.sock= server ustidan root- Sirlar image da emas:
ENV,ARG,COPY .env— ❌; build uchun--mount=type=secret - Ishga tushirishda — Compose
secretsva*_FILE - Skanerlash:
trivy image,docker scout cves; yechim — ko'pincha asos image ni yangilash - Minimal image, qotirilgan versiyalar, izolyatsiyalangan tarmoq
- Chuqur himoya — har bir qatlam muhim
Keyingi dars
40-dars: Resurslar — CPU, xotira chegaralari va restart siyosati