Linux: I2P im chroot mit AppArmor
Das I2P Netzwerk
I2P („Invisible Internet Project“) besteht aus einer Reihe auf Java basierender Anwendungen und Server, mit der ein anonymisierendes Netzwerk aus verteilten Rechnern errichtet wird. Die Rechner stellen die Benutzer des I2P Netzwerks, die ähnlich wie beim Tor Netzwerk als Teil von Transportketten aus mehreren I2P-Knoten den I2P Datenverkehr durch das Internet in I2P Tunnels transportieren, die durch die I2P Verschlüsselungs- und Anonymisierungsfunktionen gebildet werden.
Gleichzeitig können Benutzer innerhalb des I2P Netzwerks selbst Anbieter von Diensten sein, die von anderen Benutzern und ihnen selbst anonymisiert genutzt werden können. Dazu zählen z. B. eigene Websites, -foren und blogs, Torrent-Tracker oder Mailserver. I2P enthält einen BitTorrent Client („I2Psnark“), mit dem Benutzer über I2P Torrent-Tracker Daten austauschen können, eine Webserverkomponente, um Webpräsenzen (sogenannte „Eepsites“) im I2P Netzwerk aufzubauen, einen Webmail Client („susimail“) für den I2P Mail Dienst, mit dem E-Mails auch von Nicht-I2P-Nutzern empfangen und an sie gesendet werden können.
Bei I2P handelt es sich also in erster Linie um ein geschlossenes Netzwerk, das aber über Proxy Dienste von I2P Nutzern um „Schnittstellen“ zum übrigen Internet erweitert wird. So gibt es z. B. einen I2P HTTP „Outproxy“, über den das WWW anonymisiert genutzt werden kann oder einen I2P IRC Proxy zur Nutzung von IRC Servern.

