Kali-Linux mit XFCE im Docker-Container
Virtuelle Umgebung zum Aufbau von z.B. Schulungsumgebungen oder einfach nur als Jumphost.
Ich habe bereits in einem früheren Blogbeitrag beschrieben, wie man Xubuntu in einem Container betreiben kann. Leider war das nicht so stabil wie ich mir erhoffte.
Da ich in manchen Netzen einen vollständigen Linux-Desktop brauche, dort aber nur eine Docker-Umgebung vorhanden ist, muss ich das Projekt noch einmal etwas stabiler planen. Und das Ergebnis sieht sehr gut aus und lässt sich sehr einfach, wie auch schon die LXC-Variante, aus dem Internet erreichbar machen.
Überblick
Ich werde zuerst ein Image bauen und dieses dann für meinen Container nutzen. Dazu brauchen wir:
- Das Dockerfile, welches das Image beschreibt
- Daraus bauen wir dann das Image
- Mit dem Image starten wir dann einen Container
I. Dockerfile anlegen
Um ein Docker-Image zu bauen (denn diese Anforderung gibts ja noch nicht öffentlich 😉), müssen wir beschreiben, was sich darin befinden soll. Dies geschieht im Dockerfile. Ich habe folgendes dort eingetragen:
Schauen wir uns die einzelnen Schritte des Dockerfiles genauer an:
Basis-Image:
- Als Basis-Image wird "kalilinux/kali-rolling" verwendet.
Argument Definition:
- Diese Argumente übergeben wir später einfach beim Bauen des Images. Aber diese Form macht es später leichter etwas zu ändern oder auszuprobieren.
Umgebungsvariable:
DEBIAN_FRONTEND
habe ich auf "noninteractive" gesetzt, damit Paket-Installationen still im Hintergrund ablaufen.
Desktop-Umgebung:
- Wenn kein Wert für
DESKTOP_ENVIRONMENT
übergeben wird, wird standardmäßig "xfce" verwendet. - Entsprechend habe ich die passende Paketgruppe (
kali-desktop-${DESKTOP_ENVIRONMENT}
) zum Installieren definiert.
Fernzugriff:
- Ähnlich wie bei der Desktop-Umgebung wird ein Standardwert ("rdp") für
REMOTE_ACCESS
gesetzt und die passende Paketgruppe (x2goserver
oderxrdp
) festgelegt.
Kali-Pakete:
- Standardmäßig werden mit
kali-linux-default
die allgemeinen Kali-Pakete installiert. Da ich aber nur einen Desktop benötige, habe ich später beim Bauen des Images core übergeben.
Paket-Aktualisierung:
- Aktualisiert die Paketlisten und führt ein Upgrade aller installierten Pakete durch.
Grundlegende Pakete installieren:
- Installiert benötigte Pakete wie
sudo
,wget
,curl
und die Desktop-Umgebung.
Lokalisierung einrichten:
- Installiert Lokalisierungspakete.
- Aktiviert die deutsche Lokalisierung (
de_DE.UTF-8
). - Generiert die Lokalisierungsdaten.
Start-Skript erstellen:
- Erstellt ein Skript
/startkali.sh
, welches beim Starten des Containers verschiedene Dienste startet.
Kali-Pakete installieren:
- Installiert die ausgewählten Pakete aus den Kali-Repositories.
Benutzer anlegen:
- Legt einen neuen Benutzer (
UNAME
) mit Passwort (UPASS
) und Root-Rechten (sudo
) an.
SSH-Port ändern:
- Ändert den SSH-Port in der Konfigurationsdatei (
/etc/ssh/sshd_config
), da der standardmäßige Port (22) auf dem Host-System bereits belegt sein könnte.
Energiesparmodus deaktivieren (xfce):
- Deaktiviert den Energiesparmodus, falls die xfce-Desktop-Umgebung verwendet wird.
x2go Server installieren (optional):
- Installiert den x2go-Server, wenn RDP als Fernzugriff ausgewählt ist.
- Fügt den Befehl zum Starten des Servers dem
startkali.sh
-Skript hinzu.
xrdp Server installieren (optional):
- Installiert den xrdp-Server, wenn RDP als Fernzugriff ausgewählt ist (Achtung: Funktioniert aktuell nur mit xfce).
- Fügt Befehle zum Starten des Servers, Setzen des Ports (
RDP_PORT
) und Konfiguration des xrdp-Servers demstartkali.sh
-Skript hinzu. - Legt einen neuen Benutzer (
xrdp
) für den xrdp-Server an. - Setzt die gewünschte Desktop-Sitzung (
xfce4-session
) für den Benutzer.
tigervnc Server installieren (optional):
- Installiert den tigervnc-Server, wenn VNC ausgewählt wurde.
Whoohaa. Ja. Es ist etwas aufwändiger geworden. Aber dafür auch deutlich flexibler, wie man ab jetzt sehen kann 🙂.
II. Image bauen
Da wir im Dockerfile mit Argumenten/Variablen gearbeitet haben, können wir diese nun einfach übergeben. Der Build-Befehl sieht daher für mein Image so aus:
docker image build --platform linux/amd64 \
-t custom/kali-linux \
--build-arg DESKTOP_ENVIRONMENT=xfce \
--build-arg REMOTE_ACCESS=rdp \
--build-arg KALI_PACKAGE=core \
--build-arg RDP_PORT=3389 \
--build-arg VNC_PORT=5908 \
--build-arg VNC_DISPLAY=$XVNC_DISPLAY \
--build-arg SSH_PORT=20022 \
--build-arg BUILD_ENV=amd64 \
--build-arg HOSTDIR \
--build-arg CONTAINERDIR \
--build-arg UNAME=user \
--build-arg UPASS=theuserpasswd \
.
Wie man sieht, werden hier auch die Nutzerdaten festgelegt. Wer also einen anderen Benutzernamen oder Passwort haben will, hat hier die Gelegenheit das anzupassen. Schließlich werden einige Meldungen durch die Console laufen. Dies sind die Ausgaben der Befehle, die im Dockerfile durchlaufen werden.
III. Docker-Container
Wenn das Image fertig gestellt ist, können wir damit einen Container erstellen und starten. Ich habe ihn mit folgendem Befehl erstellt:
docker create --name kali-linux \
--network bridge \
--platform linux/amd64 \
-p 3389:3389 \
-p 5908:5908 \
-p 20022:20022 \
-t \
-v ./kali/home/user:/opt \
custom/kali-linux
Und dann einfach gestartet:
docker start kali-linux
Das wars dann auch schon. Jetzt kann man von Windows aus mittels mstsc.exe und den oben festgelegten Zugangsdaten user:theuserpasswd direkt auf den Desktop zugreifen. Oder von Linux aus mit folgendem Befehl:
xfreerdp /u:user /p:theuserpasswd /dynamic-resolution /v:[HOST_IP]
Das sieht dann so aus:
Wahrscheinlich will man nun noch seine Tastatur anpassen - Aber ab diesem Punkt hat man bereits ein bestens funktionierendes System. Es benötigt zwar mehr Speicher als die LXC-Lösung. Aber diese Anforderung stand in diesem Fall auf Platz 2.
Fazit
Die Daten persistent abzuspeichern ist noch nicht perfekt gelöst. Daher bevorzuge ich klar meine Proxmox LXC Lösung. Aber als stabiler Desktop in einer Docker-Welt ist dies ein sehr brauchbares System, welches sich auch wieder perfekt via Guacamole im Browserfenster anbieten lässt.
So lässt sich damit recht leicht eine Schulungsumgebung aufbauen, da jeder Teilnehmer schnell seinen Container zugewiesen bekommen kann. Und wenn dann jemand seine Umgebung zerschossen hat, hilft ein simpler Neustart des Containers und der saubere Ausgangszustand ist wieder hergestellt.