Zum Hauptinhalt springen

Produktivbetrieb

Produktivbetrieb niemals mit dem Standardprofil

Ohne SPRING_PROFILES_ACTIVE=prod startet der Scanner auf einer In-Memory-H2-Datenbank. Er funktioniert, er scannt, und er sieht völlig normal aus - aber jeder Fund, jeder Scan-Lauf, jede Regel, jede Unterdrückung, jedes Audit-Ereignis und die gespeicherte Jira-Verbindung sind nach einem Neustart weg, ohne Warnung. Nutzen Sie für alles ausser einem ersten Blick das prod-Profil und eine PostgreSQL-Datenbank.

1. PostgreSQL bereitstellen​

Das prod-Profil zielt auf PostgreSQL. Legen Sie eine leere Datenbank und einen Benutzer an, dem sie gehört; der Scanner legt sein Schema selbst an und migriert es beim Start mit Flyway.

CREATE DATABASE riskscanner;
CREATE USER riskscanner WITH ENCRYPTED PASSWORD '<starkes-passwort>';
GRANT ALL PRIVILEGES ON DATABASE riskscanner TO riskscanner;

Darüber hinaus ist kein manuelles SQL nötig. Legen Sie keine Tabellen vorab an und führen Sie Flyway nicht selbst aus.

2. Secrets erzeugen​

Zwei Secrets müssen einmalig erzeugt und danach über die gesamte Lebensdauer der Installation stabil gehalten werden.

# JIRA_CREDENTIAL_ENCRYPTION_KEY - base64-kodierter 256-Bit-AES-Schlüssel
openssl rand -base64 32

# FINDING_FINGERPRINT_HMAC_SECRET - beliebige lange Zufallszeichenfolge
openssl rand -base64 48

JIRA_CREDENTIAL_ENCRYPTION_KEY muss zu genau 32 Byte dekodieren. Andernfalls startet die Anwendung nicht, und eine beliebige Passphrase funktioniert nicht.

Beide Secrets sind dauerhaft

Ein Wechsel von JIRA_CREDENTIAL_ENCRYPTION_KEY macht die gespeicherten Jira-Zugangsdaten unentschlüsselbar; die Verbindung muss neu eingegeben werden. Ein Wechsel von FINDING_FINGERPRINT_HMAC_SECRET ändert die Identität jedes Fundes, sodass der nächste Scan bestehende Funde als neu meldet und ihre Prüfhistorie sowie passende Unterdrückungen verliert. Bewahren Sie beide in Ihrem Secret Manager auf und sichern Sie sie zusammen mit der Datenbank.

3. Deployen​

Legen Sie die Secrets in eine .env-Datei neben der Compose-Datei, nicht in die Compose-Datei selbst:

cat > .env <<EOF
POSTGRES_PASSWORD=$(openssl rand -base64 24)
JIRA_CREDENTIAL_ENCRYPTION_KEY=$(openssl rand -base64 32)
FINDING_FINGERPRINT_HMAC_SECRET=$(openssl rand -base64 48)
EOF
chmod 600 .env
services:
postgres:
image: postgres:17-alpine
environment:
- POSTGRES_DB=riskscanner
- POSTGRES_USER=riskscanner
- POSTGRES_PASSWORD=${POSTGRES_PASSWORD:?in .env setzen}
volumes:
- scanner-postgres-data:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U riskscanner -d riskscanner"]
interval: 5s
timeout: 3s
retries: 20
restart: unless-stopped

scanner:
image: arcsoftklg/sensitive-data-scanner:1.0.0 # echten Tag festlegen
depends_on:
postgres:
condition: service_healthy
ports:
- "8080:8080"
environment:
- SPRING_PROFILES_ACTIVE=prod
- SPRING_DATASOURCE_URL=jdbc:postgresql://postgres:5432/riskscanner
- SPRING_DATASOURCE_USERNAME=riskscanner
- SPRING_DATASOURCE_PASSWORD=${POSTGRES_PASSWORD:?in .env setzen}
- JIRA_CREDENTIAL_ENCRYPTION_KEY=${JIRA_CREDENTIAL_ENCRYPTION_KEY:?in .env setzen}
- FINDING_FINGERPRINT_HMAC_SECRET=${FINDING_FINGERPRINT_HMAC_SECRET:?in .env setzen}
- OIDC_ISSUER_URI=https://idp.example.com/realms/sensitive-data-scanner
- APP_BASE_URL=https://riskscanner.example.com
restart: unless-stopped

volumes:
scanner-postgres-data:
docker compose up -d

Hier kein Keycloak: im Produktivbetrieb zeigt der Scanner auf den Identity Provider, den Sie ohnehin betreiben. Die :?-Markierungen sorgen dafür, dass Compose den Start verweigert, statt stillschweigend ein leeres Secret einzusetzen.

