Sobald der BOMnipotent-Server läuft, können Sie mit dem Hochladen von Dokumenten beginnen. Ein typischer Workflow beginnt mit der Erstellung eines SBOM, einer Inventarliste der Komponenten, die Ihr Produkt enthält. Dieser Schritt sollte automatisch ausgelöst werden, sobald eine neue Version erstellt wird. Anschließend wird dieses Inventar auf bekannte Sicherheitslücken überprüft. Auch dieser Schritt sollte automatisch erfolgen, jedoch in regelmäßigen Abständen.
Falls eine Sicherheitslücke entdeckt wird, muss sie analysiert werden. Diese Aufgabe erfordert Fachwissen und kann daher nicht automatisiert werden. Das Ergebnis dieser Analyse ist ein CSAF-Dokument, das Ihren Nutzern mitteilt, ob und wie sie auf diese neue Entwicklung reagieren müssen.
Damit der BOMnipotent Server direkt mit Ihrem E-Mail-Server kommunizieren kann, richten Sie den
SMTP-Teil
Ihrer Konfigurationsdatei in etwa so ein:
[smtp]
user = "you@yourdomain.com"endpoint = "your.smtp.host"secret = "${SMTP_SECRET}"
Die genaue Form hängt stark von Ihrem E-Mail-Anbieter ab. Manche Anbieter benötigen die vollständige E-Mail-Adresse als Benutzer, andere nicht.
Clients wie Mozilla Thunderbird können die erforderlichen Parameter in der Regel sehr gut ableiten. Falls Sie nicht weiterkommen, suchen Sie dort nach ihnen.
Kommunikation über SMTP-Relay
Wenn Sie mehrere Dienste nutzen, die E-Mails versenden, kann es sinnvoll sein, lokal eine SMTP-Relay-Station zu betreiben. Sie bietet Ihrem Setup einen einzigen Endpunkt für die Kommunikation mit dem Mailserver.
Es gibt mehrere Docker-Container mit SMTP-Relay-Funktionalität. Dieses Tutorial konzentriert sich auf
crazymax/msmtpd
, da es unter den leichtgewichtigen Lösungen die beste Sicherheit bietet.
Relay über Docker Compose ausführen
Fügen Sie den folgenden Dienst zu Ihrer compose.yaml Datei hinzu:
smtp_relay:
container_name: smtp_relaydeploy:
resources:
limits:
cpus: "0.5"memory: "512M"environment:
TZ: Europe/Berlin# Ersetzen Sie dies durch Ihre bevorzugte ZeitzoneSMTP_HOST: your.smtp.host# Ersetzen Sie dies durch den korrekten EndpunktSMTP_PORT: 465SMTP_TLS: onSMTP_STARTTLS: offSMTP_TLS_CHECKCERT: onSMTP_AUTH: loginSMTP_USER: you@yourdomain.com# Ersetzen Sie dies durch Ihren BenutzernamenSMTP_FROM: you@yourdomain.com# Ersetzen Sie dies durch Ihre E-Mail-AdresseSMTP_PASSWORD: ${SMTP_PASSWORD}SMTP_DOMAIN: localhosthealthcheck:
test: ["CMD", "msmtp", "--version"]
interval: 30stimeout: 10sretries: 3image: crazymax/msmtpdlogging:
driver: localoptions:
max-size: "10m"max-file: "3"networks:
- smtp_networkrestart: unless-stopped
Dadurch wird der Container gestartet und verbindet sich mit Port 465 (dem Standard für das SMTPS-Protokoll) des SMTP-Hosts. Die Verschlüsselung erfolgt mit TLS und nicht mit STARTTLS. Der Server lauscht auf Port 2500. Dies ist zwar nicht aus der Eingabe ersichtlich, entspricht aber dem Standardverhalten von msmtp.
Die Änderung Ihrer Compose-Datei ist jedoch noch nicht abgeschlossen!
Unter „Netzwerke“ müssen Sie das SMTP-Netzwerk angeben:
Sie müssen das Netzwerk außerdem jedem Container hinzufügen, der es kontaktieren soll. Sie können diese Container auch vom SMTP-Relay abhängig machen, damit sie nicht gestartet werden, bevor die Relay Station bereit ist:
Neben den Änderungen an der Compose-Datei muss Ihre .env-Datei oder Ihre Umgebung das Geheimnis oder Passwort Ihres E-Mail-Anbieters enthalten:
SMTP_PASSWORD=eHD5B6S8Kze3
export SMTP_PASSWORD=eHD5B6S8Kze3
set SMTP_PASSWORD=eHD5B6S8Kze3
$env:SMTP_PASSWORD = "eHD5B6S8Kze3"
In Ihrer BOMnipotent Server-Konfigurationsdatei können Sie nun den SMTP-Abschnitt so anpassen, dass die Verbindung zum Relay über das Docker-Netzwerk hergestellt wird:
[smtp_config]
user = "you@yourdomain.com"endpoint = "smtp://smtp_relay:2500"
Relay im eigenständigen Docker-Container ausführen
Wenn Ihr Setup keine Compose-Datei enthält, können Sie den Container stattdessen direkt mit Docker ausführen. Stellen Sie sicher, dass Ihre Umgebung einen Wert für SMTP_PASSWORD bereitstellt, und führen Sie anschließend Folgendes aus:
Dies funktioniert im Wesentlichen wie der für die compose Datei vorgeschlagene Abschnitt. Ersetzen Sie erneut die Werte für TZ, SMTP_HOST, SMTP_USER und SMTP_FROM durch die Werte Ihres E-Mail-Anbieters.
Der obige Befehl stellt Port 2500 für localhost bereit. Ihre BOMnipotent-Konfiguration muss daher wie folgt lauten:
[smtp_config]
user = "you@yourdomain.com"endpoint = "smtp://localhost:2500"
Um den Container zu stoppen, führen Sie Folgendes aus:
docker stop smtp_relay
SBOMs mit Syft
Eine Software Bill of Materials (SBOM) ist eine Liste aller Softwarekomponenten, die in deinem Produkt verwendet werden. Im Kontext der Lieferkettensicherheit dient sie als maschinenlesbare Liste von Elementen, mit der neue Schwachstellen abgeglichen werden können, sobald sie bekannt werden.
Es gibt mehrere Tools zur automatischen Erstellung einer solchen SBOM. Dieses Tutorial konzentriert sich auf Syft von Anchore, einem Open-Source-Kommandozeilentool.
Einrichtung
Das offizielle
Syft GitHub Repository
enthält Installationsanweisungen. Die Installation ist über ein Shell-Skript oder verschiedene Paketmanager möglich.
Auf manchen Linux-Systemen sollten Sie den Installationspfad (das letzte Argument des Shell-Befehls) auf “~/.local/bin” ändern, da für Änderungen an “/usr/local/bin” Root-Rechte erforderlich sind.
Verwendung
Die grundlegende Verwendung von Syft lautet:
syft <Ziel> [Optionen]
Zusätzlich lassen sich einige Konfigurationen über Umgebungsvariablen vornehmen.
Syft unterstützt Lockfiles, Verzeichnisse, Container-Images und weitere Zieltypen.
‘SYFT_FORMAT_PRETTY=1’ setzt eine Umgebungsvariable, die Syft anweist, durch Menschen besser lesbare Ausgabe zu produzieren. Eine vollständige Liste der Konfigurationen befindet sich
hier
.
‘syft’ ruft das Syft-Programm auf.
‘Cargo.lock’ gibt an, dass Syft die Lockfile-Datei des Rust-Ökosystems analysieren soll.
‘–output cyclonedx-json=./sbom.cdx.json’ legt fest, dass die Ausgabe im
CycloneDx
JSON-Format in der Datei ‘./sbom.cdx.json’ gespeichert wird.
‘–source-name=“BOMnipotent”’ gibt an, dass diese Quellen zu der Komponente BOMnipotent gehören, was Syft nicht in allen Fällen automatisch erkennen kann.
Das CycloneDX-Schema erfordert möglicherweise keinen Komponentennamen, aber BOMnipotent benötigt ihn.
‘–source-version=“1.0.0”’ gibt Syft die aktuelle Version des Projekts an.
Falls keine Version angegeben wird, versucht BOMnipotent, stattdessen den Zeitstempel als Versionszeichenkette zu verwenden.
Syft unterstützt eine Vielzahl von Ökosystemen, welche
in Ihrem GitHub repo
aufgelistet sind.
Verzeichnis
Syft kann auf ein ganzes Verzeichnis angewendet werden, allerdings ist das oft übertrieben. Es durchsucht alle Unterverzeichnisse und erfasst alles, was entfernt wie eine Lockfile aussieht, einschließlich aller Testabhängigkeiten, Entwicklungsskripte und GitHub Actions.
Bei kompilierten Sprachen können die Ergebnisse stark abweichen, da die meisten Informationen über die Komponenten, die in die Kompilierung eingeflossen sind, verloren gehen. Andererseits enthält diese SBOM Informationen über die Umgebung, in der das Produkt später möglicherweise ausgeführt wird.
Abschließende Bemerkungen
Bei der Auswahl eines Ziels ist es wichtig, den Umfang der Anwendung zu berücksichtigen:
Was wird an den Kunden ausgeliefert? In welchem Umfang sind Sie für die Lieferkette des Produkts verantwortlich? Bei Unentschlossenheit spricht nichts dagegen, mehrere Varianten einer SBOM hochzuladen – solange der Produktname oder die Version unterschiedlich ist.
Sobald Ihre SBOM (Software Bill of Materials) erstellt wurde, ist es an der Zeit, sie kontinuierlich auf Schwachstellen zu scannen. Beachten Sie, dass einige Gesetze, wie beispielsweise der Cyber Resilience Act der EU, vorschreiben, dass Produkte ohne bekannte Schwachstellen veröffentlicht werden. Der erste Scan sollte daher vor einer Veröffentlichung erfolgen.
Es gibt verschiedene Tools zur Überprüfung eines Produkts auf Schwachstellen in der Lieferkette. Dieses Tutorial verwendet Grype von Anchore, da es sich gut mit Syft von Anchore aus dem
SBOM tutorial
integriert. Genau wie Syft ist Grype ein Open-Source-Befehlszeilenprogramm.
Einrichtung
Das offizielle
Grype GitHub Repository
enthält Installationsanweisungen. Ähnlich wie bei Syft können Sie den Installationspfad (das letzte Argument des Shell-Befehls) auf ‘~/.local/bin’ ändern, da ‘/usr/local/bin’ Root-Berechtigungen zum Ändern erfordert.
Verwendung
Sobald eine SBOM vorliegt, ist das Scannen auf Schwachstellen sehr einfach:
grype sbom:./sbom.cdx.json --fail-on low
grype sbom:./sbom.cdx.json -f low
✔ Scanned for vulnerabilities [2 vulnerability matches]
├── by severity: 0 critical, 0 high, 2 medium, 0 low, 0 negligible
└── by status: 2 fixed, 0 not-fixed, 0 ignored
NAME INSTALLED FIXED-IN TYPE VULNERABILITY SEVERITY
ring 0.17.8 0.17.12 rust-crate GHSA-4p46-pwfr-66x6 Medium
rustls 0.23.15 0.23.18 rust-crate GHSA-qg5g-gv98-5ffh Medium
[0000] ERROR discovered vulnerabilities at or above the severity threshold
Beim Ausführen dieses Befehls überprüft Grype
mehrere Schwachstellendatenbanken
auf Übereinstimmungen mit den im SBOM angegebenen Komponenten. Die Option ‘fail-on’ sorgt dafür, dass das Programm mit einem Fehlercode ungleich null beendet wird, falls eine Schwachstelle mit mindestens der angegebenen Schwere ’low’ gefunden wird.
Die Syntax zum Exportieren eines Schwachstellenberichts, der von BOMnipotent verarbeitet werden kann, ist ähnlich wie bei Syft:
Grype lässt sich leicht mit BOMnipotent kombinieren. Sie können das “bom get” Kommando von BOMnipotent Client verwenden, um den Inhalt einer BOM direkt in die Konsole ausgeben zu lassen, und diesen dann an Grype weitergeben:
bomnipotent_client bom get <BOM-NAME> <BOM-VERSION> | grype --output cyclonedx-json=./vuln.cdx.json
bomnipotent_client bom get <BOM-NAME> <BOM-VERSION> | grype -o cyclonedx-json=./vuln.cdx.json
CI/CD
BOMnipotent wurde für die Automatisierung entwickelt. Es fordert den Nutzer nie zur interaktiven Eingabe auf und ist damit vollständig skriptbar.
Diese Seite beschreibt, wie Sie den BOMnipotent-Client in Ihrer CI/CD-Pipeline verwenden, um mit jedem Release BOMs hochzuladen und täglich auf Schwachstellen zu prüfen.
Weichwerke Heidrich Software hat mehrere einsatzbereite GitHub-Actions zur Integration von BOMnipotent in Ihre Pipeline entwickelt. Die meisten davon basieren auf Bash-Skripten, um die Übertragung in andere Pipeline-Umgebungen so einfach und nahtlos wie möglich zu gestalten.
Voraussetzungen
Dieses Setup setzt voraus, dass Sie eine BOMnipotent-Serverinstanz installiert haben. Falls dies noch nicht der Fall ist, lesen Sie die
Setup-Anleitung
.
Die Pipeline erfordert außerdem, dass der Server über ein genehmigtes Roboter-Benutzerkonto mit den Berechtigungen BOM_MANAGEMENT und VULN_MANAGEMENT verfügt. Die Abschnitte zur
Kontoerstellung
und
Zugriffsverwaltung
enthalten weitere Informationen zur Einrichtung.
BOMnipotent-Client einrichten
Die Bereitstellung ausführbarer Dateien ist der Bereich, in dem sich die verschiedenen Pipeline-Umgebungen am meisten unterscheiden. Glücklicherweise ist dies auch die Hürde, die DevOps-Ingenieure sehr früh überwinden. Daher wird diese Aufgabe derzeit nur für GitHub-Actions beschrieben, für die ein einsatzbereiter Schritt vorhanden ist.
GitHub-Action
Die Action zum Einrichten von BOMnipotent Client finden Sie im
GitHub Marketplace
.
Ein typischer Ausschnitt aus Ihrer Workflow-YAML-Datei sieht wie folgt aus (mit Ausnahme der Einrückung, weil YAML…):
Ein ausführlicheres Beispiel finden Sie auf
GitHub
.
Die drei Parameter sind optional, werden aber empfohlen:
domain: Geben Sie die vollständige Domäne (einschließlich Subdomäne) für Ihre BOMnipotent-Serverinstanz an. Diese wird in einer Sitzung gespeichert, sodass Sie sie bei nachfolgenden Aufrufen nicht erneut angeben müssen.
user: Speichern Sie den Benutzernamen Ihres Roboterbenutzers, den Sie im Abschnitt
Voraussetzungen
eingerichtet haben.
secret-key: Geben Sie eine Referenz auf den geheimen Schlüssel an, der zur Authentifizierung des Roboterbenutzers verwendet wird. Sie können ihn Ihrer Pipeline über <your repo> → Einstellungen → Geheimnisse und Variablen → Aktionen → Neues Repository-Geheimnis zur Verfügung stellen. Im obigen Beispiel heißt er “CLIENT_SECRET_KEY”.
Achtung: Speichern Sie Ihren geheimen Schlüssel nicht direkt in der Pipeline oder einer anderen versionierten Datei. Genau dafür ist der GitHub-Secret-Mechanismus konzipiert.
Nach Ausführung dieser Aktion steht der Befehl “bomnipotent_client.exe” (Windows) bzw. “bomnipotent_client” (UNIX) für den Rest des Jobs zur Verfügung. Da verschiedene Jobs in unterschiedlichen Containern ausgeführt werden, kann es erforderlich sein, die Setup-Aktion im Laufe des Workflows mehrmals aufzurufen.
BOMs hochladen
Eine Stückliste / Bill of Material (BOM) ist eine Liste der Komponenten eines Produkts. Da es sich um ein statisches Dokument handelt, ist jede BOM eng mit einem bestimmten Release des Produkts verknüpft. Ändern sich die Komponenten des (veröffentlichten) Produkts, sollte dieses mit einer neuen Version versehen und einer neuen BOM zugeordnet werden.
Deshalb sollte das Hochladen einer BOM auf den Server als Teil der Release-Pipeline ausgeführt werden.
Gemäß dem Single Responisbility Prinzip sind für das Hochladen von Stücklisten einige Voraussetzungen erforderlich:
– Der BOMnipotent Client Befehl muss verfügbar sein. Es gibt eine
separate Action
, die genau das sicherstellt.
– Die Action benötigt als Eingabe eine BOM im CycloneDX-Format, die zuvor generiert werden muss.
Die Erstellung einer BOM ist sehr produktspezifisch. Das ideale Tool hängt vom jeweiligen Ökosystem und dessen Nutzung ab.
Syft
ist ein Tool, das Sie dabei unterstützen kann und eine einsatzbereite
GitHub-Action
bereitstellt. Es ist jedoch bei weitem nicht die einzige Option: Das
CycloneDX Tool Center
bietet zahlreiche Alternativen.
GitHub-Action
Ein häufiges Muster besteht darin, die Release-Pipeline durch das Pushen eines Tags auszulösen, welches einer semantischen Version entspricht:
on:
push:
tags:
- 'v[0-9]+.[0-9]+.[0-9]+'
Nachdem der BOMnipotent-Client eingerichtet und die BOM generiert wurde, kann es mit dem folgenden Ausschnitt hochgeladen werden:
bom: Dies ist das einzige obligatorische Argument. Es muss auf eine vorhandene Datei verweisen, die eine BOM im CycloneDX-Format enthält. In diesem Beispiel wurde die Stückliste unter “./bom.cdx.json” gespeichert.
name / version: Der CycloneDX-Standard erfordert für eine BOM keinen Namen und keine Version, BOMnipotent hingegen schon. Falls das zur Erstellung der Stückliste verwendete Tool die Festlegung von Name und/oder Version nicht ermöglicht, können Sie diese über Argumente überschreiben. Im obigen Beispiel wird der Repository-Name als Produktname und das auslösende Tag als Version verwendet. Alternativ können Sie auch einen Dateipfad angeben: Die Zeile version: './version.txt' weist die Aktion beispielsweise an, die Datei “./version.txt” zu lesen und den Inhalt als Versionszeichenfolge zu verwenden.
tlp: Sie können ein TLP-Label angeben, um die hochgeladene Stückliste zu klassifizieren. Falls nicht angegeben, gilt das
Default-TLP
des Servers.
Die GitHub-Action ist lediglich ein Wrapper für ein Bash-Skript. Um eine BOM über Ihre Pipeline-Infrastruktur hochzuladen, können Sie das
Skript
aus dem Repository herunterladen und verwenden.
if [ ! -f ./upload_bom.sh ]; then
curl https://raw.githubusercontent.com/Weichwerke-Heidrich-Software/upload-bom-action/refs/heads/main/upload_bom.sh > ./upload_bom.sh
chmod +x ./upload_bom.sh
fi
./upload_bom.sh <bom.cdx.json> <optional args...>
Das Skript verwendet dieselben Argumente wie die Aktion, mit der Ausnahme, dass das Argument “bom” positionell ist und optionalen Argumenten ein doppelter Bindestrich vorangestellt werden muss:
BOMs selbst sind zwar statische Objekte, die die Zusammensetzung eines Produkts dokumentieren, sie müssen aber regelmäßig auf Sicherheitslücken geprüft werden. Die meisten Datenbanken von Sicherheitslücken werden täglich aktualisiert, daher sollten Prüfungen ähnlich häufig durchgeführt werden.
Die BOMnipotent Vulnerability Action umfasst zwei Schritte:
– Aktualisierung der bekannten Sicherheitslücken aller BOMs auf dem Server.
– Überprüfung des Servers auf neue, noch nicht bewertete Sicherheitslücken.
Beide Schritte können einzeln übersprungen werden, falls sie für Ihren Anwendungsfall nicht relevant sind.
GitHub-Action
Um die Sicherheitslückenprüfung beispielsweise täglich um 3:00 Uhr morgens auszuführen, fügen Sie Ihrem Workflow-YAML-Dokument den folgenden Trigger hinzu:
on:
schedule:
- cron: '0 3 * * *'# Runs the workflow every day at 03:00 UTC
Das Skript lädt alle dem Robernutzer zugänglichen BOMs herunter, gleicht sie mit mehreren Datenbanken bekannter Sicherheitslücken ab, und aktualisiert sie auf dem Server.
Anschließend prüft es, ob noch nicht bewertete Sicherheitslücken vorhanden sind. Eine Sicherheitslücke gilt als nicht bewertet, wenn BOMnipotent-Server kein ihr zugeordnetes
CSAF-Dokument
enthält.
Andere Pipeline
Analog zum
Upload-Schritt
ist diese Action im Wesentlichen ein Wrapper für ein Bash-Skript. Sie können das
Skript
im Repository referenzieren oder direkt herunterladen und verwenden:
if [ ! -f ./upload_bom.sh ]; then
curl https://raw.githubusercontent.com/Weichwerke-Heidrich-Software/vulnerability-action/refs/heads/main/update_vulns.sh > ./update_vulns.sh
chmod +x ./update_vulns.sh
fi
./update_vulns.sh
Das Skript verwendet intern
grype
um auf Sicherheitslücken zu prüfen. Falls Sie das Skript direkt verwenden müssen Sie sicherstellen, dass das Programm installiert ist.