
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 -ql
ist 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 rsync
Upgrade-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 mount
Es 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.