15-bo‘lim

Jurnal, monitoring va aniqlash

Nimani jurnalga yozish, markazlashtirilgan yig'ish, SIEM, aniqlash qoidalari va ogohlantirishlar.

🕑 15 daqiqa o‘qish 📄 987 so‘z 👁 6 marta ko‘rilgan
Ushbu bo‘lim mundarijasi
  1. Aniqlash vaqti
  2. Nimani jurnalga yozish kerak?
  3. Tuzilmali jurnal
  4. Markazlashtirilgan yig'ish
  5. Vaqt sinxronizatsiyasi
  6. SIEM
  7. Aniqlash qoidalari
  8. MITRE ATT&CK
  9. Ogohlantirishlar
  10. Ogohlantirish charchashi
  11. Panellar
  12. Jurnalni saqlash
  13. Amaliy misol
  14. Monitoring ro'yxati
  15. Xulosa

Hujumni aniqlashning yagona yo'li - kuzatish. Jurnalsiz siz buzilishni oylar davomida bilmasligingiz mumkin.

Aniqlash vaqti #

Buzilishni aniqlash vaqti Buzilish Aniqlash Cheklash Aniqlash vaqti (MTTD) Javob vaqti (MTTR) Yaxshi monitoring bilan: soatlar. Monitoringsiz: oylar Ko'p tashkilotlar buzilishni uchinchi tomondan bilib qoladi
Aniqlash vaqti qanchalik qisqa - zarar shunchalik kam
Ko'p buzilishlar tashqaridan xabar qilinadi

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? #

KategoriyaHodisalar
AutentifikatsiyaKirish (muvaffaqiyatli va yo'q), chiqish, parol o'zgarishi, 2FA
AvtorizatsiyaRad etilgan kirish, huquq o'zgarishi
Ma'lumotMaxfiy ma'lumotga kirish, eksport, o'chirish
AdministrativSozlama o'zgarishi, foydalanuvchi yaratish
TizimIshga tushish, xatolar, yangilanishlar
TarmoqUlanishlar, bloklangan so'rovlar
IlovaBiznes hodisalari, xatolar
PHP
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 #

PHP
// 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,
]);
JSON
{
  "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"
}
Tuzilmali jurnal nima beradi?
Natija
# 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
Jurnalga sirlarni yozmang
PHP
// XATO
$this->jurnal->info('Kirish urinishi', [
    'login' => $login,
    'parol' => $parol,        // HECH QACHON
]);

Filtr qo'llang - 10-bo'limdagi MaxfiylikFiltri kabi.

Markazlashtirilgan yig'ish #

Jurnallarni markazlashtirish Veb server Ilova Baza Firewall Yig'uvchi Fluentd, Vector Saqlash Elasticsearch, Loki Vizualizatsiya Grafana, Kibana Ogohlantirish Alertmanager, PagerDuty Jurnal alohida serverda saqlansin - hujumchi uni o'chira olmasin
Markazlashtirish - hodisalarni bog'lash imkonini beradi
YAML
# 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 }}"
Jurnal serveri alohida bo'lsin

Hujumchi tizimga kirsa, birinchi ishi - izlarni o'chirish.

Jurnal shu serverda saqlansa, u o'chiriladi.

Yechim:

  1. Jurnal darhol boshqa serverga yuborilsin
  2. Ilova foydalanuvchisida jurnal serveriga faqat yozish huquqi
  3. Jurnal serveriga kirish alohida hisoblar bilan
  4. Yaxlitlikni tekshirish (zanjirli xesh yoki imzo)
Terminal
# rsyslog orqali masofaviy yuborish
echo '*.* @@jurnal.dokon.uz:514' | sudo tee -a /etc/rsyslog.conf
sudo systemctl restart rsyslog

Vaqt sinxronizatsiyasi #

