Einführung
Mehrschichtige Verteidigung (Defense in Depth) bedeutet, mehrere Sicherheitskontrollen zu kombinieren, damit ein einzelner Fehler nicht sofort ein wichtiges Asset gefährdet. Eine Token-Prüfung, eine lokale Netzwerkbindung, Dateiberechtigungen und eine Protokollierung schützen jeweils einen anderen Aspekt desselben Dienstes.
In diesem Lab härten Sie einen kleinen Python-Dienst, der eine geheime Datei ausliest. Sie nehmen jeweils eine kleine Änderung vor, starten den Dienst, testen ihn mit curl und überprüfen, wie die verschiedenen Ebenen zusammenwirken.
Start mit einem ungeschützten Geheimnis
In diesem Schritt untersuchen Sie den Dienst und beobachten die erste Kontrollinstanz: Eine Anfrage ohne das erwartete Token wird abgelehnt, während eine Anfrage mit dem korrekten Token erfolgreich ist. Mehrschichtige Verteidigung beginnt damit, zu prüfen, was bereits geschützt ist und wo eine weitere Schutzschicht erforderlich ist.
Wechseln Sie in das Projektverzeichnis:
cd /home/labex/project
Listen Sie die vorbereiteten Dateien auf:
ls -l
Sie sollten secret_service.py, secret.txt und service-check.py sehen.
Starten Sie den Dienst im Hintergrund. Das & am Ende weist die Shell an, den Dienst weiterlaufen zu lassen, während Sie weitere Befehle eingeben:
python3 secret_service.py > service.log 2>&1 &
Speichern Sie die Prozess-ID des Hintergrundprozesses, damit Sie ihn später sauber beenden können:
echo $! > service.pid
Versuchen Sie, das Geheimnis ohne Token auszulesen:
curl -i http://127.0.0.1:8081/secret
Die Antwort sollte 403 Forbidden enthalten. Senden Sie nun den erforderlichen Token-Header:
curl -s -H "X-Access-Token: lab-token-2026" http://127.0.0.1:8081/secret
Sie sollten Folgendes sehen:
Project launch code: ORBIT-742
Stoppen Sie den Dienst, bevor Sie fortfahren:
kill "$(cat service.pid)"
Führen Sie die Überprüfung für die Token-Ebene aus:
python3 service-check.py token
Das erwartete Ergebnis ist:
token: complete
Den Dienst lokal halten
In diesem Schritt bestätigen Sie die Ebene der Netzwerk-Exponierung. Ein Dienst, der nur lokalen Zugriff benötigt, sollte an 127.0.0.1 gebunden sein, auch bekannt als localhost. Diese Adresse akzeptiert nur Verbindungen von derselben Maschine.
Überprüfen Sie die Standard-Host-Einstellung des Dienstes:
grep 'default="127.0.0.1"' secret_service.py
Sie sollten die Argumentdefinition für die Option --host sehen. Dieser Standardwert bedeutet, dass der Befehl python3 secret_service.py den Dienst auf localhost startet.
Starten Sie den Dienst erneut:
python3 secret_service.py > service.log 2>&1 &
Speichern Sie die Prozess-ID:
echo $! > service.pid
Verwenden Sie ss, um die lauschenden TCP-Sockets zu untersuchen. Die Optionen -ltn stehen für listening, TCP und numerische Adressen:
ss -ltn | grep ':8081'
Die Ausgabe sollte 127.0.0.1:8081 zeigen, was beweist, dass der Dienst nur lokal erreichbar ist:
LISTEN ... 127.0.0.1:8081 ...
Stoppen Sie den Dienst:
kill "$(cat service.pid)"
Führen Sie die Überprüfung für die Localhost-Ebene aus:
python3 service-check.py localhost
Das erwartete Ergebnis ist:
localhost: complete
Die geheime Datei einschränken
In diesem Schritt fügen Sie eine Ebene mit Dateisystemberechtigungen hinzu. Selbst wenn der Dienst einen Fehler aufweist, sollte die geheime Datei nicht für jedes lokale Konto lesbar sein.
Überprüfen Sie die aktuellen Dateiberechtigungen:
ls -l secret.txt
Die Datei hat anfangs breitere Berechtigungen, damit Sie diese verbessern können. Verwenden Sie chmod 600, um die Datei nur für den Besitzer lesbar und beschreibbar zu machen:
chmod 600 secret.txt
Überprüfen Sie die Berechtigungen erneut:
ls -l secret.txt
Die Berechtigungsbits sollten nun mit -rw------- beginnen:
-rw------- ... secret.txt
Führen Sie die Überprüfung für diese Ebene aus:
python3 service-check.py permissions
Das erwartete Ergebnis ist:
permissions: complete
Abgelehnte Anfragen protokollieren
In diesem Schritt testen Sie die Erkennungsebene. Das Blockieren einer unbefugten Anfrage ist nützlich, aber die Aufzeichnung dieser Ablehnung liefert Administratoren den Beweis, dass jemand versucht hat, auf die geschützte Route zuzugreifen.
Löschen Sie alte Protokolldateien, damit dieser Schritt sauber beginnt:
rm -f access.log
Starten Sie den Dienst:
python3 secret_service.py > service.log 2>&1 &
Speichern Sie die Prozess-ID:
echo $! > service.pid
Senden Sie eine Anfrage ohne Token:
curl -s http://127.0.0.1:8081/secret
Der Antworttext sollte wie folgt lauten:
forbidden
Sehen Sie sich das Zugriffsprotokoll an:
cat access.log
Das Protokoll sollte rejected, /secret und missing_or_bad_token enthalten.
Stoppen Sie den Dienst:
kill "$(cat service.pid)"
Führen Sie die Überprüfung für die Protokollierungsebene aus:
python3 service-check.py logging
Das erwartete Ergebnis ist:
logging: complete
Die Ebenen gemeinsam verifizieren
In diesem Schritt verifizieren Sie das vollständige Ergebnis der mehrschichtigen Verteidigung. Der Dienst sollte das Token erfordern, standardmäßig lokal bleiben, die geheime Datei mit Berechtigungen nur für den Besitzer schützen und abgelehnte Anfragen protokollieren.
Führen Sie die vollständige Überprüfung aus:
python3 service-check.py all
Jede Ebene sollte als abgeschlossen markiert sein:
token: complete
localhost: complete
permissions: complete
logging: complete
Starten Sie den Dienst ein letztes Mal:
python3 secret_service.py > service.log 2>&1 &
Speichern Sie die Prozess-ID:
echo $! > service.pid
Bestätigen Sie, dass das Geheimnis für eine autorisierte Anfrage weiterhin funktioniert:
curl -s -H "X-Access-Token: lab-token-2026" http://127.0.0.1:8081/secret
Sie sollten weiterhin Folgendes sehen:
Project launch code: ORBIT-742
Stoppen Sie den Dienst:
kill "$(cat service.pid)"
Diese abschließende Prüfung ist wichtig, da die mehrschichtige Verteidigung den Dienst schützen sollte, ohne die beabsichtigte autorisierte Nutzung zu beeinträchtigen.
Zusammenfassung
Sie haben das Prinzip der mehrschichtigen Verteidigung geübt, indem Sie verschiedene Kontrollen um einen kleinen Dienst herum aufgebaut haben. Sie haben eine Token-Anforderung, eine lokale Bindung, Dateiberechtigungen nur für den Besitzer und die Protokollierung abgelehnter Zugriffe verifiziert.
Die wichtigste Erkenntnis ist, dass jede Ebene einen anderen potenziellen Fehlerpunkt absichert, während das autorisierte Verhalten des Dienstes weiterhin gewährleistet bleibt.



