Compare commits

...

4 Commits

Author SHA1 Message Date
61c30e6af5
sicherheit 2025-02-11 17:22:22 +01:00
16b10d9f87
wording 2025-02-11 16:57:56 +01:00
fc5911df8c
fix typo 2025-02-11 16:27:11 +01:00
d0a48376e0
write stuff 2025-02-11 16:26:41 +01:00
5 changed files with 102 additions and 25 deletions

View File

@ -6,7 +6,7 @@
In der Arbeitsumgebung des Partnerunternehmens besteht zum Zeitpunkt der Themenfindung der hier beleuchteten Arbeit kein In der Arbeitsumgebung des Partnerunternehmens besteht zum Zeitpunkt der Themenfindung der hier beleuchteten Arbeit kein
Management für Secrets und Logindaten zwischen Entwickler*innen. Logindaten zu den Projekten des Unternehmens liegen schlicht in einem \ac{1P}-Vault. Management für Secrets und Logindaten zwischen Entwickler*innen. Logindaten zu den Projekten des Unternehmens liegen schlicht in einem \ac{1P}-Vault.
\ac{1P} ist der vom Unternehmen verwendete Passwortmanager. Auf diesen Vault haben sämtliche internen Entwickler*innen Zugriff, jedoch keine externen Entwickler*innen. \ac{1P} ist der vom Unternehmen verwendete Passwortmanager. Auf diesen Vault haben sämtliche internen Entwickler*innen Zugriff, jedoch keine externen Entwickler*innen.
Das ist so, weil anderenfalls dLesezugriff auf sämtliche Einträge dieses Vaults gegeben werden müssten. Das ist so, weil anderenfalls Lesezugriff auf sämtliche Einträge dieses Vaults gegeben werden müssten.
\ac{1P} unterstützt keine Freigaben einzelner Einträge an andere Nutzer, ohne diese Einträge in einen eigenen Vault zu kopieren. \ac{1P} unterstützt keine Freigaben einzelner Einträge an andere Nutzer, ohne diese Einträge in einen eigenen Vault zu kopieren.
Würden diese manuell in einen eigenen Vault kopiert werden, müssten diese Einträge fortan redundant gepflegt werden. Das ist eine Fehlerquelle, die zu Würden diese manuell in einen eigenen Vault kopiert werden, müssten diese Einträge fortan redundant gepflegt werden. Das ist eine Fehlerquelle, die zu
asynchronen Einträgen führt. Außerdem ist das ein großer Arbeitsaufwand. asynchronen Einträgen führt. Außerdem ist das ein großer Arbeitsaufwand.

View File

