Gitlab CI/CD ============ .. index:: Gitlab CI/CD .. _pipeline: CI / CD Pipeline ---------------- .. index:: CI / CD Pipeline Docker ^^^^^^ Für die CI/CD Pipeline wird ein Runner benötigt, der gemäß der ``.gitlab-ci.yml`` Datei die entsprechenden Befehle und Stages ausführt. Da die Hochschule selber keine Runner hat, mussten wir uns selber einen anlegen. Dazu haben wir ein Docker Image über Docker-Compose verwendet, welches auf einer VM läuft, die sich wiederum über ein VPN im Hochschulnetz befindet, da das Hochschulgitlab nicht öffentlich erreichbar ist. .. code-block:: yaml version: "3.9" services: gitlab-runner: image: gitlab/gitlab-runner:latest container_name: gitlab-runner restart: unless-stopped volumes: - data:/etc/gitlab-runner - /var/run/docker.sock:/var/run/docker.sock volumes: data: Nachdem der Gitlab Runner erstellt und gestartet wurde muss anschließend noch bei einem Gitlab Host registriert werden: .. code-block:: bash docker exec -it gitlab-runner gitlab-runner register Daraufhin müssen folgende Informationen angegeben werden: * Gitlab Host (https://gitlab.informatik.hs-augsburg.de) * Authentikation-Token (`Token Generieren <#gitlab_token_generate>`_.) * Runner Name (z.B.: Gitlab-Runner) * Executor angeben (z.B.: docker) * Docker Image angeben (z.B: alpine) .. _gitlab_token_generate: Gitlab-Runner Token generieren: ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Im folgenden Bildern wird ein Token für den Gitlab-Runner generiert: -> Settings - CI/CD - Runners - New project runner .. index:: Gitlab-Runner Token generieren .. image:: img/02/RunnerToken.png .. image:: img/02/RunnerToken2.png .. image:: img/02/RunnerToken3.png Stages ^^^^^^ Ein wichtiger Aspekt von CI/CD sind die sogenannten Stages. Mit ihnen lässt sich die Software, die man entwickelt, bauen, testen und sogar deployen. Wenn eine Stage fehlschlägt, wird man in Form von einer E-Mail benachrichtigt. Definiert wird in der ``.gitlab-ci.yml`` alles im yaml-Format. .. code-block:: yaml image: "alpine:latest" stages: - build - deploy variables: SERVER_ADDRESS: "login.rz.hs-augsburg.de" SERVER_USER: "arwe2002" SERVER_DEST_PATH: "/www/arwe2002/sphinxbericht/" build_job: stage: build script: - apk add make py3-sphinx - cd Bericht/ - make html artifacts: when: on_success expire_in: 30 days paths: - "./Bericht/_build/*" only: - main - web - pipelines deploy_job: stage: deploy script: - apk update - apk add curl rsync openssh-client - curl --silent "https://gitlab.com/gitlab-org/incubation-engineering/mobile-devops/download-secure-files/-/raw/main/installer" | ash - chmod 600 .secure_files/HSA_CICD_ONLY - rsync -e 'ssh -i .secure_files/HSA_CICD_ONLY -o StrictHostKeyChecking=no' -zav --delete Bericht/_build/html/ $SERVER_USER@$SERVER_ADDRESS:$SERVER_DEST_PATH needs: - build_job only: - main - web - pipelines Im Unterpunkt ``stages:`` werden die Stages und die Reihenfolge, in der sie ablaufen, definiert. Wie man hier sieht gibt es 2 Stages: build und deploy. Zu jeder Stage gibt es mindestens einen Job und die Stage wird unter ``stage:`` beim Job festgelegt. Zunächst pullt sich jeder Job ein Docker Image, das bei ``Image:`` definiert ist und klont das Repository in den Docker Container. In unserem Fall haben wir uns für Alpine entschieden, da Alpine sehr leichtgewichtig ist. Beim ``script:`` Unterpunkt kann man dann einen Shell-Skript festlegen, was im Job gemacht werden soll. Hier werden die Pakete ``make`` und ``py3-sphinx`` installiert. Anschließend wird in den Bericht/ Ordner gewechselt und der ``make html`` Befehl aufgerufen, was den html-Bericht baut. Mithilfe der ``artifacts:`` kann man Ordner definieren, die über mehrere Jobs persistieren, was sehr nützlich ist, da z.B. der Output der Build Stage in der Deploy Stage benötigt wird. Außerdem kann man die Artifacts auch als Archiv herunterladen. Unter ``only:`` kann definiert werden, wann die Pipeline bzw. der Job triggert. Im ``variables:`` Unterpunkt kann man Variablen festlegen. Beim ``deploy_job:`` gibt es eine Besonderheit: Dort wurde mit **Secure Files** gearbeitet. Das sind Dateien auf die nur die Projekt Developer und Maintainer Zugriff haben und sensitive Inhalte beinhalten. Hochgeladen werden diese über folgendes Web-Interface: .. image:: img/02/SecureFile.png In diesem Fall wurde ein SSH PrivateKey hochgeladen mit dem dann der Output des Build-Jobs via rsync auf den Hochschulserver übertragen wird. Über folgende Zeile werden die Secure Files heruntergeladen: .. code-block:: bash curl --silent "https://gitlab.com/gitlab-org/incubation-engineering/mobile-devops/download-secure-files/-/raw/main/installer" | bash und in den Ordner ``.secure_files`` abgespeichert. .. _gitlab_security_features: Gitlab Security Features ------------------------ .. index:: Gitlab Security Features Secret Detection ^^^^^^^^^^^^^^^^ Secret Detection ist eine Schlüsselfunktion von GitLab, die darauf ausgerichtet ist, unbeabsichtigt in den Quellcode eingecheckte sensible Informationen wie Passwörter, API-Schlüssel oder Tokens frühzeitig zu erkennen. Dieses Sicherheitsfeature spielt eine wesentliche Rolle dabei, die Sicherheit und Integrität von Softwareprojekten während des gesamten Entwicklungsprozesses zu gewährleisten. Die Funktionalität von Secret Detection basiert auf einer Vielzahl von vordefinierten Mustern, die bekannte Formate für sensible Daten erkennen. Diese Muster werden auf jeden Commit angewendet, der in das Repository gepusht wird. Sollte ein potentielles Geheimnis gefunden werden, wird dies in der Merge Request-Ansicht markiert und kann im Detail im CI/CD-Pipeline-Bericht nachvollzogen werden. .. code-block:: yaml include: - template: Security/Secret-Detection.gitlab-ci.yml Benutzer können die Erkennungsregeln anpassen oder erweitern, um spezifische Bedürfnisse ihres Projekts oder ihrer Organisation zu berücksichtigen. Zusätzlich zu den standardmäßigen Erkennungsregeln bietet GitLab die Möglichkeit, eigene Regeln zu definieren, die dann in die CI/CD-Pipeline integriert werden können. Die Implementierung der Secret Detection ist ein Schritt zur Vermeidung von Datenlecks und zur Förderung einer Sicherheitskultur innerhalb von Entwicklungsteams. Dieses Tool ermöglicht es Teams, proaktiv auf Sicherheitsrisiken zu reagieren, bevor diese zu ernsthaften Bedrohungen werden. Zusammenfassend ist Secret Detection nicht nur eine Sicherheitsmaßnahme, sondern auch ein wichtiges Werkzeug für die Compliance, indem es hilft, die Einhaltung von Datenschutzbestimmungen sicherzustellen. Dependency Scanning ^^^^^^^^^^^^^^^^^^^ Dependency Scanning ist ein Tool, um eventuelle Schwächen im Programmcode zu identifizieren. Das beinhaltet auch die Analyse von transitiven Abhängigkeiten, sowie verwendete 3rd-party Bibliotheken. Neben Python werden noch viele weitere Pakete unterstützt, u.a. C/C++, C#, Java, und JavaScript/Typescript. Die verwendeten Programmiersprachen werden vom Dependency Scanner automatisch erkannt und daraufhin angewendet. Für u.a. Python wird versucht das Programm zu bauen oder eine Liste aller Abhängigkeiten zu finden, also z.B. wird die ``requirements.txt`` Datei gesucht. Um den Analyzer einzuschalten, wird eine ``.gitlab-ci.yml`` File vorausgesetzt, die eine ``test`` stage hat. Folgende Zeilen müssen in die ``.gitlab-ci.yml`` Datei eingefügt werden: .. code-block:: yaml include: - template: Jobs/Dependency-Scanning.gitlab-ci.yml Um zu prüfen, ob der Analyzer richtig konfiguriert wurde, kann man im Repository unter dem Tab **Build / Pipelinte editor** eine Simulation laufen lassen, die den Inhalt der ``.gitlab-ci.yml`` validiert. .. image:: img/02/DependencyScanning.jpg (*Abbildung 1*) Es gibt noch andere Methoden um den Dependency Scanner einzubinden, unter anderem gibt es vorkonfigurierte Merge-Requests. Auf diesem Weg könnte die manuelel Bearbeitung des ``.gitlab-ci.yml`` File weggelassen werden. Der Output des Scanners ist ein Report, der u.a. bereits bei Merge Merge-Requests angezeigt wird. Außerdem werden bei entdeckten potentiellen Vulnerabilities direkt Lösungen angeboten. Unglücklicherweise ist uns erst nach dem Setup des Dependency-Scanning Jobs in unserem Projekt aufgefallen, dass es sich hierbei um ein exlusives *Advanced Security Feature* handelt, dass nur mit Gitlab Ultimate zugänglich ist. Das Gitlab der Hochschule enthält dieses Feature leider nicht. Ein Beispiel Bericht sieht aus wie folgt: .. image:: img/02/dependency_scanning_report_example.png (*Abbildung 2*) SAST ^^^^ Static Application Security Testing (SAST) überprüft den Code während der Entwicklung nach Sicheheitsschwachstellen. Zusammengefasst wird diese Schwachstelle in der ``gl-sast-report.json`` und ist im Merge Request sichtbar. SAST kann für die Sprachen Python, React, TypeScript, Go und viele mehr verwendet werden und erkennt dabei automatisch die verwendete Programmiersprache Auch hierfür wird eine ``.gitlab-ci.yml`` File vorausgesetzt, die eine ``test`` stage besitzt. Folgende Zeilen müssen eingefügt werden: .. code-block:: yaml include: - template: Security/SAST.gitlab-ci.yml Das Verhalten der Analysatoren kann angepasst werden indem eine ``sast-ruleset.toml`` in das ``.gitlab`` Verzeichnis eingefügt wird. Dort können vordefinierte Regeln deaktiviert beziehungsweise überschrieben werden. Es wird jedoch empfholen die Default Ruleset zu verwenden. Es werden mehrere Analysatoren verwendet, die jeweils den Code durchgehen. Diese sind ein Wrapper um einen Scanner eines Drittanbieters. Beispielsweise wird für die meisten Sprachen der ``Semgrep-based analyzer`` verwendet, der unter anderem aus dem Sempreg open-source code besteht. .. _fazit: Fazit ----- .. index:: Fazit Mithilfe von Gitlab CI/CD kann vor allem bei größeren Projekten sehr viel Zeit eingespart werden, da die Software vollautomatisiert gebaut, getestet, deployed und auch realeased werden kann. Es gibt eine Reihe von Security Features, bei denen aber beachtet werden muss, welches Gitlab Abonnement man besitzt, da einige Features nur in der Ultimate Variante verfügbar sind. .. _lit: Literatur --------- Gitlab Pipeline Documentation https://docs.gitlab.com/ee/topics/build_your_application.html (10.04.2024) Gitlab Runner Installation https://docs.gitlab.com/runner/install/ (10.04.2024) GitLab Secret Detection https://docs.gitlab.com/ee/user/application_security/secret_detection/ (17.04.2024) GitLab dependency Scanning: https://docs.gitlab.com/ee/user/application_security/dependency_scanning/#dependency-scanning-report (12.04.2024) GitLab SAST https://docs.gitlab.com/ee/user/application_security/sast/ (17.04.2024) Abbildung 2: https://docs.gitlab.com/ee/user/application_security/dependency_scanning/img/dependency_scanning_v13_2.png (12.04.2024)