Inhaltsverzeichnis

Revizijsko beleženje

Kompleksnost: Srednja
Trajanje: 1-2 uri nastavitve
Skladnost: NIS2, ISO 27001, BSI-Grundschutz

Beleženje vseh PKI operacij skladno s predpisi za revizije in forenziko.


Arhitektura

flowchart LR subgraph SOURCES["VIRI"] S1[CA operacije] S2[API zahteve] S3[Skrbniška dejanja] S4[Sistemski dogodki] end subgraph COLLECT["ZBIRANJE"] C1[Syslog] C2[Filebeat] C3[Fluentd] end subgraph STORE["SHRANJEVANJE"] ST1[(Elasticsearch)] ST2[(Loki)] ST3[S3/Arhiv] end subgraph ANALYZE["ANALIZA"] A1[Kibana] A2[Grafana] end S1 & S2 & S3 & S4 --> C1 & C2 C1 & C2 & C3 --> ST1 & ST2 ST1 --> A1 ST2 --> A2 ST1 & ST2 --> ST3 style ST1 fill:#e3f2fd style A1 fill:#e8f5e9


Revizijski dogodki

Kategorija Dogodek Kritičnost
———————————
Certifikat Izdan Info
Certifikat Obnovljen Info
Certifikat Preklican Visoka
CA CRL ustvarjen Info
CA CA ključ uporabljen Srednja
Skrbnik Prijava Srednja
Skrbnik Sprememba konfiguracije Visoka
Sistem Zagon/ustavitev storitve Srednja
Varnost Neuspešna overitev Visoka

Oblika dnevnika

Strukturirana oblika JSON

{
  "timestamp": "2024-12-15T10:30:00.000Z",
  "level": "INFO",
  "event_type": "certificate_issued",
  "source": "ca-service",
  "actor": {
    "id": "operator-01",
    "ip": "10.0.0.50",
    "role": "pki-operator"
  },
  "subject": {
    "type": "certificate",
    "serial": "01:23:45:67:89:AB:CD:EF",
    "cn": "server.example.com",
    "validity_days": 365
  },
  "details": {
    "algorithm": "ML-DSA-65",
    "mode": "Hybrid",
    "issuer_serial": "AA:BB:CC:DD",
    "request_id": "REQ-2024-12345"
  },
  "result": "success"
}

Oblika Syslog

Dec 15 10:30:00 ca-server pki-ca[12345]: [INFO] certificate_issued actor=operator-01 serial=01:23:45:67 cn=server.example.com algo=ML-DSA-65 result=success

Linux: Rsyslog + ELK

Konfiguracija Rsyslog

# /etc/rsyslog.d/50-pki.conf
 
# PKI dnevniki v ločeni datoteki
:programname, isequal, "pki-ca" /var/log/pki/ca.log
:programname, isequal, "pki-ocsp" /var/log/pki/ocsp.log
 
# JSON predloga za Elasticsearch
template(name="pki-json" type="list") {
    constant(value="{")
    constant(value="\"timestamp\":\"")
    property(name="timereported" dateFormat="rfc3339")
    constant(value="\",\"host\":\"")
    property(name="hostname")
    constant(value="\",\"program\":\"")
    property(name="programname")
    constant(value="\",\"message\":\"")
    property(name="msg" format="json")
    constant(value="\"}\n")
}
 
# Pošiljanje v Elasticsearch
module(load="omelasticsearch")
action(type="omelasticsearch"
    server="elasticsearch.example.com"
    serverport="9200"
    template="pki-json"
    searchIndex="pki-audit"
    bulkmode="on"
    queue.type="linkedlist"
    queue.size="10000"
    queue.dequeuebatchsize="300"
    action.resumeRetryCount="-1")

Konfiguracija Filebeat

