Rationale

I2P is yet another anonymizing network (load-balanced unspoofable packet switching network) that provides access to eepsites (.i2p TLD); eepsites are a bit like Tor hidden services. Some users would like to be able to access eepsites from Tails.

Versions

I2P has been included since Tails 0.7 with Iceweasel preconfigured using FoxyProxy so that eepsites (.i2p TLD) are directed to I2P. All other traffic gets routed through Tor.

Starting with Tails 1.1.1, I2P is not enabled by default when Tails starts. In order to use I2P, a user must add the i2p boot option to the boot menu.

Starting with Tails 1.2, I2P sites are accessed with the I2P Browser. FoxyProxy is no longer installed in the Tor Browser..

Design

I2P has seen increased growth over the last few years with around 30,000 active peers routing traffic but it is still not as well known as Tor. I2P is not started automatically. Some reasons behind this decision include:

  1. increased usage of the system CPU (lots of computationally heavy crypto is needed for relaying traffic) and RAM (Java based)

  2. the possible raised suspicion from adversaries by being associated with yet another anonymity network (especially severe if one uses Tor bridges)

  3. some level of system compromise through 0-day exploits in the I2P client

Users that want to use I2P must enable it by adding the i2p boot option to the boot menu. Once enabled, I2P will be started automatically by a NetworkManager hook (see config/chroot local-includes/etc/NetworkManager/dispatcher.d/30-i2p.sh).

Implementation

The I2P project hosts an APT repository from which users can easily install I2P. It installs the application to /usr/share/i2p. Upon the first start template files are copied, with changes, to the data directory at /var/lib/i2p/i2p-config/. This separation is essential and was not possible some years ago. This package includes an initscript which is configured by default to start the I2P client as the i2psvc user.

The above package is installed but its init script is not automatically run during boot. Instead, a NetworkManager hook will start I2P if the user specified "i2p" at the boot menu. A side-effect of installing the actual I2P program into /usr is that automatic updates are disabled by the program since the installation directory is not writable by the i2psvc user.

For better performance an exception has been made in the firewall configuration that grants direct access to the network for the I2P user running the client so it can reach the I2P network directly, both through TCP and UDP. I2P is explicitly blocked from communicating with the LAN.

The I2P router is configured to run in hidden mode: killing I2P ungracefully is bad for the I2P network, and this is most likely a prevalent behaviour among Tails users. For I2P to shutdown gracefully, it needs up to 11 minutes to let all its current participatory tunnels expire. Killing I2P before that makes peers using these participatory tunnels experience timeouts and disconnects, which most definitely is bad for the network. Since Tails users are likely to shutdown Tails quickly without waiting these 11 minutes, this is a good reason to enable hidden mode, that is to disable participating in I2P traffic: config/chroot local-hooks/16-i2p config.

Starting with Tails 1.2, I2P eepsites are accessed via the I2P Browser, a modification of the Unsafe Browser's setup scripts. See its page for more information.

Disabling / Enabling I2P

During the build process, config/chroot local-hooks/97-remove i2p moves I2P from its normal location at /usr/share/i2p to /usr/share/tails/i2p-disabled. The script config/chroot local-includes/lib/live/config/2080-install-i2p checks for the string i2p in the kernel command line. If it is found, everything moved by config/chroot-local hooks/97-remove i2p is undone, making I2P available in the system.

Ports allowed through the firewall

Services on I2P are accessed through tunnels built by I2P. Services that a user hosts, such as an eepsite or IRC Server are accessed remotely via Server Tunnels. End users will access services using client tunnels. I2P is shipped with a few tunnels preconfigured and the ports that they use have exceptions added to ferm. The ports accessible to the amnesia user include:

  • 6668, Tunnel to Irc2P: Used to connect to the main I2P-only IRC network
  • 7656, SAM: SAM is an application bridge allowing non-Java clients to use I2P. More information: SAMv1, SAMv2,
  • 7659, SMTP Proxy: Tunnel to smtp.postman.i2p. More information is available from within I2P at Postman's HQ
  • 7660, POP3 Proxy: Tunnel to pop3.postman.i2p. More information is available from within I2P at Postman's HQ
  • 8998, MTN Proxy: Tunnel to mtn.i2p2.i2p, a Monotone server.

Note: These ports will only be opened if the user explicitly requests I2P at the boot prompt. See config/chroot local-includes/etc/ferm/ferm.conf for details.

