Open david415 opened 8 years ago
:+1: this would be pretty cool!
OK I've written the go-multiaddr Tor onion address decoding: https://github.com/jbenet/go-multiaddr/pull/13
This sounds like a good plan for location-anonymous tor users to have a persistent identity and announce themselves to peers, but it doesn't cover the use case of anonymously (unlinkably?) accessing data from ipfs.
For that we'll need a mode that doesn't transmit any linkable identifiers (which includes not announcing pieces to the DHT).
@leif, Good point. The only "pieces" we'll be announcing to the DHT is .onion addresses. I suspect it will be very easy for us to create a readonly client mode for non-onion using Tor users to access any IPFS storage server without announcing any identity at all.
Today I wrote a TorDialer and OnionListener; This repo also includes examples programs which can be used as an integration test with your system Tor. However it should soon have more ways to use Tor other than just the control port protocol with the system tor:
https://github.com/david415/oniondialer
Although oniondialer
could be improved, we can do this later now that we have the basic interface implementations working. Therefore the next step should be to see how this Dialer and Listener can fit into go-multiaddr ... Probably oniondialer will have to change slightly to get it to fit into go-multiaddr
.
I've been looking closely at the source for go-multiaddr
and go-multiaddr-net
...
However I'm not sure if Tor onion service multiaddr string should look like this:
/onion/timaq4ygg2iegci7.onion:80
or this
/onion/fufu.onion/tcp/80
Whereas the "readonly Tor-ified" multiaddr looks like this: /tor/example.com/tcp/80
or should the /tor/ multiaddr not encapsulate and instead look like this? /tor/example.com:80
What do IPFS developers think of all this?
from chat:
/onion/fufu.onion/ip4/tcp/80
/tor/example.com/ip6/tcp/80
Similar to /dns
in https://github.com/jbenet/go-multiaddr/issues/7#issuecomment-125745700
A more explicit, but very bloated option for /tor
: /ip4/127.0.0.1/tcp/9050/socks5/dns/example.net/ip4/tcp/80
maybe:
/onion/fufu.onion/tcp4/80
and
/tor/example.com/tcp6/80
hi. I chatted with Juan last night on #ipfs and we decided that onion multiaddrs will look like this:
Tor doesn't transport IP or TCP... but is a realiable stream transport. We don't need DNS. Tor clients use a local SOCKS proxy; therefore the remote end does the DNS resolution. I hope I've cleared up the confusion regarding this. If not then I'm afraid this ticket will grow too big with my explainations. Perhaps find me on irc instead of commenting here with queries.
For the Tor exit node case I think it should be represented like so:
So I think this sort of breaks the multiaddr parser model... and so I made my multiaddr/net dev branches do this:
That is the colon separates the embedded onion port number.
@david415 doing /onion/timaq4ygg2iegci7:80
makes sense to me, all the parameters needed by the onion protocol are in the path element following it. Using the /
is strange, as the 80
then doesnt have a label, and its not super clear what its trying to be. @jbenet thoughts?
we'll already have things like:
/ip4/1.2.3.4/tcp/80/http
/dns/foo.com/A/ip4/tcp/80/http
if we made the restriction that only one component be used, why not then:
/ip4:1.2.3.4/tcp:80/http
/dns:foo.com:A:ip4/tcp:80/http
o/ this is actually harder to impl and does not layer well on a FS approach like 9P or linux proc files, which the former one does
thats not quite what I was getting at, i'm not saying that we require only one component. I'm saying that we combine the onion address and port into one as they both are given meaning by the /onion
path element.
Any suggestions for changes to go-multiaddr-net? Do you not want Tor/Onion related stuff in DialArgs since it is not a thin-waist protocol? See here: https://github.com/jbenet/go-multiaddr-net/blob/master/convert.go#L142-L144
@david415 right, DialArgs
is for net.Dial
mostly.
What we should do is:
(i unfort dont have time to work directly on this until after Sep 15. but can CR)
However... later it would be nice to have more granular policy for operating heterogeneous ipfs nodes/gateways/proxies.
I'm looking at go-multiaddr-net and go-ipfs to see how things work... and it makes sense for thin-waist protocols... but this type of thing isn't going to work for the OnionListener use case: https://github.com/ipfs/go-ipfs/blob/master/core/corehttp/corehttp.go#L50-L55
The onion multiaddr isn't enough information to create an onion listener. We need to know the tor process control port in order to create the onion service... then after we auto-create the onion service key material the control port tells us the onion address as well.
Perhaps in this case we need an onion + multiaddr helper function to create a new onion service and it's respective multiaddr? But how to plug it into the normal usage of go-multiaddr-net where the API user expects a multiaddr Listener to be created by only feeding it the multiaddr?
@david415 maybe the listen onion multiaddr could be different, could include more information, like the proxy:
/ip4/127.0.0.1/tcp/<control-port>/onion/<onion-address>
but it still should be advertised to others as:
/onion/<onion-address>
Perhaps in this case we need an onion + multiaddr helper function to create a new onion service and it's respective multiaddr?
yeah that's definitely doable. harder to make things plug in nicely. the other option is to create a "listener-maker" and mount that onto multiaddr, like:
c := maonion.NewController(NewMultiaddr("/ip4/127.0.0.1/tcp/<control-port>"))
c.NewListener(NewMultiaddr("/onion/<onion-addr>"))
// mount onto a multiaddr-net
manet.Listen("/onion/<onion-addr>") // doesn't work
manet.AddProtocol("onion", c)
manet.Listen("/onion/<onion-addr>") // now works
//
but this is kind of "magical" in a way i dont like (i.e. static), probably makes much more sense to rework how multiaddr-net works into something like this:
n := manet.NewNetwork()
n.Add(manet.IP4)
n.Add(manet.IP6)
n.Add(manet.TCP)
n.Add(manet.UDP)
n.Add(onion.Onion)
l, err := n.Listener("/ip4/1.2.3.4/tcp/1234")
c, err := n.Dial("/onion/<onionaddr>")
// with shortcuts like:
n := manet.NewThinWaistNetwork()
n.Add(onion.Onion)
"network" is a bit odd name, but does give the idea that these networks are stacked and makes more sense why mulriaddrs work the way they do. "transport" is another possible name, but may not capture the full meaning of "network".
Sorry, let's move multiaddr pluggable-ness discussion to https://github.com/jbenet/go-multiaddr-net/issues/7
hey @david415 -- @whyrusleeping has made transport changes to go-ipfs libp2p and to https://github.com/jbenet/go-multiaddr-net/ -- chances are we can resume the tor work!
cool! i'll take a look.
I can put some effort toward this in feb too. On Sat, Jan 2, 2016 at 08:27 David Stainton notifications@github.com wrote:
cool! i'll take a look.
— Reply to this email directly or view it on GitHub https://github.com/ipfs/notes/issues/37#issuecomment-168390975.
does running an ipfs server as a tor hidden service work by default? I guess there are quite a few dimensions to the intersection of tor and ipfs, and its difficult to tell what works out of the box and what needs development
No. IPFS does not "work by default" as a Tor onion service.
It is not difficult to tell the state of the IPFS + Tor integration because it is utterly non-existent; That's why we have this ticket!
@david415 :+1:
To reiterate what @leif posted: It might work for dialing an IPFS node from a censored location but you better have a custom ipfs build that doesn't scream your identity to everybody in it's vicinity. I hope we can see different flavors of ipfs nodes before 1.0. A privacy preserving client is much needed otherwise every content you share and spread becomes a tracking cookie. I personally already have that barbed-wire in my head stopping me from using it to share music with my family and that's only a 1st world problem.
@david415 @cryptix thanks -- I look forward to seeing this ticket progress. If I get some time I will try to pick up some tasks
I just posted a $100 bounty expiring in six months. Also paid to get it tweeted from @bountysource to hopefully get it some more attention. If there are blocker issues, let me know and maybe I can post bounties for those as well. https://www.bountysource.com/issues/26255361-tor-onion-integration
Hi everybody sorry for spammy wadup, but --- Whats the overview of progress atm?
(as a payment for this spammy question, If you all need a(n) alpha/beta tester I am perfectly willing :D)
@seanlynch you wanna pay us $100 for tor integration; ah hahaha. lol.
Great work trying to help get this ball rolling @seanlynch.
One request with this feature we'd like people to be able to run dual stack nodes, reachable via onion and TCP. This way people who run openbazaar stores can opt to service people who are running onion only nodes in addition to regular users.
With dual stack node you can't provide any gaurantees of anonymity, even running ipfs itself in tor only mode will make your tor node identifiable without some major changes.
@Kubuxu In a lot of cases, thats not necessary. @cpacia just wants to be able to expose his service to peers in the clearnet, and to peers in the tor-net. His node would be identifiable, sure, but it doesnt necessarily compromise the privacy of anyone who would connect to him
Yeah that's correct. Someone running a dual stack wouldn't necessarily by trying to hide their own IP.
Thinking about it though that might mess up routing if a dual stack node publishes providers on both networks. Those providers wouldn't make it to K nodes on both networks.
@david415 I suppose you'd rather I not post a bounty at all? You were already working on it for free. My hope was that others would also contribute. So far an anonymous contributor has added another $15.
At any rate, given that I have been unable to get IPFS to even work reliably on clearnet, I'm not currently comfortable with increasing the bounty. And from reading others' comments, I am not alone in having problems. Once those problems are resolved, assuming I haven't found a better alternative, we can discuss what amount you might consider more palatable.
I'm working on a websocket ipfs transport and I will be doing a writeup of "how to make ipfs work over X" using websockets as an example. Hopefully me finishing that will make this task a bit easier.
@whyrusleeping @cpacia The other reason to allow clearnet + onion access is so that you can host a node at your house and be able to access it via your LAN when you are at home... and otherwise utilize it's onion service for connectivity. I don't see any conflict here with hiding the location of the service in this case.
Any progress on this?
@whyrusleeping did you write your howto-write-ipfs-pluggable-transports document yet?
@spinda clearly the next step is to write an onion/tor transport plugin for ipfs/go-multiaddr-net.
After that is done the focus should be on how to integrate that tor/onion plugin with the ipfs source...
We will have a discussion session at the IPFS Q3 workshop on this. Will post the link here later.
@seanlynch would love to hear more. Mind trying the 0.4.3-dev branch? It's solved a lot of problems people had with 0.4.2
We have just released 0.4.3-rc1 give it a try.
attempting to write a tor onion transport plugin here: https://github.com/david415/ipfs-onion-transport
but is this the wrong way? there's this other api which seems to make more sense -> https://github.com/ipfs/go-libp2p-transport
@jbenet @Kubuxu I will try out 0.4.3-rc1 as soon as I can (two small kids). Thanks!
ok i'm going to fix my previous onion transport that i wrote a couple months ago. the problem i was running into previously is that we need the private key material in order to start listening on a given onion service. i will proceed as if the transport has a map from onions to keys... we can store the keys in files on disk or in a database. the constructor for the transport will specify the directory to store them in. fail if key material not found; although this implies some previous admin command to create the onion keys and onion addresses.
@david415 I'm a little confused about the need for keys. Isn't it just a matter of listening on a given port on localhost and pointing the Tor hidden service configuration to that port to receive incoming traffic?
@cpacia Tor onion services use a 1024 bit RSA key. To create the service you need this private key. The onion address is in fact the truncated hash of the corresponding public key.
I fixed the transport. Here, it needs review: https://github.com/david415/ipfs-onion-transport/blob/master/onion_transport.go
Oh, ok. For my implementation I was going to use the control port to set up the hidden service which, i believe, just returns the .onion address not the key. I can look and check.
chatting with Juan Bennet at c-base, Berlin about Tor onion service integration
here's what we've identified as necessary for proper Tor integration:
/onion
to go-multiaddr -/onion/<onion-key>/ipfs/<ipfs-key>
/onion
dialing to go-multiaddr-net/onion
I know plenty of people who'd be willing to run some Tor onion bootstrap nodes.
(edited by @jbenet for links)