Umgebungsvariablen​

Im Produktivbetrieb erforderlich​

VariableBeschreibung
SPRING_PROFILES_ACTIVEMuss prod sein. Wählt PostgreSQL, Produktiv-Logging und den produktiven Scan-Worker-Dialekt.
SPRING_DATASOURCE_URLJDBC-URL, z. B. jdbc:postgresql://host:5432/riskscanner.
SPRING_DATASOURCE_USERNAMEDatenbankbenutzer.
SPRING_DATASOURCE_PASSWORDDatenbankpasswort.
FINDING_FINGERPRINT_HMAC_SECRETSecret zur Ableitung der Fund-Fingerabdrücke. Das prod-Profil startet ohne dieses Secret nicht. Siehe Warnung oben.
JIRA_CREDENTIAL_ENCRYPTION_KEYBase64-kodierter 256-Bit-AES-Schlüssel zur Verschlüsselung der gespeicherten Jira- und SMTP-Zugangsdaten.
OIDC_ISSUER_URIIssuer-URI Ihres OIDC-Providers. Siehe Identity Provider.

Empfohlen​

VariableStandardBeschreibung
APP_BASE_URLhttp://localhost:8080Öffentliche URL des Scanners. Wird für die Links in den Report-E-Mails verwendet; bleibt der Standard stehen, erhalten Empfänger unbrauchbare localhost-Links.
OIDC_CLIENT_IDsensitive-data-scanner-frontendÖffentlicher OIDC-Client, als der sich die Weboberfläche anmeldet. Setzen Sie ihn, wenn Ihr Client anders heisst. Die Weboberfläche liest ihn und den Issuer beim Start vom Scanner - das veröffentlichte Image muss für Ihren Provider also nicht neu gebaut werden.
APP_SECURITY_ADMIN_ROLEADMINRollenname, der Admin-Zugriff gewährt.
APP_SECURITY_USER_ROLEUSERRollenname für den gewöhnlichen Zugriff. Konten ohne eine der beiden Rollen werden abgewiesen.
APP_SECURITY_ROLES_CLAIMrealm_access.rolesJWT-Claim-Pfad mit den Rollen.

Aufbewahrung​

Diese steuern die Aufbewahrungsbereinigung.

VariableStandardBeschreibung
RETENTION_WINDOWP10YISO-8601-Zeitdauer, für die der Aufbewahrung unterliegende Daten gehalten werden. Null oder negativ wird beim Start abgewiesen.
RETENTION_PURGE_AUDIT_EVENTSfalseOb die Bereinigung auch Audit-Ereignisse löscht. Standardmässig aus, damit der Audit-Trail erhalten bleibt.

Grenzwerte für das Scannen von Anhängen​

Diese steuern das Scannen von Anhängen und sind nur relevant, wenn eine Scan-Konfiguration es aktiviert hat.

VariableStandard
SCAN_ATTACHMENTS_MAX_DOWNLOAD_BYTES26214400 (25 MB)
SCAN_ATTACHMENTS_PARSE_TIMEOUT60s
SCAN_ATTACHMENTS_MAX_EXTRACTED_CHARS20000000
SCAN_ATTACHMENTS_MAX_ARCHIVE_ENTRIES1000
SCAN_ATTACHMENTS_MAX_ARCHIVE_BYTES52428800 (50 MB)
SCAN_ATTACHMENTS_MAX_PARSE_THREADS20

Reverse Proxy und TLS​

Der Container liefert einfaches HTTP auf Port 8080 aus und terminiert selbst kein TLS. Stellen Sie ihn hinter Ihren eigenen Proxy:

server {
listen 443 ssl;
server_name riskscanner.example.com;

ssl_certificate /etc/ssl/certs/riskscanner.crt;
ssl_certificate_key /etc/ssl/private/riskscanner.key;

# Anhänge und CSV-Exporte können gross werden.
client_max_body_size 64m;

location / {
proxy_pass http://127.0.0.1:8080;

proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Host $host;

# Ein vollständiger Scan kann eine Anfrage beim Start offenhalten.
proxy_read_timeout 300s;
}
}

Proxen Sie den gesamten Origin statt einzelner Pfade: die UI liegt unter /ui/, die API unter /api/ und Health unter /actuator/health. Setzen Sie APP_BASE_URL auf die öffentliche HTTPS-URL, nicht auf die interne.

Installation ohne Internetzugang​

Der Scanner braucht im Betrieb kein Internet - seine einzigen ausgehenden Verbindungen gehen zu Jira, Ihrem Identity Provider, Ihrer Datenbank und optional Ihrem SMTP-Server. Die Lizenzierung ist offline, es gibt kein Phone-Home.

Um die Software hineinzubekommen, transportieren Sie das Image:

