Deadshot ist ein Pull-Request-Scanner, der nach der Einführung von Geheimnissen über PRs sucht, indem er jede Diff-Zeile mit einer Reihe bekannter geheimer Ausdrücke abgleicht.
Der Dienst ist verantwortlich für:
Der Service bietet NICHT:
Deadshot ist eine Flask-Celery-Redis-Multi-Container-Anwendung, die als Github-App installiert wird, um bei jedem Pull Request ausgeführt zu werden, der für den Hauptzweig eines Repos erstellt wird, auf dem die Github-App installiert ist.
Der Flask-Container ist der Einstiegspunkt für den Dienst, indem er in blueprints.py definierte API-Routen verfügbar macht. Sobald eine Pull-Request-Nutzlast auf der API-Route empfangen wird, leitet der Dienst die Nutzlast an eine Redis-Warteschlange weiter, damit der Celery-Container das Diff der Pull-Request abholen und durchsuchen kann. Nachdem der Sellerie-Container nach bestimmten geheimen regulären Ausdrücken gesucht hat, kommentiert er PRs, benachrichtigt Slack den Kanal des Sicherheitsteams oder erstellt ein JIRA-Ticket, das das Team weiterverfolgen kann. Die Github-App wird mit der Flask-API-URL und einem gemeinsamen Geheimnis konfiguriert, das zum Generieren der Nutzlast-SHA-Prüfsumme verwendet wird.
Eine Möglichkeit, die API-URL einzurichten, besteht darin, diesen Code auf einem Host bereitzustellen und diesem Host einen Anwendungs-Load-Balancer zuzuweisen.
Hinweis: Stellen Sie beim Erstellen der App sicher, dass Sie über ein DNS für den Host verfügen, auf dem Sie Deadshot-Container bereitstellen, und über eine sichere geheime Zeichenfolge für das Webhook-Geheimnis.
Github-Administratoren müssten eine Github-App auf Github erstellen und installieren, bevor sie die Deadshot-Anwendung ausführen oder bereitstellen können. Um mehr über die Erstellung einer Github-App zu erfahren, lesen Sie bitte diese Anleitung
App-Name: deadshot (Alles in Kleinbuchstaben. Dies ist wichtig, da der Dienst diesen Namen verwendet, um frühere Kommentare abzurufen, die er zu einer PR abgegeben hat.)
Webhook-URL: http(s)://your-hosted-deadshot-dns/api/v1/deadshot-webhook
Um dies lokal zu testen, können Sie einen Ngrok-Endpunkt erstellen, der in den Webhook-Bereich Ihrer Github-App eingespeist wird
Damit diese Anwendung funktioniert, muss Ihre Github-App die folgenden Berechtigungen und Abonnements auf der Berechtigungsseite der Github-App aktivieren: Repository-Berechtigungen:
Alle anderen Berechtigungen bleiben unverändert auf dem Standardwert „Kein Zugriff“.
Veranstaltungen abonnieren:
Klicken Sie abschließend auf „GitHub-App erstellen“. Nach erfolgreicher App-Erstellung folgen Sie dem Link „Privaten Schlüssel generieren“ im oberen Bereich der App-Webseite
Sobald der private Schlüssel generiert wurde, bewahren Sie ihn an einem sicheren Ort auf. Dieser generierte private Schlüssel ist eines der Daten, die zum Generieren eines Sitzungstokens für die App-Interaktion verwendet werden.
Nachdem Sie den privaten Schlüssel generiert haben, installieren Sie die App auf allen Organisationen, die sie überwachen soll.
Hierbei handelt es sich um eine Multi-Container-Anwendung, die alle drei Container (Flask, Celery, Redis) über /bin/run.sh aufrufen soll. Wenn Sie also das Dockerfile-Image ausführen, sollte die gesamte Anwendung aufgerufen werden
Die drei folgenden Variablen sind vom Benutzer bereitgestellte Einzelzeichenfolgenwerte
Die folgenden Umgebungsvariablen laden den Pfad zu Dateien mit Anmeldeinformationen. Laden Sie die Schlüsselwerte der JSON-Datei in die hier verfügbaren Dateien, bevor Sie die Anwendung ausführen.
Hinweis: Wenn Sie den Speicherort der JSON-Geheimnisdateien nicht verschieben, müssen Sie die oben genannten drei Umgebungsvariablenwerte, die bereits in den Dockerfiles oder docker-compose.yaml vorhanden sind, nicht aktualisieren
Dieser Befehl verwendet docker-compose.yaml, um alle Container aufzurufen. Bitte aktualisieren Sie „configuration/environment/localdev.env“ mit für Ihre Organisation relevanten Werten, bevor Sie den folgenden Befehl ausführen
make serve
Sobald Sie dies getan haben und nicht beabsichtigen, Dockerfile zum Bereitstellen der Anwendung zu verwenden, fahren Sie mit dem Abschnitt „Server Healthcheck“ fort
Es gibt zwei Möglichkeiten, die Docker-Dateien zu erstellen und auszuführen. Im Repository sind vier Dockerfiles vorhanden, von denen drei dazu verwendet werden, ein individuelles Image für jeden Container zu generieren, der für die Funktion dieses Dienstes benötigt wird, und das vierte ist ein Dockerfile-Setup zum Erstellen eines Images, das entweder zum Aufrufen des Containers verwendet werden kann Flask-Anwendung oder Sellerie-Worker, abhängig vom bereitgestellten Wert der Umgebungsvariablen DEADSHOT_RUN_MODE (API oder Worker). Um einen der folgenden Schritte auszuführen, müssen Sie sich im Stammordner des Repositorys befinden
Hinweis: Stellen Sie sicher, dass Sie die Umgebungsvariablen in den Dateien Dockerfile.api und Dockerfile.celery aktualisiert haben
Für diesen Schritt sind drei Docker-Dateien relevant. Dockerfile.api, Dockerfile.celery und Dockerfile.redis
docker build -f Dockerfile.api -t deadshot-api:<version> .
docker build -f Dockerfile.celery -t deadshot-worker:<version> .
docker build -f Dockerfile.redis -t deadshot-redis:<version> .
Die drei in den vorherigen Schritten erstellten Images laufen alle in separaten Netzwerken und können daher nicht miteinander kommunizieren. Um die Kommunikation zwischen Containern zu ermöglichen, müssen wir sie einem Containernetzwerk hinzufügen
docker network create deadshot-network
Führen Sie die Images über das erstellte Netzwerk in der folgenden Reihenfolge aus: Starten Sie den Redis-Container:
docker run --net deadshot-network --name redis deadshot-redis:<version>
Selleriebehälter starten:
docker run --net deadshot-network deadshot-worker:<version>
Starten Sie den Flask-API-Container:
docker run --net deadshot-network -p 9001:9001 deadshot-api:<version>
So erstellen Sie ein einzelnes Docker-Image zum Aufrufen der API und des Sellerie-Workers basierend auf der Umgebungsvariablen DEADSHOT_RUN_MODE
make build
Dieser Befehl erstellt auch das Redis-Image, das für den Service benötigt wird
Wenn das erstellte Image mit der Umgebungsvariablen DEADSHOT_RUN_MODE=api ausgeführt wird, wird die Flask-Anwendung aufgerufen. Wenn das Image mit der Umgebungsvariablen DEADSHOT_RUN_MODE=worker ausgeführt wird, wird der Sellerie-Worker gestartet
Da die API nun bereit ist, Anfragen zu empfangen, sollte die Navigation zu http://localhost:9001/api/v1/heartbeat
in einem Browser eine gültige Antwort zurückgeben, oder Sie könnten einen Curl ausführen
curl localhost:9001/api/v1/healthcheck
Beide sollten die folgende Meldung anzeigen: {"healthcheck": "ready"}
Wenn Sie über eine Webhook-Nutzlast der Github-App für Ihre Pull-Anfrage verfügen, können Sie den folgenden Curl-Befehl lokal ausführen, um Ihre Anwendung zu testen:
curl -X POST -H " content-type: application/json " -H " X-GitHub-Enterprise-Host: github.mockcompany.com " -H " X-Hub-Signature: sha1=85df4936c6396c149be94144befab41168149840 " -H " X-GitHub-Event: pull_request " -d @tests/fixtures/good_pr.json http://localhost:9001/api/v1/deadshot-webhook
Wenn Sie möchten, dass das Tool andere Arten von Geheimnissen überwacht, fügen Sie Ihre regulären Ausdrücke in die Datei regex.json ein
Hinweis: Mit dem Flag „Entropieprüfung“ können Sie zusätzlich zur Übereinstimmung mit regulären Ausdrücken auch nach Ergebnissen mit hoher Entropie suchen
Derzeit wurde Deadshot nur mit Github Enterprise getestet, sollte aber auch mit der Github-Cloud funktionieren.