it-swarm.com.de

Was ist die beste Vorgehensweise für den Umgang mit Passwörtern in Git-Repositories?

Ich habe ein kleines Bash-Skript, mit dem ich auf Twitter zugreifen und in bestimmten Situationen eine Growl-Benachrichtigung anzeigen kann. Wie kann ich mein Passwort am besten mit dem Skript speichern?

Ich möchte dieses Skript für das Git Repo festlegen und es auf GitHub verfügbar machen, aber ich frage mich, wie ich mein Login/Passwort dabei am besten geheim halten kann. Derzeit ist das Passwort im Skript selbst gespeichert. Ich kann es nicht direkt vor dem Push entfernen, da alle alten Commits das Passwort enthalten. Das Entwickeln ohne Passwort ist keine Option. Ich stelle mir vor, dass ich das Passwort in einer externen Konfigurationsdatei speichern sollte, aber ich dachte, ich würde prüfen, ob es eine etablierte Möglichkeit gibt, damit umzugehen, bevor ich versuchte, etwas zusammenzusetzen.

196
kubi

Die typische Methode hierfür ist das Lesen der Kennwortinformationen aus einer Konfigurationsdatei. Wenn Ihre Konfigurationsdatei foobar.config Heißt, würden Sie eine Datei mit dem Namen foobar.config.example An das Repository übergeben, die Beispieldaten enthält. Um Ihr Programm auszuführen, erstellen Sie eine lokale (nicht verfolgte) Datei namens foobar.config Mit Ihren echten Passwortdaten.

Informationen zum Herausfiltern Ihres vorhandenen Kennworts aus früheren Commits finden Sie auf der GitHub-Hilfeseite unter Entfernen vertraulicher Daten .

230
Greg Hewgill

Ein Ansatz kann darin bestehen, ein Kennwort (oder einen API-Schlüssel) mithilfe einer Umgebungsvariablen festzulegen. Dieses Passwort befindet sich also außerhalb der Revisionskontrolle.

Mit Bash können Sie Umgebungsvariablen mit festlegen

export your_env_variable='your_password'

Dieser Ansatz kann mit fortlaufenden Integrationsdiensten wie Travis verwendet werden, wobei Ihr Code (ohne Kennwort) in einem GitHub -Repository gespeichert wird und von Travis ausgeführt werden kann (wobei Ihr Kennwort mit festgelegt wird Umgebungsvariable).

Mit Bash können Sie den Wert einer Umgebungsvariablen abrufen, indem Sie Folgendes verwenden:

echo "$your_env_variable"

Mit Python können Sie den Wert einer Umgebungsvariablen abrufen, indem Sie Folgendes verwenden:

import os
print(os.environ['your_env_variable'])

PS: Seien Sie sich bewusst, dass es wahrscheinlich ein bisschen riskant ist (aber es ist eine weit verbreitete Praxis) https://www.bleepingcomputer.com/news/security/javascript-packages-caught-stealing-environment-variables/ =

PS2: dieses dev.to Artikel mit dem Titel "Wie man API-Schlüssel sicher speichert" ist möglicherweise interessant zu lesen.

24
scls

Was Greg sagte aber ich würde hinzufügen, dass es eine gute Idee ist, eine Datei einzuchecken foobar.config-TEMPLATE.

Es sollte Beispielnamen, Passwörter oder andere Konfigurationsinformationen enthalten. Dann ist es sehr offensichtlich, was die echte foobar.config enthalten soll, ohne im gesamten Code nachsehen zu müssen, welche Werte in foobar.config Vorhanden sein müssen und welches Format sie haben sollen.

Oft können Konfigurationswerte nicht offensichtlich sein, wie Datenbankverbindungszeichenfolgen und ähnliche Dinge.

16
Prof. Falken

Man kann Vault verwenden, um den Zugriff auf Token, Kennwörter, Zertifikate, API-Schlüssel usw. zu sichern, zu speichern und zu steuern. Zum Beispiel Ansible verwendet Ansible Vault was sich mit Passwörtern oder Zertifikaten befasst, die in Playbooks verwendet werden

2
El Ruso

Hier ist eine Technik, die ich benutze:

Ich erstelle einen Ordner in meinem Home-Ordner mit dem Namen: .config

In diesem Ordner platziere ich die Konfigurationsdateien für eine beliebige Anzahl von Dingen, die ich Passwörter und Schlüssel externalisieren möchte.

Ich verwende normalerweise die umgekehrte Domainnamensyntax wie:

com.example.databaseconfig

Dann mache ich im Bash-Skript Folgendes:

#!/bin/bash
source $HOME/.config/com.example.databaseconfig ||exit 1

Das || exit 1 bewirkt, dass das Skript beendet wird, wenn die Konfigurationsdatei nicht geladen werden kann.

Ich habe diese Technik für Bash-, Python- und Ant-Skripte verwendet.

Ich bin ziemlich paranoid und glaube nicht, dass eine .gitignore-Datei robust genug ist, um ein versehentliches Einchecken zu verhindern. Außerdem gibt es keine Überwachung, sodass niemand herausfinden würde, ob ein Check-in stattgefunden hat.

Wenn eine bestimmte Anwendung mehr als eine Datei erfordert, erstelle ich eher einen Unterordner als eine einzelne Datei.

2
Michael Potter

Der Umgang mit Passwörtern in Repositories wird je nach Problem unterschiedlich gehandhabt.

1. Tu es nicht.

Und Möglichkeiten, dies zu vermeiden, werden in einigen Antworten beschrieben - .gitignore, config.example usw

oder 2. Repository nur autorisierten Personen zugänglich machen

