Obserwowalność: dziennik SIEM z łańcuchem haszy i raportowanie renderowania
W skrócie
Dział zatytułowany „W skrócie”Moduł Observability udostępnia implementację używaną w czasie działania: dziennik zdarzeń zarządzania informacjami i zdarzeniami bezpieczeństwa (SIEM), który wykrywa manipulacje i opiera się na łańcuchu haszy, agregację raportów renderowania i raportów pilotażowych, dziennik audytu sprzętowego modułu bezpieczeństwa (HSM) oraz kompletne puste implementacje metryk i śladów, dzięki czemu wywołania instrumentacji są zawsze dostępne.
Jedna kanoniczna strona na zagadnienie. Kontrakty obserwowalności —
ContextAwareExceptionInterface,SpectrumInterface,JobNotificationInterfaceoraz wyliczenieDegradationPolicy— są udokumentowane na stronie Contracts / Observability. Ta strona dokumentuje konkretną implementację używaną w czasie działania. Strony są komplementarne, a nie zduplikowane: sięgnij do strony kontraktów, gdy potrzebujesz interfejsu dostawcy usług (SPI), i do tej strony dla dziennika SIEM, raportowania oraz powierzchni audytu.
Instalacja
Dział zatytułowany „Instalacja”composer require nextpdf/core:^3Omówienie koncepcyjne
Dział zatytułowany „Omówienie koncepcyjne”Ten moduł przekształca informacje o stanie silnika w czasie działania w trwałe, weryfikowalne dane wyjściowe.
HashChainSiemEventLog to powierzchnia o znaczeniu bezpieczeństwa. Implementuje kontrakt SiemEventEmitter i zapisuje dziennik w formacie JavaScript Object Notation (JSON) Lines, w którym hasz każdego rekordu jest obliczany jako
SHA-256(prev_hash_bytes || canonical_event_bytes). Ten liniowy łańcuch haszy
sprawia, że dziennik wykrywa manipulacje: jeśli zmieni się dowolny bajt, zostanie usunięty wiersz albo zmieni się kolejność wierszy, łańcuch zostaje przerwany. verifyIntegrity() przechodzi przez plik i zwraca indeks pierwszego niespójnego rekordu albo null, gdy łańcuch jest nienaruszony. readAll() strumieniuje rekordy. Blokada doradcza flock(LOCK_EX) dla danego procesu chroni sekcję krytyczną „odczyt końcówki, a następnie dopisanie”, dzięki czemu współbieżne procesy PHP korzystające z tego samego pliku nie przeplatają rekordów. Ograniczenie jest jawne: to liniowy łańcuch haszy, a nie drzewo Merkle z Request for Comments (RFC) 6962. Wystarcza do wykrywania manipulacji, lecz nie do wydajnych dowodów przynależności. Tak wynika z kodu źródłowego. SiemEvent przenosi typowane zdarzenie z metodą toCanonicalJson(). SiemEventSeverity i SiemEventType je klasyfikują. CorrelationContext i CorrelationIdGenerator przekazują identyfikator korelacji pomiędzy powiązanymi zdarzeniami.
RenderReportBuilder, RenderReport, PilotReportAggregator oraz PilotSummary tworzą powierzchnię raportowania (@since 5.1.0). Agregator zbiera obiekty RenderReport i tworzy PilotSummary, które można wyrenderować jako tablicę, JSON albo Markdown w postaci nadającej się do przeglądu operacyjnego.
HsmAuditLogInterface / HsmAuditEvent rejestrują operacje podpisywania obsługiwane przez HSM na potrzeby warstwy bezpieczeństwa. Interfejsy MetricsCounterInterface, MetricsGaugeInterface, MetricsHistogramInterface oraz TraceSpanInterface definiują strukturę metryk i śladów. Implementacje NoOp* zapewniają kompletną, bierną implementację zastępczą, dzięki czemu silnik może emitować metryki i przedziały śladów bez skonfigurowanego zaplecza.
Stabilność: eksperymentalna. Dziennik SIEM jest wewnętrznie oznaczany cyklem, zamiast przenosić zamrożoną adnotację
@sincewersjonowania semantycznego (semver), a powierzchnia raportowania jest oznaczona@since 5.1.0. Powierzchnie są funkcjonalne i przetestowane, ale kształty interfejsu programowania aplikacji (API) mogą się zmieniać. Traktuj format dziennika (kanoniczny JSON + łańcuch haszy) jako stabilny kontrakt, a interfejs PHP API jako wciąż ustalający się.
Powierzchnia API
Dział zatytułowany „Powierzchnia API”| Klasa | Kluczowe składowe | Rola |
|---|---|---|
HashChainSiemEventLog | emit(SiemEvent), verifyIntegrity(): ?int, readAll(): Generator | Dziennik SIEM wykrywający manipulacje i oparty na łańcuchu haszy |
SiemEvent | toCanonicalJson() | Typowane zdarzenie SIEM |
SiemEventSeverity / SiemEventType (wyliczenia) | klasyfikacja | Klasyfikuje istotność i typ zdarzenia |
CorrelationContext / CorrelationIdGenerator | przekazywanie korelacji | Przenosi korelację między powiązanymi zdarzeniami |
RenderReportBuilder / RenderReport | składanie raportu | Buduje raporty dla pojedynczych renderowań (@since 5.1.0) |
PilotReportAggregator | addReport(), count(), getSummary(), toJson(), toMarkdown(), exportReportsJson() | Agreguje raporty renderowania (@since 5.1.0) |
PilotSummary | toArray(), toJson(), toMarkdown() | Podsumowuje dane wyjściowe przeglądu operacyjnego (@since 5.1.0) |
HsmAuditLogInterface / HsmAuditEvent | Rekord audytu HSM | Rejestruje audyt operacji HSM |
NoOpSiemEventEmitter, NoOpMetricsCounter, NoOpTraceSpan, … | bierne implementacje zastępcze | Zapewniają kompletne puste implementacje |
Uruchom composer docs:generate-api-php -- --module=Observability, aby wygenerować pełną tabelę PHPDoc.
Przykład kodu — szybki start
Dział zatytułowany „Przykład kodu — szybki start”Wyemituj zdarzenie i zweryfikuj integralność dziennika.
<?php
declare(strict_types=1);
require_once __DIR__ . '/../vendor/autoload.php';
use NextPDF\Observability\Siem\HashChainSiemEventLog;use NextPDF\Observability\Siem\SiemEvent;
$log = new HashChainSiemEventLog('/var/log/nextpdf/siem.jsonl');$log->emit(new SiemEvent(/* type, severity, payload */));
$firstBroken = $log->verifyIntegrity();echo $firstBroken === null ? "SIEM chain intact.\n" : "Tamper detected at record {$firstBroken}.\n";Przykład kodu — środowisko produkcyjne
Dział zatytułowany „Przykład kodu — środowisko produkcyjne”Opakuj emiter tak, aby awaria zapisu do dziennika na gorącej ścieżce podpisywania była obsługiwana lokalnie, zamiast kończyć się nieprzechwyconym wyjątkiem.
<?php
declare(strict_types=1);
require_once __DIR__ . '/../vendor/autoload.php';
use NextPDF\Observability\Siem\HashChainSiemEventLog;use NextPDF\Observability\Siem\Exception\SiemEmitterException;use NextPDF\Observability\Siem\SiemEvent;use Psr\Log\LoggerInterface;
final readonly class AuditedSiemSink{ public function __construct( private HashChainSiemEventLog $log, private LoggerInterface $fallback, ) {}
public function record(SiemEvent $event): void { try { $this->log->emit($event); } catch (SiemEmitterException $e) { // Do not let SIEM I/O abort the signing path; record and continue. $this->fallback->critical('SIEM emit failed; event not chained.', [ 'error' => $e->getMessage(), ]); } }}Przypadki brzegowe i pułapki
Dział zatytułowany „Przypadki brzegowe i pułapki”emit()rzuca wyjątekSiemEmitterExceptionprzy błędach zapisu. Kod wywołujący na gorącej ścieżce podpisywania musi go opakować i lokalnie zdecydować, czy zignorować błąd, ponowić próbę, czy przerwać. Emiter nie podejmuje tej decyzji za Ciebie.verifyIntegrity()zwraca indeks pierwszego uszkodzonego rekordu albonull. Wynik różny od null oznacza, że dziennik jest naruszony od tego miejsca. Nie ufaj rekordom od tego punktu włącznie.- Doradcza blokada
flockdziała w obrębie procesu i tego samego pliku. Współbieżność między hostami wymaga kanału poza pasmem, takiego jak przekazywanie syslog. Nie zakładaj, że blokada pliku koordynuje pracę między maszynami. - To liniowy łańcuch haszy, a nie drzewo Merkle. Zapewnia wykrywanie manipulacji, a nie wydajne dowody przynależności. Nie reklamuj go jako tego drugiego.
- Implementacje zastępcze
NoOp*są kompletne i bierne. Nie rozgałęziaj kodu w zależności od dostępności zaplecza, aby „zaoszczędzić pracę”. Pusta operacja i tak nic nie kosztuje.
Wydajność
Dział zatytułowany „Wydajność”emit() odczytuje hasz poprzedniego rekordu i dopisuje jeden wiersz pod blokadą pliku: O(1) na zdarzenie plus blokada. verifyIntegrity() ma złożoność O(n) względem liczby rekordów, ponieważ przechodzi przez cały łańcuch. Uruchamiaj ją według harmonogramu, a nie na gorącej ścieżce. Agregacja raportowania jest liniowa względem liczby raportów. Profil odtwarzalności jest structural: zdarzenia i raporty zawierają znaczniki czasu oraz identyfikatory korelacji, więc dwa uruchomienia różnią się w tych polach, podczas gdy struktura łańcucha pozostaje deterministyczna.
Uwagi dotyczące bezpieczeństwa
Dział zatytułowany „Uwagi dotyczące bezpieczeństwa”Dziennik SIEM jest mechanizmem bezpieczeństwa. Jego zdolność wykrywania manipulacji zależy od ochrony zarówno pliku dziennika, jak i kroku weryfikacji: przechowuj plik na pamięci masowej przystosowanej do dopisywania i objętej kontrolą dostępu, uruchamiaj verifyIntegrity() według harmonogramu i przekazuj rekordy poza pasmem, aby naruszenie hosta nie mogło po cichu przepisać historii. Zdarzenia mogą przenosić poufny kontekst. Stosuj projektowe zasady czyszczenia dzienników przed utworzeniem zdarzenia, a nie po dołączeniu go do łańcucha, ponieważ czyszczenie wpisu po fakcie przerwałoby łańcuch. Dziennik audytu HSM rejestruje operacje podpisywania i sam jest istotny dla bezpieczeństwa. Stosuj wobec niego te same zabezpieczenia. Zobacz model zagrożeń silnika w /modules/core/security/.
Zgodność
Dział zatytułowany „Zgodność”Ten moduł nie formułuje żadnego normatywnego twierdzenia dotyczącego specyfikacji PDF. Implementuje mechanizmy integralności dzienników i obserwowalności, których projekt jest zgodny z praktykami zarządzania dziennikami i weryfikacji integralności opisanymi w NIST SP 800-92. Zgodność z tymi ramami kontrolnymi jest udokumentowana w kodzie źródłowym; nie jest to odwołanie przypięte do konkretnego fragmentu specyfikacji PDF. Zgodność dokumentów, które silnik wytwarza, jest walidowana przez wyrocznię i zestawy wzorcowe opisane w /modules/core/conformance/.
Zobacz także
Dział zatytułowany „Zobacz także”- Contracts / Observability — interfejs dostawcy usług (SPI): ustrukturyzowane wyjątki, Spectrum oraz polityka degradacji.
- Moduł Telemetry — most OpenTelemetry do zewnętrznych zapleczy.
- Moduł Audit — eksporter dowodów zgodności współpracujący z dziennikiem SIEM.
- Moduł Security — operacje podpisywania rejestrowane przez dziennik audytu HSM.
- Omówienie zgodności