Es gibt einige Optionen zum Speichern von Kennwörtern und anderen Geheimnissen, die ein Python-Programm verwenden muss, insbesondere ein Programm, das im Hintergrund ausgeführt werden muss und den Benutzer nicht einfach zur Eingabe des Kennworts auffordern kann.
Zu vermeidende Probleme:
- Einchecken des Passworts in die Quellcodeverwaltung, wo andere Entwickler oder sogar die Öffentlichkeit es sehen können.
- Andere Benutzer auf demselben Server lesen das Kennwort aus einer Konfigurationsdatei oder einem Quellcode.
- Das Passwort in einer Quelldatei haben, in der andere es über Ihre Schulter sehen können, während Sie es bearbeiten.
Option 1: SSH
Dies ist nicht immer eine Option, aber wahrscheinlich die beste. Ihr privater Schlüssel wird niemals über das Netzwerk übertragen. SSH führt lediglich mathematische Berechnungen durch, um zu beweisen, dass Sie den richtigen Schlüssel haben.
Damit es funktioniert, benötigen Sie Folgendes:
- Auf die Datenbank oder auf was auch immer Sie zugreifen, muss SSH zugreifen können. Versuchen Sie, nach "SSH" und dem Dienst zu suchen, auf den Sie zugreifen. Zum Beispiel "ssh postgresql" . Wenn dies keine Funktion in Ihrer Datenbank ist, fahren Sie mit der nächsten Option fort.
- Erstellen Sie ein Konto, um den Dienst auszuführen, der die Datenbank aufruft, und generieren Sie einen SSH-Schlüssel .
- Fügen Sie entweder den öffentlichen Schlüssel zu dem Dienst hinzu, den Sie aufrufen möchten, oder erstellen Sie ein lokales Konto auf diesem Server und installieren Sie den öffentlichen Schlüssel dort.
Option 2: Umgebungsvariablen
Dieser ist der einfachste, also könnte es ein guter Anfang sein. Es ist gut in der Twelve Factor App beschrieben . Die Grundidee ist, dass Ihr Quellcode nur das Kennwort oder andere Geheimnisse von Umgebungsvariablen abruft und Sie diese Umgebungsvariablen dann auf jedem System konfigurieren, auf dem Sie das Programm ausführen. Es kann auch eine nette Geste sein, wenn Sie Standardwerte verwenden, die für die meisten Entwickler funktionieren. Sie müssen das abwägen, um Ihre Software "standardmäßig sicher" zu machen.
Hier ist ein Beispiel, in dem Server, Benutzername und Kennwort aus Umgebungsvariablen abgerufen werden.
import os
server = os.getenv('MY_APP_DB_SERVER', 'localhost')
user = os.getenv('MY_APP_DB_USER', 'myapp')
password = os.getenv('MY_APP_DB_PASSWORD', '')
db_connect(server, user, password)
Suchen Sie nach Informationen zum Festlegen von Umgebungsvariablen in Ihrem Betriebssystem und erwägen Sie, den Dienst unter einem eigenen Konto auszuführen. Auf diese Weise haben Sie keine vertraulichen Daten in Umgebungsvariablen, wenn Sie Programme in Ihrem eigenen Konto ausführen. Achten Sie beim Einrichten dieser Umgebungsvariablen besonders darauf, dass andere Benutzer sie nicht lesen können. Überprüfen Sie beispielsweise die Dateiberechtigungen. Natürlich können alle Benutzer mit Root-Berechtigung sie lesen, aber das kann nicht geholfen werden.
Option 3: Konfigurationsdateien
Dies ist den Umgebungsvariablen sehr ähnlich, aber Sie lesen die Geheimnisse aus einer Textdatei. Ich finde die Umgebungsvariablen immer noch flexibler für Dinge wie Bereitstellungstools und Server für die kontinuierliche Integration. Wenn Sie sich für die Verwendung einer Konfigurationsdatei entscheiden, unterstützt Python verschiedene Formate in der Standardbibliothek, z. B. JSON , INI , netrc und XML . Sie können auch externe Pakete wie PyYAML und TOML finden . Ich persönlich finde JSON und YAML am einfachsten zu verwenden, und YAML erlaubt Kommentare.
Drei Dinge, die bei Konfigurationsdateien zu beachten sind:
- Wo ist die Datei? Möglicherweise ein Standardspeicherort wie
~/.my_app
und eine Befehlszeilenoption, um einen anderen Speicherort zu verwenden.
- Stellen Sie sicher, dass andere Benutzer die Datei nicht lesen können.
- Übertragen Sie die Konfigurationsdatei natürlich nicht in den Quellcode. Möglicherweise möchten Sie eine Vorlage festschreiben, die Benutzer in ihr Ausgangsverzeichnis kopieren können.
Option 4: Python-Modul
Einige Projekte stecken ihre Geheimnisse einfach direkt in ein Python-Modul.
# settings.py
db_server = 'dbhost1'
db_user = 'my_app'
db_password = 'correcthorsebatterystaple'
Importieren Sie dann dieses Modul, um die Werte abzurufen.
# my_app.py
from settings import db_server, db_user, db_password
db_connect(db_server, db_user, db_password)
Ein Projekt, das diese Technik verwendet, ist Django . Natürlich sollten Sie sich nicht settings.py
auf die Quellcodeverwaltung festlegen, obwohl Sie möglicherweise eine Datei festlegen möchten, settings_template.py
die Benutzer kopieren und ändern können.
Ich sehe einige Probleme mit dieser Technik:
- Entwickler könnten die Datei versehentlich der Quellcodeverwaltung übergeben. Durch Hinzufügen
.gitignore
wird dieses Risiko verringert.
- Ein Teil Ihres Codes unterliegt nicht der Quellcodeverwaltung. Wenn Sie diszipliniert sind und hier nur Zeichenfolgen und Zahlen eingeben, ist dies kein Problem. Wenn Sie hier Protokollierungsfilterklassen schreiben, hören Sie auf!
Wenn Ihr Projekt diese Technik bereits verwendet, ist der Übergang zu Umgebungsvariablen einfach. Verschieben Sie einfach alle Einstellungswerte in Umgebungsvariablen und ändern Sie das Python-Modul so, dass es aus diesen Umgebungsvariablen liest.