ipfs / notes

IPFS Collaborative Notebook for Research
MIT License
401 stars 30 forks source link

Dynamic DNS and Let's Encrypt certificates for secure websockets #252

Open JustinDrake opened 7 years ago

JustinDrake commented 7 years ago

A browser js-libp2p node A communicating with a go-libp2p node B over secure websockets wss:// requires B to have a valid SSL certificate. This means libp2p web apps are either restricted to http:// (sucks), or need to use a wss:// proxy server for SSL termination (better, but still sucks).

The Nimiq whitepaper has a good idea to address this issue:

Powerful browser APIs are restricted to secure origins. So for browsers to connect, Backbone Nodes need to provide an encrypted connection via SSL. This requires a domain and an SSL certificate. For easy and cheap access to domains, we will provide dynamic DNS and Letsencrypt packaged in an installer.

go-libp2p nodes could programatically get an SSL certificate for themselves. I am imagining a service (e.g. maintained by ProtocolLabs) where subdomains of libp2p.io or ipfs.io could be registered given a request signed by a peer ID.

For example, the owner of the QmZXGKrRRe5RTDhvzhZfSTe8vYBDGV7HBoNz5FS3U9FnUa peer ID would be able create an A record mapping QmZXGKrRRe5RTDhvzhZfSTe8vYBDGV7HBoNz5FS3U9FnUa.libp2p.io to its IP address, and then get a Let's Encrypt certificate for itself.

Thoughts?

JustinDrake commented 7 years ago

I just learned about IP-only certificates, which could be useful to solve this problem.

https://stackoverflow.com/questions/2043617/is-it-possible-to-have-ssl-certificate-for-ip-address-not-domain-name

daviddias commented 7 years ago

go-libp2p nodes could programatically get an SSL certificate for themselves.

That's a pretty cool idea. It would be useful for any socket really. It would be the mix of a SSL Termination proxy plus a Let's Encrypt Cert auto set up.

re: Certs for IPs

Interesting! It seems that the IP needs to be static first though, you can't simply emit certs for IPs on the fly.

@kyledrake, @lgierth thoughts?

kyledrake commented 7 years ago

The one thing I'm not sure about is how you make this work with NAT firewalls. I'm assuming the CSR has to include an IP address when it signs, but the local machine is only aware of the LAN IP, so it would need to communicate with some sort of external service to determine it's public IP address.

If NAT isn't an issue and this is only for direct static IPs, then this should work fine, though I'm just as surprised as you that it exists as a concept.

kyledrake commented 7 years ago

Also: If https://github.com/ipfs/go-ipfs/issues/4143 happens then this code could be used for both. Then it works for IP addresses and domain names (and as a consequence, subdomain-jailed IPFS hashes).

ghost commented 7 years ago

Caddy does a pretty decent job at automatically getting Let's Encrypt certs. We could have look into what it'd take to integrate the relevant parts into the go-libp2p websockets transport. For permanent nodes in datacenters, this would nicely remove the need for a TLS-terminating reverse proxy.

I'm not sure what the use case is for non-datacenter nodes. Something like DynDNS-style dynamic IPs? I'm not sure it's worth that big of a fight against the nature of TLS and certificate authorities. It would introduce us to a whole bag full of edge cases and things that just won't work for dubious reasons.

Let's start small.

go-libp2p nodes could programatically get an SSL certificate for themselves. I am imagining a service (e.g. maintained by ProtocolLabs) where subdomains of libp2p.io or ipfs.io could be registered given a request signed by a peer ID.

I'm not clear yet where this is going. Sounds intriguing on the one hand and uncomfortable on the other :)