In unserem Lab-Projekt zeigen wir auf, wie sich die Sicherheit von Sourcecode mit einfachsten Mitteln und Open Source Tools erhöhen lässt. Wir erläutern unser Vorgehen dabei Schritt für Schritt, sämtliche Ressourcen stehen als GitLab-Repository zur Verfügung.
Für unser Demo-Lab verwenden wir exemplarisch ein Sourcecode Management Tool sowie einen Sourcecode Scanner. Wir wählen in diesem Fall die Tools GitLab und SonarQube. GitLab ist in der Community Edition kostenfrei verfügbar und bringt von Haus aus nützliche Funktionalitäten wie z.B. Continuous Integration (CI) ein. Auf diese Weise kann eine YAML-Datei im eigenen Projektordner abgelegt werden.
SonarQube ist in der Community Edition ebenfalls ein frei verwendbares Tool und bietet eine große Diversität unterstützter Programmiersprachen.
Der Aufbau unserer Lab Umgebung ist dabei wie folgt:
Architekturdiagramm. Bildquelle: carmasec
Flussdiagramm. Bildquelle: carmasec
Der Scope
Dieses Lab legt den Fokus sehr stark auf die automatisierte Überprüfung der Sicherheit von Sourcecode. Zur Vereinfachung werden folgende Themen nicht berücksichtigt (siehe auch Architektur-Diagramm):
⦁ OS Hardening
⦁ Network Hardening
⦁ Container Security
⦁ Application Security
Das Deployment
Für das Deployment der Artefakte des Labs wird Ansible verwendet. Hierzu wird ein Ansible Playbook erstellt, welches folgende Funktionen erfüllt:
⦁ Updaten des Systems
⦁ Entfernen der vorinstallierten Docker Version
⦁ Installieren der Docker Community Edition
⦁ Anlegen eines Docker Users
⦁ Kopieren von Bash-Scripten auf das Zielsystem
⦁ Ändern der Berechtigung der Bash-Scripte
Die Bash-Scripte erfüllen verschiedene Aufgaben im Zusammenspiel mit den Docker-Containern. Ein Script kopiert die aktuellsten Images, welche für das Lab benötigt werden, von Docker Hub: Dies sind zum einen GitLab, des Weiteren GitLab Runner sowie SonarQube Server. Ein vorheriges manuelles Herunterladen des SonarQube Scanners ist nicht erforderlich, da dies durch die CI-Funktionalität von GitLab automatisch durchgeführt wird.
Die übrigen Scripte werden benötigt, um die Container auszuführen und einen persistenten Speicher innerhalb der Container zuzuweisen, sowie für die Dienste entsprechende Ports zu setzen und jeden Container eindeutig zu benennen.
Zusätzlich wird ein weiteres Script ausgeliefert, welches den GitLab-Runner konfiguriert. Dazu muss zunächst innerhalb von GitLab ein Runner-Token erstellt werden, welches anschließend dem Script weitergegeben und somit der Runner GitLab zugewiesen wird.
Die Besonderheit einer containerisierten GitLab Instanz ist die Portzuweisung. Am Anfang des Projektes traten häufiger Probleme mit git-Befehlen auf der Konsole auf, sofern GitLab nicht der Standard SSH Port 22 zugewiesen wurde. Daher entschließen wir uns, dem Host System einen alternativen SSH Port zuzuweisen und GitLab auf dem Standard SSH Port zu nutzen.
Projekte, Projekte, Projekte
Um ein Repository scannen zu können, muss zunächst ein SonarQube Projekt angelegt und ein Project Key vergeben werden. Anschließend wird ein Token generiert. Dies geschieht durch Vergabe eines Token Namens, zu dem SonarQube einen alphanumerischen String erzeugt.
Als nächstes muss im Projektordner die Konfigurationsdatei sonar-project.properties angelegt werden. Diese enthält insbesondere die Parameter Project.Key und Project.Name. Ohne diese generiert SonarQube eine Fehlermeldung. Weiterhin muss zwingend die Quelle (d.h. der Pfad zum Sourcecode) spezifiziert werden. Zusätzlich können noch weitere Eigenschaften wie Kodierung und Programmiersprache konfiguriert werden, was jedoch in unserem Fall nicht erforderlich ist.
Das Anlegen der Konfigurationsdatei sonar-project.properties ist ebenfalls nicht zwingend notwendig: Alternativ können die Werte Project.Key und Project.Name auch in GitLab selbst hinterlegt und anschließend in der .gitlab-ci.yml zugewiesen werden.
Die .gitlab-ci.yml
Das Herzstück der Automatisierung dieses kleinen Labs bildet die in YAML geschriebene Datei .gitlab-ci.yml. Für diesen Anwendungsfall ist die Komplexität minimal gehalten, alle Anweisungen werden vom GitLab-Runner ausgeführt.
In diesem simplen Fall sucht der GitLab-Runner das Sonar-Scanner-Image auf Dockerhub, sofern es nicht bereits lokal vorliegt. Hier kommt das alphanumerische Token zum Einsatz, welcher an den Scanner übergeben wird. Zusätzlich muss die Host-Adresse von SonarQube angegeben werden, um nach dem Scan die Ergebnisse auf den Server zu pushen. Nachdem dies ausgeführt wurde, beendet sich der Container mit dem Sonar-Scanner wieder automatisch und wird erst dann erneut gestartet, wenn ein neuer Merge-Request auf den Master aufgeführt wird.
Ausblick
Wie oben erwähnt sind einige Security-Best-Practices, wie die Härtung von Betriebssystem und Netzwerk, hier nicht berücksichtigt.
Auch dieser Ausblick fokussiert daher eher den horizontalen Ausbau rechts und links der im Architekturdiagramm skizzierten Lösung. Beginnen wir mit der Betrachtung des „Links“:
Dem Sourcecode Management Tool vorgelagert sitzt im Normalfall der Editor oder die IDE des Entwicklers. Hier können verschiedene Plugins genutzt werden, um z.B. implementierte Kryptographie zu identifizieren und festzustellen, ob die Schlüssellänge richtig gewählt ist. Somit können Sicherheitsmängel sofort behoben werden. Danach erfolgt ein Commit und ggf. der Merge-Request und ein automatischer SonarQube-Scan.
Dem Lab nachgelagert (gedanklich rechts von unserer Lösung) sind andere Sicherheitsfeatures eingereiht, z.B. ein eigenes Image Repository und ein Image Vulnerability Scanner. Somit kann sichergestellt werden, dass die Security-Abteilung diese Images vorab überprüfen kann, bevor Entwickler diese nutzen. Auch hier ist Kommunikation zwischen den Abteilungen sehr wichtig.
Zu guter Letzt sollen weitere nicht-funktionalen Tests noch Erwähnung finden: Ebenso wie funktionale- und End-to-End Tests können auch einige Security Tests automatisiert durch Scanner und andere Tools durchgeführt werden. Diese sind nicht nur hilfreich für die Entwickler, sondern auch für die Operatoren, da auch Konfigurationen mit in diese Tests einbezogen werden.
Fazit
Die Qualität von Sourcecode in Hinblick auf Security-Aspekte zu erhöhen, muss weder aufwändig noch kostenintensiv sein. So lässt sich die Integration eines Basissets von (Open Source) Security-Tools in die Entwicklungspipeline bereits mit einfachen Mitteln realisieren und liefert dabei einen klaren Mehrwert.
Wie so oft führen viele Wege zum Ziel und jede Reise beginnt mit dem ersten Schritt.
Lesen Sie hier Teil 1: Schritt für Schritt zur DevSecOps Pipeline
Jan Sudmeyer ist Managing Partner und Senior Trusted Advisor der carmasec GmbH & Co. KG. Seine Expertise liegt im Bereich Cybersecurity, sowie dem Aufbau von Managementsystemen zur Informationssicherheit (ISMS).
Kevin Kloft ist Security Solution Architect der carmasec GmbH & Co KG. Er beschäftigt sich schwerpunktmäßig mit der Evaluation neuer Technologien und der Implementierung von DevSecOps Tools und Praktiken.