Bỏ qua để đến nội dung

Observability: nhật ký SIEM theo chuỗi băm và báo cáo kết xuất

Mô-đun Observability cung cấp phần triển khai trạng thái lúc chạy: nhật ký sự kiện quản lý thông tin và sự kiện bảo mật (SIEM) theo chuỗi băm có khả năng phát hiện giả mạo, phần tổng hợp báo cáo kết xuất và pilot, nhật ký kiểm toán của mô-đun bảo mật phần cứng (HSM), cùng các phần triển khai no-op đầy đủ cho metrics và trace để phần đo lường luôn có thể gọi được.

Mỗi chủ đề có một trang chính tắc. Các contract observability — ContextAwareExceptionInterface, SpectrumInterface, JobNotificationInterface, và enum DegradationPolicy — được mô tả trên Contracts / Observability. Trang này mô tả các phần triển khai trạng thái lúc chạy cụ thể. Hai trang này bổ sung cho nhau, không trùng lặp: dùng trang contract cho giao diện nhà cung cấp dịch vụ (SPI), và dùng trang này cho nhật ký SIEM, báo cáo và các bề mặt kiểm toán.

Terminal window
composer require nextpdf/core:^3

Mô-đun này biến trạng thái lúc chạy của engine thành đầu ra bền vững, có thể kiểm chứng.

HashChainSiemEventLog là bề mặt cấp bảo mật. Nó triển khai contract SiemEventEmitter và ghi nhật ký JavaScript Object Notation (JSON) Lines, trong đó hash của mỗi bản ghi là SHA-256(prev_hash_bytes || canonical_event_bytes). Chuỗi băm tuyến tính đó làm cho nhật ký có khả năng phát hiện giả mạo: nếu bất kỳ byte nào thay đổi, một dòng bị xóa, hoặc các dòng bị sắp xếp lại thứ tự, chuỗi sẽ bị đứt. verifyIntegrity() duyệt qua tệp và trả về chỉ mục của bản ghi không nhất quán đầu tiên, hoặc null khi chuỗi còn nguyên vẹn. readAll() phát trực tuyến các bản ghi. Khóa khuyến nghị theo tiến trình flock(LOCK_EX) bảo vệ vùng tới hạn đọc-phần-cuối-rồi-ghi-thêm, nên các tiến trình PHP chạy đồng thời trên cùng một tệp sẽ không xen kẽ các bản ghi. Giới hạn được nêu rõ: đây là chuỗi băm tuyến tính, không phải cây Merkle theo Request for Comments (RFC) 6962. Nó đủ để phát hiện giả mạo, nhưng không dùng cho các bằng chứng bao hàm hiệu quả. Mã nguồn cũng nêu rõ điều đó. SiemEvent mang sự kiện có kiểu cùng với toCanonicalJson(). SiemEventSeveritySiemEventType phân loại sự kiện đó. CorrelationContextCorrelationIdGenerator mang một correlation id xuyên suốt các sự kiện liên quan.

RenderReportBuilder, RenderReport, PilotReportAggregator, và PilotSummary tạo nên bề mặt báo cáo (@since 5.1.0). Bộ tổng hợp thu thập các RenderReport và tạo ra một PilotSummary có thể kết xuất thành array, JSON hoặc Markdown, theo dạng dùng được trong một buổi đánh giá vận hành.

HsmAuditLogInterface / HsmAuditEvent ghi lại các thao tác ký dựa trên HSM cho lớp bảo mật. MetricsCounterInterface, MetricsGaugeInterface, MetricsHistogramInterface, và TraceSpanInterface định nghĩa hình dạng của metrics và trace. Các phần triển khai NoOp* cung cấp bản dự phòng trơ hoàn chỉnh, nên engine có thể phát ra metrics và span mà không cần backend đã cấu hình.

Độ ổn định: thử nghiệm. Nhật ký SIEM được gắn thẻ theo chu kỳ trong nội bộ thay vì mang một @since Semantic Versioning (semver) cố định, và bề mặt báo cáo là @since 5.1.0. Các bề mặt này hoạt động được và đã được kiểm thử, nhưng hình dạng của giao diện lập trình ứng dụng (API) vẫn có thể thay đổi. Hãy coi định dạng nhật ký (JSON chính tắc + chuỗi băm) là contract ổn định, còn API PHP là phần vẫn đang định hình.