docker pull arcsoftklg/sensitive-data-scanner:1.0.0
docker save arcsoftklg/sensitive-data-scanner:1.0.0 | gzip > scanner-1.0.0.tar.gz
docker load < scanner-1.0.0.tar.gz

Taggen Sie es anschliessend um, laden Sie es in Ihre interne Registry und setzen Sie das image: in der Compose-Datei darauf.

Health und Monitoring​

  • Health-Endpunkt: GET /actuator/health. Es ist der einzige exponierte Actuator-Endpunkt und zeigt nie Details - nutzen Sie ihn als Liveness- und Readiness-Probe.
  • Das Image bringt einen eigenen HEALTHCHECK auf denselben Endpunkt mit.
  • Anwendungslogs gehen nach stdout. Im prod-Profil steht der Root-Logger auf WARN und com.projectriskscanner auf INFO.

Dimensionierung​

  • CPU und Arbeitsspeicher - ein einzelner Container mit 2 vCPU und 2 GB Heap bewältigt die Standardeinstellungen der Scan-Engine problemlos. Das Scannen von Anhängen ist der speicherintensive Teil: erhöhen Sie den Speicher, bevor Sie SCAN_ATTACHMENTS_MAX_PARSE_THREADS erhöhen.
  • Datenbank - Funde, Vorkommen und Audit-Ereignisse dominieren. Dimensionieren Sie nach der Anzahl der Issues im Scope, nicht nach der Anzahl der Scans; die Aufbewahrung begrenzt unbegrenztes Wachstum auf die konfigurierte Aufbewahrungsfrist, standardmässig zehn Jahre. Audit-Ereignisse werden standardmässig nicht gelöscht; planen Sie daher mit unbegrenztem Wachstum für diese.
  • Durchsatz - der begrenzende Faktor ist normalerweise Jira, nicht der Scanner. Stellen Sie Worker-Anzahl und maximale Issues pro Minute je Konfiguration ein, siehe Scans.

Mehrere Instanzen betreiben​

Der Scanner ist auf einen einzigen Mandanten ausgelegt: eine Jira-Verbindung, ein Satz Scan-Konfigurationen, eine Lizenz. Weitere Instanzen sind Repliken derselben Installation auf derselben PostgreSQL-Datenbank und keine getrennten Mandanten; alle müssen dieselben Secrets und dieselbe Datenbank verwenden.

Repliken bringen Verfügbarkeit für UI und API. Sie bringen keinen höheren Scan-Durchsatz, und sie haben Grenzen, die Sie vor dem Skalieren kennen sollten:

  • Zeitpläne und Reports sind abgesichert. Das Auslösen eines geplanten Scans und die Report-Planung beanspruchen ihren Slot in der Datenbank; zwei Instanzen lösen deshalb weder einen geplanten Scan doppelt aus noch versenden sie denselben Report zweimal.
  • Die Anmeldung braucht keine Sticky Sessions. Die Authentifizierung hält keinen serverseitigen Sitzungszustand, jede Instanz kann jede Anfrage bedienen.
  • Ein einzelner Scan verteilt sich nicht über Instanzen. Arbeitspakete werden aus der Datenbank geleast, es wird also nie etwas doppelt verarbeitet - die Worker laufen aber alle in der Instanz, die den Scan gestartet hat. Mehr Instanzen machen einen einzelnen Scan nicht schneller; erhöhen Sie stattdessen die Worker-Anzahl, siehe Scans.
  • Die Mustererkennung ist instanzlokal. Die Inhalte, die ein Scan für Mustervorschläge sammelt, liegen im Arbeitsspeicher der Instanz, die den Scan ausgeführt hat. Fragen Sie eine andere Instanz nach Vorschlägen, erhalten Sie ohne Fehlermeldung unvollständige oder gar keine Ergebnisse, und hinter einem Load Balancer haben Sie nicht in der Hand, welche Instanz antwortet. Die Funktion ist standardmässig deaktiviert, das betrifft Sie also nur, wenn Sie sie eingeschaltet haben.
Verwaiste Scans werden automatisch bereinigt

Stoppt die Instanz, die einen Scan ausführt, meldet sich der Lauf nicht mehr als aktiv und wird innerhalb von rund 90 Sekunden von einer beliebigen laufenden Instanz als fehlgeschlagen markiert. Er setzt am letzten Checkpoint auf, ohne Funde zu duplizieren (siehe Scans). Pausierte Scans sind nie betroffen und überstehen einen Neustart.

Eine einzelne Instanz bleibt die einfachste Betriebsform, und die beiden obigen Grenzen bedeuten, dass weitere Instanzen Verfügbarkeit bringen und nicht Geschwindigkeit. Laufende Scans kosten sie Sie aber nicht mehr: Der Start oder Neustart einer Instanz lässt die Scans anderer Instanzen unangetastet.