It is possible to run a fully working prosody server over i2p…

To setup a prosody server over i2p, you will need:

  • A server can run i2p
  • i2p s2s prosody module
  • brian and hand

setup i2p

Here, I choose i2pd, and it will be almost same if you use i2p or i2p+.
Install and run it, i2pd can be installed from source in most gnu/linux distro.

create tunnel conf, write following lines in tunnels.conf

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
[prosody-s2s]
type=server
host=127.0.0.1
port=5269
inport=5269
keys=xmpp.dat

[prosody-c2s]
type=server
host=127.0.0.1
port=5222
inport=5222
keys=xmpp.dat

[prosody-httpserver]
type=server
host=127.0.0.1
port=5281
inport=5281
keys=xmpp.dat

If you plan to use messenger local only, remove the s2s section.
If you don’t need http server, remove the httpserver section.

After adding the config, you can restart i2pd to apply the new settings. Then, check the http://127.0.0.1:7070/ page i2p tunnels,
you should see the xxx.b32.i2p address of the prosody,it’s the domain of your prosody server.

setup prosody

Check official document to install it.

The default custom modules path should be plugin_paths = { "/usr/local/lib/prosody/modules" } in prosody.conf, where you put the s2s module for i2p.
You need to install lua-bit32 to use the modules. (but it still works without it, I don’t know why….)
You can use the mod_i2p. Just download the .lua file to the custom modules path.

ps: why you should not use https://github.com/majestrate/mod_darknet: the chat.xxx.b32.i2p is not a true i2p address, and the darknet mod can’t process it, which causes that you can’t connect to the other’s Component, and what mod_i2p added is simply a to_address=string.match(to_host,"%w+.%w+.i2p"); to reroute.

Then, edit the /etc/prosody/prosody.cfg.lua, replace xxx.b32.i2p with your address.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
interfaces = { "127.0.0.1" };
admins = { "admin@xxx.b32.i2p" }; -- the admin address you will use
modules_enabled = {
-- choose by your need
};
modules_disabled = {};

plugin_paths = { "/usr/local/lib/prosody/modules" }

allow_registration = false;
c2s_require_encryption = true;
s2s_secure_auth = false;
authentication = "internal_hashed";

certificates = "certs";

pidfile = "/run/prosody/prosody.pid";

-- if you want to use http server, set this
http_host = "xxx.b32.i2p"

VirtualHost "xxx.b32.i2p";
-- enable the module in the vhost
modules_enabled={
"i2p",
}
-- if you want Component like muc, do it like this.NOTICE,every component
Component "conference.xxx.b32.i2p" "muc"
modules_enabled={ "i2p" }

Then, you can generate the certs.

1
2
3
4
openssl genrsa -out /etc/prosody/certs/xxx.b32.i2p.key 2048
openssl req -new -x509 -key /etc/prosody/certs/xxx.b32.i2p.key -out /etc/prosody/certs/xxx.b32.i2p.crt -days 3650
chown root:prosody /etc/prosody/certs/*.b32.i2p.{key,crt}
chmod 640 /etc/prosody/certs/*.b32.i2p.{key,crt}

then restart the prosody.

create account and use it

Run this to add an account.

1
sudo prosodyctl adduser admin@xxx.b32.i2p

You can use many clients.

connect local

It depends on the client you use, it should provide configure to choose the address of the server. Just set it to the ip of your server.

connect through i2p

in computer

With gajim, you can set the proxy and connect to server directly.

in phone

The conversation-i2p is no longer maintaining, how ever you can still use other clients.
My solution is using the ClashMetaForAndoroid and any i2p mobile client.
here is the rule for clash:

1
2
3
4
5
6
7
8
9
10
11
12
13
port: 7890
mode: rule
external-controller: 127.0.0.1:9090


proxies:
- name: i2p
type: http
server: 127.0.0.1
port: 4444

rules:
- DOMAIN-SUFFIX,i2p,i2p

then, use any mobile xmpp client to connect the server through i2p.

http only(optional)

The xep tells you that you must use https to upload…, but we don’t have a official ca for i2p… so we need to use http only server.

Prosody provides an http server in 5280, but you can’t directly use it, you should use an reverse proxy for it.

for example, you can configure nginx like this

1
2
3
4
5
6
7
8
9
10
11
12
server{
listen 127.0.0.1:890;
server_name xxx.b32.i2p;
location / {
proxy_pass http://localhost:5280;
proxy_set_header Host "xxx.b32.i2p";
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_buffering off;
tcp_nodelay on;
}
}

then, you can add an i2p tunnel.