Tim Bastin - Softwarearchitekt & Software Sicherheitsspezialist
Tim Bastin
Softwarearchitekt & Software Sicherheitsspezialist
2.7.2023

Git Commit Signing: Eine detaillierte Anleitung

Bonn, 2.7.20231 Minuten Lesezeit
Git Commit Signing: Eine detaillierte Anleitung

In der heutigen, hochvernetzten Welt wird die Priorisierung von Sicherheitsmaßnahmen in der Softwareentwicklung immer wichtiger. Mit der steigenden Relevanz verteilter Versionsverwaltungssysteme wie Git und kontinuierlicher Integrationsplattformen wie GitLab geht auch eine erhöhte Gefahr von Angriffen auf die Software-Supply-Chain einher. Laut ENISA Report: "Threat Landscape for Supply Chain Attacks" versuchten 2021 62% der Angreifer das Vertrauen von Unternehmen in die eigene Software-Lieferkette auszunutzen und über diese Angriffe, wie beispielsweise das einschleusen von Malware, durchzuführen.

Englische Version des Artikels

In diesem Kontext wird die Implementierung einer robusten Sicherheitsinfrastruktur zu einer unverzichtbaren Anforderung. Ein Schlüsselelement zur Stärkung dieser Infrastruktur ist das Commit Signing. Commit Signing ist ein Sicherheitsmechanismus in Git, der den Autor eines Commits verifiziert und die Integrität des Commits gewährleistet. Bei aktiviertem Commit Signing werden Commits mit dem privaten Schlüssel des Autors signiert. Jeder, der den zugehörigen öffentlichen Schlüssel hat, kann die Signatur überprüfen und damit sicherstellen, dass der Commit tatsächlich vom angegebenen Autor stammt und nicht manipuliert wurde. Durch die Verifizierung des Autors eines Commits und die Gewährleistung der Integrität des Commits bietet das Commit Signing einen wirksamen Schutz gegen unautorisierte oder manipulierte Codeänderungen.

Um den Schutz noch weiter zu verstärken, kann der Einsatz eines YubiKeys in Betracht gezogen werden. Der YubiKey ist ein physisches Authentifizierungsgerät, das eine starke Zwei-Faktor- und Multi-Faktor-Authentifizierung bietet. Dieses Hardware-Gerät kann nicht nur kryptographische Schlüssel sicher speichern, sondern führt auch kryptographische Operationen auf dem Gerät selbst durch. Das bedeutet, dass ein privater Schlüssel nie das Gerät verlässt und daher nicht kopiert oder gestohlen werden kann.

Durch die Verwendung eines YubiKeys für das Commit Signing wird die Sicherheit dieses Prozesses deutlich erhöht und die Widerstandsfähigkeit der Software-Supply-Chain gegen Angriffe verbessert. Zusätzlich, lässt sich der YubiKey auch für den durch Git durchgeführten Verbindungsaufbau mittels SSH verwenden. Wenn ein Commit an ein Remote-Repository gesendet wird, fordert Git eine SSH-Authentifizierung an. Anstatt den privaten Schlüssel aus einer Datei auf dem Computer zu lesen, kommuniziert SSH mit dem YubiKey, um die notwendigen kryptographischen Operationen durchzuführen. Da der YubiKey physisch an den Computer angeschlossen sein muss, um diese Operationen durchzuführen, bietet dies eine starke Form der Zwei-Faktor-Authentifizierung: etwas, das gewusst werden muss (Passwort) und etwas, das besitzt werden muss (YubiKey).

Angesichts der zunehmenden Bedrohungen für die Software-Supply-Chain ist es von größter Bedeutung, dass alle verfügbaren Werkzeuge und Technologien genutzt werden, um den Softwareentwicklungsprozesse abzusichern. Die Kombination von Git, GitLab, Commit Signing und YubiKey bietet eine effektive Lösung, um diesen Herausforderungen zu begegnen. Der nächste Abschnitt beschreibt die konkrete Konfiguration aller Komponenten.

Sichern der SSH-Verbindung

Um den YubiKey mit Git für den SSH-Verbindungsaufbau unter MacOS zu verwenden, sind zusätzliche Schritte erforderlich, da die Standard-OpenSSH-Version auf MacOS nicht das Erstellen von geheimen Schlüsseln (secret keys) unterstützt. Die entsprechenden Schritte sind:

1. (nur MacOS) Installieren von OpenSSH mit Homebrew

MacOS-Benutzer müssen zunächst eine aktualisierte Version von OpenSSH installieren, die das Erstellen von geheimen Schlüsseln unterstützt (sk). Dies kann mit dem Paketmanager Homebrew erfolgen. Wenn Homebrew auf Ihrem System noch nicht installiert ist, können Sie es von der offiziellen Website herunterladen. Installieren Sie dann OpenSSH mit dem folgenden Terminalbefehl: brew install openssh

2. (nur MacOS) Sicherstellen, dass die korrekte OpenSSH-Version verwendet wird

