· Kubernetes  · 9 Min. Lesezeit

Die eigene Registry mit Harbor: scannen, cachen, absichern

Harbor speichert Container-Images nicht nur, es scannt sie mit Trivy und spiegelt fremde Registries als Proxy-Cache. Der Scanner ist dabei nicht im Standard-Setup enthalten, und die Sperre für verwundbare Images greift beim Pull statt beim Push. Aufbau mit Prüfbefehlen und die dokumentierten Fallen.

Harbor speichert Container-Images nicht nur, es scannt sie mit Trivy und spiegelt fremde Registries als Proxy-Cache. Der Scanner ist dabei nicht im Standard-Setup enthalten, und die Sperre für verwundbare Images greift beim Pull statt beim Push. Aufbau mit Prüfbefehlen und die dokumentierten Fallen.

Eine eigene Container-Registry gilt schnell als bloßer Bilderspeicher. Harbor ist mehr, aber nicht automatisch mehr. Die Funktionen, wegen derer Harbor überhaupt gewählt wird, sind fast alle Schalter, die jemand bewusst umlegen muss. Wer das nicht weiß, betreibt eine Registry mit Sicherheitsversprechen im Datenblatt und ohne Wirkung im Betrieb.

Dieser Beitrag geht den Aufbau in der Reihenfolge durch, in der die Bausteine greifen: Voraussetzungen, Konfiguration, Installation mit Scanner, Scan-on-push, Proxy-Cache und Zugriffskonten. Nach jedem Schritt steht ein Prüfbefehl.

Wann Harbor die richtige Wahl ist

Harbor ist ein eigener Betrieb. Die Registry bringt PostgreSQL, Redis, einen Jobservice und einen vorgelagerten nginx mit, bei aktivem Scanning dazu den Trivy-Adapter mit laufend zu aktualisierender Schwachstellendatenbank. Der Aufwand rechnet sich, wenn einer dieser drei Punkte zutrifft:

  • Sie betreiben mehrere Cluster oder Standorte, die dieselben Images ziehen, und wollen den Weg nach draußen an einer Stelle bündeln.
  • Sie arbeiten in einem abgeschotteten Netz ohne freien Ausgang zu docker.io oder ghcr.io.
  • Sie müssen nachweisen können, welches Artefakt wann mit welchem Befund in die Umgebung gelangt ist.

Für einen einzelnen kleinen Cluster ohne diese Anforderungen ist die öffentliche Registry plus ein Scan im Cluster einfacher und ausreichend. Ich halte dabei den Proxy-Cache für den betrieblich wertvolleren Teil von Harbor, nicht das Scanning. Ein Scanner lässt sich auch anderswo betreiben, ein kontrollierter gecachter Ausgang nach draußen nicht.

Die drei Installationswege im Vergleich

VarianteVoraussetzungBelegte Eigenheit
sudo ./install.shDocker Engine > 20.10, Compose > 2.3Reine Registry. Ohne weiteres Flag wird kein Scanner ausgerollt.
sudo ./install.sh --with-trivywie obenRollt die Scanning-Fähigkeit mit aus. Der Weg, wenn Sie Scan-on-push nutzen wollen.
Helm-Chart harbor/harborKubernetes 1.20+, Helm v3.2.0+Die Chart-Version hinkt hinterher. Chart 1.18 liefert Harbor v2.14, Chart 1.17 die v2.13. Der master-Branch ist nicht für den Einsatz gedacht.

Die folgenden Schritte beschreiben den Compose-Weg über install.sh, weil dort alle Schalter an einer Stelle sichtbar sind. Aktueller Stand ist v2.15.2 vom 2026-07-02. Mit v2.15.0 wurde die Bezeichnung “pull-through cache” durch “proxy cache” ersetzt, beide Begriffe meinen dasselbe.

Schritt 1: Voraussetzungen prüfen

Die Dokumentation nennt als Mindestausstattung 2 CPU, 4 GB RAM und 40 GB Disk, empfohlen sind 4 CPU, 8 GB RAM und 160 GB Disk. Die vollständige Liste steht in den Installationsvoraussetzungen.

docker version --format '{{.Server.Version}}' && docker compose version && nproc && free -g && df -h /data

Prüfung: Die Docker-Version muss über 20.10 liegen, die Compose-Version über 2.3. Bleiben Sie unter den Mindestwerten, gehen Sie nicht weiter.

Schritt 2: harbor.yml aus der Vorlage ableiten

Die Konfiguration entsteht mit cp harbor.yml.tmpl harbor.yml. Die Standardwerte der Vorlage sind Platzhalter und gehören alle angefasst, darunter hostname: reg.mydomain.com und harbor_admin_password: Harbor12345. Für eine Instanz unter harbor.lab.rz.jabi-it.de:

hostname: harbor.lab.rz.jabi-it.de
https:
  port: 443
  certificate: /etc/harbor/tls/harbor.lab.rz.jabi-it.de.crt
  private_key: /etc/harbor/tls/harbor.lab.rz.jabi-it.de.key
harbor_admin_password: <eigenes-passwort>
data_volume: /data

Harbor liefert keine Zertifikate mit. Wer die https-Sektion auskommentiert lässt und über HTTP fährt, muss auf jedem Docker-Client die Registry als unsicher eintragen, sonst schlagen Login und Pull fehl.

Die Trivy-Sektion derselben Datei steuert den Scanner. Drei Schalter sind planungsrelevant: ignore_unfixed blendet auf true alles aus, wofür es keinen Fix gibt, Standard ist false. security_check nimmt eine Liste aus vuln, config und secret, Standard ist vuln. Und skip_update auf true heißt, dass Sie die Schwachstellendatenbank selbst bereitstellen.

Prüfung:

grep -E '^(hostname|data_volume)|^\s+(port|certificate|private_key|db_repository):' harbor.yml

Es darf kein Platzhalter mehr auftauchen, weder reg.mydomain.com noch /your/certificate/path.

Schritt 3: Mit Scanner installieren

Das Schwachstellen-Scanning ist nicht Bestandteil des Standard-Setups. Ohne das Flag wird der Scanner-Container nicht ausgerollt, und Harbor läuft als reine Registry. Der Installer-Doku zufolge lautet der richtige Aufruf sudo ./install.sh --with-trivy.

Prüfung:

sudo docker compose ps && sudo docker compose ps | grep trivy

Alle Container müssen ein Up zeigen, darunter harbor-core, harbor-db, harbor-jobservice, nginx, registry und redis. Bleibt die zweite Ausgabe leer, wurde ohne das Flag installiert. Die Logs liegen unter /var/log/harbor/.

Schritt 4: Projekt anlegen und den Scan scharf schalten

Scan-on-push ist keine globale Automatik, sondern eine Einstellung je Projekt. Legen Sie das Projekt an und setzen Sie unter Configuration die Checkbox Automatically scan images on push. Das gilt für jedes Projekt einzeln, auch für jedes neu angelegte.

Im selben Dialog sitzt Prevent vulnerable images from running. Die Wirkung steht in der Projektkonfiguration: Images können nicht mehr gezogen werden, wenn ihre Einstufung gleich oder höher als die gewählte Schwere ist. Es ist eine Pull-Sperre, keine Push-Sperre. Die Stufe negligible blockiert Harbor grundsätzlich nie.

Prüfung:

curl -u "admin:<pass>" -k https://harbor.lab.rz.jabi-it.de/api/v2.0/projects/produktion

Im Feld metadata muss auto_scan auf "true" stehen. Steht es dort nicht, ist die Checkbox nicht gesetzt, unabhängig davon, was die Oberfläche anzeigt. Einen ersten Scan über den Bestand lösen Sie unter Interrogation Services über Scan Now aus. Die Dokumentation benennt den Vorgang als ressourcenintensiv.

Schritt 5: Proxy-Cache einrichten

Der Proxy-Cache braucht zwei Objekte, und die Reihenfolge ist nicht beliebig. Zuerst entsteht der Registry-Endpoint unter Administration, Registries. Als Ziel unterstützt Harbor laut Dokumentation unter anderem Harbor selbst, Docker Hub, AWS ECR, Quay, GitHub Container Registry und JFrog Artifactory. Hinterlegen Sie dort ein Zugangskonto mit möglichst engen Rechten. Der Grund steht unten unter Stolperstein 2 und ist der sicherheitsrelevanteste Punkt des Aufbaus.

curl -u "admin:<pass>" -k https://harbor.lab.rz.jabi-it.de/api/v2.0/registries

Der Endpoint muss in dieser Liste erscheinen. Erst danach legen Sie über New Project ein Projekt an, aktivieren Proxy Cache, wählen den Endpoint und setzen ein Bandbreitenlimit, wobei -1 für unbegrenzt steht. Den Ablauf beschreibt die Doku zum Proxy-Cache.

Beim ersten Pull holt Harbor das Image vom Ziel, liefert es aus und legt es lokal ab. Bei späteren Pulls prüft Harbor das Manifest der Zielregistry und liefert bei Gleichstand aus dem Cache. Ist die Zielregistry nicht erreichbar, gibt Harbor die gecachte Kopie heraus, was den Proxy-Cache in gestörten Netzen wertvoll macht. Zwei Einschränkungen gehören eingeplant: Es kann nicht gepusht werden, und Harbor legt automatisch eine Aufbewahrungsregel von sieben Tagen an.

Prüfung: Der Pull über den Proxy-Pfad muss gelingen, der Push über denselben Pfad muss scheitern. Gelingt der zweite Teil, haben Sie kein Proxy-Cache-Projekt vor sich.