# /etc/filebeat/filebeat.yml
filebeat.inputs:
  - type: log
    enabled: true
    paths:
      - /var/log/pki/*.log
    json.keys_under_root: true
    json.add_error_key: true
    fields:
      log_type: pki-audit

output.elasticsearch:
  hosts: ["elasticsearch.example.com:9200"]
  index: "pki-audit-%{+yyyy.MM.dd}"

setup.template.name: "pki-audit"
setup.template.pattern: "pki-audit-*"

Beleženje v aplikaciji (C#)

// PkiAuditLogger.cs
using Microsoft.Extensions.Logging;
using System.Text.Json;
 
public class PkiAuditLogger
{
    private readonly ILogger _logger;
 
    public PkiAuditLogger(ILogger<PkiAuditLogger> logger)
    {
        _logger = logger;
    }
 
    public void LogCertificateIssued(
        X509Certificate2 cert,
        string actor,
        string requestId,
        CryptoMode mode)
    {
        var auditEvent = new
        {
            event_type = "certificate_issued",
            timestamp = DateTimeOffset.UtcNow,
            actor = new { id = actor },
            subject = new
            {
                serial = cert.SerialNumber,
                cn = cert.GetNameInfo(X509NameType.SimpleName, false),
                not_after = cert.NotAfter
            },
            details = new
            {
                algorithm = cert.SignatureAlgorithm.FriendlyName,
                mode = mode.ToString(),
                request_id = requestId
            },
            result = "success"
        };
 
        _logger.LogInformation(
            "AUDIT: {Event}",
            JsonSerializer.Serialize(auditEvent));
    }
 
    public void LogCertificateRevoked(
        string serial,
        X509RevocationReason reason,
        string actor)
    {
        var auditEvent = new
        {
            event_type = "certificate_revoked",
            timestamp = DateTimeOffset.UtcNow,
            actor = new { id = actor },
            subject = new { serial },
            details = new { reason = reason.ToString() },
            result = "success"
        };
 
        _logger.LogWarning(
            "AUDIT: {Event}",
            JsonSerializer.Serialize(auditEvent));
    }
}

Predloga indeksa Elasticsearch

PUT _index_template/pki-audit
{
  "index_patterns": ["pki-audit-*"],
  "template": {
    "settings": {
      "number_of_shards": 1,
      "number_of_replicas": 1,
      "index.lifecycle.name": "pki-audit-policy"
    },
    "mappings": {
      "properties": {
        "timestamp": { "type": "date" },
        "level": { "type": "keyword" },
        "event_type": { "type": "keyword" },
        "source": { "type": "keyword" },
        "actor.id": { "type": "keyword" },
        "actor.ip": { "type": "ip" },
        "actor.role": { "type": "keyword" },
        "subject.type": { "type": "keyword" },
        "subject.serial": { "type": "keyword" },
        "subject.cn": { "type": "text" },
        "result": { "type": "keyword" }
      }
    }
  }
}

ILM politika (hramba)

PUT _ilm/policy/pki-audit-policy
{
  "policy": {
    "phases": {
      "hot": {
        "actions": {
          "rollover": {
            "max_size": "10GB",
            "max_age": "7d"
          }
        }
      },
      "warm": {
        "min_age": "30d",
        "actions": {
          "shrink": { "number_of_shards": 1 },
          "forcemerge": { "max_num_segments": 1 }
        }
      },
      "cold": {
        "min_age": "90d",
        "actions": {
          "allocate": { "require": { "data": "cold" } }
        }
      },
      "delete": {
        "min_age": "365d",
        "actions": { "delete": {} }
      }
    }
  }
}

Kibana nadzorne plošče

Pregled revizije

{
  "title": "PKI Audit Dashboard",
  "panels": [
    {
      "title": "Dogodki na dan",
      "type": "visualization",
      "visState": {
        "type": "line",
        "aggs": [
          { "type": "date_histogram", "field": "timestamp", "interval": "1d" }
        ]
      }
    },
    {
      "title": "Dogodki po tipu",
      "type": "visualization",
      "visState": {
        "type": "pie",
        "aggs": [
          { "type": "terms", "field": "event_type" }
        ]
      }
    },
    {
      "title": "Preklici",
      "type": "visualization",
      "visState": {
        "type": "metric",
        "aggs": [
          { "type": "count", "filter": { "term": { "event_type": "certificate_revoked" } } }
        ]
      }
    }
  ]
}

Zahteve za skladnost

Standard Zahteva Implementacija
———-————————-
NIS2 čl. 21 Beleženje incidentov Beleženje vseh PKI dogodkov
ISO 27001 A.12.4 Celovitost dnevnikov Shranjevanje odporno na posege
BSI C5 Hramba Min. 1 leto
GDPR čl. 30 Evidenca obdelave Dnevniki dostopa

Arhiviranje dnevnikov

#!/bin/bash
# /usr/local/bin/archive-pki-logs.sh
 
# Arhiviranje dnevnikov starejših od 90 dni
find /var/log/pki -name "*.log" -mtime +90 -exec gzip {} \;
 
# Nalaganje arhiva v S3
aws s3 sync /var/log/pki/*.gz s3://pki-audit-archive/$(date +%Y/%m)/
 
# Brisanje lokalnih arhivov starejših od 365 dni
find /var/log/pki -name "*.gz" -mtime +365 -delete

Kontrolni seznam

# Kontrolna točka
—————–
1 Oblika dnevnika definirana (JSON)
2 Vsi PKI dogodki beleženi
3 Centralno zbiranje (ELK/Loki)
4 Politika hrambe konfigurirana
5 Nadzorna plošča ustvarjena
6 Arhiviranje nastavljeno
7 Pregled skladnosti

Povezana dokumentacija


« ← Preverjanje preklica | → Nastavitev opozarjanja »


Wolfgang van der Stille @ EMSR DATA d.o.o. - Post-Quantum Cryptography Professional