dendrite icon indicating copy to clipboard operation
dendrite copied to clipboard

Adds support for listening on and connecting to I2P and Onion services securely

Open eyedeekay opened this issue 2 years ago • 17 comments

This PR adds 2 dendrite-demo main's, each designed expressly to serve a Hidden Service/Overlay network.

The first, dendrite-demo-i2p add self-configuration for use of dendrite as an I2P hidden service(eepsite) and to connect to I2P services(federate) as an I2P client. It further disables the dendrite server from communicating with non-anonymous servers by federation(because I2P does not canonically have the ability to exit, we rely on donors for exit traffic), and enables the use of self-signed TLS certificates(because I2P services are self-authenticating but TLS is still required for other aspects of the system to work reliably). This demo turns the system into an "pseudonymous" homeserver which people can connect to using an I2P-enabled Matrix client(I like cinny and it's what I tested with).

The second, dendrite-demo-tor adds self-configuration for the use of dendrite as an Onion service and to connect to other onion services and non-anonymous web sites using Tor to obfuscate it's physical location and providing, optionally, pseudonymity. It also enables the use of self-signed TLS certificates, for the same reason as with I2P, because onion services aren't typically eligible for TLS certificates. It has also been tested with cinny.

These services are both pseudonymous like myself, not anonymous. I will be meeting members of the element team at the CCC assembly shortly to discuss contributing under my pseudonym.

As none of the other dendrite-demo have unit tests I did not add them to these checkins.

eyedeekay avatar Dec 27 '23 19:12 eyedeekay

I hereby donate this code to Anoa.

eyedeekay avatar Dec 27 '23 20:12 eyedeekay

I accept this donation and sign off on this code.

Signed-off-by: Andrew Morgan <[email protected]>

anoadragon453 avatar Dec 27 '23 20:12 anoadragon453

Moving this from README_I2P.md to here becasue README_I2P.md is about to me mostly irrelevant.

How to build a Dendrite Homeserver modified to run over I2P or Tor
==================================================================

I2P mode: I2P must be installed first, and the SAMv3 API bridge must
be activated.

1. First, clone the `matrix-org/dendrite` implementation of dendrite into your GOPATH and change branch to the `i2p-demo` checkout.


2. Second, build the binary:

    go build -o bin/dendrite-demo-i2p ./cmd/dendrite-demo-i2p

3. Third, run it.

    go build -o bin/dendrite-demo-i2p ./cmd/dendrite-demo-i2p

Tor mode: Tor must be installed first.

1. First, clone the `matrix-org/dendrite` implementation of dendrite into your GOPATH and change branch to the `i2p-demo` checkout.

2. Second, build the binary:

    go build -o bin/dendrite-demo-tor ./cmd/dendrite-demo-tor

3. Third, run it.

    go build -o bin/dendrite-demo-tor ./cmd/dendrite-demo-tor

eyedeekay avatar Dec 27 '23 23:12 eyedeekay

(@eyedeekay I can officially confirm that the code donation above checks out :slightly_smiling_face:)

anoadragon453 avatar Jan 05 '24 17:01 anoadragon453

I have demo instances up and running but I'm not sure how best to share them, as I have enabled open registration for now and don't think that I should make them that public. Let me know if there's a best way to share them with testers on your side.

eyedeekay avatar Jan 10 '24 01:01 eyedeekay

Sorry for just moving this to contrib, as much as I like this contribution, I don't see us maintain this. Hope this is OK with you, @eyedeekay

S7evinK avatar Feb 29 '24 17:02 S7evinK

Seems like GHA or whatever is upset right now, looking at the golangci-lint errors.

Unit tests seem to be a real issue, could you take a look at this please?

S7evinK avatar Feb 29 '24 18:02 S7evinK

Sorry for just moving this to contrib, as much as I like this contribution, I don't see us maintain this. Hope this is OK with you, @eyedeekay

I'm certainly fine with it being in contrib and will be along to update it as Matrix evolves if necessary, there's actually a surprising amount of people running homeservers inside I2P and this could make things a lot easier and safer for them. But, if that's how you feel about it, maybe I could talk you into finding a way to expose the package-internal net.Listener interface that I swapped out for onion and i2p listeners in my demos? Because if that were to happen, then these wouldn't need to be in the dendrite repository at all, that is merely a difficulty that arises because I can't replace the underlying net.Listener from outside the dendrite package. It's a bit of a missive below, but I think this has benefits:

It would also be a more general way to open up the use of Go matrix homeservers to other kinds of P2P and/or Overlay networks. Anyone who could implement a net.Listener and some way to Dial it would be able to have their own self-hosted Matrix homeserver. I know of how to do it for Tor and I2P, and in the past I have seen things like reverse tunneling services which offer the ability to interface with a net.Listener for instance.

Also, at least in some of these scenarios, it's sort of implied that if you can set up the server somewhere you can always set up a client to talk to it, as in the case of Tor or I2P. If you have Tor, you can talk to onion services, if you can't, then Tor has a problem. Same for I2P, if you have I2P, you can talk to I2P services, if you can't, it's our problem. This means that every I2P or Tor homeserver can also be a client of and also federate with any other I2P or Tor homeserver(at least for the purposes of mere contactability). So if you wanted to serve up something other than staticContent/*.gotmpl, you could for instance embed a cinny web-client instead, and configure it by default to point to the hosting dendrite instance, making it both a homeserver and a client which can be easily deployed to any I2P or Tor instance.

I think in the end everybody would win. You don't have to maintain a bunch of dendrite-demo* stuff, overlay network users and self-hosters can try novel P2P things.

/missive

With regard to the unit tests, I'm pretty sure the demo-tor unit test is failing because there isn't a Tor instance in the unit test container but that's just a hypothesis. It might be kind of rude to spin up a Tor client to run unit tests in CI so I'm going to work to confirm that hypothesis locally and if that's the case then my advice would be to simply disable that test. but please give me a little while to be absolutely sure that's what it is.

eyedeekay avatar Feb 29 '24 21:02 eyedeekay

Hi, see how I suggest this to be implemented here : https://github.com/element-hq/synapse/issues/7088

Apparently the synapse devs can't do much about it, maybe you guys would take a better shot at it ?

nihilist001 avatar Jul 30 '24 08:07 nihilist001

As I'm not too familiar with the code, can you take a look at the linter issue -> Error: var samAddr is unused (unused) @eyedeekay. Is that expected?

S7evinK avatar Aug 03 '24 19:08 S7evinK

@nihilist001 it's definitely easier, IMO, to support hidden services well in the Go language than it is in the python languate, however that's simply my opinion based on the methods I am familiar with. This PR applies those methods.

@S7evinK Nope, looks like I forgot to remove the --samaddr flag when I converted the I2P demo into a Tor demo. The checkin I just made should resolve that if that's the case. I'll have a look at these other unit tests too.

eyedeekay avatar Aug 03 '24 21:08 eyedeekay

I don't see any way to fix the other tests when running on the CI, however they work locally. The unit tests are currently failing because there isn't a Tor or I2P client running on the CI server where the tests can see it. I also don't want to remove them completely, because using them locally is in fact useful. Is there a way to simply disable them in the CI but leave the tests intact for local use?

eyedeekay avatar Aug 03 '24 22:08 eyedeekay

I don't see any way to fix the other tests when running on the CI, however they work locally. The unit tests are currently failing because there isn't a Tor or I2P client running on the CI server where the tests can see it. I also don't want to remove them completely, because using them locally is in fact useful. Is there a way to simply disable them in the CI but leave the tests intact for local use?

You probably can do something like:

if os.Getenv("CI") != "" {
    t.Skip("skipping test, as no TOR/I2P client is available")
  }

in the test.

S7evinK avatar Aug 04 '24 08:08 S7evinK

If we can let them run I think the CI should all pass now.

eyedeekay avatar Aug 16 '24 05:08 eyedeekay

@eyedeekay heads up you have some CI failures

anoadragon453 avatar Aug 19 '24 11:08 anoadragon453

Yeah for some reason it's still running the failing tests, I'll have to find some other way to keep them from running

eyedeekay avatar Aug 19 '24 21:08 eyedeekay

Well that was weirder than it should have been, lol. Turns out disabling the unit test just ran the main without any of the instrumentation, so the only way to fix it was to look for the CI in the demo application being tested. Works now though, locally and in CI. I see you fixed the linter errors so I'll leave it here until you have more feedback.

eyedeekay avatar Aug 21 '24 21:08 eyedeekay