Diese Variante des sehr ähnlichen Setups mit Docker Compose richtet nicht nur einen laufenden BOMnipotent-Server ein, sondern auch einen nginx Reverse-Proxy.
Vorgeschlagene Dateistruktur
Die vorgeschlagene Dateistruktur im Lieblingsverzeichnis Ihres Servers sieht folgendermaßen aus:
Dieses Tutorial führt Sie durch die Dateien und erklärt sie einzeln.
proxy_config/conf.d/default.conf
Die Verwendung von nginx als Reverse-Proxy ist lediglich ein Vorschlag. Sie können ihn durch jede andere Serversoftware Ihrer Wahl ersetzen.
Vereinfacht ausgedrückt dient der Reverse-Proxy als Tor zu Ihrem Server: Er ermöglicht Ihnen, mehrere Dienste (BOMnipotent-Server, eine Website usw.) hinter derselben IP-Adresse zu hosten. Jede Anfrage an eine Ihrer URLs landet beim Reverse-Proxy, der sie dann an den richtigen Dienst weiterleitet. So landen Sie beim Besuch von doc.bomnipotent.de auf einer anderen Website als beim Besuch von www.bomnipotent.de, obwohl beide hinter derselben IP-Adresse gehostet werden.
Nginx sucht seine Konfiguration an verschiedenen Orten. Später in der compose.yaml verwenden wir Mount-Binding, um unsere Konfiguration hinterrücks in den Nginx-Docker-Container einzuschleusen.
Sie können Folgendes als Ausgangspunkt für Ihre default.conf verwenden:
# Anfragenbegrenzung: Erlaubt bis zu 5 Anfragen pro Sekunde pro IP-Adresse, gespeichert in einem 10 MB großen Speicherbereich.
limit_req_zone $binary_remote_addr zone=api_limit:10mrate=5r/s;
# BOMnipotent Server
server {
# Hierdurch hört der Server auf Port 443, der typischerweise für HTTPS verwendet wird.
listen443sslhttp2;
# Ersetzen Sie dies durch die tatsächliche Domain Ihres BOMnipotent Servers.
server_namebomnipotent.your-domain.com;
# Ersetzen Sie dies durch das tatsächliche Zertifikat Ihrer Domain.
ssl_certificate/etc/ssl/certs/your-domain-fullchain.crt;
# Ersetzen Sie dies durch den tatsächlichen privaten Schlüssel Ihres Zertifikats.
ssl_certificate_key/etc/ssl/private/your-domain_private_key.key;
ssl_protocolsTLSv1.2TLSv1.3;
ssl_prefer_server_cipherson;
ssl_ciphers"ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384";
location/ {
# Anfragenbegrenzung anwenden
limit_reqzone=api_limitburst=10nodelay;
# Dies weist nginx an, Anfragen an Port 8080 des Docker-Containers weiterzuleiten.
proxy_passhttp://bomnipotent_server:8080;
proxy_set_headerHost $host;
# Die folgenden Zeilen stellen sicher,
# dass die BOMnipotent-Logs die IP des Absenders enthalten,
# anstelle der lokalen IP des Reverse-Proxys.
proxy_set_headerX-Real-IP $remote_addr;
proxy_set_headerX-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_headerX-Forwarded-Proto $scheme;
}
}
Sie möchten wahrscheinlich weitere “Server” Blöcke hinzufügen – warum sonst würden Sie sich für die Einrichtung eines Reverse-Proxy entscheiden?
.env
BOMnipotent-Server benötigt einige geschützte Informationen. Dazu gehören die Passwörter für die SQL Datenbank, für den geheimen OpenPGP Schlüssel, und für den SMTP Server.
Es empfiehlt sich, diese Passwörter in einer separaten .env-Datei zu speichern, anstatt direkt im compose.yaml.
Der Name der Datei muss “.env” lauten, ansonsten erkennt Docker sie nicht.
Falls Sie ein Versionierungssystem zum Speichern Ihres Setups verwenden, vergessen Sie nicht, “.env” zu Ihrer .gitignore oder analogen Ignore-Datei hinzuzufügen!
config.toml
BOMnipotent Server benötigt eine Konfigurationsdatei, die in einem anderen Abschnitt ausführlicher erläutert wird.
Der Name der Datei ist grundsätzlich beliebig, aber der einsatzbereite Docker-Container von BOMnipotent Server ist so eingerichtet, dass er nach “config.toml” sucht.
Eine minimale Konfiguration für einen BOMnipotent Server hinter einem Reverse-Proxy sieht so aus:
# Die db_url hat die Struktur [db_client]://[Benutzer]:[Passwort]@[Container]:[Port]/[db]# Beachten Sie, dass ${BOMNIPOTENT_DB_PW} auf eine Umgebungsvariable verweist.db_url = "postgres://bomnipotent_user:${BOMNIPOTENT_DB_PW}@bomnipotent_db:5432/bomnipotent_db"# Domain, hinter der der Bomnipotent-Server gehostet wirddomain = "https://bomnipotent.<Ihre-Domain>.<Top-Level>"# Optional, aber empfohlen[open_pgp]
# Der Pfad zu Ihrem öffentlichen OpenPGP Schlüsselpublic_key_path = "/etc/bomnipotent_server/configs/open_pgp_public_key.asc"# Der Pfad zu Ihrem geheimen OpenPGP Schlüsselsecret_key_path = "/etc/bomnipotent_server/configs/open_pgp_secret_key.asc"# Eine optionale Passphrase um auf ihren geheimen OpenPGP Schlüssel zuzugreifenpassphrase = "${PGP_PASSPHRASE}"[tls]
# Die TLS-Verschlüsselung erfolgt über den Reverse-Proxy,# der BOMnipotent-Server ist nicht direkt über das Internet erreichbar.allow_http = true[smtp]
# Der Nutzername für den Mail-Anbieter, üblicherweise Ihre Mail Adresseuser = "<you@yourdomain.com>"# Der SMTP Endpunkt Ihres Mail-Anbietersendpoint = "<your.smtp.host>"# Das Geheimnis um sich gegenüber dem Mail-Anbieter zu authentifizierenn, üblicherweise Ihr Passwortsecret = "${SMTP_SECRET}"# Herausgeberdaten gemäß dem unten verlinkten CSAF-Standard[provider_metadata.publisher]
name = "<Geben Sie den Namen Ihrer Organisation an>"# Namespace Ihrer Organisation in Form einer vollständigen URLnamespace = "https://<Ihre Domain>.<Top-Level>"# Dies ist höchstwahrscheinlich die gewünschte Kategoriecategory = "vendor"# Kontaktdaten sind optional und in freier Formcontact_details = "<Bei Sicherheitsfragen kontaktieren Sie uns bitte unter...>"
Füllen Sie die Klammern mit Ihren Daten aus.
Falls Sie es bevorzugen, eine lokal laufende SMTP Relay Station zu nutzen, schauen Sie sich die notwendigen Anpassungen der compose Datei an.
Die Herausgeberdaten werden verwendet, um dem OASIS CSAF-Standard zu entsprechen.
Es wird empfohlen, Ihre config.toml-Datei in einem dedizierten Verzeichnis zu speichern, in diesem Beispiel “bomnipotent_config”. Die Docker-Compose-Datei gewährt Lesezugriff auf diesen Ordner. Dieses Setup hat zwei Vorteile:
Im unwahrscheinlichen Fall einer Sicherheitsverletzung des BOMnipotent Server-Containers hätte ein Angreifer nur Zugriff auf Ihr Konfigurationsverzeichnis und sonst nichts auf Ihrem Server.
BOMnipotent Server überwacht das Verzeichnis auf Änderungen und versucht, die Konfigurationsdatei neu zu laden, wenn sie geändert wurde. Dies funktioniert nicht, wenn nur eine einzige Datei dem Docker-Container zugänglich gemacht wird.
Viele Konfigurationseinstellungen unterstützen Hot Reloading, d. h. sie können geändert werden, ohne den Server neu zu starten.
Nachdem Sie Ihre config.toml eingerichtet haben, möchten Sie sie möglicherweise beispielsweise als config.toml.default kopieren, um Ihre ursprüngliche Konfiguration schnell wiederherstellen zu können. Dies ist jedoch völlig optional.
open_pgp_*_key.asc
OpenPGP ist ein Standard zum Verschlüsseln und Signieren von Dateien und Nachrichten. Eine andere Seite dieser Dokumentation bietet einen Überblick sowie einen leichten Einstieg in das Thema.
Der geheime Schlüssel wird verwendet, um heruntergeladene BOMs und CSAF Dokumente zu signieren.
Falls Ihr geheimer Schlüssel durch eine Passphrase geschützt ist, müssen Sie diese in der .env Datei angeben und in der config.toml verwenden. Andernfalls können Sie das Argument weglassen.
Der öffentliche Schlüssel wird von den Verwendern Ihres Servers benötigt, um die Signatur zu überprüfen. Er ist deswegen unter der URL “<Ihre-Domain>/openpgp-key.asc” zu finden.
BOMnipotent Server bemerkt, falls Sie aus Versehen öffentlichen und geheimen Schlüssel vertauschen, oder falls diese nicht zusammenpassen.
Nur falls Sie beide Schlüsseldateien in der config.toml angeben darf BOMnipotent Server sie als csaf_trusted_provider ausweisen.
compose.yaml
In der Compose-Datei geben Sie das Container-Setup an. Sobald es reibungslos läuft, muss es nicht mehr so oft geändert werden, aber wenn Sie Docker noch nicht kennen, kann es einige Zeit dauern, bis Sie es verstanden haben.
Die Datei muss “compose.yaml” heißen, da kann Docker etwas pingelig sein.
Eine vollständig einsatzbereite Compose-Datei sieht so aus:
# Die Namensgebung für das Setup ist optional, andernfalls wird der Name von Docker hergeleitet.name: bomnipotent_server_containers# Die Docker-Container müssen kommunizieren und benötigen dafür ein Netzwerk.networks:
# Dieses Netzwerk benötigt eine Referenz.bomnipotent_network:
# Da sich die Container auf demselben Docker-Host befinden, ist "bridge" eine sinnvolle Treiberwahl.driver: bridge# Es ist zulässig, dem Netzwerk denselben Namen wie der Referenz zu geben.name: bomnipotent_network# Der Reverse-Proxy muss mit dem BOMnipotent-Server kommunizieren, nicht jedoch mit der Datenbank.proxy_network:
driver: bridgename: proxy_networkvolumes:
# Definieren Sie das Volume für die persistente Speicherung der Datenbank.bomnipotent_data:
driver: local# Der Server selbst benötigt ebenfalls Persistenz, wenn das Abonnement nicht nach jedem Neustart aktiviert werden soll.bomnipotent_subscription:
driver: localservices:
reverse_proxy:
# Name des Reverse-Proxy-Containerscontainer_name: reverse_proxydeploy:
resources:
limits:
# Begrenzen Sie die CPU-Auslastung auf 0,5 Kerne.cpus: "0.5"# Begrenzen Sie die Speichernutzung auf 512 MB.memory: "512M"healthcheck:
# Prüfen Sie, ob Nginx läuft und die Konfiguration analysieren kann.test: ["CMD-SHELL", "nginx -t || exit 1"]
# Intervall zwischen Integritätsprüfungeninterval: 60s# Timeout für jede Integritätsprüfungtimeout: 10s# Anzahl der Wiederholungsversuche, bevor der Container als fehlerhaft eingestuft wirdretries: 3# Startzeitraum vor der ersten Integritätsprüfungstart_period: 60simage: nginx:latestlogging:
# Lokalen Protokolltreiber verwendendriver: localoptions:
# Protokollgröße auf 10 MB begrenzenmax-size: "10m"# Maximal 3 Protokolldateien speichernmax-file: "3"networks:
# Mit dem angegebenen Netzwerk verbinden - proxy_networkports:
# Port 443 des Containers freigeben# Dies ermöglicht eine verschlüsselte Verbindung über das Internet - "443:443"# Container neu starten, falls er aus einem anderen Grund als einem Benutzerbefehl gestoppt wurderestart: on-failurevolumes:
# Bind-Mount des SSL-Verzeichnisses, damit nginx das TLS-Zertifikat und den Schlüssel findet. - type: bindsource: /etc/ssltarget: /etc/sslread_only: true# Bind-Mount des Konfigurationsordners auf dem Host - type: bindsource: ./proxy_config/conf.dtarget: /etc/nginx/conf.dread_only: truebomnipotent_db:
# Name des Datenbankcontainerscontainer_name: bomnipotent_dbdeploy:
resources:
limits:
# CPU-Auslastung auf 0,5 Kerne begrenzencpus: "0.5"# Speichernutzung auf 512 MB begrenzenmemory: "512M"environment:
# Datenbanknamen festlegenPOSTGRES_DB: bomnipotent_db# Datenbankbenutzer festlegenPOSTGRES_USER: bomnipotent_user# Datenbankpasswort aus der Variable der .env-Datei festlegenPOSTGRES_PASSWORD: ${BOMNIPOTENT_DB_PW}healthcheck:
# Prüfen, ob die Datenbank bereit isttest: ["CMD-SHELL", "pg_isready -U bomnipotent_user -d bomnipotent_db"]
# Intervall zwischen Integritätsprüfungeninterval: 60s# Timeout für jede Integritätsprüfungtimeout: 10s# Anzahl der Wiederholungsversuche, bevor der Container als fehlerhaft eingestuft wirdretries: 5# Startzeitraum vor der ersten Integritätsprüfungstart_period: 10s# Das angegebene PostgreSQL-Image verwenden# Sie können den Container-Tag nach Belieben anpassenimage: postgres:17logging:
# Lokalen Logging-Treiber verwendendriver: localoptions:
# Log-Größe auf 10 MB begrenzenmax-size: "10m"# Maximal 3 Log-Dateien speichernmax-file: "3"networks:
# Mit dem angegebenen Netzwerk verbinden - bomnipotent_network# Container neu starten, wenn er aus einem anderen Grund als einem Benutzerbefehl gestoppt wurde.restart: alwaysvolumes:
# Volume für persistente Datenspeicherung mounten - bomnipotent_data:/var/lib/postgresql/databomnipotent_server:
# Name des Server-Containerscontainer_name: bomnipotent_serverdepends_on:
# Sicherstellen, dass der Datenbankdienst fehlerfrei ist, bevor der Server gestartet wird.bomnipotent_db:
condition: service_healthydeploy:
resources:
limits:
# CPU-Auslastung auf 0,5 Kerne begrenzen.cpus: "0.5"# Speichernutzung auf 512 MB begrenzen.memory: "512M"environment:
# Datenbankpasswort an den Server weitergeben.BOMNIPOTENT_DB_PW: ${BOMNIPOTENT_DB_PW}# Geben Sie das SMTP Geheimnis an den Server weiter.SMTP_SECRET: ${SMTP_SECRET}healthcheck:
# Servergesundheit überprüfentest: ["CMD-SHELL", "curl --fail http://localhost:8080/health || exit 1"]
# Intervall zwischen Integritätsprüfungeninterval: 60s# Timeout für jede Integritätsprüfungtimeout: 10s# Anzahl der Wiederholungsversuche, bevor der Container als fehlerhaft eingestuft wirdretries: 5# Startzeitraum vor der ersten Integritätsprüfungstart_period: 10s# Dies ist das offizielle Docker-Image, auf dem eine BOMnipotent-Serverinstanz ausgeführt wird.image: wwhsoft/bomnipotent_server:latestlogging:
# Verwenden Sie den lokalen Protokollierungstreiberdriver: localoptions:
# Begrenzen Sie die Protokollgröße auf 10 MBmax-size: "10m"# Bewahren Sie maximal 3 Protokolldateien aufmax-file: "3"networks:
# Verbindung zwischen Server und Reverse-Proxy. - proxy_network# Verbindung zwischen Server und Datenbank. - bomnipotent_network# Starten Sie den Container neu, wenn er aus einem anderen Grund als einem Benutzerbefehl angehalten wurderestart: alwaysvolumes:
# Mounten Sie den Konfigurationsordner auf dem Host per Bind - type: bindsource: ./bomnipotent_configtarget: /etc/bomnipotent_server/configs/read_only: true# Die Subscription darf gern in dem Container persisitert werden - bomnipotent_subscription:/root/.config/bomnipotent