Features that require an administration password

The amnesia user does not have access to /var/lib/i2p. In practice this will not be an issue unless one wants to

  • host content on an eepsite
  • use the integrated I2P-only bittorrent client, I2PSnark

In order to utilize these features users need to set an administration password.

Changes from upstream

  • i2cp, allowing java clients to communicate with I2P from outside of the JVM, is disabled
  • IPv6 is disabled
  • Outproxies are disabled
  • HiddenMode is set for all users
  • Updating I2P from within the I2P network is disabled; updates are done using the .debs
  • Inbound connections are disabled
  • I2P plugins are disabled
  • The webapp susimail will leave mail on the server

Package source and upgrading I2P

Tails uses the I2P (and deps) Debian packages prepared by KillYourTV, the official I2P Linux package maintainer as listed on the I2P Team page. The I2P source package and its binaries are imported into to our own custom APT repository into the devel or stable suite. The suite will depend on whether a major- or point-release is being prepared.

Prepare a Git topic branch

Create a Git branch, forked off the branch into which the new packages shall eventually be imported into, and called e.g. feature/i2p-0.n.m. Push this branch.

Get the packages

  1. Enter a Jessie i386 chroot and take note of its temporary directory.
  2. In the chroot, download the source and binary packages:

     dpkg --add-architecture amd64 && \
     echo 'deb http://deb.i2p2.no/ jessie main' > \
        /etc/apt/sources.list.d/i2p.list && \
     echo 'deb-src http://deb.i2p2.no/ jessie main' > \
        /etc/apt/sources.list.d/i2p-sources.list && \
     apt-key add - &&
     apt update && \
     apt-get --download-only source i2p && \
     apt-get download i2p i2p-router libjbigi-jni:i386 libjbigi-jni:amd64
    
  3. Copy {i2p,i2p-router,libjbigi-jni}_* outside of the chroot.

Check the binary packages

Content

dpkg-deb --contents i2p-router_*.deb | awk '{print $6}' | \
   grep -v -E '^\./($|usr/(share/doc/i2p-router/|share/i2p/|share/$|share/doc/$|bin/eepget|bin/i2prouter-nowrapper|share/man/man1/eepget\.1\.gz$|share/man/$|share/man/man1/$|bin/$|$))'

dpkg-deb --contents i2p_*.deb | awk '{print $6}' | \
   grep -v -E '^\./($|etc/(apparmor.d/(abstractions/)?)?$|etc/apparmor.d/(system_i2p|usr.bin.i2prouter|abstractions/i2p)$|etc/i2p/|etc/init\.d/i2p$|etc/init\.d/$|lib/$|lib/systemd/$|lib/systemd/system/$|lib/systemd/system/i2p\.service$|usr/$|usr/share/$|usr/share/man/$|usr/share/man/man1/$|usr/share/man/man1/i2prouter\.1\.gz$|usr/share/doc/$|usr/share/doc/i2p$|usr/bin/$|usr/bin/i2prouter$)'

dpkg-deb --contents libjbigi-jni_*.deb | awk '{print $6}' | \
   grep -v -E '^\./($|usr/$|usr/lib/$|usr/lib/jni/|usr/share/$|usr/share/doc/$|usr/share/doc/libjbigi-jni$)'

Maintainer scripts

Have a look at *.{pre,post}{inst,rm} config *.config maintainer scripts in each binary package.

Import the packages

  1. scp the source and binary packages to incoming.deb.tails.boum.org
  2. move the uploaded files somewhere, and set permissions on it, so that the reprepro user can read it
  3. use reprepro includedsc to import the source package(s) into the APT suite dedicated to the Git topic branch create above (e.g. feature-i2p-0.n.m)
  4. use reprepro includedeb to import the binary package(s) into the same dedicated APT suite
  5. add the feature-i2p-0.n.m APT suite to config/APT_overlays.d/ on the feature/i2p-0.n.m Git branch:

     VERSION=0.n.m
     touch "config/APT_overlays.d/feature-i2p-${VERSION}"   && \
     git add "config/APT_overlays.d/feature-i2p-${VERSION}" && \
     git commit "config/APT_overlays.d/feature-i2p-${VERSION}" \
        -m "Add the feature-i2p-${VERSION} overlay APT suite."
    
  6. build an ISO from the feature/i2p-0.n.m Git branch

  7. test this ISO
  8. merge the feature/i2p-0.n.m branch into the appropriate base branch