====== Audit-Logging ======
**Komplexität:** Mittel \\
**Dauer:** 1-2 Stunden Setup \\
**Compliance:** NIS2, ISO 27001, BSI-Grundschutz
Compliance-konforme Protokollierung aller PKI-Operationen für Audits und Forensik.
----
===== Architektur =====
flowchart LR
subgraph SOURCES["📝 QUELLEN"]
S1[CA Operations]
S2[API Requests]
S3[Admin Actions]
S4[System Events]
end
subgraph COLLECT["📥 SAMMLUNG"]
C1[Syslog]
C2[Filebeat]
C3[Fluentd]
end
subgraph STORE["💾 SPEICHERUNG"]
ST1[(Elasticsearch)]
ST2[(Loki)]
ST3[S3/Archive]
end
subgraph ANALYZE["🔍 ANALYSE"]
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
----
===== Audit-Ereignisse =====
| Kategorie | Ereignis | Kritikalität |
|-----------|----------|--------------|
| **Zertifikat** | Ausgestellt | Info |
| **Zertifikat** | Erneuert | Info |
| **Zertifikat** | Widerrufen | Hoch |
| **CA** | CRL generiert | Info |
| **CA** | CA-Schlüssel verwendet | Mittel |
| **Admin** | Login | Mittel |
| **Admin** | Konfigurationsänderung | Hoch |
| **System** | Service Start/Stop | Mittel |
| **Security** | Fehlgeschlagene Auth | Hoch |
----
===== Log-Format =====
==== Strukturiertes JSON-Format ====
{
"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"
}
==== Syslog-Format ====
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 =====
==== Rsyslog Konfiguration ====
# /etc/rsyslog.d/50-pki.conf
# PKI-Logs in separater Datei
:programname, isequal, "pki-ca" /var/log/pki/ca.log
:programname, isequal, "pki-ocsp" /var/log/pki/ocsp.log
# JSON-Template für 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")
}
# An Elasticsearch senden
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")
==== Filebeat Konfiguration ====
# /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-*"
----
===== Anwendungs-Logging (C#) =====
// PkiAuditLogger.cs
using Microsoft.Extensions.Logging;
using System.Text.Json;
public class PkiAuditLogger
{
private readonly ILogger _logger;
public PkiAuditLogger(ILogger 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));
}
}
----
===== Elasticsearch Index Template =====
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 Policy (Retention) ====
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 Dashboards =====
==== Audit-Übersicht ====
{
"title": "PKI Audit Dashboard",
"panels": [
{
"title": "Events pro Tag",
"type": "visualization",
"visState": {
"type": "line",
"aggs": [
{ "type": "date_histogram", "field": "timestamp", "interval": "1d" }
]
}
},
{
"title": "Events nach Typ",
"type": "visualization",
"visState": {
"type": "pie",
"aggs": [
{ "type": "terms", "field": "event_type" }
]
}
},
{
"title": "Widerrufe",
"type": "visualization",
"visState": {
"type": "metric",
"aggs": [
{ "type": "count", "filter": { "term": { "event_type": "certificate_revoked" } } }
]
}
}
]
}
----
===== Compliance-Anforderungen =====
| Standard | Anforderung | Umsetzung |
|----------|-------------|-----------|
| **NIS2 Art. 21** | Incident-Protokollierung | Alle PKI-Events loggen |
| **ISO 27001 A.12.4** | Log-Integrität | Tamper-proof Storage |
| **BSI C5** | Aufbewahrung | Min. 1 Jahr |
| **DSGVO Art. 30** | Verarbeitungsverzeichnis | Zugriffslogs |
----
===== Log-Archivierung =====
#!/bin/bash
# /usr/local/bin/archive-pki-logs.sh
# Logs älter als 90 Tage archivieren
find /var/log/pki -name "*.log" -mtime +90 -exec gzip {} \;
# Archiv nach S3 hochladen
aws s3 sync /var/log/pki/*.gz s3://pki-audit-archive/$(date +%Y/%m)/
# Lokale Archive älter als 365 Tage löschen
find /var/log/pki -name "*.gz" -mtime +365 -delete
----
===== Checkliste =====
| # | Prüfpunkt | ✓ |
|---|-----------|---|
| 1 | Log-Format definiert (JSON) | ☐ |
| 2 | Alle PKI-Events geloggt | ☐ |
| 3 | Zentrale Sammlung (ELK/Loki) | ☐ |
| 4 | Retention Policy konfiguriert | ☐ |
| 5 | Dashboard erstellt | ☐ |
| 6 | Archivierung eingerichtet | ☐ |
| 7 | Compliance-Review | ☐ |
----
===== Verwandte Dokumentation =====
* [[.:alerting-setup|Alerting Setup]] – Benachrichtigungen
* [[de:int:pqcrypt:business:compliance|Compliance]] – Regulatorische Anforderungen
* [[de:int:pqcrypt:administrator:betrieb|Betrieb]] – Systemwartung
----
<< [[.:revocation-check|← Revocation-Check]] | [[.:alerting-setup|→ Alerting Setup]] >>
----
//Wolfgang van der Stille @ EMSR DATA d.o.o. - Post-Quantum Cryptography Professional//
{{tag>audit logging elk elasticsearch compliance nis2 operator}}