Als nächstes müssen Sie sicherstellen, dass Ihr System die gerade installierte Version von OpenSSH verwendet und nicht die Standardversion von MacOS. Sie können dies überprüfen, indem Sie das folgende Kommando im Terminal ausführen: which ssh-keygen. Die Ausgabe sollte Folgendem entsprechen: /opt/homebrew/bin/ssh-keygen

Sollte dem nicht so sein, müssen Sie Ihre Shell-Konfigurationsdatei (.zshrc, .bashrc, etc.) ändern. Fügen Sie die folgende Zeile hinzu, um den Pfad der OpenSSH-Version, die Sie gerade installiert haben, zur PATH-Umgebungsvariablen hinzuzufügen: export PATH=$(brew --prefix openssh)/bin:$PATH

Sie müssen die Konfigurationsdatei neu laden oder ein neues Terminalfenster öffnen, damit diese Änderung wirksam wird. Beispielsweise durch: source .zshrc

3. Generieren Sie den SSH-Schlüssel

Nachdem Sie sichergestellt haben, dass Sie die korrekte OpenSSH-Version verwenden, können Sie einen neuen SSH-Schlüssel generieren. Dazu verwenden Sie den Befehl ssh-keygen mit einem speziellen Typ, welcher auf den YubiKey abgelegt werden kann.

Sie können entweder einen Schlüssel des Typs ed25519-sk oder ecdsa-sk generieren. Beide Schlüsseltypen bieten eine starke Sicherheit, aber ed25519-sk ist neuer und wird oft als sicherer angesehen.

ssh-keygen -t ed25519-sk -O resident -O application=ssh -O verify-required

Bei der Ausführung dieser Befehle werden Sie aufgefordert, Ihr YubiKey-Gerät einzustecken und zu berühren, um die Schlüsselgenerierung zu bestätigen. Sie können auch aufgefordert werden, ein Passwort für den Schlüssel einzugeben, um eine zusätzliche Sicherheitsebene hinzuzufügen.

Mit diesen Schritten haben Sie einen neuen SSH-Schlüssel auf Ihrem YubiKey generiert, der jetzt bereit ist, für sichere SSH-Verbindungen, unter anderem von Git, verwendet zu werden.

4. Hinterlegen des öffentlichen Schlüssels in GitLab

Nachdem Sie Ihren neuen SSH-Schlüssel generiert haben, müssen Sie Ihren öffentlichen Schlüssel in GitLab hinterlegen. Dadurch wird GitLab ermöglicht, Sie zu authentifizieren, wenn Sie SSH verwenden, um eine Verbindung zu Ihrem Repository herzustellen.

Befolgen Sie diese Schritte, um Ihren öffentlichen Schlüssel in GitLab zu hinterlegen:

  1. Öffnen Sie zunächst das Terminal und geben Sie den folgenden Befehl ein, um den Inhalt Ihres öffentlichen Schlüssels anzuzeigen (ersetzen Sie "id_ed25519_sk.pub" oder "id_ecdsa_sk.pub" durch den tatsächlichen Pfad zu Ihrer öffentlichen Schlüsseldatei):

    cat ~/.ssh/id_ed25519_sk.pub
    
  2. Kopieren Sie den gesamten Ausgabetext, der Ihren öffentlichen Schlüssel darstellt.

  3. Melden Sie sich nun in Ihrem GitLab-Konto an und navigieren Sie zu den Einstellungen Ihres Kontos (klicken Sie auf Ihr Profilbild in der rechten oberen Ecke und wählen Sie "Settings").

  4. Auf der linken Seite klicken Sie auf "SSH Keys".

  5. Fügen Sie nun Ihren öffentlichen Schlüssel in das Feld "Key" ein. Sie können optional einen Titel für den Schlüssel angeben, um ihn leichter zu identifizieren.

  6. Als Usage-Type wählen Sie "Authentication & Signing" um den Key sowohl für die Signierung als auch für die Authentifizierung mittels SSH zu verwenden.

  7. Klicken Sie auf "Add Key", um den Schlüssel zu Ihrem Konto hinzuzufügen.

Jetzt ist Ihr YubiKey für die Verwendung mit SSH in GitLab konfiguriert. Wenn Sie versuchen, per SSH auf GitLab zuzugreifen, fordert Ihr System Sie auf, Ihren YubiKey einzustecken und zu berühren, um die Aktion zu bestätigen.

5. Testen der Verbindung

Nachdem Sie Ihren öffentlichen SSH-Schlüssel in GitLab hinterlegt haben, sollten Sie die Verbindung testen, um sicherzustellen, dass alles ordnungsgemäß eingerichtet ist.

Sie können dies tun, indem Sie versuchen, per SSH eine Verbindung zu GitLab herzustellen. Geben Sie dazu den folgenden Befehl in Ihr Terminal ein:

ssh -T git@gitlab.com

Wenn Sie dazu aufgefordert werden, fügen Sie Ihren YubiKey ein und berühren Sie ihn zur Bestätigung.

