Runbook — дохио бүрд юу хийх вэ¶
Prometheus-ийн дохио бүрд: юу болсон, эхний 5 минутад юу шалгах, яаж засах, хэзээ өргөжүүлэх.
Баримт бичгийн төв рүү буцах · Ажиллагаа
Дохионы нэрс нь 2026-10-25-нд хаагдсан nexus.gerege.mn-ийн ажиглалтын стекийн Prometheus дүрмүүдийнх (тэр стек энэ репоос хасагдсан). Алхмууд нь платформын зан төлөвийг тайлбарладаг тул хүчинтэй хэвээр.
Нэр ба зам. Одоогийн цорын ганц суулгац nexus.gerege.net: core-app-02 дээр
/opt/nexus хавтаст docker compose-оор ажиллана, API 127.0.0.1:8080,
frontend 127.0.0.1:3000 (deploy-dev.yml).
Compose файл, .env, нөөцлөлт нь
proxmox-gerege-net (stack/nexus)
репод. Доорх командууд /opt/nexus дотроос:
Ерөнхий зарчим¶
Хоёр түвшин. severity: page нь хэн нэгнийг сэрээх ёстой — хэрэглэгч
одоо хохирч байна. severity: ticket нь ажлын өдөр засах — засахгүй бол
хохирол болно. Ticket дээр 03:00 цагт хариу үйлдэл хийх нь alert fatigue-ийн
хамгийн богино зам бөгөөд түүний төгсгөл нь page-ийг ч үл тоох явдал.
Эхлээд хэмжилт, дараа нь тааварлалт. Дохио бүрийн эхний алхам нь Grafana дээр аль хэсэг эвдэрсэнийг харах. Restart нь бараг үргэлж шинжтомжийг арилгаад шалтгааныг нь нуудаг.
Юу хийснээ бич. Осол бүрийн дараа энэ файлыг засах нь дараагийн хүнд өгөх хамгийн үнэ цэнэтэй зүйл.
Тайван байдал. Платформын ихэнх дохио нь өгөгдөл алдагдсан гэсэн үг биш. Өгөгдөл алдагдах ганц бодит эрсдэл нь дискний дүүрэлт бөгөөд түүнд тусдаа хоёр дохио бий.
API¶
NexusAPIDown¶
Юу болсон. Prometheus 2 минутын турш backend-ийн /metrics-ийг уншиж
чадсангүй. Процесс унасан, гацсан, эсвэл сүлжээ тасарсан.
Энэ үед бусад бүх API дохио чимээгүй болно — өгөгдөл ирэхгүй тул дүрэм тооцоологдохгүй. Тиймээс энэ дохио дангаараа ирж байгаа нь "өөр юу ч болоогүй" гэсэн үг биш.
Эхний 5 минут.
docker compose ps backend
docker compose logs --tail 200 backend
curl -s 127.0.0.1:8080/health
curl -s 127.0.0.1:8080/ready
- Контейнер огт байхгүй эсвэл
Restartingбол → логоос яагаад гарсныг унш. /healthхариулж байгаа атлаа/metricsуншигдахгүй бол → сүлжээний асуудал, Prometheus backend-д хүрч чадаж байгаа эсэхийг шалга./healthOK,/ready503 бол → хариуныmessage-ийг унш:database unreachable→ NexusPostgresDown;database schema is behind this release→ миграц ажиллаагүй (docker compose run --rm migrate up);tenant isolation is not active yet→ dbguard-ийн probe хараахан амжаагүй (өгөгдлийн сан хүрэхгүй эсвэл роль/grant буруу), логтdbguard:мөрийг хай. Схемийн шалгалт логтschema version check is offгэж байвал API-ийн рольpublic.goose_db_version-ийг уншиж чадахгүй байна (42501) —/ready-г блоклохгүй, гэхдээ хоцорсон схемийг барихгүй; хэрэгтэй болSELECTэрх өг.
Засах.
Дахин асаахын өмнө логийг хадгал — контейнер дахин үүсэхэд Loki-д очоогүй мөрүүд алга болно:
Байнга унаж байвал: санах ой (docker stats), OOM
(dmesg | tail -50), эсвэл миграц дуусаагүй байх магадлалтай.
Өргөжүүлэх. 15 минутын дотор сэргээгээгүй бол платформын хариуцсан хүнд. Өгөгдлийн сан хөндөгдсөн сэжигтэй бол шууд.
NexusAPIErrorBudgetBurningFast¶
Юу болсон. Сүүлийн 1 цаг ба сүүлийн 5 минутад хоёуланд нь 5xx-ийн хувь 1.44%-иас давлаа. Ийм хурдаар сарын алдааны төсөв 2 хоногт дуусна.
Хоёр цонх зэрэг давсан үед л дохио өгдөг гэдэг нь чухал: түр зуурын үсрэлт энэ дохиог өгөхгүй, харин одоо ч үргэлжилж байгаа эвдрэл өгнө.
Эхний 5 минут. Grafana → API тойм:
- Алдаа хамгийн их гаргаж буй замууд — нэг зам уу, бүгд үү?
- Нэг зам → тэр функцийн саяхны өөрчлөлт, эсвэл түүний хамаарал.
- Бүх зам → өгөгдлийн сан, эсвэл дөнгөж deploy хийсэн хувилбар.
- Хүсэлтийн урсгал — 5xx-ийн эхэлсэн мөч deploy-тэй давхцаж байна уу?
- Loki:
Засах.
- Deploy-ийн дараа эхэлсэн бол → буцаа. Оношлохоос өмнө буцаах нь зөв
дараалал. Өмнөх хувилбарын image GHCR-д commit-ийн SHA-гаар байгаа тул
deploy-dev.yml-ийг тэр SHA-гаар гараар ажиллуул: Схем нь шинэ хэвээр үлдэнэ — миграц нэг хувилбарын турш хойш нийцтэй байх дүрэм (Ажиллагаа) яг үүний төлөө. Дараа нь засварааmainруу түлхэхэд CI ногоон болмогц deploy шинэ image-ийг гаргана. - Гадаад системээс шалтгаалсан бол → NexusExternalSystemFailing.
- Өгөгдлийн сангаас → NexusDatabasePoolExhausted.
Өргөжүүлэх. 30 минутын дотор алдааны хувь буурахгүй бол.
NexusAPIErrorBudgetBurning¶
Юу болсон. 6 цаг ба 30 минутын цонхонд 0.6%-иас дээш. Огцом уналт биш, тогтвортой эвдрэлтэй төлөв — ихэвчлэн нэг зам, нэг гадаад систем, эсвэл зөвхөн тодорхой нөхцөлд гардаг алдаа.
Эхний 5 минут. Дээрхтэй адил, гэхдээ 6 цагийн хугацаанд: Алдаа хамгийн их гаргаж буй замууд панелийн хугацааг 6 цаг болго. Тогтмол нэг зам харагдвал тэр нь шалтгаан.
Засах. Ихэвчлэн код засвар шаардана. Хэрэглэгчид үргэлжлүүлэн хохирч байгаа тул засвар нь дараагийн ээлжийн ажил биш, өнөөдрийнх.
Өргөжүүлэх. Ажлын цагт хариуцсан багт. Шөнө сэрээх шаардлагагүй —
энэ нь page боловч 15 минутын for-той бөгөөд дэлбэрэлт биш.
NexusAPIErrorBudgetSlowBurn¶
Юу болсон. 3 хоног ба 6 цагийн аль алинд нь SLO-гоос давсан. Хэн ч сэрэх шаардлагагүй, гэхдээ энэ сарын 99.9% биелэхгүй болох замдаа явж байна.
Эхний 5 минут. Үлдсэн алдааны төсөв панелийг хар. Сөрөг бол зорилт аль хэдийн биелэхгүй болсон.
Засах. Тасалдсан хэдэн зам, эсвэл нэг тогтмол алдаа гаргадаг үйлдлийг
ол. Ихэвчлэн: боловсруулагдаагүй nil, timeout-гүй гадаад дуудлага, эсвэл
тодорхой өгөгдөл дээр л унадаг handler.
Өргөжүүлэх. Шаардлагагүй. Ажлын тасалбар үүсгэ.
NexusAPILatencyHigh¶
Юу болсон. Урт poll-оос бусад бүх замын p95 хариу 10 минутын турш 2 секундээс давлаа.
Эхний 5 минут.
- Grafana → Тэсвэрлэлт → Өгөгдлийн сангийн pool.
pgxpool_acquired_connsтаазанд ойрхон,empty_acquireөсөж байвал → шалтгаан нь pool. - Гадаад системүүд → p95. Аль нэг систем удааширсан бол handler-ууд түүнийг хүлээж байна.
- Инфраструктур → CPU, iowait. iowait өндөр бол диск.
Засах.
- Pool дүүрсэн → удаан query-г ол:
- Гадаад систем удаан → тухайн rail-ыг түр хаах боломжтой эсэхийг хар (жишээ нь eSign HSM-ийг гарын үсгийн бодлогоос).
- Диск удаан → NexusDiskFillingUp шалга, дүүрсэн диск удаашралын түгээмэл шалтгаан.
Өргөжүүлэх. Хэрэглэгчид "систем ажиллахгүй байна" гэж мэдэгдэж эхэлбэл
page шиг хандах.
NexusLoadShedding¶
Юу болсон. Зэрэг үйлчлэх хүсэлтийн тааз (1000)-д хүрч, шинэ хүсэлтүүд 503-аар татгалзагдаж байна. Хамгаалалт ажиллаж байгаа хэрэг — гэхдээ хэрэглэгч алдаа хараад байна.
Эхний 5 минут.
- Тэсвэрлэлт → Зэрэг үйлчилж буй хүсэлт. Огцом үсэрсэн үү, аажим өссөн үү?
- Огцом → урсгалын оргил эсвэл халдлага. API тойм → rps.
- Аажим → хүсэлтүүд дуусахгүй хуримтлагдаж байна: удаан гадаад дуудлага эсвэл өгөгдлийн сангийн түгжээ.
- Эх сурвалж нэг IP мөн эсэхийг nginx-ийн логоос:
Засах.
- Халдлага бол → nginx дээр хязгаарла (тэнд аль хэдийн
limit_reqбүсүүд бий). - Бодит ачаалал бол → яагаад хүсэлтүүд удаж байгааг ол; таазыг өсгөх нь сүүлийн арга бөгөөд ихэвчлэн буруу арга — 1000 зэрэг хүсэлт нь 25 холболттой pool-той машины хувьд аль хэдийн их.
- Урт poll-ууд (eID) хуримтлагдсан бол энэ нь хэвийн: тэдгээр нь секундүүдээр барих зориулалттай.
Өргөжүүлэх. 15 минутаас удаан үргэлжилбэл.
Гадаад системүүд¶
NexusExternalSystemFailing¶
Юу болсон. {{ system }} рүү хийсэн дуудлагын тэн хагасаас олон нь 10
минутын турш амжилтгүй. Энэ нь ихэвчлэн энэ платформын доголдол биш —
гэхдээ хэрэглэгчид нэвтэрч эсвэл гарын үсэг зурж чадахгүй байна.
Аль систем ямар үйлчилгээг зогсоох вэ:
| Систем | Зогсох зүйл |
|---|---|
eid |
Gerege ID-гаар нэвтрэх, баталгаажсан гарын үсэг |
dan |
ДАН-аар нэвтрэх |
xyp |
Иргэн/байгууллагын лавлагаа |
esign |
HSM-ийн гарын үсэг (хуучин зам) |
gemini |
AI туслах, орчуулга, яриа таних |
emailverify |
Хаяг баталгаажуулах и-мэйл |
Эхний 5 минут.
- Гадаад системүүд dashboard → p95 — үйлдлээр. Бүх үйлдэл унасан уу, нэг нь уу?
- Гараар шалга — жишээ нь eID:
- Loki:
- Итгэмжлэл дууссан эсэхийг шалга — 401/403 нь тэдний уналт биш, бидний тохиргооны асуудал.
Засах.
- Тэдний тал бол: тухайн үйлчилгээ үзүүлэгчид мэдэгд. Хэмжилтээ хамт өг —
external_request_duration_secondsнь яг хэдэн цагт, ямар хувьтай гэдгийг хэлнэ. - Бидний тал бол (итгэмжлэл, тохиргоо):
.env-ийг шалга, backend-ыг дахин асаа. - Хэрэглэгчдэд: өөр нэвтрэх зам байгаа эсэхийг мэдэгд (eID унасан ч нууц үг, Google ажиллаж байгаа бол).
Өргөжүүлэх. Нэвтрэлтийн бүх зам (eid, dan, google, sso) зэрэг унасан бол шууд — тэр үед хэн ч орж чадахгүй байна.
NexusExternalSystemDegraded¶
Юу болсон. 30 минутын турш алдааны хувь 15%-иас дээш. Зургаа тутмын нэг хүсэлт унана — хэрэглэгчийн хувьд "заримдаа ажилладаг", энэ нь бүрэн уналтаас удаан анзаарагддаг тул илүү их гомдол авчирдаг.
Эхний 5 минут. Дээрхтэй адил. Нэмж: алдаа тодорхой хэв маягтай юу — тодорхой регистрийн дугаар, тодорхой хэмжээний файл?
Засах. Ихэвчлэн хүлээх нь зөв — эсвэл давтан оролдох логик нэмэх. Дуудлага бүр өөрийн timeout-той эсэхийг шалга.
Өргөжүүлэх. Шаардлагагүй. Ажлын тасалбар.
NexusExternalSystemSlow¶
Юу болсон. {{ system }}-ийн p95 хариу 10 секундээс удаан. Удаан гадаад
дуудлага нь хүсэлтийн goroutine болон pool-ын холболтыг барьж байдаг тул
тухайн систем рүү огт хандаагүй хүсэлтүүд ч удаашрана.
Эхний 5 минут. Pool-ын байдлыг шалга (Тэсвэрлэлт dashboard).
resilience_in_flight_requests өсөж байвал энэ нь удахгүй load shedding
болно.
Засах. Тухайн rail-ыг түр хаах, эсвэл timeout-ыг богиносгох. Хамгийн муу төлөв нь удаан дуудлага + урт timeout: платформ бүхэлдээ нэг гадаад системийн хурдаар ажиллана.
Өргөжүүлэх. Load shedding эхэлбэл.
Инфраструктур¶
NexusDiskFillingUp¶
Юу болсон. {{ mountpoint }} дээр сул зай 15%-иас бага. 93% давбал
NexusDiskAlmostFull нь page болж ирнэ.
Энэ бол өгөгдөл алдагдах бодит эрсдэл бүхий цөөхөн дохионы нэг. 100% хүрэхэд Postgres бичихээ болино, WAL бичигдэхгүй, платформ бүхэлдээ зогсоно.
Эхний 5 минут.
Хамгийн түгээмэл гурван шалтгаан:
- Docker-ийн хуучин image, build cache — deploy бүр шинэ image татдаг.
- Prometheus/Loki-ийн өгөгдөл — 20 GB / 31 хоногийн таазтай ч эхний тохиргооны алдаа таазыг хэтрүүлж болно.
- Postgres — үнэхээр өссөн, эсвэл vacuum ажиллаагүй.
Засах.
# 1 — build cache. Хамгийн аюулгүй, ихэвчлэн хамгийн том.
docker builder prune -af
# 2 — ашиглагдаагүй image-ууд. deploy-dev.yml амжилттай rollout бүрийн дараа
# үүнийг өөрөө ажиллуулдаг ч диск дүүрсэн бол гараар шууд.
docker image prune -f
# Postgres-ийн хамгийн том хүснэгтүүд
docker compose exec -T postgres psql -U postgres -d platform_db -c "
SELECT relname, pg_size_pretty(pg_total_relation_size(c.oid)) AS size
FROM pg_class c JOIN pg_namespace n ON n.oid = c.relnamespace
WHERE n.nspname = 'public' AND c.relkind = 'r'
ORDER BY pg_total_relation_size(c.oid) DESC LIMIT 15;"
Устгаж болохгүй зүйлс: Postgres-ийн өгөгдлийн volume, шифрлэлтийн
түлхүүр агуулсан .env файлууд, гарын үсэгтэй PDF-үүд.
Хамгийн сүүлд гарсан: 2026-08-30, nexus.gerege.mn — 81%. Хэмжсэн зүйл: 294 image / 42.7 GB, build cache 11.9 GB. Ихэнх нь өдөр бүрийн deploy-ийн хуучин tag байсан — backend 129, frontend 130. Build cache ба хуучин tag-уудыг цэвэрлэхэд 61 GB → 22 GB (81% → 29%). Зогссон контейнерууд хуучин tag дээр суугаагүйг эхлээд шалгасан.
2026-10-12, nexus.gerege.mn — 100%. Энэ cron суугаагүй байсан (дээрх loop
хуучин private-gerege-nexus repo нэрийг заасан тул юу ч устгахгүй байв): 166
tag / repo, containerd 58 GB. private_nexus_postgres recovery-ийн checkpoint
дээр No space left on device PANIC-аар давтаж, eID нэвтрэлт «session could not
be started» гэж хэдэн цаг хариулсан — receiver хоосон тул хэн ч мэдээгүй.
Цэвэрлэсний дараа 44%; nexus_js_postgres restart backoff-д гацсан тул
docker restart хэрэгтэй болсон.
deploy бүр шинэ image нэмдэг ба ghcr-retention.yml нь зөвхөн GHCR талыг
цэвэрлэдэг, хостын дискийг биш — одоо deploy-dev.yml rollout бүрийн дараа
docker image prune -f ажиллуулна.
Өргөжүүлэх. 95% давбал шууд — цаг хэдхэн байна.
NexusDiskAlmostFull¶
93%. Дээрхтэй ижил, гэхдээ page. Эхлээд docker builder prune -af ба
docker image prune -f.
NexusHostMemoryPressure¶
Юу болсон. Сул санах ой 10%-иас бага. Дараагийн алхам нь OOM killer бөгөөд тэр нь ихэвчлэн хамгийн том процессыг — Postgres-ийг — алдаг.
Эхний 5 минут.
Инфраструктур dashboard → Контейнер бүрийн санах ой. Аль контейнер өссөн бэ, тогтмол өсөж байна уу (leak) эсвэл нэг үсрэлт үү?
Засах.
- Мониторингийн стек өөрөө хэт их идэж байвал → Prometheus-ийн retention багасга, эсвэл Loki-г түр унтраа. Платформ энэ хоёрын алийг нь ч шаарддаггүй.
- Backend leak → дахин асаа, дараа нь
go_goroutinesграфикийг хар (API тойм). Тогтмол өсөж байгаа goroutine нь дуусаагүй урт poll. - Postgres →
shared_buffersхэт өндөр тохируулсан эсэхийг шалга.
Өргөжүүлэх. OOM killer аль хэдийн ажилласан бол шууд.
NexusPostgresDown¶
Юу болсон. postgres_exporter өгөгдлийн санд холбогдож чадахгүй байна.
Эхлээд ялга: үнэхээр Postgres унасан уу, эсвэл зөвхөн exporter-ийн нэвтрэлт эвдэрсэн үү? Хоёр дахь нь платформд огт нөлөөгүй.
# Платформ өөрөө өгөгдлийн санд хүрч байна уу
curl -s 127.0.0.1:8080/ready
docker compose ps postgres
docker compose logs --tail 100 postgres
/ready нь {"status":"ready"} гэж хариулж байвал → Postgres хэвийн,
асуудал нь exporter-ийн нууц үг. backend/db/migrations/00044_monitoring_role.sql
доторх GRANT-ыг дахин ажиллуул.
Postgres үнэхээр унасан бол.
Диск дүүрсэн эсэхийг заавал шалга — Postgres-ийн зогсох хамгийн түгээмэл шалтгаан бол сул зай дуусах.
Өргөжүүлэх. Postgres үнэхээр унасан бол шууд. Өгөгдөл эвдэрсэн шинж
тэмдэг (PANIC, corrupted) харагдвал дахин асаахаа боль — эхлээд
backup-аа шалга.
NexusPostgresConnectionsHigh¶
Юу болсон. Зөвшөөрөгдсөн холболтын 80% эзлэгдсэн. Дүүрэхэд шинэ холболт бүр татгалзагдана.
Платформын pool нь replica тутамд 25-аар хязгаарлагдсан тул энэ нь ихэвчлэн pool-оос гадуурх ямар нэг зүйл холбогдож байгааг илтгэнэ.
Эхний 5 минут.
SELECT usename, application_name, state, count(*)
FROM pg_stat_activity GROUP BY 1,2,3 ORDER BY 4 DESC;
idle in transactionолон → commit хийгээгүй гүйлгээ. Түгжээ барьж, vacuum-ыг зогсооно.- Танихгүй
application_name→ өөр стек, нээлттэй үлдсэнpsql, эсвэл дуусаагүй миграц.
Засах.
-- 10 минутаас удаан idle in transaction байгаа холболтуудыг таслах
SELECT pg_terminate_backend(pid) FROM pg_stat_activity
WHERE state = 'idle in transaction'
AND now() - state_change > interval '10 minutes';
max_connections-ыг өсгөх нь сүүлийн арга: холболт бүр санах ой иддэг,
өсгөх нь ихэвчлэн асуудлыг хойшлуулна.
Өргөжүүлэх. 95% давбал.
NexusDatabasePoolExhausted¶
Юу болсон. Платформын өөрийн pool-ын 90%-иас дээш нь 10 минутын турш эзлэгдсэн. Хүсэлтүүд холболт хүлээж эхэлнэ — энэ нь удаашралыг тайлбарлах хамгийн эхний газар.
Postgres чөлөөтэй атлаа энэ дүүрсэн байх нь бүрэн боломжтой: асуудал нь холболтын тоо биш, тэднийг барьж буй хугацаа.
Эхний 5 минут.
- Тэсвэрлэлт → Хүлээлт.
empty_acquireтэгээс салсан мөч нь эхлэл. - Удаан query:
- Түгжээ:
Засах. Удаан query-г ол, индекс нэм. Түр арга нь тухайн query-г таслах
(pg_cancel_backend). Pool-ын хэмжээг өсгөх нь Postgres руу асуудлыг
шилжүүлнэ.
Өргөжүүлэх. p95 2 секундээс давбал.
NexusRedisDown¶
Юу болсон. Redis хариу өгөхгүй байна.
Платформ ажиллана. Redis нь энд кэш хүчингүй болгох мессеж болон deployment-ийн хэмжээний хурдны хязгаарын тоолуурыг барьдаг. Унасан үед хязгаар нь процесс тус бүрийнх болж, эрх цуцлах нь бусад replica дээр кэшийн TTL-ийн хугацаагаар хоцрогдоно. Өгөгдөл алдагдахгүй — Redis-д хадгалагдах ёстой юу ч байхгүй.
Эхний 5 минут.
docker compose ps redis
docker compose logs --tail 50 redis
docker compose exec redis redis-cli ping
Засах.
Санах ойн таазанд хүрсэн бол энэ нь хэвийн — allkeys-lru бодлого хуучин
түлхүүрүүдийг хаяна.
Өргөжүүлэх. Шаардлагагүй.
NexusContainerRestarting¶
Юу болсон. {{ name }} сүүлийн 30 минутад 3-аас олон удаа дахин эхэллээ.
Docker-ийн restart: unless-stopped нь эвдрэлийг нуух гол арга: үйлчилгээ
"ажиллаж байгаа" харагдана, гэхдээ хэсэг хугацаанд хариу өгөхгүй бөгөөд лог
нь контейнер бүрийн хамт алга болно.
Эхний 5 минут.
docker compose ps -a
docker inspect <контейнер> --format '{{.State.ExitCode}} {{.State.Error}}'
docker compose logs --tail 300 <үйлчилгээ>
- ExitCode 137 → OOM. NexusHostMemoryPressure.
- ExitCode 1 + тохиргооны алдаа →
.env. - Healthcheck унаж байгаа → шалтгаан нь тэр контейнер биш, түүний хамаарал.
Засах. Шалтгааныг зас. Дахин асаах нь мөчлөгийг л үргэлжлүүлнэ.
Өргөжүүлэх. backend эсвэл postgres бол шууд.
NexusTLSCertificateExpiringSoon¶
Юу болсон. {{ domain }}-ийн сертификат 14 хоногт дуусна — өөрөөр хэлбэл
certbot-ын автомат сунгалт ажиллаагүй байна.
Дуусахад бүх браузер сэрэмжлүүлэг үзүүлнэ, native клиентүүд огт холбогдохоо болино (тэд сертификатын алдааг алгасах товчгүй).
Эхний 5 минут.
sudo certbot certificates
sudo systemctl status certbot.timer
sudo journalctl -u certbot --since '7 days ago' | tail -50
Засах.
sudo certbot renew --dry-run # эхлээд туршилт
sudo certbot renew
sudo nginx -t && sudo systemctl reload nginx
Түгээмэл шалтгаан: .well-known/acme-challenge/ руу очих зам nginx-д
хаагдсан, DNS өөрчлөгдсөн, эсвэл 80 порт хаалттай.
Өргөжүүлэх. 3 хоног үлдсэн бол шууд.
Мониторинг өөрөө ба нөөцлөлт¶
Ажиглалтын стекийн өөрийнх нь болон нөөцлөлтийн дохионууд (NexusMonitoring*,
NexusAlertmanager*, NexusPrometheus*, NexusLoki*, NexusBackup*,
NexusTLSExpiryUnknown) хаагдсан хостын скрипт, стекийнх байсан. nexus.gerege.net-ийн
нөөцлөлт proxmox-gerege-net
(stack/nexus) репод.
Операторын консол¶
Консолын дохионууд бусдаасаа өөр асуулт тавьдаг: "систем эрүүл үү" биш,
"хэн нэгэн орох гэж оролдож байна уу". Консол нь хаягийн жагсаалтын
(CONTROL_PLANE_ALLOWED_CIDRS) ард байдаг тул эдгээр оролдлого нь зөвшөөрөгдсөн сүлжээнээс
ирж байна — гаднаас ирсэн бол энэ хүртэл хүрэхгүй байсан.
NexusControlPlaneLoginFailures¶
Юу болсон. 15 минутын дотор консол руу 5-аас олон удаа амжилтгүй нэвтрэх оролдлого болов.
Эхний 5 минут.
- Шалтгааныг ялга — Prometheus дээр:
bad_passwordдавамгайлж байвал → нууц үг тааж байна.bad_codeдавамгайлж байвал → нууц үг нь зөв байж болзошгүй, зөвхөн хоёр дахь хүчин зүйл нь зогсоож байна. Энэ нь илүү яаралтай.unknownдавамгайлж байвал → байхгүй и-мэйл хаягуудыг оролдож байна: жагсаалт таамаглаж байгаа хэрэг.no_second_factor→ bootstrap тасалдсан бүртгэл байна. §3.4-ийг үз.- Аль хаягнаас ирснийг:
- Тэр хаяг хэний вэ?
CONTROL_PLANE_ALLOWED_CIDRSдотор хэн байгааг хар.
Засах.
- Оператор өөрөө андуурсан бол → түгжээ 15 минутын дараа өөрөө тайлагдана. Яаралтай бол DB-ээс:
- Танихгүй хаяг бол → тэр хаягийг
CONTROL_PLANE_ALLOWED_CIDRS-аас хасаад backend-ыг дахин асаа. Дараа нь тухайн сүлжээнд юу болж байгааг шалга: жагсаалтад байгаа хаягнаас оролдлого ирсэн нь тэр машин эсвэл VPN-ийн бүртгэл алдагдсан гэсэн үг. bad_passwordолон боловч дараа ньsuccessгарсан бол → тэр session-ыгoperator_audit-аас шалга: хэн, хаанаас, юу хийсэн.
Өргөжүүлэх. bad_code олноор гарсан, эсвэл амжилтгүйн дараа амжилттай
нэвтрэлт болсон бол — тухайн операторт утсаар холбогдож, өөрөө мөн эсэхийг
асуу. Тийм биш бол бүх session-ыг цуцалж, нууц үг ба TOTP-ийг дахин үүсгэ.
NexusControlPlaneLockout¶
Юу болсон. Аль хэдийн түгжигдсэн бүртгэл рүү оролдлого үргэлжилж байна. Хүн андуурсан бол зогсдог; үргэлжилж байгаа нь автоматжуулсан оролдлого.
Эхний 5 минут.
- Дээрхтэй ижил — аль бүртгэл, аль хаягнаас.
operator_audit-д тэр бүртгэлээр амжилттай юу болсныг шалга:
Засах.
- Хаягийг
CONTROL_PLANE_ALLOWED_CIDRS-аас шууд хас,docker compose up -d backend. - Бүртгэлийг идэвхгүй болго:
- Бусад операторуудад мэдэгд.
Өргөжүүлэх. Шууд. Энэ бол хамгийн эрхтэй интерфэйс рүү чиглэсэн үргэлжилсэн оролдлого бөгөөд аль хэдийн дотоод сүлжээнд байгаа хэн нэгнээс ирж байна.
NexusBreakGlassUsed¶
Юу болсон. Онцгой байдлын (break-glass) операторын бүртгэлээр консол руу нэвтэрлээ. Энэ бүртгэлийн нууц үг офлайн сейфэнд байдаг бөгөөд ердийн үед хэзээ ч хэрэглэгддэггүй.
Эхний 5 минут.
- Хэн нээв? Сейфийг хариуцагчаас утсаар асуу — мессежээр биш.
- Хаанаас: Мөр нь и-мэйл ба IP-г агуулна.
- Тэр session юу хийснийг:
Засах.
- Төлөвлөгөөт бол (бүх superadmin-ий TOTP алдагдсан г.м.): ажил дууссаны дараа нууц үгийг нь ЗААВАЛ солиж, сейфэнд шинээр хийнэ. Дараа нь энгийн superadmin бүртгэлүүдийг сэргээ.
- Төлөвлөгөөт биш бол — зөвшөөрөлгүй хандалт гэж үз:
Дараа нь
UPDATE operator_accounts SET disabled_at = NOW() WHERE break_glass; UPDATE operator_sessions SET revoked_at = NOW() WHERE revoked_at IS NULL;CONTROL_PLANE_ALLOWED_CIDRS-аас танихгүй хаягийг хасаж, backend-ыг дахин асааж,operator_audit-ыг бүхэлд нь шалга.
Өргөжүүлэх. Шууд, хэн нэгнийг сэрээж. Энэ бол платформын хамгийн эрхтэй хаалга бөгөөд дуут дохио нь зориудаар чанга.
NexusControlPlaneUnrecordedWrite¶
Юу болсон. Консолын хүсэлт 500 буцаалаа. Хамгийн магадлалтай шалтгаан нь
RequireAudit — Service.Do-г тойрч бичсэн handler-ийн хариуг барьсан.
Эхний 5 минут.
docker compose logs backend 2>&1 | grep -i "without an audit record"
docker compose logs backend 2>&1 | grep -i "control plane:" | tail -30
- "answered successfully without an audit record" → кодын алдаа. Тухайн
handler
Do-г ашиглах ёстой. Мөрөнд бичигдсэнpathнь хаанаас хайхыг хэлнэ. - "is not available (run the migrations up to 00049_control_plane)" → миграц
ажиллаагүй.
docker compose run --rm migrate up. - "permission denied for table ..." → operator role-д тухайн хүснэгтийн эрх олгогдоогүй. Энэ нь зөв ажиллаж буй хамгаалалт: query нь тэр хүснэгтийг унших ёстой эсэхийг эхлээд шийд, дараа нь миграцаар тодорхой нэмнэ.
Засах. Кодын алдаа тул засвар нь commit. Түр зуурын тойрох арга байхгүй — audit-гүй бичилтийг зөвшөөрөх нь энэ давхаргын утгыг бүхэлд нь алдагдуулна.
Өргөжүүлэх. Ажлын өдөр. Гэхдээ өгөгдлийн санд ул мөргүй өөрчлөлт орсон байж болзошгүй тул тухайн үйлдлийг гараар шалга.
eID нэвтрэлт¶
eID sign-in smoke¶
Юу. .github/workflows/eid-smoke.yml (2 цаг тутам) scripts/eid-smoke.sh-ээр
POST /api/v1/auth/eid/start-ийг ширээний хөтөч шиг (callback-гүй QR session)
дуудаж, 200 ба device_link_url (legacy https://…/dl?sessionId=…&vc=… эсвэл
v3 …/dl?deviceLinkType=QR&elapsedSeconds=…&authCode=…) ирэхийг шаардана.
Callback илгээхгүй: CA callback-тай session-ийг App2App гэж тоолдог тул
батлагдахгүй smoke нь CA-ийн статистикийг App2App timeout-оор дүүргэж байв
(2026-09-30 хүртэл 30 мин тутам). Унасан
хуваарьт ажлыг GitHub имэйлээр мэдэгдэнэ (Alertmanager-т receiver тохируулаагүй).
Шалгах.
bash scripts/eid-smoke.sh https://nexus.gerege.net
docker compose logs backend 2>&1 | grep -i "eid" | tail -20
docker compose exec backend printenv EID_BASE_URL
- 502 «session could not be started» → CA хариулсангүй.
EID_BASE_URL-ийн зам буруу эсэхийг хар: rp.eidmongolia.mn нь root дээр хариулдаг,/v3дор 404 (2026-09-29). ca-eid-ийн nginx логт энэ хостын хүсэлт ямар замаар, ямар статустай очсоныг тулга. - 401/403 CA-аас → RP secret эсвэл mTLS cert (
EID_CLIENT_CERT_FILE) хүчингүй эсвэл хугацаа дууссан; CA-ийн RP-ийн IP allowlist. - 429 → энэ хостоос start-ийн хязгаар (30/мин) дүүрсэн; дахин ажиллуул.
Засах. Тохиргоо бол .env-ийг proxmox-gerege-net (stack/nexus)-ээр засаж
backend-ыг дахин асаа. CA талын өөрчлөлт бол eID-ийн багт мэдэгд.
Хамраагүй. CA callback-ийг хүлээн авсан эсэхийг (callback_hosts) энэ шалгалт
харахгүй — жинхэнэ зөвшөөрлийн signature.flowType (App2App) л үүнийг харуулна.