Terminal
sudo apt install chrony
sudo systemctl enable --now chronyd
chronyc sources
Natija
MS Name/IP address     Stratum Poll Reach LastRx Last sample
^* time.cloudflare.com       3    6   377     15   -142us
Vaqt to'g'ri bo'lmasa - tahlil imkonsiz

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.

VositaTuri
WazuhOchiq kodli, to'liq
Elastic SecurityOchiq kod + tijorat
GraylogOchiq kodli
SplunkTijorat, kuchli
Microsoft SentinelBulut
Terminal
# Wazuh o'rnatish (agent)
curl -sO https://packages.wazuh.com/4.x/wazuh-install.sh
sudo bash ./wazuh-install.sh -a
XML
<!-- 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 #

YAML
# 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
YAML
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
YAML
title: Katta hajmdagi ma'lumot eksporti
detection:
  tanlash:
    hodisa: 'malumot_eksport'
    yozuvlar_soni: '>1000'
  shart: tanlash
level: high
Sigma - universal format

Sigma qoidalari istalgan SIEM uchun tarjima qilinadi:

Terminal
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 #

MITRE ATT&CK taktikalari Razvedka Ma'lumot yig'ish Dastlabki kirish Fishing Bajarish Skript, buyruq Doimiylik Cron, xizmat Huquq oshirish sudo, SUID Yashirinish Jurnal o'chirish Lateral harakat SSH, SMB Chiqarish Ma'lumot o'g'irlash Nima uchun foydali? Har bir taktika uchun aniqlash qoidasi bormi? - qamrovni baholash Umumiy til: "T1110 - kuch bilan hujum" hamma tushunadi
ATT&CK - hujumchi texnikalarining tizimlashtirilgan bazasi
MARKDOWN
# 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 |
Qamrov xaritasi

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 #

YAML
# 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"
"Jurnal kelmayapti" - eng muhim ogohlantirish

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 #

Ogohlantirish charchashi muammosi Yomon holat Kuniga 200 ta ogohlantirish 90% soxta Natija: hammasi e'tiborsiz qoladi Yaxshi holat Kuniga 5-10 ta ogohlantirish Har biri tekshiriladi Natija: haqiqiy hujum topiladi Qoida Ogohlantirish harakat talab qilsin. Aks holda u metrika bo'lsin.
Kam, lekin sifatli ogohlantirishlar
Ogohlantirishlarni sozlash
  1. Har bir ogohlantirish uchun ish daftarchasi bo'lsin
  2. Jiddiylikni to'g'ri belgilang (kritik - tunda uyg'otish)
  3. Soxta natijalarni darhol tuzating
  4. Oyiga bir marta qayta ko'rib chiqing
  5. Guruhlash - 100 ta bir xil ogohlantirish o'rniga bitta
  6. Susaytirish - texnik ishlar paytida o'chirish
YAML
# 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 #

MARKDOWN
# 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
SQL
-- 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 turiSaqlash muddati
Xavfsizlik hodisalari1-3 yil
Audit jurnali3-7 yil (qonun talabiga ko'ra)
Ilova jurnali30-90 kun
Veb server kirish90 kun
Nosozlik tuzatish7 kun
YAML
# 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": {} }
      }
    }
  }
}
Xarajat va foyda muvozanati

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 #

PHP
// 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 #

Tekshirish
TalabBajarildi
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
Amaliy topshiriq
  1. Ilovangizga tuzilmali xavfsizlik jurnalini qo'shing.
  2. Kirish, huquq rad etish va admin amallarini yozing.
  3. Maxfiylik filtrini qo'llang.
  4. Jurnalni JSON formatda chiqaring.
  5. Markazlashtirilgan yig'ishni sozlang (Loki yoki Elasticsearch).
  6. NTP ni sozlang va vaqtni tekshiring.
  7. Uchta Sigma qoidasi yozing.
  8. MITRE ATT&CK qamrov xaritasini tuzing.
  9. Beshta ogohlantirish qoidasini yozing.
  10. 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.

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.