LớpThành viên chínhVai trò
HashChainSiemEventLogemit(SiemEvent), verifyIntegrity(): ?int, readAll(): GeneratorNhật ký SIEM theo chuỗi băm có khả năng phát hiện giả mạo
SiemEventtoCanonicalJson()Sự kiện SIEM có kiểu
SiemEventSeverity / SiemEventType (enum)phân loạiPhân loại mức độ nghiêm trọng và loại của sự kiện
CorrelationContext / CorrelationIdGeneratorxâu chuỗi correlationXâu chuỗi correlation qua các sự kiện liên quan
RenderReportBuilder / RenderReportlắp ráp báo cáoXây dựng báo cáo cho từng lần kết xuất (@since 5.1.0)
PilotReportAggregatoraddReport(), count(), getSummary(), toJson(), toMarkdown(), exportReportsJson()Tổng hợp các báo cáo kết xuất (@since 5.1.0)
PilotSummarytoArray(), toJson(), toMarkdown()Tóm tắt đầu ra cho buổi đánh giá vận hành (@since 5.1.0)
HsmAuditLogInterface / HsmAuditEventBản ghi kiểm toán HSMGhi lại các bản kiểm toán thao tác HSM
NoOpSiemEventEmitter, NoOpMetricsCounter, NoOpTraceSpan, …các bản dự phòng trơCung cấp các phần triển khai no-op đầy đủ

Chạy composer docs:generate-api-php -- --module=Observability để tạo bảng PHPDoc đầy đủ.

Phát một sự kiện và xác minh tính toàn vẹn của nhật ký.

<?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";

Bọc bộ phát để lỗi ghi nhật ký trong đường dẫn nóng của quá trình ký vẫn chỉ là một quyết định cục bộ, thay vì trở thành ngoại lệ không được bắt.

<?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(),
]);
}
}
}
  • emit() ném SiemEmitterException khi có lỗi ghi. Bên gọi trong đường dẫn nóng của quá trình ký phải bọc nó lại và tự quyết định cục bộ nên nuốt lỗi, thử lại, hay hủy bỏ. Bộ phát không quyết định thay cho bạn.
  • verifyIntegrity() trả về chỉ mục của bản ghi bị hỏng đầu tiên, hoặc null. Một kết quả khác null nghĩa là nhật ký đã bị xâm phạm từ điểm đó trở đi. Đừng tin các bản ghi tại điểm đó hoặc sau đó.
  • Khóa khuyến nghị flock hoạt động theo từng tiến trình và trên cùng một tệp. Tính đồng thời xuyên nhiều máy chủ cần một đích nhận ngoài luồng, chẳng hạn như chuyển tiếp syslog. Đừng giả định rằng khóa tệp có thể phối hợp giữa các máy.
  • Đây là một chuỗi băm tuyến tính, không phải cây Merkle. Nó cung cấp khả năng phát hiện giả mạo, không phải các bằng chứng bao hàm hiệu quả. Đừng quảng bá nó như loại sau.
  • Các bản dự phòng NoOp* là hoàn chỉnh và trơ. Đừng rẽ nhánh theo việc backend có sẵn hay không để “tiết kiệm công sức”. Bản no-op vốn không tốn gì đáng kể.

emit() đọc hash của bản ghi trước đó và ghi thêm một dòng dưới một khóa tệp: O(1) cho mỗi sự kiện, cộng với chi phí khóa. verifyIntegrity() là O(n) theo số lượng bản ghi vì nó duyệt qua toàn bộ chuỗi. Hãy chạy nó theo lịch, không chạy trong đường dẫn nóng. Việc tổng hợp báo cáo là tuyến tính theo số lượng báo cáo. Hồ sơ khả năng tái lập là structural: các sự kiện và báo cáo mang dấu thời gian và correlation id, nên hai lần chạy sẽ khác nhau ở các trường đó, trong khi cấu trúc chuỗi vẫn mang tính tất định.

Nhật ký SIEM là một biện pháp kiểm soát bảo mật. Khả năng phát hiện giả mạo của nó phụ thuộc vào việc bảo vệ cả tệp nhật ký lẫn bước xác minh: lưu tệp trên kho lưu trữ phù hợp với kiểu ghi thêm và có kiểm soát truy cập, chạy verifyIntegrity() theo lịch, và chuyển tiếp các bản ghi ngoài luồng để một vụ xâm phạm máy chủ không thể âm thầm viết lại lịch sử. Các sự kiện có thể mang theo ngữ cảnh nhạy cảm. Hãy áp dụng nghĩa vụ làm sạch nhật ký của dự án trước khi dựng sự kiện, chứ không phải sau khi đã đưa vào chuỗi, vì một bản viết lại đã được làm sạch sẽ làm đứt chuỗi. Nhật ký kiểm toán HSM ghi lại các thao tác ký và bản thân nó cũng liên quan đến bảo mật. Hãy bảo vệ nó bằng cùng các biện pháp đó. Xem mô hình mối đe dọa của engine tại /modules/core/security/.

Mô-đun này không đưa ra tuyên bố mang tính quy chuẩn nào về các đặc tả PDF. Nó triển khai các cơ chế toàn vẹn nhật ký và observability có thiết kế phù hợp với các thông lệ quản lý nhật ký và xác minh tính toàn vẹn trong NIST SP 800-92. Sự phù hợp với khung kiểm soát đó được ghi lại trong mã nguồn; nó không phải là một trích dẫn PDF ghim theo chunk. Sự phù hợp của các tài liệu mà engine tạo ra được kiểm chứng bởi các bộ oracle và golden được mô tả trong /modules/core/conformance/.