docker pull harbor.lab.rz.jabi-it.de/dockerhub-proxy/goharbor/harbor-core:dev && docker push harbor.lab.rz.jabi-it.de/dockerhub-proxy/test:1

Schritt 6: Robot-Accounts für Pipeline und Cluster

Persönliche Logins gehören nicht in eine Pipeline. Harbor kennt dafür Robot-Accounts auf System- und auf Projektebene. Ab v2.12.0 tragen beide Arten sämtliche Berechtigungen, mit Ausnahmen im Konfigurationsbereich. Einen System-Robot legen Sie über Administration, Robot Accounts, New Robot Account an. Drei Eigenschaften entscheiden über Erfolg oder späteren Ausfall:

  • Das Secret wird von Harbor nicht gespeichert und ist nach dem Anlegen nicht wieder abrufbar. Sichern Sie es sofort.
  • Beim Login zählt nur der vollständige Name aus Präfix und Kontoname. Der Standardpräfix ist robot$, aus einem System-Robot namens ci wird damit robot$ci. Der Präfix ist änderbar und wirkt dann auf alle bestehenden und künftigen System- und Projekt-Robots, ausgenommen Konten aus Harbor v2.1 und älter, die bei robot$ bleiben.
  • Die Standardablaufzeit beträgt 30 Tage. Administratoren ändern den Wert unter System Settings als Robot Token Expiration (Days), einzelne Konten lassen sich auf Never Expired setzen.

Prüfung:

echo -n "<secret>" | docker login harbor.lab.rz.jabi-it.de -u 'robot$ci' --password-stdin

Die Ausgabe muss Login Succeeded lauten. Die einfachen Anführungszeichen sind nicht optional, sonst frisst die Shell das Dollarzeichen. Für den Cluster erzeugen Sie daraus ein Pull-Secret per kubectl create secret docker-registry, geprüft mit --dry-run=client -o yaml.

Die drei folgenreichsten Stolpersteine

1. Die Blockade verwundbarer Images wirkt scheinbar nicht

Symptom: Trotz aktivierter Blockade landen verwundbare Images weiterhin in der Registry.

Ursache: Die Option blockiert den Pull, nicht den Push. Das Image wird gespeichert, nur die Herausgabe wird verweigert.

Prüfung: Ein bewusst verwundbares Image hochladen, dann den Pull versuchen. Der Push gelingt, der Pull muss abgewiesen werden.

docker push harbor.lab.rz.jabi-it.de/produktion/testimage:1 && docker pull harbor.lab.rz.jabi-it.de/produktion/testimage:1

Lösung: Wer den Push verhindern will, braucht eine vorgelagerte Prüfung in der Pipeline. Harbor ist hier die letzte Instanz vor der Auslieferung, nicht die erste vor der Ablage.

2. Das Proxy-Cache-Projekt vererbt die Reichweite des Upstream-Kontos

Symptom: Über das Proxy-Cache-Projekt lassen sich private Images der Zielregistry ziehen, die dort eigentlich geschützt sind.

Ursache: Ein Proxy-Cache-Projekt kann jedes Image der Zielregistry ziehen, auf das das im Endpoint hinterlegte Zugangskonto Zugriff hat. Damit steht allen Nutzern des Proxy-Projekts jedes Image offen, das dem Upstream-Konto offensteht.

Prüfung: Mit einem gewöhnlichen Projektmitglied ein privates Upstream-Image ziehen, das dieses Mitglied nicht sehen dürfte. Gelingt der Pull, ist das Upstream-Konto zu breit berechtigt.

Lösung: Für die Zielregistry ein Konto mit minimalen Rechten anlegen, ausschließlich dieses im Endpoint hinterlegen und den Zugriff auf das Proxy-Projekt eng halten.

3. Nach etwa einem Monat schlagen alle Pulls fehl

Symptom: Im Cluster erscheinen ImagePullBackOff, Pipeline-Logins scheitern, ohne dass etwas geändert wurde.

Ursache: Robot-Accounts laufen standardmäßig nach 30 Tagen ab.

Prüfung: curl -u "admin:<pass>" -k https://harbor.lab.rz.jabi-it.de/api/v2.0/robots und dort das Feld expires_at der betroffenen Konten.

Lösung: Die Ablaufzeit bewusst setzen. Entweder Never Expired für Systemkonten oder den globalen Wert Robot Token Expiration (Days) anpassen und die Rotation einplanen.

Die vollständige Sammlung der Stolpersteine