Das heißt Personen, die das Passwort kennen dürfen. chmod und Benutzergruppen kommen in den Sinn; Auch Probleme wie sollten Github- oder AWS-Mitarbeiter Dinge sehen dürfen, wenn Sie Ihre Repositorys oder Server extern hosten?

oder 3. Verschlüsseln Sie die sensiblen Daten (Zweck dieser Antwort)

Wenn Sie Ihre Konfigurationsdateien mit vertraulichen Informationen (z. B. Kennwörtern) an einem öffentlichen Ort speichern möchten, müssen Sie sie verschlüsseln. Die Dateien könnten entschlüsselt werden, wenn sie aus dem Repository wiederhergestellt werden, oder sogar direkt aus ihrer verschlüsselten Form verwendet werden.

Unten sehen Sie ein Beispiel für eine Javascript-Lösung zur Verwendung verschlüsselter Konfigurationsdaten.

const fs = require('fs');
const NodeRSA = require('node-rsa');

let privatekey = new NodeRSA();
privatekey.importKey(fs.readFileSync('private.key', 'utf8'));
const config = privatekey.decrypt(fs.readFileSync('config.RSA', 'utf8'), 'json');

console.log('decrypted: ', config);

Decrypted Config File

So können Sie eine verschlüsselte Konfigurationsdatei wiederherstellen, indem Sie nur ein paar Zeilen Javascript schreiben.

Beachten Sie, dass das Ablegen einer Datei config.RSA in ein Git-Repository würde es effektiv zu einer Binärdatei machen und so viele der Vorteile von etwas wie Git verlieren, z. die Fähigkeit, Änderungen daran vorzunehmen.

Die Lösung hierfür könnte darin bestehen, Schlüsselwertpaare oder nur Werte zu verschlüsseln. Sie können alle Werte verschlüsseln, z. B. wenn Sie eine separate Datei für vertrauliche Informationen haben, oder nur die vertraulichen Werte verschlüsseln, wenn Sie alle Werte in einer Datei haben. (siehe unten)

Mein Beispiel oben ist ein bisschen nutzlos für jeden, der einen Test damit durchführen oder als Beispiel davon ausgehen möchte, dass einige RSA-Schlüssel und eine verschlüsselte Konfigurationsdatei vorhanden sind config.RSA.

Hier sind einige zusätzliche Codezeilen hinzugefügt, um RSA-Schlüssel und eine Konfigurationsdatei zum Spielen zu erstellen.

const fs = require('fs');
const NodeRSA = require('node-rsa');

/////////////////////////////
// Generate some keys for testing
/////////////////////////////

const examplekey = new NodeRSA({b: 2048});

fs.writeFileSync('private.key', examplekey.exportKey('pkcs8-private'));
fs.writeFileSync('public.key', examplekey.exportKey('pkcs8-public'));

/////////////////////////////
// Do this on the Machine creating the config file
/////////////////////////////

const configToStore = {Goodbye: 'Cruel world'};

let publickey = new NodeRSA();
publickey.importKey(fs.readFileSync('public.key', 'utf8'));

fs.writeFileSync('config.RSA', publickey.encrypt(configToStore, 'base64'), 'utf8');

/////////////////////////////
// Do this on the Machine consuming the config file
/////////////////////////////

let privatekey = new NodeRSA();
privatekey.importKey(fs.readFileSync('private.key', 'utf8'));

const config = privatekey.decrypt(fs.readFileSync('config.RSA', 'utf8'), 'json');
console.log('decrypted: ', config);

Nur Werte verschlüsseln

fs.writeFileSync('config.RSA', JSON.stringify(config,null,2), 'utf8');

enter image description here

Mit so etwas können Sie eine Konfigurationsdatei mit verschlüsselten Werten entschlüsseln.

const savedconfig = JSON.parse(fs.readFileSync('config.RSA', 'utf8'));
let config = {...savedconfig};
Object.keys(savedconfig).forEach(key => {
    config[key] = privatekey.decrypt(savedconfig[key], 'utf8');
});

Mit jedem Konfigurationselement in einer separaten Zeile (z. B. Hello und Goodbye oben) erkennt Git besser, was in einer Datei vor sich geht, und speichert Änderungen an Informationselementen als Unterschiede und nicht als vollständige Dateien . Git wird auch in der Lage sein, Merges und Cherry Picks usw. besser zu verwalten.

Je mehr Sie jedoch Änderungen an vertraulichen Informationen der Versionskontrolle unterziehen möchten, desto mehr bewegen Sie sich in Richtung einer SAFE REPOSITORY-Lösung (2) und weg von einer ENCRYPTED INFO (3) -Lösung.

1
Ivan

Wenn Sie Ruby auf Rails verwenden, ist das Figaro-Juwel sehr gut, einfach und zuverlässig. Es hat auch einen geringen Kopfschmerzfaktor in Bezug auf die Produktionsumgebung.

0
ahnbizcad

Vertrauen aber überprüfen.

Im .gitignore dies würde ein "sicheres" Verzeichnis vom Repo ausschließen:

secure/

Aber ich teile die Paranoia von @ Michael Potter . Um .gitignore zu überprüfen, folgt ein Python Unit-Test , der ein Klaxon auslöst, wenn dieses "sichere" Verzeichnis jemals überprüft wird Und um die Prüfung zu überprüfen, wird auch ein legitimes Verzeichnis getestet:

def test_github_not_getting_credentials(self):
    safety_url = 'https://github.com/BobStein/fliki/tree/master/static'
    danger_url = 'https://github.com/BobStein/fliki/tree/master/secure'

    self.assertEqual(200, urllib.request.urlopen(safety_url).status)

    with self.assertRaises(urllib.error.HTTPError):
        urllib.request.urlopen(danger_url)
0
Bob Stein