15-bo‘lim
Jurnal, monitoring va aniqlash
Nimani jurnalga yozish, markazlashtirilgan yig'ish, SIEM, aniqlash qoidalari va ogohlantirishlar.
Ushbu bo‘lim mundarijasi
Hujumni aniqlashning yagona yo'li - kuzatish. Jurnalsiz siz buzilishni oylar davomida bilmasligingiz mumkin.
Aniqlash vaqti #
Tashkilotlar buzilishni ko'pincha o'zi emas, boshqalar aytgach biladi:
- Mijoz "mening ma'lumotim internetda" deydi
- Bank soxta to'lovlar haqida xabar beradi
- Tadqiqotchi ochiq bazani topadi
- Ma'lumot sotuvga chiqadi
Bu monitoring yo'qligining aniq belgisi.
Nimani jurnalga yozish kerak? #
| Kategoriya | Hodisalar |
|---|---|
| Autentifikatsiya | Kirish (muvaffaqiyatli va yo'q), chiqish, parol o'zgarishi, 2FA |
| Avtorizatsiya | Rad etilgan kirish, huquq o'zgarishi |
| Ma'lumot | Maxfiy ma'lumotga kirish, eksport, o'chirish |
| Administrativ | Sozlama o'zgarishi, foydalanuvchi yaratish |
| Tizim | Ishga tushish, xatolar, yangilanishlar |
| Tarmoq | Ulanishlar, bloklangan so'rovlar |
| Ilova | Biznes hodisalari, xatolar |
final class XavfsizlikJurnali
{
public function kirish(string $login, bool $muvaffaqiyat, array $qoshimcha = []): void
{
$this->yozing($muvaffaqiyat ? 'kirish_muvaffaqiyatli' : 'kirish_muvaffaqiyatsiz', [
'login' => $login,
'sabab' => $qoshimcha['sabab'] ?? null,
], $muvaffaqiyat ? 'info' : 'warning');
}
public function huquqRadEtildi(Foydalanuvchi $f, string $resurs, string $amal): void
{
$this->yozing('huquq_rad_etildi', [
'foydalanuvchi_id' => $f->id,
'resurs' => $resurs,
'amal' => $amal,
], 'warning');
}
public function maxfiyMalumotgaKirish(Foydalanuvchi $f, string $tur, int $soni): void
{
$this->yozing('maxfiy_malumotga_kirish', [
'foydalanuvchi_id' => $f->id,
'malumot_turi' => $tur,
'yozuvlar_soni' => $soni,
], $soni > 100 ? 'warning' : 'info');
}
private function yozing(string $hodisa, array $tafsilotlar, string $daraja): void
{
$this->logger->log($daraja, $hodisa, array_merge($tafsilotlar, [
'hodisa' => $hodisa,
'vaqt' => (new DateTimeImmutable())->format('c'),
'ip' => $this->sorov->ip(),
'agent' => $this->sorov->agent(),
'sorov_id' => $this->sorov->id(),
'sessiya' => session_id() ?: null,
]));
}
}
Tuzilmali jurnal #
// YOMON - qidirib bo'lmaydi
error_log("Foydalanuvchi 42 buyurtma 1042 ni bekor qildi");
// YAXSHI - tuzilmali
$this->jurnal->info('buyurtma_bekor_qilindi', [
'foydalanuvchi_id' => 42,
'buyurtma_id' => 1042,
'sabab' => 'mijoz_sorovi',
'oldingi_holat' => 'tolangan',
'summa' => 750000,
]);
{
"vaqt": "2026-09-15T14:22:31.482+05:00",
"daraja": "info",
"hodisa": "buyurtma_bekor_qilindi",
"foydalanuvchi_id": 42,
"buyurtma_id": 1042,
"sabab": "mijoz_sorovi",
"oldingi_holat": "tolangan",
"summa": 750000,
"ip": "203.0.113.45",
"sorov_id": "req_8f3a1d0e",
"xizmat": "dokon-api",
"muhit": "production"
}
# Matnli jurnal
grep "bekor qildi" jurnal.log | grep "42"
# Tuzilmali jurnal
hodisa="buyurtma_bekor_qilindi" AND foydalanuvchi_id=42 AND summa>500000
Ikkinchi variant:
- Aniq filtrlash
- Agregatsiya (yig'indi, o'rtacha)
- Vizualizatsiya
- Ogohlantirish qoidalari
// XATO
$this->jurnal->info('Kirish urinishi', [
'login' => $login,
'parol' => $parol, // HECH QACHON
]);
Filtr qo'llang - 10-bo'limdagi MaxfiylikFiltri kabi.
Markazlashtirilgan yig'ish #
# vector.yaml - jurnal yig'uvchi
sources:
nginx_kirish:
type: file
include: ["/var/log/nginx/access.log"]
ilova:
type: file
include: ["/var/log/dokon/*.log"]
tizim:
type: journald
transforms:
nginx_tahlil:
type: remap
inputs: ["nginx_kirish"]
source: |
. = parse_nginx_log!(.message, "combined")
.xizmat = "nginx"
.muhit = "production"
sirlarni_tozalash:
type: remap
inputs: ["ilova"]
source: |
if exists(.parol) { .parol = "***" }
if exists(.token) { .token = "***" }
if exists(.authorization) { .authorization = "***" }
sinks:
loki:
type: loki
inputs: ["nginx_tahlil", "sirlarni_tozalash", "tizim"]
endpoint: "https://loki.dokon.uz"
labels:
xizmat: "{{ xizmat }}"
muhit: "{{ muhit }}"
Hujumchi tizimga kirsa, birinchi ishi - izlarni o'chirish.
Jurnal shu serverda saqlansa, u o'chiriladi.
Yechim:
- Jurnal darhol boshqa serverga yuborilsin
- Ilova foydalanuvchisida jurnal serveriga faqat yozish huquqi
- Jurnal serveriga kirish alohida hisoblar bilan
- Yaxlitlikni tekshirish (zanjirli xesh yoki imzo)
# rsyslog orqali masofaviy yuborish
echo '*.* @@jurnal.dokon.uz:514' | sudo tee -a /etc/rsyslog.conf
sudo systemctl restart rsyslog
Vaqt sinxronizatsiyasi #
sudo apt install chrony
sudo systemctl enable --now chronyd
chronyc sources
MS Name/IP address Stratum Poll Reach LastRx Last sample
^* time.cloudflare.com 3 6 377 15 -142us
Bir necha serverdagi hodisalarni bog'lash uchun ularning soati sinxron bo'lishi kerak.
5 daqiqalik farq - hodisalar ketma-ketligini butunlay buzadi.
Barcha jurnallarda UTC yoki vaqt mintaqasi aniq ko'rsatilgan ISO 8601 formatidan foydalaning.
SIEM #
Security Information and Event Management - jurnallarni yig'adi, bog'laydi va hujumlarni aniqlaydi.
| Vosita | Turi |
|---|---|
| Wazuh | Ochiq kodli, to'liq |
| Elastic Security | Ochiq kod + tijorat |
| Graylog | Ochiq kodli |
| Splunk | Tijorat, kuchli |
| Microsoft Sentinel | Bulut |
# Wazuh o'rnatish (agent)
curl -sO https://packages.wazuh.com/4.x/wazuh-install.sh
sudo bash ./wazuh-install.sh -a
<!-- Wazuh qoidasi: ko'p muvaffaqiyatsiz kirish -->
<group name="autentifikatsiya">
<rule id="100100" level="10" frequency="8" timeframe="120">
<if_matched_sid>5716</if_matched_sid>
<same_source_ip />
<description>Bir IP dan 2 daqiqada 8 ta muvaffaqiyatsiz SSH urinishi</description>
<mitre>
<id>T1110</id>
</mitre>
</rule>
<rule id="100101" level="12">
<if_sid>5715</if_sid>
<time>22:00-06:00</time>
<description>Ish vaqtidan tashqari muvaffaqiyatli SSH kirish</description>
</rule>
</group>
Aniqlash qoidalari #
# Sigma formati - universal aniqlash qoidasi
title: Ko'p muvaffaqiyatsiz kirish urinishi
id: a1b2c3d4-e5f6-7890-abcd-ef1234567890
status: stable
description: Bir hisobga qisqa vaqtda ko'p muvaffaqiyatsiz urinish
author: Xavfsizlik jamoasi
date: 2026/09/15
logsource:
product: dokon
service: autentifikatsiya
detection:
tanlash:
hodisa: 'kirish_muvaffaqiyatsiz'
vaqt_oynasi: 5m
shart: tanlash | count() by login > 10
falsepositives:
- Foydalanuvchi parolni unutgan
- Avtomatlashtirilgan test
level: medium
tags:
- attack.credential_access
- attack.t1110
title: Ish vaqtidan tashqari maxfiy ma'lumotga kirish
detection:
tanlash:
hodisa: 'maxfiy_malumotga_kirish'
vaqt:
soat: '<06 or >22'
shart: tanlash and vaqt
level: high
title: Katta hajmdagi ma'lumot eksporti
detection:
tanlash:
hodisa: 'malumot_eksport'
yozuvlar_soni: '>1000'
shart: tanlash
level: high
Sigma qoidalari istalgan SIEM uchun tarjima qilinadi:
sigmac -t elastalert qoida.yml
sigmac -t splunk qoida.yml
sigmac -t es-qs qoida.yml
Jamiyat tomonidan yaratilgan minglab tayyor qoidalar mavjud.
MITRE ATT&CK #
# Aniqlash qamrovi
| Taktika | Texnika | Qoida bormi | Manba |
|---------|---------|-------------|-------|
| Dastlabki kirish | T1110 Kuch bilan | Ha | auth.log |
| Dastlabki kirish | T1566 Fishing | Qisman | email jurnali |
| Bajarish | T1059 Skript | Ha | auditd |
| Doimiylik | T1053 Rejalashtirilgan vazifa | Ha | auditd |
| Doimiylik | T1098 Hisob manipulyatsiyasi | Ha | auth.log |
| Huquq oshirish | T1548 sudo | Ha | auth.log |
| Yashirinish | T1070 Jurnalni o'chirish | Yo'q | — |
| Chiqarish | T1041 C2 orqali | Qisman | tarmoq |
Bu jadval qayerda ko'r nuqta borligini ko'rsatadi.
"Jurnalni o'chirish" uchun qoida yo'q - demak hujumchi izlarni o'chirsa, biz bilmaymiz.
Yechim: jurnalni alohida serverga yuborish va o'chirish urinishini aniqlash.
Ogohlantirishlar #
# Prometheus alertmanager qoidalari
groups:
- name: xavfsizlik
rules:
- alert: KopMuvaffaqiyatsizKirish
expr: |
sum(rate(kirish_urinishlari_total{natija="xato"}[5m])) by (ip) > 1
for: 2m
labels:
jiddiylik: ogohlantirish
taktika: credential_access
annotations:
xulosa: "{{ $labels.ip }} dan ko'p muvaffaqiyatsiz kirish"
runbook: "https://wiki.dokon.uz/runbook/kuch-bilan-hujum"
- alert: YangiAdminHisob
expr: increase(admin_hisoblar_total[1h]) > 0
labels:
jiddiylik: kritik
annotations:
xulosa: "Yangi administrator hisobi yaratildi"
- alert: KattaEksport
expr: |
sum(rate(malumot_eksport_yozuvlar[10m])) by (foydalanuvchi) > 100
for: 5m
labels:
jiddiylik: kritik
annotations:
xulosa: "{{ $labels.foydalanuvchi }} katta hajmda ma'lumot eksport qilmoqda"
- alert: JurnalKelmayapti
expr: |
time() - max(jurnal_oxirgi_yozuv_vaqti) by (xizmat) > 600
labels:
jiddiylik: kritik
annotations:
xulosa: "{{ $labels.xizmat }} dan 10 daqiqadan beri jurnal kelmayapti"
Agar jurnal to'satdan to'xtasa, bu:
- Xizmat qulagan, yoki
- Hujumchi jurnalni o'chirgan
Ikkala holat ham darhol tekshirishni talab qiladi.
Bu ogohlantirishni albatta qo'shing.
Ogohlantirish charchashi #
- Har bir ogohlantirish uchun ish daftarchasi bo'lsin
- Jiddiylikni to'g'ri belgilang (kritik - tunda uyg'otish)
- Soxta natijalarni darhol tuzating
- Oyiga bir marta qayta ko'rib chiqing
- Guruhlash - 100 ta bir xil ogohlantirish o'rniga bitta
- Susaytirish - texnik ishlar paytida o'chirish
# Alertmanager: guruhlash va susaytirish
route:
group_by: ['alertname', 'xizmat']
group_wait: 30s
group_interval: 5m
repeat_interval: 4h
routes:
- match:
jiddiylik: kritik
receiver: navbatchi-telefon
group_wait: 10s
- match:
jiddiylik: ogohlantirish
receiver: slack-xavfsizlik
inhibit_rules:
# Server qulagan bo'lsa, undagi xizmat ogohlantirishlarini yubormaslik
- source_match:
alertname: ServerIshlamayapti
target_match_re:
alertname: '.*'
equal: ['server']
Panellar #
# Xavfsizlik paneli
## Real vaqt
- Faol sessiyalar soni
- Kirish urinishlari (muvaffaqiyatli / muvaffaqiyatsiz)
- Bloklangan IP lar
- 4xx va 5xx xatolar darajasi
- WAF bloklashlari
## Kunlik
- Yangi foydalanuvchilar
- Huquq o'zgarishlari
- Administrativ amallar
- Maxfiy ma'lumotga kirishlar
- Eksport hajmi
## Trendlar
- Ogohlantirishlar soni (7 kun)
- O'rtacha javob vaqti
- Aniqlash vaqti (MTTD)
- Ochiq zaifliklar
-- Shubhali faollik so'rovlari
-- Ko'p muvaffaqiyatsiz kirish
SELECT ip, COUNT(*) AS urinishlar, MIN(vaqt), MAX(vaqt)
FROM kirish_urinishlari
WHERE muvaffaqiyat = 0
AND vaqt > DATE_SUB(NOW(), INTERVAL 1 HOUR)
GROUP BY ip
HAVING urinishlar > 10
ORDER BY urinishlar DESC;
-- Bir hisobga ko'p IP dan kirish
SELECT foydalanuvchi_id, COUNT(DISTINCT ip) AS ip_soni,
GROUP_CONCAT(DISTINCT ip) AS iplar
FROM kirish_urinishlari
WHERE muvaffaqiyat = 1
AND vaqt > DATE_SUB(NOW(), INTERVAL 24 HOUR)
GROUP BY foydalanuvchi_id
HAVING ip_soni > 3;
-- Ish vaqtidan tashqari administrativ amallar
SELECT f.email, a.amal, a.vaqt, a.ip
FROM audit_jurnali a
JOIN foydalanuvchilar f ON f.id = a.foydalanuvchi_id
WHERE HOUR(a.vaqt) NOT BETWEEN 8 AND 20
AND a.amal LIKE 'admin.%'
AND a.vaqt > DATE_SUB(NOW(), INTERVAL 7 DAY)
ORDER BY a.vaqt DESC;
-- Katta hajmdagi ma'lumot ko'rish
SELECT foydalanuvchi_id, SUM(yozuvlar_soni) AS jami, COUNT(*) AS sorovlar
FROM malumotga_kirish_jurnali
WHERE vaqt > DATE_SUB(NOW(), INTERVAL 1 DAY)
GROUP BY foydalanuvchi_id
HAVING jami > 5000
ORDER BY jami DESC;
Jurnalni saqlash #
| Jurnal turi | Saqlash muddati |
|---|---|
| Xavfsizlik hodisalari | 1-3 yil |
| Audit jurnali | 3-7 yil (qonun talabiga ko'ra) |
| Ilova jurnali | 30-90 kun |
| Veb server kirish | 90 kun |
| Nosozlik tuzatish | 7 kun |
# Elasticsearch ILM siyosati
{
"policy": {
"phases": {
"hot": {
"actions": {
"rollover": { "max_size": "50GB", "max_age": "1d" }
}
},
"warm": {
"min_age": "7d",
"actions": { "shrink": { "number_of_shards": 1 } }
},
"cold": {
"min_age": "30d",
"actions": { "freeze": {} }
},
"delete": {
"min_age": "90d",
"actions": { "delete": {} }
}
}
}
}
Jurnalni cheksiz saqlash qimmat.
Yondashuv:
- Issiq (7 kun) - tez qidiruv, qimmat
- Iliq (30 kun) - sekinroq, arzonroq
- Sovuq (1 yil) - arxiv, juda arzon
- O'chirish - muddat tugagach
Xavfsizlik hodisalarini esa uzoqroq saqlang - buzilish oylar davomida aniqlanmasligi mumkin.
Amaliy misol #
// To'liq xavfsizlik jurnali oraliq qatlami
final class XavfsizlikJurnaliOraliqQatlami
{
private const KUZATILADIGAN_YOLLAR = [
'/api/admin/',
'/api/eksport',
'/api/foydalanuvchilar',
];
public function ishlang(Sorov $sorov, callable $keyingi): Javob
{
$boshlandi = microtime(true);
$javob = $keyingi($sorov);
$davomiylik = (microtime(true) - $boshlandi) * 1000;
$kuzatilsinmi = $javob->kod() >= 400
|| $this->kuzatiladiganYolmi($sorov->yol())
|| $sorov->metod() !== 'GET';
if (!$kuzatilsinmi) {
return $javob;
}
$daraja = match (true) {
$javob->kod() >= 500 => 'error',
$javob->kod() === 403 => 'warning',
$javob->kod() === 401 => 'warning',
$javob->kod() === 429 => 'warning',
default => 'info',
};
$this->jurnal->log($daraja, 'http_sorov', [
'metod' => $sorov->metod(),
'yol' => $sorov->yol(),
'kod' => $javob->kod(),
'davomiylik_ms' => round($davomiylik, 1),
'ip' => $sorov->ip(),
'agent' => $sorov->agent(),
'foydalanuvchi' => $this->joriy?->id,
'sorov_id' => $sorov->id(),
]);
return $javob;
}
}
Monitoring ro'yxati #
| Talab | Bajarildi |
|---|---|
| Autentifikatsiya hodisalari yoziladi | |
| Huquq rad etishlari yoziladi | |
| Administrativ amallar yoziladi | |
| Maxfiy ma'lumotga kirish yoziladi | |
| Jurnal tuzilmali (JSON) | |
| Sirlar filtrlangan | |
| Markazlashtirilgan yig'ish | |
| Jurnal alohida serverda | |
| Vaqt sinxronlangan (NTP) | |
| Aniqlash qoidalari yozilgan | |
| Ogohlantirishlar sozlangan | |
| Har bir ogohlantirishga ish daftarchasi | |
| "Jurnal kelmayapti" ogohlantirishi | |
| Saqlash muddati belgilangan | |
| Panellar yaratilgan |
- Ilovangizga tuzilmali xavfsizlik jurnalini qo'shing.
- Kirish, huquq rad etish va admin amallarini yozing.
- Maxfiylik filtrini qo'llang.
- Jurnalni JSON formatda chiqaring.
- Markazlashtirilgan yig'ishni sozlang (Loki yoki Elasticsearch).
- NTP ni sozlang va vaqtni tekshiring.
- Uchta Sigma qoidasi yozing.
- MITRE ATT&CK qamrov xaritasini tuzing.
- Beshta ogohlantirish qoidasini yozing.
- Xavfsizlik panelini yarating.
Xulosa #
- Monitoringsiz buzilish oylar davomida aniqlanmasligi mumkin.
- Tuzilmali jurnal (JSON) qidiruv va tahlilni osonlashtiradi.
- Jurnalga sirlarni yozmang - filtr qo'llang.
- Jurnal alohida serverda saqlansin - hujumchi o'chira olmasin.
- Vaqt sinxronizatsiyasi (NTP) hodisalarni bog'lash uchun shart.
- SIEM jurnallarni bog'laydi va hujumlarni aniqlaydi.
- Sigma - universal aniqlash qoidasi formati.
- MITRE ATT&CK qamrov xaritasi ko'r nuqtalarni ko'rsatadi.
- "Jurnal kelmayapti" - eng muhim ogohlantirishlardan biri.
- Ogohlantirish charchashi haqiqiy hujumni yashiradi.
- Ogohlantirish harakat talab qilsin, aks holda u metrika.
- Xavfsizlik jurnallarini uzoqroq saqlang.
Keyingi bo'limda hodisalarga javob berishni ko'ramiz.
O‘qish tarixini saqlamoqchimisiz?
Tizimga kirsangiz, tugatgan bo‘limlaringiz saqlanadi va qoldirgan joyingizdan davom etasiz.
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.