Die Bedienung und Einrichtung des eigenen I2P-Knotens wird primär über die „I2P Router Konsole“ in einem beliebigen Webbrowser durchgeführt. Weitere bzw. erweiterte Konfigurationen können in den I2P Konfigurationsdateien (*.config) durchgeführt werden.
Vorbereitungen
Die Maßnahmen wurden unter Ubuntu durchgeführt. Für andere Linux-Distributionen sind einzelne Maßnahmen ggf. zu modifizieren. Weitere Änpassungen können sich bei Änderungen im Dateisystem ergeben, z. B. wenn Bibliotheken mit einem neuen Release woanders gespeichert werden als zuvor.
Zuerst ist zu überlegen, wo die chroot Umgebung für I2P und Java angelegt werden soll. In der Anleitung ist es /mp/chroot/i2p/: mp kann irgendein mountpoint sein, also ein logisches Volume bzw. eine Partition, die nur für chroot Umgebungen genutzt wird, mit dem chroot Verzeichnis und i2p Unterverzeichnis, das für I2P und Java zum Wurzelverzeichnis / wird. Später kann man für andere Anwendungen unterhalb von /mp/chroot/ weitere Umgebungen einrichten, z. B. /mp/chroot/tor für Tor.
Java
Die Anleitung geht vom Einsatz der Oracle Java SE (Standard Edition) aus. Da ab Oracle Java SE 1.7.0 Java Pakete offiziell nicht mehr durch Linux-Distributoren verbreitet werden dürfen, wird die Java SE manuell installiert. Aktuelle Information zu neuen Versionen erhält man über den Oracle Security Alerts Feed oder den Java SE News Feed.
Über die Java Downloadseite wird das JRE Archiv (x64 statt i586 für 64-bit) der Java Standard Edition heruntergeladen und danach installiert:
sudo mkdir /usr/lib/jvm ; cd /usr/lib/jvm sudo tar -xzf /pfad/jre-N-linux-[i586|x64].tar.gz sudo update-alternatives --install /usr/bin/java java /usr/lib/jreN.N.N/bin/java 100
Danach muss sich eine ähnliche Ausgabe in der Konsole einstellen:
$ java -version java version "1.7.0" Java(TM) SE Runtime Environment (build 1.7.0-b147) Java HotSpot(TM) Client VM (build 21.0-b17, mixed mode)
Wer lieber das Java Runtime Environment (JRE) des OpenJDK Projekt verwendet (openjdk-N-jre
Paket), kann auch dabei bleiben, muss aber das Skript zur Erstellung der chroot Umgebung entsprechend anpassen.
Anmerkung: Hier gab es Probleme mit dem OpenJDK JRE bei der Darstellung der I2P Performance Grafiken, die nicht zu lösen waren. Im I2P Forum wurde die Meinung geäußert, dass die CPU- und Speichernutzung mit dem Sun JRE besser sei als mit dem OpenJDK JRE.
Über das Alternativen-System können bei Bedarf neben der java Anwendung weitere Anwendungen des installierten Oracle JRE systemweit aufgenommen und verschiedene JREs parallel installiert werden.
I2P
I2P wird zunächst installiert und die I2P Dateien per Skript in die chroot Umgebung kopiert. Anschließend kann das installierte I2P wieder entfernt werden.
Manuelle Installation
Download des aktuellen Java Installationsarchivs i2pinstall_version.jar und der GnuPG Signaturdatei i2pinstall_version.jar.sig über die I2P oder geti2p.net Website mit anschließendem Abgleich der SHA-256 Prüfsumme und Prüfung der OpenPGP Signatur.
Anschließend:
sudo java -jar i2pinstall_version.exe -console press 1 to continue, 2 to quit, 3 to redisplay 1 Select target path /var/lib/i2p press 1 to continue, 2 to quit, 3 to redisplay 1
I2P Benutzer
Anlage des I2P Benutzers:
sudo adduser --system --home /mp/chroot/i2p/var/lib/i2p \ --shell /bin/false --no-create-home \ --group --disabled-password i2p-daemon
chroot einrichten
Umgebung mit Skript erstellen
Das folgende Skript als i2p_makechroot abspeichern:
#!/bin/bash CHROOTDIR="/mp/chroot/i2p" USERNAME="i2p-daemon" I2PINST="/var/lib/i2p" # JAVAINST="/usr/lib/jvm/java-N-openjdk" JAVAINST="/usr/lib/jvm/jreN.N.N" echo "Lege $CHROOTDIR und Verzeichnisse in $CHROOTDIR an" mkdir -p $CHROOTDIR/bin mkdir -p $CHROOTDIR/dev mkdir -p $CHROOTDIR/etc mkdir -p $CHROOTDIR/lib mkdir -p $CHROOTDIR/proc mkdir -p $CHROOTDIR/tmp mkdir -p $CHROOTDIR/var/lib mkdir -p $CHROOTDIR$JAVAINST/bin mkdir -p $CHROOTDIR/lib/tls/i686/cmov echo "Erzeuge Devicedateien" touch $CHROOTDIR/dev/random touch $CHROOTDIR/dev/urandom mknod -m 0666 $CHROOTDIR/dev/null c 1 3 echo "Kopiere Java und I2P" cp -RLp $I2PINST $CHROOTDIR/var/lib cp -p $JAVAINST/bin/java $CHROOTDIR$JAVAINST/bin cp -Rp $JAVAINST/lib $CHROOTDIR$JAVAINST echo "Füge $USERNAME in $CHROOTDIR/etc/passwd und $CHROOTDIR/etc/group ein" grep $USERNAME /etc/passwd > $CHROOTDIR/etc/passwd grep $USERNAME /etc/group > $CHROOTDIR/etc/group echo "" echo " Nicht vergessen, die Angaben in beiden Dateien vor dem ersten Start abzuändern" echo "" echo "Kopiere Systemprogramme" cp /bin/dash $CHROOTDIR/bin cp -d /bin/sh $CHROOTDIR/bin cp /bin/false $CHROOTDIR/bin echo "Kopiere Systemeinstellungen" # cp -Rp /etc/java-N-openjdk $CHROOTDIR/etc cp /etc/nsswitch.conf $CHROOTDIR/etc cp /etc/host.conf $CHROOTDIR/etc cp /etc/resolv.conf $CHROOTDIR/etc cp /etc/hosts $CHROOTDIR/etc cp /etc/localtime $CHROOTDIR/etc echo "Kopiere Systembibliotheken" cp /lib/libnsl* $CHROOTDIR/lib cp /lib/libnss_* $CHROOTDIR/lib cp /lib/libresolv* $CHROOTDIR/lib cp /lib/ld-linux* $CHROOTDIR/lib cp /lib/libz.so.? $CHROOTDIR/lib cp /usr/lib/libfreetype.so.? $CHROOTDIR/usr/lib ln -s $CHROOTDIR$JAVAINST/lib/i386/client/libjvm.so $CHROOTDIR$JAVAINST/lib/i386/ ln -s $CHROOTDIR$JAVAINST/lib/i386/jli/libjli.so $CHROOTDIR$JAVAINST/lib/i386/ cp /lib/tls/i686/cmov/libc.so.? $CHROOTDIR/lib/tls/i686/cmov cp /lib/tls/i686/cmov/libdl.so.? $CHROOTDIR/lib/tls/i686/cmov cp /lib/tls/i686/cmov/libnsl.so.? $CHROOTDIR/lib/tls/i686/cmov cp /lib/tls/i686/cmov/libpthread.so.? $CHROOTDIR/lib/tls/i686/cmov cp /lib/tls/i686/cmov/libresolv.so.? $CHROOTDIR/lib/tls/i686/cmov cp /lib/tls/i686/cmov/libm.so.? $CHROOTDIR/lib/tls/i686/cmov echo "Vergebe Berechtigungen" chown -R $USERNAME:$USERNAME $CHROOTDIR/var/lib/i2p chmod 0750 $CHROOTDIR/var/lib/i2p chmod 1777 $CHROOTDIR/tmp echo "Fertig" echo "" echo " Nicht vergessen, das I2P init Skript abzuändern oder einzurichten" echo ""
Anmerkung: Das Skript basiert auf den Skripten zur Einrichtung von chroot Umgebungen für Tor und Privoxy von northernsecurity.
Sofern das OpenJDK JRE verwendet wird, die Zeile mit der Definition der JAVAINST Variable für das Oracle Java JRE löschen und dafür die Zeilen für das OpenJDK JRE auskommentieren.
In der Zeile mit der Definition der CHROOTDIR Variable den Pfad zur chroot Umgebung auf das eigene System anpassen.
Die Skriptdatei ausführbar machen und ausführen:
chmod +x i2p_makechroot sudo ./i2p_makechroot
init Skript für chroot
Das folgende Skript als i2prouter abspeichern:
#!/bin/sh # # Start/Stop the I2P-router ### BEGIN INIT INFO # Provides: i2prouter # Required-Start: $network # Required-Stop: $network # Default-Start: 2 3 4 5 # Default-Stop: 0 1 6 # Short-Description: the router for the Invisible Internet Project # Description: The Invisibel Internet Project is a highly anonymous # network. This router offers a proxy to access the net. ### END INIT INFO set -e DESC="I2P router" NAME="i2prouter" USER="i2p-daemon" GROUP="i2p-daemon" CHROOTDIR="/mp/chroot/i2p" I2PDIR="/var/lib/i2p" DAEMON="i2psvc_start" I2PPID="/tmp/i2p.pid" pid="" getpid() { if [ -f $CHROOTDIR$I2PPID ] then if [ -r $CHROOTDIR$I2PPID ] then pid=`cat $CHROOTDIR$I2PPID` if [ "X$pid" != "X" ] then # Verify that a process with this pid is still running. pid=`ps -p $pid | grep $pid | grep -v grep | awk '{print $1}' | tail -n 1` if [ "X$pid" = "X" ] then # This is a stale pid file. rm -f $CHROOTDIR$I2PPID echo "Removed stale pid file: $CHROOTDIR$I2PPID" fi fi else echo "Cannot read $CHROOTDIR$I2PPID." exit 1 fi fi } case $1 in start) mount --bind /dev/random $CHROOTDIR/dev/random && \ mount --bind /dev/urandom $CHROOTDIR/dev/urandom && \ mount -t proc proc $CHROOTDIR/proc echo -n "Starting $DESC: $NAME..." start-stop-daemon --start --quiet --oknodo --chuid $USER:$GROUP --chroot $CHROOTDIR --pidfile $I2PPID --exec $I2PDIR/$DAEMON echo "done." ;; stop) echo -n "Stopping $DESC: " start-stop-daemon --stop --oknodo --pidfile $CHROOTDIR$I2PPID --retry 30 echo "done." && \ umount $CHROOTDIR/dev/urandom && umount $CHROOTDIR/dev/random && \ umount $CHROOTDIR/proc ;; status) getpid if [ "X$pid" = "X" ] then echo "$DESC is not running." exit 1 else echo "$DESC is running ($pid)." exit 0 fi ;; restart) echo "Restarting $DESC: " start-stop-daemon --stop --oknodo --pidfile $CHROOTDIR$I2PPID --retry 30 echo "$DESC stopped " sleep 15 echo "Starting $DESC: " start-stop-daemon --start --quiet --oknodo --chuid $USER:$GROUP --chroot $CHROOTDIR --pidfile $I2PPID --exec $I2PDIR/$DAEMON echo "done." ;; *) echo "Usage: $0 (start|stop|restart|status)" >&2 exit 1 ;; esac exit 0
Auch hier gilt es, in der Zeile mit der Definition der CHROOTDIR Variable den Pfad zur chroot Umgebung auf das eigene System anzupassen.
Das init Skript in das /etc/init.d Verzeichnis kopieren und ausführbar machen:
sudo cp i2prouter /etc/init.d/ sudo chmod +x /etc/init.d/i2prouter
Das i2prouter init Skript aktivieren:
sudo update-rc.d i2prouter defaults
Anpassungen im chroot
i2psvc_start Skript
Da Aufruf und Start von I2P und Java über das init Skript nicht mehr mit dem Start der i2psvc
Anwendung über das i2prouter
Skript im I2P Verzeichnis durchgeführt wird, sondern mit dem i2psvc_start
Shellskript als „daemon“, muss das folgende Shellskript als i2psvc_start Datei in das /mp/chroot/i2p/var/lib/i2p Verzeichnis kopiert werden:
#!/bin/sh # PATH="/bin:/var/lib/i2p:/usr/lib/jvm/java-N-openjdk/jre/bin" PATH="/bin:/var/lib/i2p:/usr/lib/jvm/jreN.N.N/bin" I2PDIR=/var/lib/i2p DAEMON_CONF="$I2PDIR/wrapper.config" I2PPID="/tmp/i2p.pid" $I2PDIR/i2psvc $DAEMON_CONF i2psvc.pidfile=$I2PPID wrapper.daemonize=TRUE exit 0
Sofern man das OpenJDK JRE verwendet, muss die Zeile mit der Definition der PATH Variable für das Oracle Java JRE entfernt und dafür die Zeile mit der PATH Variable für das OpenJDK JRE auskommentiert werden.
Das i2psvc_start Shellskript kopieren, ausführbar machen und den Eigentümer ändern:
sudo cp i2psvc_start /mp/chroot/i2p/var/lib/i2p/ sudo chmod 0744 /mp/chroot/i2p/var/lib/i2p/i2psvc_start sudo chown i2p-daemon:i2p-daemon /mp/chroot/i2p/var/lib/i2p/i2psvc_start
I2P Benutzer
Die Daten des I2P Benutzers wurden mit der Erstellung der chroot Umgebung aus der /etc/passwd der Systemumgebung in die /etc/passwd im chroot kopiert, aber die Angaben zum Heimatverzeichnis und zur Shell beziehen sich immer noch auf die Systemumgebung. Deshalb muss die /mp/chroot/i2p/etc/passwd editiert und die Angaben geändert werden:
sudo vi mp/chroot/i2p/etc/passwd
i2p-daemon:x:nnn:nnn::/mp/chroot/i2p/var/lib/i2p:/bin/false
in:
i2p-daemon:x:nnn:nnn::/var/lib/i2p:/bin/false
Erster Start
I2P zum ersten Mal im chroot starten:
sudo service i2prouter start
Danach müsste folgende Ausgabe zu sehen sein:
sudo service i2prouter status I2P router is running (10227).
Und die I2P Router Konsole über die Adresse http://localhost:7657/index.jsp im Webbrowser zugänglich sein. Läuft I2P, kann abschließend das unter /var/lib/i2p installierte I2P entfernt werden:
sudo rm -rf /var/lib/i2p
AppArmor
AppArmor ist ein Sicherheitssystem, mit dem die Nutzung von Internetprotokollen, Zugriffs- und Ausführungsberechtigungen auf Verzeichnisse, Dateien und Programme für Anwendungen und Prozesse festgelegt bzw. eingeschränkt werden. Für AppArmor ist das AppArmor Kernelmodul zuständig, das beim Systemstart geladen wird und die Profildateien der Anwendungen auswertet, in denen die Berechtigungsregeln für die Anwendungen definiert sind.
Die Einrichtung und Anwendung von AppArmor wird in AppArmor mit Ubuntu nutzen erklärt. Dort wird auch der Aufbau und die Erstellung eigener AppArmor Profile beschrieben.
Im Fall von I2P betrifft das die java
Anwendung des Oracle oder OpenJDK JRE im /mp/chroot/i2p/usr/lib/jvm/jreN.N.N/bin bzw. /mp/chroot/i2p/usr/lib/jvm/openjdk/jre/bin Verzeichnis.
AppArmor Java Profil
Die AppArmor Profile sind im /etc/apparmor.d Verzeichnis gespeichert und die Dateinamen werden aus dem absoluten Pfad zur Anwendung gebildet, wobei Punkte den /
ersetzen.
Hier ein Beispiel für das AppArmor Profil für die Oracle JRE java Anwendung, das als „mp.chroot.i2p.usr.lib.jvm.jreN.N.N.bin.java“ Datei im /etc/apparmor.d Verzeichnis gespeichert ist.
# Last Modified: Sat Jan 16 23:35:32 2010 @{HOMEDIRS} = @{HOME}, @{HOME} = /mp/chroot/i2p/var/lib/i2p/, @{PROC} = /mp/chroot/i2p/proc/, /mp/chroot/i2p/usr/lib/jvm/jreN.N.N/bin/java { #include <abstractions/base> #include <abstractions/nameservice> /mp/chroot/i2p/usr/lib/jvm/jreN.N.N/bin/java rix, /mp/chroot/i2p/usr/lib/jvm/jreN.N.N/lib/** mr, /mp/chroot/i2p/usr/lib/libfreetype.so.? mr, /mp/chroot/i2p/dev/* r, /mp/chroot/i2p/etc/* mr, /mp/chroot/i2p/lib/* mr, /mp/chroot/i2p/lib/tls/i686/** mr, owner /mp/chroot/i2p/proc/** r, /mp/chroot/i2p/proc/meminfo r, /mp/chroot/i2p/proc/stat r, /mp/chroot/i2p/tmp/ r, owner /mp/chroot/i2p/tmp/** mrw, owner /mp/chroot/i2p/var/lib/i2p/** r, owner /mp/chroot/i2p/var/lib/i2p/.i2p/** r, owner /mp/chroot/i2p/var/lib/i2p/*.config rw, owner /mp/chroot/i2p/var/lib/i2p/*.so mr, owner /mp/chroot/i2p/var/lib/i2p/*.txt rw, owner /mp/chroot/i2p/var/lib/i2p/docs/news.xml rw, owner /mp/chroot/i2p/var/lib/i2p/lib/*.so mr, owner /mp/chroot/i2p/var/lib/i2p/lib/*.jar mr, owner /mp/chroot/i2p/var/lib/i2p/webapps/*.war mr, owner /mp/chroot/i2p/var/lib/i2p/.i2p/*.config rw, owner /mp/chroot/i2p/var/lib/i2p/.i2p/*.txt rw, owner /mp/chroot/i2p/var/lib/i2p/.i2p/prngseed.rnd rw, owner /mp/chroot/i2p/var/lib/i2p/.i2p/router.info rw, owner /mp/chroot/i2p/var/lib/i2p/.i2p/addressbook/* rw, owner /mp/chroot/i2p/var/lib/i2p/.i2p/docs/news.xml rw, owner /mp/chroot/i2p/var/lib/i2p/.i2p/eepsite/eepPriv.dat rw, owner /mp/chroot/i2p/var/lib/i2p/.i2p/eepsite/logs/*.log rw, owner /mp/chroot/i2p/var/lib/i2p/.i2p/i2psnark/** rw, owner /mp/chroot/i2p/var/lib/i2p/.i2p/keyBackup/*.key rw, owner /mp/chroot/i2p/var/lib/i2p/.i2p/logs/*.txt rw, owner /mp/chroot/i2p/var/lib/i2p/.i2p/netDb/*.dat rw, owner /mp/chroot/i2p/var/lib/i2p/.i2p/peerProfiles/*.dat rw, }
Das Profil kann man nach Änderung des chroot mountpoint verwenden oder sich ein eigenes I2P / Java AppArmor Profil erstellen und nutzen.
Zur Erzeugung von privaten Schlüsseldateien für eigene I2P Tunnel muss in dem Profil fallweise die mknod capability aktiviert werden.
Eigenes Java Profil
Hier folgt eine kurze Anleitung, um sich ein eigenes AppArmor Profil für Java zu erstellen:
- am besten drei root Konsolen mit
sudo -i
öffnen - 1. Konsole:
tail -f -n 20 /var/log/messages
- 2. Konsole:
service i2prouter stop
- 3. Konsole:
aa-genprof /mp/chroot/i2p/usr/lib/jvm/jreN.N.N/bin/java
- 2. Konsole:
service i2prouter start
- in der I2P Router Konsole alle Links anklicken, möglichen I2P Einstellungen vornehmen, I2P Dienste nutzen, um Rohdaten zu gewinnen, aus denen aa-genprof nach dem Scan der messages Logdatei das Profil generiert - dabei die Logausgabe in der 1. Konsole beobachten
- 2. Konsole:
service i2prouter stop
- 3. Konsole: den aa-genprof Scan mit „S“ Taste durchführen und beenden
- 3. Konsole: die Abfragen zur Berechtigungsvergabe bestätigen, verweigern oder ändern (z. B. auch mit Abgleich der Logdateiausgabe in der 1. Konsole oder Inspektion der chroot Dateisystemstruktur in der 2. Konsole oder per Dateimanager)
- 3. Konsole: nach Abarbeitung aller Abfragen das Profil mit „F“ Taste speichern lassen
- 3. Konsole: mit
aa-status
nachprüfen, ob das Profil im „complain“ Modus angezeigt wird bzw. mitaa-complain /etc/apparmor.d/mp.chroot.i2p.usr.lib.jvm.jreN.N.N.bin.java
in den „complain“ Modus setzen - der „complain“ Modus bedeutet, die Anwendung und Auswirkung der Regeln werden zwar in der Logdatei ausgegeben, aber sie werden tatsächlich nicht angewendet und erzwungen - 3. Konsole: mit
service apparmor reload
die AppArmor Profile neuladen und erneut mitaa-status
überprüfen - 2. Konsole:
service i2prouter start
Danach wie unter Punkt 6 weiterhin I2P nutzen und die Logausgabe in der 1. Konsole beobachten.
Deuten spätere Logausgaben darauf hin, dass weitere Abänderungen des Profils nötig sind, geht man wie folgt vor:
1. Überprüfung und Auswertung der /var/log/messages Ausgabe:
sudo aa-logprof
2. Das Profil wie unter Punkt 9 - 10 justieren.
3. Neuladen des Java Profils nach jeder Änderungen per aa-logprof:
sudo apparmor_parser -r /etc/apparmor.d/mp.chroot.i2p.usr.lib.jvm.jreN.N.N.bin.java
Ist das AppArmor Profil vollständig, kann es in den „enforce“ Modus versetzt werden, d. h. die Regeln werden tatsächlich angewendet und damit die Berechtigungen und ihre Verweigerung gesetzt:
sudo aa-enforce /etc/apparmor.d/mp.chroot.i2p.usr.lib.jvm.jreN.N.N.bin.java sudo apparmor_parser -r /etc/apparmor.d/mp.chroot.i2p.usr.lib.jvm.jreN.N.N.bin.java