Produktivbetrieb
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.
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
| Variable | Beschreibung |
|---|---|
SPRING_PROFILES_ACTIVE | Muss prod sein. Wählt PostgreSQL, Produktiv-Logging und den produktiven Scan-Worker-Dialekt. |
SPRING_DATASOURCE_URL | JDBC-URL, z. B. jdbc:postgresql://host:5432/riskscanner. |
SPRING_DATASOURCE_USERNAME | Datenbankbenutzer. |
SPRING_DATASOURCE_PASSWORD | Datenbankpasswort. |
FINDING_FINGERPRINT_HMAC_SECRET | Secret zur Ableitung der Fund-Fingerabdrücke. Das prod-Profil startet ohne dieses Secret nicht. Siehe Warnung oben. |
JIRA_CREDENTIAL_ENCRYPTION_KEY | Base64-kodierter 256-Bit-AES-Schlüssel zur Verschlüsselung der gespeicherten Jira- und SMTP-Zugangsdaten. |
OIDC_ISSUER_URI | Issuer-URI Ihres OIDC-Providers. Siehe Identity Provider. |
Empfohlen
| Variable | Standard | Beschreibung |
|---|---|---|
APP_BASE_URL | http://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_ID | sensitive-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_ROLE | ADMIN | Rollenname, der Admin-Zugriff gewährt. |
APP_SECURITY_USER_ROLE | USER | Rollenname für den gewöhnlichen Zugriff. Konten ohne eine der beiden Rollen werden abgewiesen. |
APP_SECURITY_ROLES_CLAIM | realm_access.roles | JWT-Claim-Pfad mit den Rollen. |
Aufbewahrung
Diese steuern die Aufbewahrungsbereinigung.
| Variable | Standard | Beschreibung |
|---|---|---|
RETENTION_WINDOW | P10Y | ISO-8601-Zeitdauer, für die der Aufbewahrung unterliegende Daten gehalten werden. Null oder negativ wird beim Start abgewiesen. |
RETENTION_PURGE_AUDIT_EVENTS | false | Ob 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.
| Variable | Standard |
|---|---|
SCAN_ATTACHMENTS_MAX_DOWNLOAD_BYTES | 26214400 (25 MB) |
SCAN_ATTACHMENTS_PARSE_TIMEOUT | 60s |
SCAN_ATTACHMENTS_MAX_EXTRACTED_CHARS | 20000000 |
SCAN_ATTACHMENTS_MAX_ARCHIVE_ENTRIES | 1000 |
SCAN_ATTACHMENTS_MAX_ARCHIVE_BYTES | 52428800 (50 MB) |
SCAN_ATTACHMENTS_MAX_PARSE_THREADS | 20 |
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
HEALTHCHECKauf denselben Endpunkt mit. - Anwendungslogs gehen nach stdout. Im
prod-Profil steht der Root-Logger aufWARNundcom.projectriskscanneraufINFO.
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_THREADSerhö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.
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.