Gibt es irgendwo ein Chroot-Build-Skript?

Gibt es irgendwo ein Chroot-Build-Skript?

Ich bin dabei, ein kleines Skript zum Sammeln von Informationen für ein Chroot-Jail zu entwickeln.

In meinem Fall sieht das (auf den ersten Blick) ziemlich einfach aus: Die Anwendung hat eine saubere RPM-Installation und hat fast alle Dateien in einem Unterverzeichnis von /opt installiert.

Meine Idee ist:

  • Suchen Sie nach allen Binärdateien
  • Überprüfen Sie ihre Bibliotheksabhängigkeiten
  • Notieren Sie die Ergebnisse in einer Liste
  • Führen Sie vor dem Start der Anwendung einen Rsync dieser Liste in das Chroot-Zielverzeichnis durch

Jetzt frage ich mich: Gibt es schon ein Skript, das diese Aufgabe erledigt (Perl/Bash/Python)?

Bisher habe ich nur spezialisierte Lösungen für einzelne Anwendungen gefunden (wie sftp-chroot).

Obwohl es (meiner Meinung nach) keine Rolle spielt – das Betriebssystem ist CentOS 5 x86_64, aktuelle Nebenversion und Patch-Level.

rpm -qlist meiner Meinung nach nicht allgemein genug, da es nur abdecktU/min-basierte Distributionen. Die Erwähnung der „sauberen Installation“ oben war nur ein Hinweis darauf, dass die Dateien der Software nicht über das gesamte Dateisystem verteilt sind. Mein Ausgangspunkt ist also – im Moment – ​​ein find /opt/directory/…, das auf fast jedem System funktionieren sollte (auch nicht auf Linux).

Antwort1

Ich würde vorschlagen, eine Chroot-Vorlage zu erstellen und alle gewünschten Pakete zu installieren, als wäre es ein normales Betriebssystem. Danach können Sie die Chroot mit Ihren üblichen Tools (Aktualisierungsskripte, Paketmanager usw.) verwalten und die Aktualisierungen per rsync in jede Chroot-Vorlage übertragen, die mit dieser Vorlage erstellt wurde.

Dieser Ansatz bietet einige Vorteile. Die beiden größten sind, dass Sie die Vorlage mit vertrauten Tools verwalten können (keine seltsamen Hürden, die Sie überwinden müssen, um Ihr Chroot zu aktualisieren), und wenn Sie ein Chroot haben, daskippenaus irgendeinem Grund aktualisiert werden muss (sagen wir, es benötigt eine bestimmte Version eines bestimmten Pakets), können Sie es vom rsyncUpgrade-Prozess ausschließen und es unabhängig verwalten, als wäre es eine eigenständige Maschine, indem Sie das Paket als „zurückgehalten“ oder gleichwertig markieren, damit es nicht überschrieben wird.

Ihre Laufleistung (und Implementierungsanforderungen) können variieren …

Antwort2

Hier ist der aktuelle Stand meines Skripts:

mkchroot.cfg:

# Configuration file for building a chroot envirnoment with Linux
#
# V 1.2 2012-10-24
#
# Define which directories to scan for executables
#  use space to separate directories
DIRS="/opt/application /opt/bin"
#
# Define a number of files to check outside the dirctories set in the DIRS
# directive above. Use space to separate entries.
FILES="/bin/sh"
#
# Define additional things that should be added to chroot without check.
# This could be block or char-devices. Use space to separate entries. 
ADDITIONAL="/dev/urandom /dev/null /var/lock/subsys /var/application"
#
# Target chroot-directory
TARGETDIR=="/var/lib/application"
#
# Here goes the list of files that has to be synced to chroot
FILELIST="/tmp/chroot_files.dat"
#

mkchroot.sh

#!/bin/sh
. /opt/application/mkchroot.cfg
getlibs ()
{
  # Parameter1: Name of a file containing files to check
  for b in $(cat ${1})
    do
      ldd $b |grep -v ":"|grep "/"|sed "s/.*>//g; s/ (.*//g"|awk '{print $1}'
  done
}
# Main program
clear
for f in ${FILELIST}_bin ${FILELIST}_tmp ${FILELIST}_lib ${FILELIST}
  do
    [ -f $f ] && rm $f
done
for d in $DIRS
  do
    echo Build filelist for directory $d
    find $d -type f -exec file {} \; 2>/dev/null |grep ELF |cut -d : -f 1 >>${FILELIST}_bin
done
for f in $FILES
  do
    echo $f >>${FILELIST}_bin
done
echo Find libaries on stage 1
getlibs ${FILELIST}_bin >>${FILELIST}_tmp
# Now find indirect libraries until list does not get any longer...
sort -u ${FILELIST}_tmp >${FILELIST}_lib
typeset -i LIBNEW="$(wc -l <${FILELIST}_lib )" LIBOLD=0 STAGE=2
while [ $LIBNEW -ne $LIBOLD ]
  do
    echo Find libaries on stage $STAGE
    let STAGE++
    LIBOLD=$LIBNEW
    cp ${FILELIST}_lib ${FILELIST}_tmp
    getlibs ${FILELIST}_lib >>${FILELIST}_tmp
    sort -u ${FILELIST}_tmp >${FILELIST}_lib
    LIBNEW=$(wc -l <${FILELIST}_lib)
done
cp ${FILELIST}_lib ${FILELIST}_tmp
for e in $ADDITIONAL
  do
    echo $e >>${FILELIST}_tmp
done
echo Für chroot zu synchronisierende Dateien:
GDIRS=$(echo $DIRS |sed "s/ /\\\|/g;")
grep -v "$GDIRS" ${FILELIST}_tmp |sort -u >${FILELIST}
cat $FILELIST

Das Problem besteht immer noch: In meinem Chroot befinden sich Shell-Dateien. Diese verweisen möglicherweise auf andere Binärdateien.

Als Workaround müssen diese manuell in $FILES eingefügt werden.

Antwort3

Es gibt eine Reihe von Tools namensJailkit.

Dies funktioniert möglicherweise auch unter Linux. Laut der Homepage ist dies bestätigt unter

  • Solaris
  • "viele" Linux-Distributionen
  • OpenBSD
  • FreeBSD
  • Mac OS X

Seine Abhängigkeiten sehen gut aus:

  • (g)libc
  • Python
  • POSIX-Threads

Antwort4

Erster Ansatz (der Dienst ist die Anwendung selbst): Führen Sie ein Bind-Ro-Mount im Chroot für alle „üblichen“ Binärdateien, Bibliotheken usw. durch:

  • /usw
  • /Behälter
  • /usr
  • /lib
  • /lib64
  • /var
  • /home/gebrauchte_konten
  • /opt/Dienst

Nun war es ok, zu testen, ob der Dienst im Chroot läuft. Zu meinem Erstaunen teilte mir mein HIDS mit, dass sich ein Schreibzugriff in einem Unterverzeichnis in/opt/Dienst.

Also habe ich mich manuell mit einer Shell per Chroot-Verfahren eingeloggt und den Schreibzugriff getestet – was funktioniert hat!

Wenn also nichts anderes hilft – RTFM. man mountEs wurde darauf hingewiesen, dass ein Read-Only-Bind-Mount nur mit Kernel 2.6.26 oder höher funktioniert (Pech hier: CentOS 5 ist 2.6.18).

Ein weiterer Nachteil: Ein potenzieller Angreifer hat dadurch Zugriff auf alle Betriebssystem-Tools.

verwandte Informationen