Anonymous and Secure Communication with XMPP + I2P

Anonymous communication is crucial for protecting free speech, but the increasing greed of certain individuals and organizations seeking information has made it more difficult to maintain. Fortunately, the fight for freedom is not a lonely one. Today, we can stand on the shoulders of giants by using tools like XMPP + OMEMO for encrypted communication or accessing the internet anonymously via Tor or I2P. But what happens when we combine these technologies? In this article, I'll explain, as simply as possible, how to set up XMPP communication over the I2P network on your own computer.

This guide is based on "Arch Linux" and uses the C++ version of i2pd, with Prosody as the XMPP server and the darknet module. The setup process is similar for other systems. I followed this guide with some adjustments and additions.

Note: Replace any content inside <...> with your own specific configurations.

Table of Contents

Install and Configure the I2P Network

If you have any questions while following this section, you can check the following resources:

Connecting to the I2P Network

First, we need to install and configure I2P:

$ sudo pacman -S i2pd
$ sudo systemctl start i2pd.service

If everything goes smoothly, you should be able to access the i2pd webconsole by entering http://127.0.0.1:7070 in your browser. At this point, i2pd is up and running. However, due to the nature of I2P, newly installed nodes need some time to "reseed," and the duration can vary depending on your network quality. If you're unable to connect to the I2P network right away, I recommend letting your computer run for a day or so and then trying again. The specifics of browsing I2P sites (known as Eepsites) are beyond the scope of this article.

The difficulty of connecting and the slow speeds are some of the reasons why I2P struggles to gain widespread adoption. Many people give up after installing I2P because it doesn't connect immediately, which is a common challenge for decentralized networks. Tor faces similar issues to some extent. These problems are inherent to the decentralized architecture, but this discussion is outside the scope of this article. In general, the more people use I2P and the longer they keep it running, the better the overall experience becomes. For this reason, I recommend setting I2P to start automatically when your computer boots up:

$ sudo systemctl enable i2pd.service

While waiting for I2P to finish reseeding, we can move on to the next configurations.

Creating a New I2P Tunnel

First, add the following content to the tunnels.conf file (usually located at /etc/i2pd/tunnels.conf):

[prosody-s2s]
type=server
host=127.0.0.1
port=5269
inport=5269
keys=prosody.dat

After saving the changes, restart the i2pd service:

$ sudo systemctl restart i2pd.service

Once restarted, go to http://127.0.0.1:7070 in your browser to access the i2p webconsole, then click on I2P tunnels. In the Server Tunnels section, you should see the prosody-s2s tunnel you just added. Note the address that appears—this will be the address for your XMPP server, which we'll refer to as <address>.b32.i2p throughout this article.

Install and Configure the XMPP Server

If you run into any issues while following this section, the following resources may help:

Install Prosody

Next, we'll install and configure the XMPP server using Prosody with the darknet module.

First, install prosody and lua52-sec (for TLS/SSL support):

$ sudo pacman -S prosody lua52-sec

Install mod_darknet

Now, we need to install mod_darknet. Before doing so, install lua-bit32:

$ sudo pacman -S lua-bit32

Then, download and install the darknet module from the mod_darknet repository. The default installation path is usually /usr/lib/prosody/modules. You can refer to the original author's guide for detailed instructions.

Configure Prosody

With the preparations complete, we can now configure Prosody by editing the /etc/prosody/prosody.cfg.lua file. Use the following configuration (replace ... with your specific details as needed). If you encounter issues, ensure you remove any unused VirtualHost entries from the config file:

interfaces = { "127.0.0.1" }
...
admins = { "admin@<address>.b32.i2p" }
...
modules_enabled = {
    ...
    "darknet";
}
...
darknet_only = true
...
authentication = "internal_plain"
...
VirtualHost "<address>.b32.i2p"
    certificate = "/var/lib/prosody/<address>.b32.i2p.crt"

After configuring, remember to restart the Prosody service:

$ sudo systemctl restart prosody

Generate SSL/TLS Certificates

You may have noticed that the certificate mentioned in the configuration doesn't exist yet. After configuring and restarting Prosody, you can generate an SSL/TLS certificate for your XMPP server's address:

$ sudo prosodyctl cert generate <address>.b32.i2p

The certificate will typically be saved in /var/lib/prosody/. Adjust your configuration file based on the generated path.

Add Users

Next, let's add an admin user to Prosody. Follow the prompts to set the password:

$ sudo prosodyctl adduser admin@<address>.b32.i2p

Since the server is hosted on your own machine, the admin user might not be essential, so feel free to adjust this according to your needs.

Once everything is set up, you can restart the Prosody service to load the updated configuration. You may also want to enable it to start on boot:

$ sudo systemctl restart prosody
$ sudo systemctl enable prosody

Install and Configure the XMPP Client

If you have any questions while following this section, you can refer to the following resource:

Install Gajim

With the server configured, we now need to install and set up an XMPP client. You can choose any client you prefer; in this example, I'll be using Gajim. The setup process for other clients is quite similar. First, install Gajim:

$ sudo pacman -S gajim

As of Gajim 1.8.0, OMEMO support is built-in, so there's no need for additional configuration. You can skip directly to the "Login to Your Account" section. However, for reference, I've retained the instructions for configuring OMEMO for those who need it, though note that the relevant AUR package has been removed and is no longer available on Arch Linux.

To configure OMEMO after installing Gajim, first install the necessary dependencies:

$ sudo pacman -S python-axolotl python-qrcode

Then, install the AUR package for OMEMO:

$ git clone https://aur.archlinux.org/gajim-plugin-omemo.git
$ cd gajim-plugin-omemo
$ makepkg
$ sudo pacman -U gajim-plugin-omemo-<version>.pkg.tar.zst

Once installed, go to Gajim -> Plugins and select OMEMO (it should be enabled by default).

Login to Your Account

Now let's try logging into your account. Open Gajim, select Add Account, and enter your username (e.g., admin@<address>.b32.i2p) and password. Check Advanced Settings, then click Log In to access the advanced options. Set the Hostname and Port to 127.0.0.1 and 5222, respectively, then click Log In again to connect. If you receive a "Certificate Verification Failed" warning, verify that the certificate matches the one you generated earlier, and if so, choose "Add to Trusted Certificates."

That's it—you're all set! Go ahead and start chatting with your friends (*•̀ㅂ•́)و