Wenn die Einrichtung erfolgreich war, erhalten Sie eine Nachricht, die etwa so lautet:

Welcome to GitLab, @username!

Hierbei steht @username für Ihren GitLab-Benutzernamen. Wenn Sie diese Nachricht sehen, bedeutet das, dass Ihr YubiKey erfolgreich für die SSH-Verbindung mit GitLab eingerichtet wurde.

Wenn Sie stattdessen eine Fehlermeldung erhalten, überprüfen Sie bitte die vorherigen Schritte und stellen Sie sicher, dass Sie Ihren öffentlichen Schlüssel korrekt in GitLab eingetragen haben und dass Ihr YubiKey ordnungsgemäß funktioniert.

Sichern der Git-Commits mittels YubiKey

Sobald Ihr YubiKey für die Verwendung mit SSH in GitLab konfiguriert ist, können Sie ihn auch für die Signierung Ihrer Git-Commits verwenden.

Dies ist mit drei einfachen Kommandos möglich:

git config --global user.signingkey ~/.ssh/id_ed25519_sk
git config --global user.signingkey ~/.ssh/id_ed25519_sk
git config --global gpg.format ssh
git config --global commit.gpgsign true

Ersetzen Sie, wenn nötig "~/.ssh/id_ed25519_sk" mit dem Pfad zu Ihrem privaten SSH-Schlüssel.

Mittels der --global Flag wird Commit-Signing für alle Projekte mit den übergebenen Argumenten aktiviert. Für projektspezifische Einstellungen kann die --global Flag weggelassen werden.

Testen des Signaturprozesses

Nachdem Sie Ihren SSH-Schlüssel in Git und GitLab konfiguriert haben, sollten Sie den Signaturprozess testen, um sicherzustellen, dass alles ordnungsgemäß funktioniert. Dies können Sie tun, indem Sie einen neuen Commit erstellen und prüfen, ob er ordnungsgemäß signiert wurde.

Navigieren Sie zunächst zu einem lokalen Git-Repository auf Ihrem Computer, führen Sie einen Commit durch und pushen Sie diesen in das externe Gitlab Repository. Dieser Commit sollte nun als "verified" gekennzeichnet werden.

(optional) Lokales Verifizieren von Commit-Signaturen

Auffällig ist, dass lokal alle Commits als "nicht signiert" ausgewiesen werden. Zusätzlich führt folgender Befehl:

git log --show-signature

zu einer Fehlermeldung, die etwa wie folgt lautet

error: gpg.ssh.allowedSignersFiles needs to be confgiured and exist for ssh signature verification

Git ist nicht in der Lage, die Signaturen der erstellten Commits lokal zu verifizieren, da es schlicht nicht weiß, welchen Schlüsseln es vertrauen kann. Um Git-Commits auch Lokal verifizieren zu können, ist es nötig, ein sogenanntes Signers-File anzulegen, welches eine Liste von vertrauenswürdigen E-Mail-Adressen und öffentlichen Schlüsseln-Pärchen enthält.

Erstellen Sie hierfür eine neue Datei auf Ihrem System und fügen Sie dort zeilenweise, mit einem Leerzeichen getrennt, vertrauenswürdige E-Mail-Adressen und öffentliche Schlüssel ein.

Ein Beispiel wäre folgende Datei:

# ~/.config/git/allowed_signers
tim.bastin@l3montree.com ssh-ed25519 AAAAC3NzaC1lZDI1NTE6AAAAIE5bRSsXZ5HnUkMMEWS5/jxEQaqbLb+i6xjMyC6qiXsb timbastin@local
# <E-Mail Adresse> <Öffentlicher Schlüssel>
# <E-Mail Adresse 2> <Öffentlicher Schlüssel 2>

Nun müssen Sie Git nur noch mitteilen, dass es die erstellte Datei als Signers-File verwenden soll.

git config [--global] gpg.ssh.allowedSignersFile "$HOME/.config/git/allowed_signers"

Valide signierte Commits sollten nun auch lokal als solche gekennzeichnet werden!

Fazit

Die Absicherung des Softwareentwicklungsprozesses ist eine kontinuierliche und notwendige Aufgabe in unserer digitalen Welt. Durch die Implementierung von Commit Signing und die Verwendung von YubiKey in Kombination mit Git und GitLab können wir die Integrität unserer Codebasis schützen und die Vertrauenswürdigkeit unserer Software-Lieferkette gewährleisten. Mit der hier bereitgestellten detaillierten Anleitung hoffen wir, dass Sie einen klaren Weg zur Integration dieser wertvollen Sicherheitstools in Ihren eigenen Softwareentwicklungsprozess finden. Die Reise zur Stärkung der Software-Sicherheit ist lang und erfordert kontinuierliche Anstrengungen, aber mit den richtigen Werkzeugen und Kenntnissen können wir gemeinsam eine sicherere und vertrauenswürdige digitale Zukunft gestalten.