Ein Fehler im Server eines kleinen Shops
Jemand findet einen Fehler in dem Programm, das die Seiten eines Shops ausliefert. Jetzt kann er dieses Programm Dinge tun lassen.
Was er danach erreicht, hängt davon ab, als wer das Programm läuft. Es hängt auch davon ab, was sonst im Image steckt und was darin geschrieben steht.
Am Ende dieser Lektion
Notiz
Ich kann sagen, was ein Image sicher zum Ausliefern macht, und ein unsicheres Dockerfile verbessern.
Schlüsselbegriffe
| Begriff | Was er bedeutet | Beispiel |
|---|---|---|
| Root | der Benutzer, der auf dem System alles ändern darf | uid=0 |
| Normaler Benutzer | ein gewöhnlicher Benutzer mit begrenzten Rechten | |
| Fester Tag | ein Image-Tag, der genau eine Version nennt | nginx:1.27-alpine |
| Geheimnis | ein Passwort oder Schlüssel, den nur das Programm kennen soll | |
| Angriffsfläche | alles in einem Image, was ein Angreifer nutzen könnte |
Die Zellen, die Lernende ausfüllen, bleiben in dieser Vorschau leer.
Als Benutzer laufen, der wenig darf
Wenn nichts anderes gesagt wird, läuft das Programm eines Containers als root. Root darf jede Datei ändern, in die der Container schreiben kann, auch ein eingebundenes Volume.
Ein normaler Benutzer darf das nicht. Wird das Programm angegriffen, bleibt der Schaden kleiner. Vergleichen Sie die beiden Hauptdienste Ihres Labs.
Als wer läuft web?
docker exec web idHier angezeigt, nicht ausgeführt. Erstellen Sie ein kostenloses Konto, um „Ausführen“ zu drücken und ihn im Terminal Ihres eigenen Labs einzugeben.
Als wer läuft cache?
docker exec cache idHier angezeigt, nicht ausgeführt. Erstellen Sie ein kostenloses Konto, um „Ausführen“ zu drücken und ihn im Terminal Ihres eigenen Labs einzugeben.
cache in /etc schreiben lassen
docker exec cache touch /etc/probeHier angezeigt, nicht ausgeführt. Erstellen Sie ein kostenloses Konto, um „Ausführen“ zu drücken und ihn im Terminal Ihres eigenen Labs einzugeben.
web dasselbe versuchen lassen
docker exec web touch /etc/probeHier angezeigt, nicht ausgeführt. Erstellen Sie ein kostenloses Konto, um „Ausführen“ zu drücken und ihn im Terminal Ihres eigenen Labs einzugeben.
Einen Benutzer im Dockerfile anlegen
FROM python:3.12-alpine
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY app.py .
RUN adduser -D -u 10001 shop
USER shop
CMD ["python", "app.py"]
Ein häufiger Irrtum
Warnung
Viele glauben, root im Container sei egal, weil der Container abgeschottet ist. Wände haben Fehler, und ein eingebundenes Volume sind echte Daten. Legen Sie einen Benutzer an und wechseln Sie mit USER zu ihm, wie es der cache des Labs tut.
Weniger im Image, weniger anzugreifen
Jedes Programm in einem Image ist eine mögliche Schwachstelle mehr. Jedes Werkzeug ist ein Werkzeug mehr für einen Angreifer.
Eine schlanke Basis wie ein Alpine-Image enthält viel weniger. Der Tag entscheidet, welche Version Sie bekommen. Ein Tag wie latest wandert: Ein Neubau im nächsten Monat kann ein anderes Image sein.
Beispiel: zwei Tags eines Images
| Tag | Größe auf unserem Testrechner | Was es bedeutet |
|---|---|---|
| nginx:1.27 | 284 MB | ein volles System darunter |
| nginx:1.27-alpine | 76,8 MB | ein kleines System darunter |
| nginx:latest | nicht gemessen | was beim Bauen gerade am neuesten ist |
Die Zellen, die Lernende ausfüllen, bleiben in dieser Vorschau leer.
Welchen Tag legt cache fest?
docker inspect --format '{{.Config.Image}}' cacheHier angezeigt, nicht ausgeführt. Erstellen Sie ein kostenloses Konto, um „Ausführen“ zu drücken und ihn im Terminal Ihres eigenen Labs einzugeben.
Ein Geheimnis im Image bleibt dort
Ein Image wird geteilt. Es wird in eine Registry geschoben, auf Server kopiert und an Kollegen gegeben. Was in einem Layer liegt, reist mit.
Ein Passwort in einem Dockerfile bleibt für immer in den Layern, auch wenn ein späterer Schritt die Datei löscht. Halten Sie Geheimnisse aus dem Image heraus und geben Sie sie dem Container beim Start.
Ein Dockerfile mit Geheimnis, nicht nachmachen
FROM alpine:3.20
ENV API_KEY=abc123-not-real
RUN echo hello
Beispiel: wo ein Geheimnis auftauchte
| Wie es gesetzt wurde | Wo wir es zurückgelesen haben | Was erschien |
|---|---|---|
| ENV im Dockerfile | docker history --no-trunc | die Zeile ENV API_KEY=abc123-not-real |
| -e beim Start des Containers | docker inspect, Config.Env | DB_PASSWORD=hunter2 in der Liste |
| Keines von beiden | nichts im Image oder in den Einstellungen | ein Geheimnis, das erst zur Laufzeit übergeben wird |
Die Zellen, die Lernende ausfüllen, bleiben in dieser Vorschau leer.
Alles lesen, was cache gesagt wurde
docker inspect --format '{{json .Config.Env}}' cacheHier angezeigt, nicht ausgeführt. Erstellen Sie ein kostenloses Konto, um „Ausführen“ zu drücken und ihn im Terminal Ihres eigenen Labs einzugeben.
Weiterführend
Nehmen Sie das Dockerfile mit dem Geheimnis. Schreiben Sie es so um, dass es seinen Tag festlegt, als Benutzer läuft und kein Geheimnis enthält.
Führen Sie dann die drei Funktionen der Aufgabe auf der alten und Ihrer neuen Fassung aus. Die neue sollte sauber durchkommen.