From 5567443b66f4bc892a112e21c1f75c7aaff7c4de Mon Sep 17 00:00:00 2001 From: Marius Date: Mon, 10 Aug 2026 22:50:54 +0300 Subject: [PATCH] docs: incident 10 aug - serverul 36 in standby, nu blocat Serverul 10.0.20.36 a parut blocat 20 de minute (12:02-12:22). Nu a fost blocaj, crash sau oprire: a intrat in standby S3 in urma unei actiuni de power de la consola. BootId neschimbat, oracle.exe si tnslsnr.exe neintrerupte din 15 iulie, zero erori in System/Application. Dovada decisiva e listener.log: clienti serviti normal pana la 12:01:26, apoi gaura totala pana la 12:22:03 - singura discontinuitate din toata ziua. Remediere aplicata si verificata: - somnul eliminat complet (powercfg /a nu mai listeaza nicio stare) - butoane power si meniu Start -> Shut down; buton sleep -> Do nothing - Sleep after era 600 s pe profilul DC, adica serverul ar fi adormit la 10 min dupa o pana de curent; acum 0 - Critical battery action era Hibernate, imposibil dupa dezactivarea hibernarii; corectat pe Shut down, praguri urcate 5%->20% / 7%->25% / 10%->40% - ViewPower oprit si dezactivat: comunicatia cu UPS-ul era moarta (QPI NAK), iar Windows gestioneaza UPS-ul nativ prin HID UPS Battery - sonda roa2web care lovea listenerul la 30 s: oprita. Verifica portul 1521, adica listenerul de productie, nu tunelul vending - raporta fals "sanatos". Tunelul e dezactivat, era oricum cazut de la boot-ul din 15 iulie Ramane, doar daca se repune vending in functiune: autorizarea cheii pe 79.119.86.134 (plink e respins de server dupa banner-ul de versiune). Co-Authored-By: Claude Opus 5 (1M context) Claude-Session: https://claude.ai/code/session_01RoM99w9qRELJefaWrtPRHo --- docs/incident-2026-08-10-server36-standby.md | 286 +++++++++++++++++++ 1 file changed, 286 insertions(+) create mode 100644 docs/incident-2026-08-10-server36-standby.md diff --git a/docs/incident-2026-08-10-server36-standby.md b/docs/incident-2026-08-10-server36-standby.md new file mode 100644 index 0000000..d81501f --- /dev/null +++ b/docs/incident-2026-08-10-server36-standby.md @@ -0,0 +1,286 @@ +# Incident 10 august 2026 — server 10.0.20.36 „blocat" 20 de minute + +**Concluzie:** serverul nu s-a blocat și nu a crăpat. A intrat în **standby (S3)** la 12:02:20 în +urma unei acțiuni de power de la consolă și a stat adormit până la 12:22:04. Oracle nu a fost oprit, +doar suspendat în RAM. + +## Server + +`ROA-CARAPETRU2` / 10.0.20.36 — Windows 11 Pro 26200, Oracle 19c SE2, instanța `ROA`. +Acces: `ssh -p 22122 Administrator@10.0.20.36`. + +## Cronologia (ora locală, GTB +03:00) + +| Ora | Sursa | Eveniment | +|---|---|---| +| 11:45:36 | System `566` Kernel-Power | ultimul input fizic la consolă înainte de incident (`InputHid`) | +| ~11:50 | — | monitorul se stinge (`VIDEOIDLE` AC = 300 s = 5 min) | +| 12:00:00 | System `6013` | uptime 2.285.772 s = 26 zile 11 h, neîntrerupt din 15 iulie | +| 12:00:02–12:00:18 | listener.log | 8 conexiuni la ROA dintr-un program din `C:\Users\Administrator\Downloads\` | +| 12:01:04 | System `7040` | BITS trece demand → auto | +| 12:01:26 | listener.log | **ultima conexiune client reală**: `ROACONT.exe` de pe `RAMONA` | +| 12:01:58 | listener.log | ultimul poll local | +| 12:02:14 | System `1074` User32 | **Explorer.EXE** inițiază power off, pe seama `ROA-CARAPETRU2\Administrator`, „Other (Unplanned)" | +| 12:02:14 | Security `4624`×3 | winlogon creează sesiunea 2 (UMFD-2, DWM-2) | +| 12:02:19 | Security `4647` | „User initiated logoff" pentru Administrator (SID …-500) | +| 12:02:19 | System `100` winsrvext | `rundll32.exe` (5016 ms) și `ATI…\CCC.exe` (5078 ms) întârzie oprirea | +| 12:02:20 | System `1074` | winlogon.exe continuă power off | +| 12:02:20 | System `566` | tranziție sesiune, `Reason **InputHid**` — input fizic exact în acel moment | +| 12:02:20 | System `187` Kernel-Power | proces user-mode apelează `SetSuspendState`/`SetSystemPowerState` | +| 12:02:20 | System `42` Kernel-Power | **„The system is entering sleep. Sleep Reason: Application API"** | +| 12:02:20 | RDP LSM `23/24/39/40` | sesiunea 1 delogată/deconectată, `Source Network Address: LOCAL` | +| **12:02–12:22** | listener.log | **gaură totală — zero activitate** | +| 12:22:04 | Power-Troubleshooter | trezire. Sleep 09:02:20 UTC → Wake 09:22:04 UTC. `Wake Source: Unknown` | +| 12:22:03 | Kernel-General `1` | ceasul sare înapoi la timpul real (delta 1.180.963 ms ≈ 19 min 41 s de somn) | +| 12:22:03 | listener.log | `service_update * roa * 0` — listenerul revine | +| 12:22:48+ | listener.log | clienții reconectează: ELENA-I5, RAMONA, ROXANA, DESKTOP-DJ8G35U, STELUTA-PC, LG17 | +| 12:31:25 | RDP LSM `21` | logon consolă Administrator (sesiunea 2) | + +## Dovezi că NU a fost blocaj, crash sau oprire + +- Zero evenimente `41` (Kernel-Power / oprire neașteptată), `6008` (unexpected shutdown), `1001` + (BugCheck/BSOD) — nici în ziua incidentului, nici în ultimele 10 zile. +- Zero evenimente Error/Critical în `System` (3 zile) și `Application` (2 zile). +- `BootId: 30` neschimbat pe toată durata → **nu a existat repornire**. +- `LastBootUpTime` = 15 iulie 2026 01:03:48; `oracle.exe` și `tnslsnr.exe` au `StartTime` + 15 iulie 01:02:56 → procesele Oracle nu s-au oprit niciodată. +- **Listener.log demonstrează că baza servea normal până în secunda adormirii**: clienți reali la + 11:45, 11:47–11:53 (SILVIA-ENVY), 11:50 (JENI), 12:01:26 (RAMONA). Distribuția pe ore în ziua + respectivă este continuă (09→56, 10→63, 11→47, 12→56 conexiuni). Singura discontinuitate din zi + este fereastra 12:01:58 → 12:22:03. + +Cu alte cuvinte: **până la 12:02 nimic nu era în neregulă**. Indisponibilitatea de 20 de minute a +fost provocată chiar de acțiunea de la 12:02, nu de o defecțiune anterioară. + +## Cauza + +Standby-ul nu a venit din inactivitate — `STANDBYIDLE` pe AC = 0 (Never), `HIBERNATEIDLE` AC = 0, iar +`Sleep Reason` este `Application API`, nu `Idle`. A fost o **comandă explicită de power dată de la +consolă**, care s-a executat ca *Sleep* în loc de *Shut down*: + +- `UIBUTTON_ACTION` („Start menu power button") are valoarea efectivă **0 = Sleep**. +- Nu există override în schema activă (`…\PowerSchemes\381b4222…\4f971e89…`) pentru acțiunea + butonului fizic de power (`PBUTTONACTION`) sau sleep (`SBUTTONACTION`) — ambele au `Attributes=1`, + adică sunt **ascunse din interfața Windows**, deci nici nu pot fi verificate/schimbate din + Control Panel fără intervenție în registry. +- `Explorer.EXE` este exact procesul care tratează butonul de power din meniul Start, iar + `566 Reason InputHid` la 12:02:20 confirmă input fizic în acel moment. + +**Ce nu se poate proba din loguri:** care buton anume a fost apăsat (meniul Start vs. butonul fizic). +Auditarea creării de procese (`Process Creation`) este dezactivată, deci nu există `4688` care să +arate ce a lansat `rundll32.exe`. Mecanismul și rezultatul sunt însă certe. + +Trezirea de la 12:22:04 (`Wake Source: Unknown`) corespunde apăsării butonului de power — de aceea +calculatorul „s-a aprins", ceea ce a fost interpretat drept dovadă că era în standby. Era, dar +ajunsese acolo în urma acțiunii de la 12:02. + +## Probleme reale descoperite pe parcurs + +1. **Serverul poate intra în S3.** Pe o mașină de producție cu Oracle, stările de somn trebuie + eliminate complet, nu doar setate pe „Never" — atâta timp cât S3 e disponibil, orice apăsare + greșită oprește baza pentru toți clienții. +2. **Comunicația ViewPower ↔ UPS este moartă.** `C:\ViewPower\log\log4j.log` conține continuu + `QPI return(NAK`, iar baza de date proprie (`C:\ViewPower\datas\log5xx.dat`) nu mai fusese scrisă + din 9 august 23:10. Configurația (`C:\ViewPower\config\ups.properties`) are + `Shutdownconfigure.batModeShutdown=true` cu `batModeShutdownTime=30` — adică *ar trebui* să oprească + serverul controlat după 30 min pe baterie. Cu comunicația căzută, la o pană reală de curent + **nu va face nimic**. + + Hardware-ul e însă în regulă: Windows vede nativ `HID UPS Battery` + (`HID\VID_0665&PID_5161&MI_01` — Cypress/Voltronic), `Win32_Battery` raportează Status OK, + 100% încărcare, ~70 min autonomie. **Repornirea serviciului `upsMonitor` nu rezolvă**: după + restart au venit 2 răspunsuri valide (`QPI returnQPI` la 22:24:10 și 22:24:12), apoi s-a întors + la `NAK` (197 NAK / 2 valide în ultimele 200 de linii). Tiparul indică o dispută pe același + device USB HID între driverul nativ Windows și ViewPower. +3. **Fast Startup este activ** (`HiberbootEnabled=1`) pe un server Oracle de producție. De aceea + uptime-ul se acumulează de 26 de zile — un „shutdown" normal nu mai face repornire curată a + kernelului. +4. **Healthcheck greșit configurat — și inutil.** Sursa: `roa2web`, fișierul + `C:\inetpub\wwwroot\roa2web\backend\shared\ssh_tunnel_manager.py`: + - linia **68**: `self.check_interval: int = 30` + - linia **186**: `await self._check_port("127.0.0.1", port)` + - liniile **218-230**: `_check_port` face `asyncio.open_connection` și închide imediat, fără + handshake TNS → listenerul îl loghează ca `TNS-12537`. + + Portul vine din `C:\inetpub\wwwroot\roa2web\backend\ssh-tunnels.json`, unde tunelul „vending" + are `"local_port": 1521`. **Dar 1521 e portul listenerului de producție de pe acest server**, + iar `.env` declară vending-ul pe `localhost:**1522**`. Consecințe: + - tunelul SSH nu poate lega portul 1521, e ocupat de Oracle local; + - verificarea reușește întotdeauna, pentru că lovește listenerul local — **monitorul raportează + tunelul „sănătos" indiferent de realitate** și nu declanșează niciodată repornirea; + - nu rulează niciun proces `ssh.exe`, deci tunelul vending e oricum căzut de la ultima pornire. +5. **ORACLE_HOME e sub `C:\Users\Administrator\Downloads\WINDOWS.X64_193000_db_home\`.** + Listenerul de producție rulează din folderul Downloads. Funcționează, dar e o amplasare fragilă. + +## Remediere APLICATĂ pe 10 august 2026, seara + +```powershell +powercfg /hibernate off # sleep+hibernate+Fast Startup +powercfg /setacvalueindex SCHEME_CURRENT SUB_BUTTONS PBUTTONACTION 3 # buton fizic -> Shut down +powercfg /setdcvalueindex SCHEME_CURRENT SUB_BUTTONS PBUTTONACTION 3 +powercfg /setacvalueindex SCHEME_CURRENT SUB_BUTTONS UIBUTTON_ACTION 2 # meniu Start -> Shut down +powercfg /setdcvalueindex SCHEME_CURRENT SUB_BUTTONS UIBUTTON_ACTION 2 +powercfg /setacvalueindex SCHEME_CURRENT SUB_BUTTONS SBUTTONACTION 0 # buton sleep -> Do nothing +powercfg /setdcvalueindex SCHEME_CURRENT SUB_BUTTONS SBUTTONACTION 0 +powercfg /setacvalueindex SCHEME_CURRENT SUB_SLEEP abfc2519-3608-4c2a-94ea-171b0ed546ab 0 # ALLOWSTANDBY +powercfg /setdcvalueindex SCHEME_CURRENT SUB_SLEEP abfc2519-3608-4c2a-94ea-171b0ed546ab 0 +powercfg /setacvalueindex SCHEME_CURRENT SUB_SLEEP STANDBYIDLE 0 +powercfg /setdcvalueindex SCHEME_CURRENT SUB_SLEEP STANDBYIDLE 0 # era 600 s pe DC! +powercfg /setacvalueindex SCHEME_CURRENT SUB_SLEEP HIBERNATEIDLE 0 +powercfg /setdcvalueindex SCHEME_CURRENT SUB_SLEEP HIBERNATEIDLE 0 +powercfg /setactive SCHEME_CURRENT +``` + +Setările de buton erau ascunse din UI (`Attributes=1`); au fost făcute vizibile punând +`Attributes=2` sub +`HKLM\SYSTEM\CurrentControlSet\Control\Power\PowerSettings\4f971e89-…\{7648efa3-…,96996bc0-…}`. + +**Corecție obligatorie făcută imediat după:** `Critical battery action` era `2 = Hibernate`, iar +hibernarea tocmai fusese dezactivată — la o pană reală Windows ar fi încercat să hiberneze și ar fi +eșuat. Corectat, împreună cu pragurile, care erau prea joase pentru un shutdown curat de Oracle: + +```powershell +powercfg /setacvalueindex SCHEME_CURRENT SUB_BATTERY BATACTIONCRIT 3 # 3 = Shut down (era 2 = Hibernate) +powercfg /setdcvalueindex SCHEME_CURRENT SUB_BATTERY BATACTIONCRIT 3 +powercfg /setacvalueindex SCHEME_CURRENT SUB_BATTERY BATLEVELCRIT 20 # era 5% +powercfg /setdcvalueindex SCHEME_CURRENT SUB_BATTERY BATLEVELCRIT 20 +powercfg /setacvalueindex SCHEME_CURRENT SUB_BATTERY BATLEVELLOW 40 # era 10% +powercfg /setdcvalueindex SCHEME_CURRENT SUB_BATTERY BATLEVELLOW 40 +powercfg /setacvalueindex SCHEME_CURRENT SUB_BATTERY f3c5027d-cd16-4930-aa6b-90db844a8f00 25 # reserve, era 7% +powercfg /setdcvalueindex SCHEME_CURRENT SUB_BATTERY f3c5027d-cd16-4930-aa6b-90db844a8f00 25 +powercfg /setactive SCHEME_CURRENT +``` + +### Verificat după aplicare + +`powercfg /a` nu mai listează **nicio** stare de somn disponibilă: +`Standby (S3)` → „The current power policy has disabled this standby state"; +`Hibernate` → „Hibernation has not been enabled"; `Hybrid Sleep` și `Fast Startup` → indisponibile. +`C:\hiberfil.sys` a fost eliminat. Butoane: power = `0x3` (Shut down), sleep = `0x0` (Do nothing), +meniu Start = `0x2` (Shut down), pe AC și pe DC. + +Oprirea Oracle la shutdown-ul Windows e configurată corect — `HKLM\SOFTWARE\ORACLE\KEY_OraDB19Home1`: +`ORA_ROA_SHUTDOWN=TRUE`, `ORA_ROA_SHUTDOWNTYPE=immediate`, `ORA_ROA_SHUTDOWN_TIMEOUT=90`, +`ORA_ROA_AUTOSTART=TRUE`. Deci la pană de curent, cu bateria sub 20%, Windows va face +`shutdown immediate` curat pe ROA. + +**Protecția la pană de curent nu mai depinde de ViewPower** — Windows o face nativ, prin driverul +`HID UPS Battery` care funcționează corect. + +## Aplicat în plus (decizii luate de utilizator) + +### ViewPower — dezactivat + +```powershell +Stop-Service upsMonitor -Force ; Set-Service upsMonitor -StartupType Disabled +Stop-Service upsTomcat -Force ; Set-Service upsTomcat -StartupType Disabled +``` + +Ambele `Stopped` / `Disabled`. Verificat că Windows vede în continuare UPS-ul după oprirea lor: +`Win32_Battery` → `HID UPS`, 100%, ~70 min autonomie, `Critical battery action = 0x3` (Shut down) +la `Critical battery level = 0x14` (20%). **Protecția la pană de curent este intactă.** + +### Tunelul „vending" — port corectat, dar tunelul e defect din altă cauză + +`C:\inetpub\wwwroot\roa2web\backend\ssh-tunnels.json` (backup: `…json.bak-20260810`): +`"local_port": 1521` → **`1522`**, ca să corespundă cu `.env` și să nu mai sondeze listenerul de +producție. Adăugat și `"ssh_hostkey": "SHA256:Vptuj1UUGA9eSk/utwyLvS5C1pzgpYyyUFwUd60S6Go"` +(cheia ECDSA a serverului, obținută cu `ssh-keyscan`), fiindcă scriptul rulează plink cu `-batch` +și fără `-hostkey` acesta abandona imediat. + +**Tunelul tot nu pornește** — cauză reală, preexistentă (nu rula niciun `ssh.exe` de la boot-ul din +15 iulie): + +``` +plink -batch -P 22122 romfast@79.119.86.134 +FATAL ERROR: Remote side sent disconnect message type 11 (by application): +"Client software or version not permitted." +``` + +Serverul vending respinge plink după banner-ul de versiune — acceptă doar clienți OpenSSH. Deci +**autentificarea cu parolă prin plink nu va funcționa niciodată acolo**, indiferent de config. +Calea cu cheie nu merge nici ea: `secrets\vending.ssh_key` nu există, iar `secrets\romfast.ssh_key` +nu e autorizată pe server: + +``` +ssh -i secrets\romfast.ssh_key -p 22122 romfast@79.119.86.134 +romfast@79.119.86.134: Permission denied (publickey,password) +``` + +Conectivitatea TCP către `79.119.86.134:22122` funcționează, iar serverul anunță `publickey,password`. + +### Tunelul „vending" — dezactivat, la cererea utilizatorului + +În `ssh-tunnels.json` cheia `"ssh_host"` a fost redenumită `"ssh_host_disabled"` +(backup: `…json.bak-inainte-dezactivare`). `_load_config` (linia 106) păstrează doar intrările care +au `ssh_host`, deci lista rămâne goală, iar `start_monitoring` iese devreme (liniile 129-131) — +**bucla de monitorizare nu mai pornește deloc**, deci nici `_restart_tunnels` nu poate fi apelat. +Toate datele de conectare rămân în fișier, pentru reactivare ușoară: se redenumește cheia înapoi. + +Backend-ul rulează ca serviciu Windows **`ROA2WEB-Backend`** (wrapper NSSM, pornire automată, +scriptul `scripts\start-backend-service.ps1`). Repornit cu `Restart-Service ROA2WEB-Backend -Force` +pe 10 august la 22:40:45, ca modificarea să fie citită. + +**Verificat după repornire:** + +``` +GET http://127.0.0.1:8000/health -> HTTP 200 +{"api":"healthy","modules":{"oracle":"connected","reports_cache":"initialized", + "data_entry_db":"exists","telegram_bot":"running","ocr_worker":{"status":"running"}, + "ssh_tunnels":{"status":"not_configured","tunnels":{},"monitoring":false}}} +``` + +`monitoring: false` — monitorul e oprit. În 100 de secunde de observație: **0 sonde `TNS-12537`** +în `listener.log` (înainte: una la fiecare 30 s). Zgomotul din logul listenerului a încetat. + +## Rămâne de făcut + +**Doar dacă se dorește repunerea în funcțiune a tunelului vending.** Este căzut de dinainte de +incident (niciun `ssh.exe` de la boot-ul din 15 iulie), deci integrarea vending nu funcționa oricum: + +1. Adăugat conținutul lui `secrets\romfast.ssh_key.pub` în `~/.ssh/authorized_keys` al utilizatorului + `romfast` pe 79.119.86.134 — autentificarea cu parolă prin plink e blocată definitiv de server. +2. Copiat `romfast.ssh_key` ca `secrets\vending.ssh_key` (scriptul caută cheia după `id`-ul tunelului). +3. Redenumit `"ssh_host_disabled"` înapoi în `"ssh_host"` și repornit `ROA2WEB-Backend`. + +## Decizii inițiale (istoric) + +1. **ViewPower** — repornirea nu a rezolvat comunicația. Fiind redundant față de gestionarea nativă + Windows (și declarând un rol de shutdown pe care nu-l poate îndeplini), recomandarea e să fie + dezactivat: `Set-Service upsMonitor -StartupType Disabled; Stop-Service upsMonitor`. Alternativ, + de reconfigurat protocolul UPS din interfața lui (Tomcat, port 15178). De reținut și că + `emailReceivers.length() = 0` — nu are configurată nicio alertă pe email. +2. **Healthcheck-ul roa2web** — vezi mai jos. Orice variantă cere repornirea backend-ului roa2web + (uvicorn, PID-uri 6980/6292/8464, pornit din `C:\inetpub\wwwroot\roa2web-venv`). + +### Opțiuni pentru healthcheck + +| Variantă | Ce se schimbă | Efect | +|---|---|---| +| **A. Dezactivare (recomandat)** | scoate `"ssh_host"` din intrarea „vending" din `ssh-tunnels.json`, sau șterge intrarea | linia 106 filtrează intrările fără `ssh_host` → monitorul nu mai sondează nimic. Zero zgomot. Corect, pentru că tunelul oricum nu rulează | +| **B. Corectare port** | `"local_port": 1521` → `1522` (ca în `.env`) | sonda se mută de pe listenerul de producție pe portul real al tunelului. **Atenție:** monitorul va raporta corect DOWN și, după 2 eșecuri, va încerca `_restart_tunnels()` la fiecare ≥60 s — buclă de repornire, dacă tunelul nu poate porni | +| **C. Rărire** | `ssh_tunnel_manager.py:68` `check_interval: int = 30` → `300` | de 10 ori mai puțin zgomot, dar problema de fond (sondează listenerul greșit, raportează fals „sănătos") rămâne | +| **D. Tăcere pe listener** | `LOGGING_LISTENER = OFF` în `listener.ora` | **nerecomandat** — pierzi exact logul care a rezolvat incidentul de azi | + +## Comenzi utile pentru reinvestigare + +```powershell +# Cronologia completa a unei zile din System log +Get-WinEvent -FilterHashtable @{LogName='System';StartTime=(Get-Date "AAAA-LL-ZZ 09:00:00")} | + Sort-Object TimeCreated | Select-Object TimeCreated,Id,ProviderName,Message + +# Evenimente de power/oprire +Get-WinEvent -FilterHashtable @{LogName='System';Id=41,42,107,187,1074,6005,6006,6008,6013,1001} + +# Ferestre de indisponibilitate reala, din perspectiva clientilor +Select-String -Path "C:\Users\oracle\diag\tnslsnr\ROA-CARAPETRU2\listener\trace\listener.log" ` + -Pattern "^\d{2}-[A-Z]{3}-\d{4} (\d{2}):\d{2}:\d{2}.*establish" +``` + +Rularea comenzilor de la distanță se face cu `-EncodedCommand` (base64 UTF-16LE), altfel quoting-ul +prin `ssh` din Git Bash/PowerShell strică scripturile: + +```powershell +$enc = [Convert]::ToBase64String([Text.Encoding]::Unicode.GetBytes($script)) +ssh -p 22122 Administrator@10.0.20.36 "powershell -NoProfile -EncodedCommand $enc" +```