ipfs / kubo

An IPFS implementation in Go
https://docs.ipfs.tech/how-to/command-line-quick-start/
Other
16.04k stars 3k forks source link

API to allow peers to ask for a port check #6593

Open andrasfuchs opened 5 years ago

andrasfuchs commented 5 years ago

The idea came from a feature request for IPFS Desktop: https://github.com/ipfs-shipyard/ipfs-desktop/issues/1042.

Currently the nodes can't tell if their ports are open to other peers or not. As a non-technical user it would be good to see that I need to configure my firewall and/or router to benefit the IPFS network more by allow incoming connections to my running node. In order for the client to show any warning messages or tutorials how to do it, the node itself would need to know if its own port looks open from the outside.

To achieve this we could use an external service (as some torrent and ftp clients do), but depending on a 3rd party service is probably not good idea. It would be much better, if a node could ask another node to check its own port status. Ideally anyone could ask its peers periodically to check the reachability of a ipv4 or ipv6 address from the asked peer's point of view.

So, my recommendation would be to add a new API command to accomplish the port check for multiple addresses/ports (if the node has more than one) and protocols (ipv4/tcp, ipv6/tcp, tor, etc.) and return the results to the requesting node.

Stebalien commented 5 years ago

You'll be happy to hear that this feature already exists. It's called "autonat" (https://github.com/libp2p/go-libp2p-autonat/) and all of our bootstrappers support this. We currently use it to determine if we should switch to using a relay (the "autorelay" feature).

But you're right, we should better expose this to the user.

andrasfuchs commented 5 years ago

Fantastic! :)

Is this autonat library exposed on the go-ipfs daemon in any way, so could IPFS Desktop somehow query the daemon's port state?

Stebalien commented 5 years ago

Not at the moment.

At the moment, we only use it when autorelay is enabled. When we do, we simply remove the unreachable addresses and start advertising relays. You can tell if relays are being used with ipfs id.

andrasfuchs commented 5 years ago

I see.

So then this feature request would essentially be to expose autonat on the daemon's API. We would only need a few methods: one to enable/disable autonat, and one to return a detailed status of autonat (including if the addresses of the daemon are reachable from other peers).

Would it be possible?

Also, I tried the ipfs id command, and I might be doing something wrong, but I could not tell from the response if I use/need to use a relay.

My config: image

ipfs id: image

Stebalien commented 5 years ago

Also, I tried the ipfs id command, and I might be doing something wrong, but I could not tell from the response if I use/need to use a relay.

That's because you've set EnableRelayHop to true. That tells ipfs to act as a relay, not to use relays. That's also IPFS's "please DOS me flag". I'd turn it off.

andrasfuchs commented 5 years ago

Thanks, I didn't know that.

So I modified my settings: image

ipfs id: image

I'm behind a VPN at the moment and I got the same results. At this point I don't know how to tell if autonat is even enabled or what state is it in.

So the feature request would be to have autonat information either withing the response of the ipfs id command, or as a response of a new API command.

Stebalien commented 5 years ago

So I modified my settings:

Note: AutoNATService enables the server-side AutoNAT feature (i.e., it allows you to help others figure out if they're behind NATs). Enabling AutoRelay automatically enables the autonat client.


193.37.253.118 is a public address. It looks like NAT port mapping may have worked. It also looks like you may have some valid IPv6 public addresses.

How long was the node online? AutoRelay can take a few minutes to kick in.

If/when it does, you'd see a bunch of /p2p-circuit addresses.

andrasfuchs commented 5 years ago

I see, alright, thank you @Stebalien for the explanation!

So, if we wanted to show a warning message to ipfs-desktop users when they are in passive mode (their port looks closed from the outside), we should: 1, check if AutoReplay is enabled in their config file (because it's needed for the port checking) 2, check if ipfs id returns any addresses with the "p2p-circuit" substring (because this means that our port looks closed)

Is my understanding correct?

Stebalien commented 5 years ago

At the moment, yes. We should use autonat regardless of autorelay (and get better at detecting NAT status in general) but we don't really have anyone to work on that at the moment.

andrasfuchs commented 5 years ago

@hacdias, Would you consider implementing the logic mentioned above in ipfs-desktop as a realization of the "Show a warning if IPFS port is closed" feature request?

hacdias commented 5 years ago

@andrasfuchs @Stebalien thanks for digging into this.

@andrasfuchs sure we can. I will update the issue with the new info