Diese drei sind die folgenreichsten, aber nicht die einzigen. Der fehlende Scanner ohne --with-trivy, der Schwellwert, der negligible durchlässt, die Sieben-Tage-Regel im Proxy-Cache, der Trivy-Adapter im abgeschotteten Netz, TLS-Ketten, das Verhalten hinter einem Reverse-Proxy, der eingeschränkte Upgrade-Pfad und die Selbstsperre über CONFIG_OVERWRITE_JSON gehören ebenfalls dazu. Die vollständige Sammlung der Stolpersteine, jeder mit Symptom, Ursache, Prüfung und Lösung, steht im Beitrag Harbor: die Stolpersteine im Überblick. Gehen Sie sie einmal durch, bevor die erste Pipeline an Harbor hängt.

Grenzen

Signaturen werden nicht gescannt. Schwachstellenscans von Cosign-Signaturen werden nicht unterstützt. Signaturen prüfen Sie über die Cosign-Verifikation.

Ein Scanner ist eine Meinung. Die Dokumentation begründet den parallelen Betrieb mehrerer Scanner damit, dass unterschiedliche Scanner unterschiedliche Datenbanken nutzen, unterschiedliche CVE-Mengen erfassen und unterschiedliche Schwellwerte anlegen. Weitere Scanner binden Sie über Interrogation Services, New Scanner an.

Der Proxy-Cache ist für den Pull gedacht, nicht als Ablage. Kein Push, sieben Tage Standardaufbewahrung, und die Rechte des Upstream-Kontos wirken durch. Gegen Docker Hub setzen Sie mindestens v2.1.1 ein, denn ab dieser Version prüft Harbor die Aktualität per HEAD-Request, was nicht gegen das Rate-Limit zählt.

Der Upgrade-Pfad ist eng. Die aktuelle Anleitung deckt ausschließlich Migrationen ab v2.12.0 ab. Ein sehr alter Bestand wird zu einer Kette von Zwischenschritten, jeder mit eigenem Backup.

Der ehrliche Schluss lautet damit: Harbor ist kein Sicherheitsprodukt, das man einschaltet. Es ist eine Registry mit scharfen Werkzeugen, die einzeln aktiviert, konfiguriert und geprüft werden müssen. Wer die Installation abschließt und annimmt, damit sei die Lieferkette abgesichert, hat vor allem eine Registry mehr im Betrieb.

Sie wollen kontrollieren, welche Images in Ihre Systeme gelangen, und sie vorab prüfen? Ich baue Registry- und Scanning-Setups, die Sicherheit an die Quelle holen, passend zur Größe Ihrer Umgebung. Mehr unter Infrastruktur & Cloud, das Erstgespräch ist unverbindlich.

Alex Jabi, Jabi IT

Alex Jabi

Ich betreue IT, Informationssicherheit und Datenschutz für KMU und Praxen an der Bergstraße und im Odenwald, persönlich, dokumentiert und ohne Cloud-Zwang.

Mehr über mich
Zurück zum Blog

Passende Artikel

Alle Artikel »
Harbor: die Stolpersteine im Überblick

Harbor: die Stolpersteine im Überblick

Die vollständige Fallsammlung zum Betrieb von Harbor: fehlender Scanner, Scan-on-push je Projekt, der Schwellwert, der negligible durchlässt, geerbte Upstream-Rechte im Proxy-Cache, ablaufende Robot-Accounts, TLS-Ketten, Reverse-Proxy-Header und die Selbstsperre über CONFIG_OVERWRITE_JSON. Jeder Fall mit Symptom, Ursache, Prüfung und Lösung.

Wissen, welche Lücken laufen: Schwachstellen-Scanning mit Trivy

Wissen, welche Lücken laufen: Schwachstellen-Scanning mit Trivy

Der Trivy-Operator scannt die tatsächlich laufenden Workloads und legt das Ergebnis als Kubernetes-Ressource ab. Installation per Helm, Umstellung vom Standalone- auf den ClientServer-Modus, Spiegeln der Schwachstellen-Datenbank in die eigene Registry und die Fallen, die die Dokumentation dabei ausdrücklich benennt.

Trivy auf Kubernetes: die vollständige Stolperstein-Sammlung

Trivy auf Kubernetes: die vollständige Stolperstein-Sammlung

Vierzehn dokumentierte Fallen beim Betrieb des Trivy-Operators, jede nach dem Schema Symptom, Ursache, Prüfung und Lösung. Von der Ratenbegrenzung beim Datenbank-Download über die gespiegelte Registry und den Supply-Chain-Vorfall vom März 2026 bis zu CRD-Änderungen beim Upgrade.

Wenn der einzige Zugang die Rancher-Shell ist

Wenn der einzige Zugang die Rancher-Shell ist

Kein kubeconfig, kein kubectl von außen, nur die Kubectl-Shell im Browser. Wie man darin sauber arbeitet: Rechte feststellen, Manifeste ohne Datei-Upload anlegen, vor dem Schreiben prüfen und Ergebnisse einsammeln, ohne interaktiv im Cluster herumzustochern.