@ -128,7 +128,7 @@ abgefragt werden. Hier ist ein CLI-API-Aufruf pro Eintrag erforderlich. Sind ein
mit einer bestimmten originalen ID im Durchschnitt $n=30; \frac{n}{2} = 15$ Sekunden. Im langsamsten Fall wären es $n=30$ Sekunden. mit einer bestimmten originalen ID im Durchschnitt $n=30; \frac{n}{2} = 15$ Sekunden. Im langsamsten Fall wären es $n=30$ Sekunden.
Ein Kopierforgang stellt zwei Aufrufe dar (=\textit{lesen,erstellen}), also dauert das Kopieren von 30 Einträgen $n=30; 2n = 60$ Sekunden. Ein Kopierforgang stellt zwei Aufrufe dar (=\textit{lesen,erstellen}), also dauert das Kopieren von 30 Einträgen $n=30; 2n = 60$ Sekunden.
Das \ac{1P}-CLI kann zwar für Detail-Aufrufe mehrere Eintrags-IDs auf Standard-Input annehmen und bearbeiten, jedoch zeigen Versuche des Autors dies zu implementieren, dass das nicht die Das \ac{1P}-CLI kann zwar für Detail-Aufrufe mehrere Eintrags-IDs auf Standard-Input annehmen und bearbeiten, jedoch zeigen Versuche des Autors dies zu implementieren, dass das nicht die
Zeitkomplexität von $O(n)$ verändert. Das heisst, eine Anfrage für 10 Einträge zu stellen, dauert in etwa zehn mal so lange, Zeitkomplexität von $O(n)$ verändert. Das heißt, eine Anfrage für 10 Einträge zu stellen, dauert in etwa zehn mal so lange,
wie zehn Anfragen für jeweils einen Eintrag zu stellen. wie zehn Anfragen für jeweils einen Eintrag zu stellen.
Eine spätere Ergänzung, um die programmatische Auslesung der Einträge in $O(n)$ anstatt $O(n^2)$ zu gewährleisten, ist die Unterhaltung von Mapping-Objekten in Entwickler*innen-Vaults. Eine spätere Ergänzung, um die programmatische Auslesung der Einträge in $O(n)$ anstatt $O(n^2)$ zu gewährleisten, ist die Unterhaltung von Mapping-Objekten in Entwickler*innen-Vaults.
@ -210,47 +210,112 @@ Ein Beispiel mit dem im Rahmen dieser Ausarbeitung bereitgestellten Filtermodul
\label{fig:flowchart-filtermodule-resolve-1p-secret} \label{fig:flowchart-filtermodule-resolve-1p-secret}
\end{nicepic} \end{nicepic}
Die generelle Funktionsweise des Filtermoduls ist es, drei Arten von Eingabeformaten zu unterstützen. \subsection{Akzeptierte Formate}
Diese sind: Das Filtermodul akzeptiert mehrere, verschiedene Eingabeformate und ist rückwärtskompatibil.
\subsection*{Kein erkanntes Format}
Wird kein bekanntes Format, wird der Wert unverändert zurückgegeben. Das ermöglicht Rückwärtskompatibilät, dass
nach-wie-vor hardgecodede Secrets weiterhin funktionieren, und nicht versehentlich als \ac{UUID} interpretiert werden.
\subsection*{1P:<...>} \subsubsection*{Kein erkanntes Format}
Beginnt der Wert mit \enquote{1P:}, so wird alles nach danach als \ac{UUID} interpretiert. Wird kein bekanntes Format erkannt, wird der Wert unverändert zurückgegeben. Das ermöglicht Rückwärtskompatibilät,
sodass nach-wie-vor hardgecodede Secrets funktionieren, und nicht versehentlich als \ac{UUID} interpretiert werden.
Das gewährleistet eine flüssigere Migration der Host-Konfigurationen, da somit bestehende Dateien weiterhin valide sind.
\subsubsection*{1P:<...>}
Beginnt der Wert mit \enquote{1P:}, so wird alles Nachfolgende als \ac{UUID} interpretiert.
Es wird versucht, das Feld \enquote{password} aus diesem Eintrag zu dereferenzieren. Es wird versucht, das Feld \enquote{password} aus diesem Eintrag zu dereferenzieren.
\subsection*{Objektformat} \subsubsection*{Objektformat}
Wird ein Yaml-Objekt übergeben, werden die Keys \enquote{1P\_secret\_uuid} und \enquote{1P\_field\_id} erwartet, Wird ein Yaml-Objekt übergeben, so werden die Keys \enquote{1P\_secret\_uuid} und \enquote{1P\_field\_id} erwartet.
die die \ac{UUID} und eine Feld-ID für den Eintrag erwarten. Das ermöglicht z.B. auch den Benutzernamen (\textit{1P\_field\_id: username}) eines Diese definieren die Werte der Eintrags-\ac{UUID} und der Feld-ID in der ein Secret steht. Das ermöglicht z.B. auch den Benutzernamen (\textit{1P\_field\_id: username}) eines
Eintrages abzufragen, anstelle nur des Passworts. Ist keine Feld-ID gegeben, wird auf den Standardwert \enquote{password} zurückgefallen. Eintrages abzufragen, anstelle nur des Passworts. Ist keine Feld-ID gegeben, so wird auf das Standardfeld \enquote{password} zurückgefallen.
\subsection{Übersetzung der UUIDs} \subsection{Übersetzung der UUIDs}
Um die für eine*n Entwickler*in gegebene, private \ac{UUID} für eine öffentliche, sich in der Host-Konfiguration gesetzte Um die private \ac{UUID} zu ermitteln, die zu der öffentlichen \ac{UUID} gehört, die in der Host-Konfiguration steht,
\ac{UUID} zu ermitteln, frägt das Filtermodul zunächst den Mapping-Eintrag aus dem Entwickler*innen-Vault ab und schlägt frägt das Filtermodul den Mapping-Eintrag aus dem jeweiligen Entwickler*innen-Vault an und schlägt die öffentliche \ac{UUID} darin nach.
hierin die öffentliche \ac{UUID} nach. Die daraus resultierende \ac{UUID} kann von einem*r externen Entwickler*in angefragt werden.
\subsection{Unterscheidung zwischen internen und externen Entwickler*innen} \subsection{Unterscheidung zwischen internen und externen Entwickler*innen}
Ist in der Docker-Ansible-Konfigurationsdatei eine Entwickler*innen-Vault-\ac{UUID} definiert, wird von einem*r externe*n Entwickler*in ausgegangen. Ist in der Docker-Ansible-Konfigurationsdatei eine Entwickler*innen-Vault-\ac{UUID} definiert, so wird von einem*r externe*n Entwickler*in ausgegangen.
Ist stattdessen definiert, dass die in den Host-Konfigurationen angegebenen, öffentlichen \acp{UUID} direkt angefragt werden sollen, wird Ist stattdessen definiert, dass die in den Host-Konfigurationen angegebenen, öffentlichen \acp{UUID} direkt angefragt werden sollen, wird
von einem*r interne*n Entwickler*in ausgegangen. Sind beide Konfigurationen gegeben, wird ein Inkompatibilitätsfehler erhoben. von einem*r interne*n Entwickler*in ausgegangen. Sind beide Konfigurationen zugleich gegeben, wird ein Inkompatibilitätsfehler erhoben.
Ist ein*e interne*r Entwickler*in angenommen, so wird der Mapping-Schritt übersprungen. Der verbleibende Prozess bleibt unberührt. Ist ein*e interne*r Entwickler*in angenommen, so wird der Mapping-Schritt übersprungen. Der verbleibende Prozess bleibt unberührt.
\subsection{Kommunikation mit 1Password} \subsection{Kommunikation mit 1Password}
Ist eine \ac{UUID} ermittelt, auf die der*ie Nutzer*in Zugriff hat, wird diese über das \ac{1P}-CLI angefragt. Ist eine \ac{UUID} ermittelt, auf die der*ie Nutzer*in Zugriff hat, wird diese über das \ac{1P}-CLI angefragt.
Das geht via \textit{op item get <UUID>} mit dem Zusatz \textit{--format json}, um die Ausgabe programmatisch auswertbar zu machen. Dieser Aufruf ist: \textit{op item get <UUID>} mit dem Zusatz \textit{--format json}, um die Ausgabe programmatisch auswerten zu können.
\subsection{Performanz und Benchmarks} \subsection{Performanz und Benchmarks}
Um diese Konfiguration zu testen, werden in einem Testszenario fünf Werte aus \ac{1P} ausgelesen: Um diese Konfiguration zu testen, werden in einem Testszenario fünf Werte aus \ac{1P} ausgelesen:
\begin{itemize} \begin{itemize}
\item[Datenbank-Host] \item Datenbank-Host
\item[Datenbank-Port] \item Datenbank-Port
\item[Datenbank-Benutzername] \item Datenbank-Benutzername
\item[Datenbank-Passwort] \item Datenbank-Passwort
\item[Datenbank-Name] \item Datenbank-Name
\end{itemize} \end{itemize}
Diese Einträge abzufragen dauert durch das imperformante \ac{1P}-CLI rund 17 Sekunden. Diese Einträge abzufragen dauert durch das imperformante \ac{1P}-CLI rund 17 Sekunden.
\subsection{Optimierung} \subsection{Optimierung}
Es bieten sich einige Möglichkeiten an den in \fullref{fig:flowchart-resolve-1p-secret} zu beschleunigen. Es bieten sich zwei Möglichkeiten an, den in \fullref{fig:flowchart-filtermodule-resolve-1p-secret} abgebildeten Prozess zu beschleunigen.
Diese beschäftigen sich damit, zu limitieren, wie oft das \ac{1P}-CLI angefragt wird:
\begin{description}
\item [Das Mapping-Objekt zwischenspeichern] \hfill \\
Anstatt das Mapping-Objekt für jedes angefragte Secret erneut abzufragen, könnte es zwischengespeichert werden.
\item [Ganze Einträge zwischenspeichern] \hfill \\
Für den Fall, dass ein Eintrag mehrach angefragt wird, könnte ein einmal angefragter Eintrag zwischengespeichert werden.
Würden mehrere Felder eines Eintrages angefragt werden (z.B. \textit{=Host, Port, Benutzername, Passwort, Name}), so müsse der gesamte Eintrag nur ein mal angefragt werden.
\end{description}
All diese Ansätze erfordern es Daten zwischenzuspeichern. Filtermodule haben allerdings keinen persistenten Arbeitsspeicher über verschiedene Aufrufe hinaus.
E.g. nach jedem angefragten Secret, verliert er seinen internen Zustand.
Daher muss dieses zwischengespeichert in einer Datei stattfinden. Hierfür wird eine Tempdatei über Pythons \textit{tempfile.gettempdir()}-Funktion ermittelt.
Diese Zwischenspeicher beinhalten die vom \ac{1P}-CLI zurückgegebenen Informationen.
\begin{nicepic}
\includegraphics[width=1\textwidth]{images/flowchart-resolve-1p-secret-with-caching.png}
\captionof{figure}{Flussdiagramm: Businesslogik des 1P-Resolver-Filtermoduls, mit Zwischenspeicher}
\caption*{Quelle: Eigene Darstellung}
\label{fig:flowchart-filtermodule-resolve-1p-secret-with-caching}
\end{nicepic}
\subsubsection{Mapping-Zwischenspeicher}
Wenn das Mapping-Objekt angefragt wird, so wird zunächst geprüft, ob es eine lokal zwischengespeicherte Version gibt.
Falls ja, wird diese geladen und verwendet.
Falls nein, wird es via dem \ac{1P}-CLI angefragt und lokal gespeichert.
Sollte der Mapping-Zwischenspeicher verwendet werden und das gesuchte Objekt nicht darin gefunden werden, so wird dieser Zwischenspeicher gelöscht und das Mapping-Objekt erneut angefragt.
Das deckt folgenden Problemfall ab:
\begin{enumerate}
\item Zwischenspeicher wird erstellt
\item Entwickler*in erhält mehr Berechtigungen
\item Entwickler*in will diese Berechtungen nutzen
\item Der Zwischenspeicher wird verwendet, spiegelt diese neuen Berechtigungen aber nicht wider
\item Der Prozess schlägt zu Unrecht fehl
\end{enumerate}
Dieser Prozess würde durch diese Vorkehrung so aussehen:
\begin{enumerate}
\item Zwischenspeicher wird erstellt
\item Entwickler*in erhält mehr Berechtigungen
\item Entwickler*in will diese Berechtungen nutzen
\item Der Zwischenspeicher wird verwendet, spiegelt diese neuen Berechtigungen aber nicht wider
\item Das System erneuert den Zwischenspeicher
\item Der Zwischenspeicher spiegelt nun die neuen Berechtiungen wider
\item Der Prozess ist erfolgreich
\end{enumerate}
Durch die Implementation des Mapping-Zwischenspeichers wird die Ausführzeit von 17 Sekunden auf acht Sekunden reduziert.
\subsubsection{Eintrags-Zwischenspeicher}
Wird ein Eintrag von \ac{1P} angefragt, so wird dieser lokal zwischengespeichert. Das stellt ein Problem dar, sobald der Eintrag
im Entwickler*innen-Vault manuell verändert wird. Das ist jedoch nicht angedacht.
Die Entwickler*innen sollten keine Schreibberechtigung auf diesen haben und das Synchronisierungs-Werkzeug
löscht Einträge und erstellt diese neu. Damit erhalten diese eine neue \ac{UUID} und sind somit im Zwischenspeicher nicht mehr repräsentiert.
\subsubsection{Eintrags-Zwischenspeicher}
Durch das implementieren des Eintrags-Zwischenspeichers wird die Ausführzeit von acht Sekunden auf zwei Sekunden reduziert.
\subsubsection{Sicherheit}
Um zu vermeiden, dass sensible Daten, wie zum Beispiel die Secrets in den Eintrags-Daten des Passwortmanagers im Klartext im Zwischenspeicher, für viele Prozesse lesbar, gespeichert werden,
werden diese in der Schreib- und Lesefunktion mit AES-256 verschlüsselt.
Die Wahl fällt auf AES-256, weil es keine bekannten Angriffe gegen AES-256 gibt, die wesentlich effektiver sind als generische Angriffe gegen Blockchiffren. \cite{bib:BSI-TR-02102-1-2024}

View File

@ -42,3 +42,15 @@
year = {2025}, year = {2025},
note = {Zugriff: Februar 2025} note = {Zugriff: Februar 2025}
} }
@techreport{bib:BSI-TR-02102-1-2024,
author = {{ BSI }},
title = {Cryptographic Mechanisms: Recommendations and Key Lengths},
institution = {Federal Office for Information Security (BSI)},
type = {Technical Guideline TR-02102},
version = {2024-1},
number = {TR-02102-1},
date = {2024-02-02},
year = {2024},
note = {Provides an assessment of the security and long-term orientation for selected cryptographic mechanisms.},
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 136 KiB

BIN
main.pdf

Binary file not shown.