Jenkins Credentials in AWS sicher ablegen

Wer einen Continuous Integration betreibt, kennt das Problem: viele der Builds benötigen Zugriff auf geschützte Ressource um ihre Arbeit zu erledigen. Beispielsweise müssen sie Quellcode aus einem nicht-öffentlichen Git-Repository laden, Docker-Instanzen für Integrationstests auf einer entfernten Maschine starten und die Ergebnisse des Builds in einem Repository für Binärdateien ablegen.

Jenkins als ein Vertreter einer Continuous Integration Plattform hat eine Verwaltung für die notwendigen Zugangsdaten eingebaut, den „Credentials Store“. Dort kann man zentral die Zugangsdaten hinterlegen, die man dann in den Builds referenziert. Damit vermeidet man, die Zugangsdaten in den Quellen der Builds einzubauen, was zum einen unsicher wäre und zum anderen zu starrer Kopplung führt — schließlich müsste man in dem Fall alle Daten in allen Builds anpassen, wenn sie sich ändern.

Zugangsdaten auf einen automatisch aufgesetzten Jenkins bringen

Richtig kompliziert wird es, wenn Jenkins vollautomatisch aufgesetzt werden soll. Was würde automatische Installation nützen, wenn man die Zugangsdaten von Hand in den Credentials Store eintragen muss?

Folgerichtig ist es notwendig, dass Jenkins die Zugangsdaten ebenfalls automatisch erhält und das auf sichere Weise.

Verschlüsselte Credentials, S3 und KMS

In unserem Setup stellen wir die Credentials in einem nicht-öffentlichen S3-Bucket für Jenkins bereit. Die Jenkins-Instanzen erhalten über AWS Rollen Zugriff. Damit im Falle einer Fehlkonfiguration kein Unheil passiert, sind die Credentials einzeln verschlüsselt. Das erledigt der Key Management Service (KMS).

Credentials auf Jenkins installieren
Credentials auf Jenkins installieren

In einem Satz zusammengefasst simuliert KMS ein Hardware-Security-Modul, also ein Verschlüsselungsgerät, das Ver- und Entschlüsselung als Dienst anbietet, dabei aber niemals die internen Schlüssel exponiert.

Ein Skript erledigt die Verschlüsselung der Credentials mit KMS und die anschließende Ablage im S3-Bucket. Ein weiteres läuft auf der Jenkins-Instanz und sorgt regelmäßig dafür, dass der Jenkins-Credential-Store mit den Credentials im S3-Bucket synchronisiert wird.

Die Crux mit der Kettenverschlüsselung

Egal wie oft man etwas verschlüsselt, irgendwann braucht man den Klartext. Wir können die Credentials ohne Probleme verschlüsselt lagern und verteilen, aber es kommt der Punkt, an dem Jenkins damit arbeiten muss.

KMS verhindert, dass auf der Jenkins-Instanz das Master-Passwort herumliegt. Um mit KMS zu sprechen muss man sich vorher authentifizieren. Und das ist der Punkt an dem die Kette endet. Die Jenkins-Instanz muss die Zugangsdaten zum Verschlüsselungsdienst kennen. Wer die Instanz übernimmt, kann daher mit den Rechten von Jenkins den Verschlüsselungsdienst nutzen. Sorgfalt im Umgang mit dem Zugang zu den Jenkins-Instanzen ist also trotzdem unabdingbar.

Key Management Dienst versus Vendor-Lock-In

KMS zu nutzen bedeutet auch ein Stück weit Vendor-Lock-In. Als Systemdesigner müssen wir uns daher schon bei der Entscheidung für KMS überlegen, wie wir die Lösung portabel halten und wo unsere Schnittstellen sind.

In unserem Beispiel würde Portierung in den zwei Skripten passieren. Statt S3 könnte dort schlicht ein anderer Objekt-Store, ein entferntes Dateisystem oder einfach ein Zugriff auf einen HTTP-Server stehen.

Auch KMS lässt sich in den Skripten ersetzen, zum Beispiel durch Hashicorp’s Vault.

Die Credentials selbst sind XML Dateien, die exakt so aussehen, wie Jenkins sie als Eingabeformat für seine HTTP-API erwartet. Hier fällt kein Portierungsaufwand an.

Kommentar schreiben

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.