Best Practices für die sichere Verwaltung von Jenkins-Anmeldeinformationen
Jenkins dient als zentrales Nervensystem für Continuous Integration und Continuous Deployment (CI/CD) und benötigt oft Zugriff auf hochsensible Ressourcen, einschließlich Produktionsdatenbanken, Cloud-APIs, Artefakt-Repositories und sichere Infrastrukturen. Die ordnungsgemäße Verwaltung der für diese Operationen benötigten Geheimnisse – Passwörter, API-Schlüssel und private SSH-Schlüssel – ist entscheidend für die Aufrechterhaltung der Sicherheit und Integrität Ihrer Deployment-Pipeline.
Ein schlechtes Management von Anmeldeinformationen, wie das Hardcodieren von Geheimnissen direkt in Pipeline-Skripte oder deren Speicherung im Klartext, stellt eine erhebliche Sicherheitslücke dar. Dieser Leitfaden beschreibt wesentliche Strategien und architektonische Best Practices für die Nutzung des integrierten Jenkins Credentials Plugin und die Integration fortgeschrittener Sicherheitskontrollen, um sicherzustellen, dass Ihre sensiblen Daten geschützt bleiben.
Die Grundlage: Das Jenkins Credentials Plugin
Das Credentials Plugin ist der Standardmechanismus, den Jenkins zur Speicherung sensibler Daten verwendet. Es bietet ein zentralisiertes, verschlüsseltes Repository für Anmeldeinformationen und stellt sicher, dass Geheimnisse niemals in Build-Logs, der Quellcodeverwaltung oder Konfigurationsdateien offengelegt werden.
Wenn Jenkins Anmeldeinformationen speichert, werden diese mit der Java Cryptography Extension (JCE) verschlüsselt. Diese Verschlüsselung ist an eine einzigartige master.key-Datei gebunden, die auf dem Jenkins-Controller gespeichert ist. Diese Architektur bedeutet, dass der Zugriff auf das Dateisystem des Controllers streng kontrolliert werden muss.
Wichtige Anmeldeinformationstypen
Das Verständnis der verfügbaren Anmeldeinformationstypen ist der erste Schritt zu einer sicheren Implementierung. Wählen Sie den Typ, der am genauesten dem zu speichernden Geheimnis entspricht:
- Geheimer Text (Secret Text): Wird für generische, kurze Textwerte wie API-Token, Zugriffsschlüssel, OAuth-Token oder Webhook-Geheimnisse verwendet.
- Benutzername und Passwort (Username and Password): Standardpaarung, die zur Authentifizierung gegenüber Diensten wie Maven-Repositories, privaten Registries (Docker Hub, Artifactory) oder internen Anwendungen verwendet wird.
- SSH-Benutzername mit privatem Schlüssel (SSH Username with Private Key): Unerlässlich für den Zugriff auf Remote-Agents, das Klonen privater Git-Repositories oder die Ausführung von Befehlen auf Remote-Infrastrukturen. Der private Schlüssel kann direkt eingegeben, als Pfad bereitgestellt oder vom Jenkins-Controller verwaltet werden.
- Geheime Datei (Secret File): Wird zum Hochladen ganzer sensibler Dateien verwendet, z. B. Keystores, Zertifikate (
.pem,.crt) oder Konfigurationsdateien, die Geheimnisse enthalten.
Tipp: Verwenden Sie immer den granularsten Anmeldeinformationstyp. Wenn Sie beispielsweise nur einen API-Schlüssel benötigen, verwenden Sie Geheimer Text (Secret Text), anstatt ihn in ein Benutzername-und-Passwort-Feld einzufügen.
Prinzip der geringsten Rechte: Anmeldeinformationen eingrenzen
Der Geltungsbereich von Anmeldeinformationen bestimmt, wo diese innerhalb der Jenkins-Umgebung zugänglich sind. Die Anwendung des Prinzips der geringsten Rechte – also nur den für die Aufgabe notwendigen Zugriff zu gewähren – ist entscheidend.
1. System-Geltungsbereich
Anmeldeinformationen mit System-Geltungsbereich (gespeichert unter Jenkins verwalten > Anmeldeinformationen verwalten > Jenkins) sind global für alle Jobs, Ordner und Pipelines auf der Jenkins-Instanz verfügbar.
- Verwendung: Verwenden Sie den System-Geltungsbereich nur für Geheimnisse, die für den gesamten Jenkins-Betrieb erforderlich sind, wie z. B. Anmeldeinformationen, die von globalen Konfigurations-Plugins oder Geheimnisse, die für alle Agentenverbindungen benötigt werden.
- Warnung: Minimieren Sie die Nutzung des System-Geltungsbereichs. Jeder kompromittierte Job könnte potenziell auf alle global verfügbaren Geheimnisse zugreifen.
2. Ordner-Geltungsbereich
Anmeldeinformationen mit Ordner-Geltungsbereich werden innerhalb eines bestimmten Ordners definiert (erstellt mit dem Folder-Plugin oder über Organisationsordner). Diese Geheimnisse sind nur für Jobs sichtbar und nutzbar, die sich innerhalb dieses Ordners und seiner Unterordner befinden.
- Empfehlung: Bevorzugen Sie immer den Ordner-Geltungsbereich. Dies schottet den Zugriff ab und begrenzt den Schadensbereich, falls ein Projekt kompromittiert wird.
Sichere Injektion in deklarative Pipelines
Das Hardcodieren von Anmeldeinformationen in Pipeline-Skripten oder die Verwendung von Standard-Umgebungsvariablen ist strengstens verboten, da Umgebungsvariablen leicht in Logs oder Shell-Befehlen offengelegt werden können.
Die sichere Methode für den Zugriff auf Anmeldeinformationen in einer deklarativen Pipeline ist die Verwendung des integrierten withCredentials-Schritts. Dieser Schritt lädt die angegebenen Anmeldeinformationen in eine umgrenzte Umgebungsvariable, die nur während der Ausführung des Blocks verfügbar ist.
Beispiel 1: Injizieren von geheimem Text (API-Token)
Dieses Beispiel ruft sicher eine geheime Text-Anmeldeinformation (MY_API_TOKEN) ab und weist ihren Wert der internen Variable SECRET_TOKEN zu. Sobald der withCredentials-Block abgeschlossen ist, wird SECRET_TOKEN automatisch aus der Umgebung entfernt.
pipeline {
agent any
stages {
stage('Deploy via API') {
steps {
script {
withCredentials([string(credentialsId: 'MY_API_TOKEN', variable: 'SECRET_TOKEN')]) {
// Die sicher injizierte Variable verwenden
sh "echo 'Calling external API...'"
sh "curl -X POST -H 'Authorization: Bearer ${SECRET_TOKEN}' https://api.mycorp.com/deploy"
}
// Variable ist außerhalb dieses Blocks nicht verfügbar
sh 'echo "Attempting to access token: ${SECRET_TOKEN}"'
// ^ Dies wird null oder den vorherigen Umgebungswert ausgeben (Schutz vor versehentlicher Offenlegung)
}
}
}
}
}
Beispiel 2: Injizieren von Benutzername und Passwort
Bei der Verwendung von Benutzername-und-Passwort-Anmeldeinformationen teilt der withCredentials-Schritt das Geheimnis in zwei Variablen auf: eine für den Benutzernamen und eine für das Passwort, typischerweise mit den Suffixen _USR und _PSW (oder benutzerdefinierten Namen).
pipeline {
agent any
stages {
stage('Login to Registry') {
steps {
withCredentials([usernamePassword(credentialsId: 'DOCKER_REGISTRY_CRED', usernameVariable: 'DOCKER_USER', passwordVariable: 'DOCKER_PASS')]) {
sh "docker login -u ${DOCKER_USER} -p ${DOCKER_PASS} my.registry.com"
}
}
}
}
}
Sicherheitswarnung: Log-Unterdrückung
Jenkins versucht automatisch, Anmeldeinformationswerte aus Standard-Build-Logs zu unterdrücken. Dies basiert jedoch auf einfachem String-Matching. Verwenden Sie niemals
echo, um den Wert der Anmeldeinformationsvariablen auszugeben. Wenn das Debugging das Wissen um den Variableninhalt erfordert, stellen Sie sicher, dass Sie die durch denwithCredentials-Schritt bereitgestellte redigierte Form verwenden, und löschen Sie die Debug-Ausgabe sofort nach Behebung des Problems.
Erweiterte Sicherheitsintegration
Für Hochsicherheitsumgebungen ist es oft nicht ausreichend, sich ausschließlich auf den lokalen Jenkins-Master-Schlüssel zu verlassen. Die Integration mit einem externen Geheimnisverwaltungssystem bietet eine Trennung der Verantwortlichkeiten, zentralisierte Auditierung und verbesserte Verschlüsselungsfunktionen.
Externe Anmeldeinformationsspeicher
Beliebte Integrationen umfassen:
- HashiCorp Vault: Mit dem Vault Plugin kann Jenkins zur Laufzeit dynamisch Geheimnisse von Vault anfordern. Das bedeutet, dass die Geheimnisse niemals dauerhaft auf dem Jenkins-Controller gespeichert werden, sondern nur temporär im Speicher während der Ausführungsphase.
- AWS Secrets Manager/Azure Key Vault: Cloud-native Plugins ermöglichen Pipelines, Geheimnisse direkt von diesen Diensten unter Verwendung von IAM-Rollen oder Service-Principals abzurufen, wodurch die Offenlegung statischer Anmeldeinformationen minimiert wird.
Die Verwendung externer Speicher entspricht den Best Practices für Sicherheit durch:
- Trennung der Speicherung: Die Geheimnisinfrastruktur ist vom CI/CD-Server entkoppelt.
- Dynamischer Zugriff: Geheimnisse können häufig rotiert werden, ohne manuelle Jenkins-Konfigurationsaktualisierungen zu erfordern.
- Verbesserte Auditierung: Alle Zugriffsversuche auf Geheimnisse werden im externen Vault-System protokolliert.
Rollenbasierte Zugriffskontrolle (RBAC)
Die Implementierung eines RBAC-Plugins (wie der Role-based Authorization Strategy) ermöglicht es Administratoren, nicht nur zu kontrollieren, wer einen Job ausführen, sondern auch, wer spezifische Anmeldeinformationen konfigurieren und anzeigen darf.
- Definieren Sie Rollen, die die Berechtigung zur Verwendung von Anmeldeinformationen erteilen (z. B.
Job.UseCredentials). - Beschränken Sie die Möglichkeit, System-Anmeldeinformationen zu ändern oder zu erstellen, auf eine kleine Gruppe von Sicherheits- oder Plattformadministratoren.
Zusammenfassung der Best Practices für die Verwaltung von Anmeldeinformationen
| Praxis | Beschreibung | Sicherheitsvorteil |
|---|---|---|
| Ordner-Geltungsbereich verwenden | Begrenzen Sie den Zugriff auf Anmeldeinformationen auf die spezifischen Jobs/Ordner, die diese benötigen. | Begrenzt Offenlegung und Schadensradius. |
| Hardcodierung vermeiden | Platzieren Sie niemals Geheimnisse in Jenkinsfile, Build-Skripten oder der Quellcodeverwaltung. |
Eliminiert Quellcode-Schwachstellen. |
withCredentials verwenden |
Injizieren Sie Geheimnisse sicher in Pipeline-Schritte mit der offiziellen Jenkins-API. | Gewährleistet automatische Log-Redaktion und Umgebungsbereinigung. |
| Externen Vault integrieren | Verwenden Sie Vault, AWS Secrets Manager oder Azure Key Vault für Unternehmens-Deployments. | Entkoppelt die Speicherung und ermöglicht dynamische Rotation. |
| RBAC anwenden | Verwenden Sie Autorisierungs-Plugins, um einzuschränken, wer Anmeldeinformationen konfigurieren, anzeigen und verwenden kann. | Erzwingt das Prinzip der geringsten Rechte unter Benutzern. |
| Regelmäßige Rotation | Rotieren Sie API-Schlüssel und Passwörter regelmäßig (idealerweise automatisiert über einen externen Vault). | Minimiert das Zeitfenster für die Ausnutzung kompromittierter Geheimnisse. |
| Controller sichern | Stellen Sie strenge Dateisystemberechtigungen auf dem Jenkins-Controller sicher, um master.key zu schützen. |
Schützt den Kern-Verschlüsselungsmechanismus. |
Durch die Befolgung dieser Best Practices verwandeln Sie Jenkins von einer potenziellen Sicherheitslücke in eine robuste, sichere Automatisierungs-Engine, die sicherstellt, dass sensible Daten während des gesamten CI/CD-Lebenszyklus verantwortungsvoll gehandhabt werden.