Website-Suche

So automatisieren Sie das Einbinden von /dev in Chroot-Umgebungen unter Linux


Wenn Sie mmdebstrap verwenden, um minimale Debian-basierte Systeme zu erstellen, könnte es lästig sein, das /dev-Verzeichnis jedes Mal manuell einzuhängen und auszuhängen, wenn Sie das Chroot verwenden. Die gute Nachricht ist, dass es Möglichkeiten gibt, diesen Prozess zu automatisieren! In diesem Leitfaden zeigen wir Ihnen, wie Sie Ihren Arbeitsablauf effizienter gestalten können, indem Sie das /dev automatisch einhängen, wenn Sie die Chroot-Umgebung betreten, und es aushängen, wenn Sie sie verlassen.

Warum das Einbinden von /dev automatisieren?

Wenn Sie eine Chroot-Umgebung erstellen, hat sie standardmäßig keinen Zugriff auf das /dev-Verzeichnis des Hostsystems. Dies kann zu Fehlern führen, wenn Befehle wie apt update ausgeführt werden, da Programme Zugriff auf Gerätedateien wie /dev/null benötigen.

[...]
/usr/bin/apt-key: 95: cannot create /dev/null: Permission denied
/usr/bin/apt-key: 95: cannot create /dev/null: Permission denied
E: gpgv, gpgv2 or gpgv1 required for verification, but neither seems installed
Err:3 http://deb.debian.org/debian bookworm-updates InRelease
  gpgv, gpgv2 or gpgv1 required for verification, but neither seems installed
[...]

Sie können dieses Problem lösen, indem Sie /dev manuell einhängen ([[Fehlerbehebung mmdebstrap]]) jedes Mal, wenn Sie das Chroot verwenden. Aber es ist mühsam und zeitaufwendig. Die Automatisierung dieses Prozesses spart Ihnen Aufwand und macht Ihren Arbeitsablauf reibungsloser.

Lösung 1: Verwenden Sie systemd-nspawn, um das Einbinden von /dev in einem Chroot zu automatisieren

systemd-nspawn ist ein Kommandozeilen-Tool, das Teil der systemd-Suite ist und es Ihnen ermöglicht, leichte, isolierte Systemcontainer auf Linux-Systemen zu erstellen und auszuführen. Es bietet eine Möglichkeit, Befehle oder sogar ganze Betriebssysteme innerhalb einer geschützten Umgebung auszuführen.

Das systemd-nspawn-Werkzeug kann das Einhängen von /dev und anderen Verzeichnissen automatisch übernehmen.

Schritt 1: Installiere systemd-nspawn

Auf Debian-basierten Systemen installieren Sie es mit:

sudo apt update
sudo apt install systemd-container

Schritt 2: Betreten Sie das Chroot mit systemd-nspawn

Erstellen Sie eine chroot-Umgebung mit mmdebstrap:

mmdebstrap --variant=minbase stable /tmp/debian-rootfs

Als Nächstes betreten Sie die chroot mit dem Befehl:

sudo systemd-nspawn -D /tmp/debian-rootfs

systemd-nspawn mountet /dev, /proc und /sys automatisch innerhalb des Chroots. Wenn Sie den Chroot verlassen, werden diese Verzeichnisse automatisch ungemountet.

Lösung 2: Verwenden Sie das Chrootmnt-Skript, um /dev in Chroot-Umgebungen automatisch zu mounten und zu unmounten

Chrootmnt ist ein Bash-Skript zum Einhängen und Aushängen von /dev innerhalb einer Chroot-Umgebung, das einen nahtlosen Gerätezugriff und eine automatische Bereinigung für eine sichere Linux-Systemverwaltung gewährleistet.

Hauptmerkmale

  1. Flexible Eingaben: Funktioniert mit jedem chroot-Verzeichnis und Befehl.
  2. Fehlerbehandlung: Verhindert Ausfälle, die durch fehlende Verzeichnisse oder falsche Argumente verursacht werden.
  3. Automatische Bereinigung: Vermeidet das Hinterlassen von eingebundenen Ressourcen im Falle einer Unterbrechung.
  4. Unterstützung für Pseudo-Terminals: Gewährleistet die Kompatibilität mit interaktiven Tools wie SSH, screen und tmux.

Das Chrootmnt-Skript ist auf unserer OSTechNix GitHub Gist-Seite verfügbar. Sie können es frei herunterladen und nach Belieben ändern.

Schritt 1: Erstellen Sie das Drehbuch

Speichern Sie das folgende Skript als chrootmnt.sh:

#!/usr/bin/env bash

# ------------------------------------------------------------------
# Script Name:   chrootmnt.sh
# Description:   A Bash script to mount and unmount /dev 
#                inside a chroot environment
# Website:       https://gist.github.com/ostechnix
# Version:       1.0
# Usage:         ./chrootmnt.sh /path/to/chroot command args
# ------------------------------------------------------------------

# Validate input
if [ $# -lt 2 ]; then
  echo "Usage: $0 /path/to/chroot command [args...]"
  exit 1
fi

# Path to the chroot directory
CHROOT_DIR="$1"
shift  # Remove the first argument (chroot path)

# Ensure the chroot directory exists
if [ ! -d "$CHROOT_DIR" ]; then
  echo "Error: Chroot directory $CHROOT_DIR does not exist."
  exit 1
fi

# Mount /dev and /dev/pts
sudo mount --bind /dev "$CHROOT_DIR/dev"
sudo mount --bind /dev/pts "$CHROOT_DIR/dev/pts"

# Handle unmounting on exit
cleanup() {
  sudo umount "$CHROOT_DIR/dev/pts"
  sudo umount "$CHROOT_DIR/dev"
}
trap cleanup EXIT

# Enter the chroot
sudo chroot "$CHROOT_DIR" "$@"

Hier ist eine schrittweise Erklärung, wie das Skript funktioniert:

1. Eingabevalidierung

if [ $# -lt 2 ]; then
  echo "Usage: $0 /path/to/chroot command [args...]"
  exit 1
fi
  • Stellt sicher, dass der Benutzer mindestens zwei Argumente angibt:

    1. Der Pfad zum Chroot-Verzeichnis.
    2. Ein Befehl (z. B. /bin/bash), der innerhalb des chroot ausgeführt werden soll.
  • Wenn Argumente fehlen, werden die Benutzungsanweisungen angezeigt und das Programm beendet.

2. Speicherargumente

CHROOT_DIR="$1"
shift  # Remove the first argument (chroot path)
  • Speichert den Chroot-Verzeichnispfad in CHROOT_DIR.
  • Verwendet shift, um dieses Argument zu entfernen und nur den Befehl sowie seine optionalen Argumente zu belassen.

    • Beispiel: Wenn die Eingabe ist: ./chrootmnt.sh /tmp/debian-rootfs /bin/bash

      • CHROOT_DIR=/tmp/debian-rootfs
      • Verbleibende Argumente (/bin/bash) werden an chroot übergeben.

3. Verzeichnisprüfung

if [ ! -d "$CHROOT_DIR" ]; then
  echo "Error: Chroot directory $CHROOT_DIR does not exist."
  exit 1
fi
  • Bestätigt, dass das angegebene Chroot-Verzeichnis existiert.
  • Wenn das Verzeichnis fehlt, wird ein Fehler ausgegeben und das Programm beendet.

4. Mounten von /dev und /dev/pts

sudo mount --bind /dev "$CHROOT_DIR/dev"
sudo mount --bind /dev/pts "$CHROOT_DIR/dev/pts"
  • Bindet das /dev und /dev/pts des Hosts innerhalb des Chroots.

    • /dev: Stellt Gerätedateien bereit (z. B. /dev/null, /dev/tty).
    • /dev/pts: Unterstützt Pseudo-Terminals (wird von Programmen wie SSH und screen verwendet).
  • Stellt sicher, dass Programme innerhalb des Chroots Geräte und Terminals korrekt zugreifen können.

5. Aufräumfunktion

cleanup() {
  sudo umount "$CHROOT_DIR/dev/pts"
  sudo umount "$CHROOT_DIR/dev"
}
trap cleanup EXIT
  • Definiert eine Funktion (cleanup), die /dev und /dev/pts aushängt.
  • Registriert diese Funktion, um automatisch beim Beenden des Skripts ausgeführt zu werden (bei Erfolg oder Fehler).

    • Verhindert das Zurücklassen veralteter Mounts, falls etwas schiefgeht.

6. Betrete das Chroot

sudo chroot "$CHROOT_DIR" "$@"
  • Verwendet den Befehl chroot, um zum angegebenen Root-Verzeichnis (CHROOT_DIR) zu wechseln.
  • Führt den als zusätzliche Argumente bereitgestellten Befehl ($@) aus.

    • Beispiel: ./chrootmnt.sh /tmp/debian-rootfs /bin/bash

      • Führt /bin/bash innerhalb des Chroot aus.

7. Automatische Bereinigung

  • Wenn die chroot-Sitzung endet (entweder normal oder aufgrund eines Fehlers), führt das Skript automatisch aus:

    1. Hängt /dev/pts aus.
    2. Hängt /dev aus.

Schritt 2: Machen Sie das Skript ausführbar

Führen Sie den folgenden Befehl aus, um das Skript ausführbar zu machen:

chmod +x chrootmnt.sh

Schritt 3: Verwenden Sie das Skript

Stellen Sie zunächst sicher, dass Sie die Chroot-Umgebung erstellt haben:

mmdebstrap --variant=minbase stable /tmp/debian-rootfs

Jetzt, anstatt sudo chroot /tmp/debian-rootfs zu verwenden, benutze das Skript, um das Chroot zu betreten:

Starten Sie eine Shell innerhalb von /tmp/debian-rootfs:

./chrootmnt.sh /tmp/debian-rootfs /bin/bash

Führen Sie einen Befehl aus (z. B. ls -l /) innerhalb des chroot:

./chrootmnt.sh /tmp/debian-rootfs ls -l /

Stellen Sie nur sicher, dass Sie den richtigen Pfad Ihres Chroot-Umgebung eingegeben haben. In diesem Fall ist das Chroot-Verzeichnis /tmp/debian-tootfs. Ersetzen Sie dies durch Ihr eigenes.

Welche Lösung sollten Sie verwenden?

  • systemd-nspawn: Am besten für fortgeschrittene Benutzer, die ein containerähnliches Erlebnis wünschen.
  • Chrootmnt-Skript: Am besten für Einfachheit und Automatisierung.

Fazit

Das manuelle Einhängen und Aushängen von /dev jedes Mal, wenn Sie das chroot verwenden, ist nicht produktiv. Durch die Verwendung von systemd-nspawn oder eines Wrapper-Skripts können Sie diesen Prozess automatisieren und Zeit sparen. Wählen Sie die Methode, die am besten zu Ihrem Arbeitsablauf passt, und genießen Sie ein reibungsloseres Erlebnis mit mmdebstrap!