I work on the libp2p project (libp2p.io) which is an open source networking stack meant to make it easier for developers to build networked applications, and particular ones that operate in a peer-to-peer or distributed manner. Some of the most well known users of libp2p include: IPFS (https://ipfs.tech/), Ethereum (https://ethereum.org/) and Filecoin (https://filecoin.io/) among many others both big and small.
My team (Interplanetary Shipyard) would like to launch a service that allows users to register for DNS names like <peer identifier>.libp2p.direct
and enable them to get wildcard certificates from Let’s Encrypt for *.<peer identifier>.libp2p.direct
via DNS01 ACME challenges. This would enable users to generate addresses like 1-2-3-4.<peer id>.libp2p.direct
, which would resolve via DNS to 1.2.3.4 , and have those addresses usable in web browsers and other user agents that require CA signed certificates.
There are hundreds of thousands of libp2p nodes in the wild and while many wouldn’t need a certificate (e.g. they don’t have public IP addresses anyway and would have to deal with DNS rebinding protections) a whole lot would. IPFS’ Amino DHT alone has tens of thousands of publicly reachable server nodes Amino DHT | ProbeLab.
The Ask
Having read through the documentation it seems like we would qualify for increased rate-limits for the libp2p.direct
domain name (i.e. the Certificates per Registered Domain limit). At the moment raising the limit to 5k-10k certificates per week seems sufficient. However, this may need to increase to >10k over time. However, I wanted to engage with the community here to see if there are any issues for us to be concerned about before applying for the raised limit.
More information about the problem we’re trying to solve and why having raised limits for certificates seems like the best way forward as well as an analysis of prior art, risks and explored alternatives is below:
Problem statement
libp2p (libp2p.io) is an open source networking stack meant to make it easier for developers to build networked applications, and particular ones that operate in a peer-to-peer or distributed manner. Some of the most well known users of libp2p include: IPFS (https://ipfs.tech/), Ethereum (https://ethereum.org/) and Filecoin (https://filecoin.io/) among many others both big and small.
Since the Web platform is a major way in which developers deliver applications to their users it’s important for the libp2p project to be able to make applications usable in web browsers like Chromium-variants, Firefox, and Safari. Given that browsers now lean heavily on Secure Contexts (MDN, W3C) it’s important that any communications that a web browser needs to make occur within a secure context. At the moment the ways to do this are: Have a CA signed certificates, use WebRTC with pre-determined certifcate hashes, use WebTransport with pre-determined certificates hashes.
Unfortunately, the most widely used browsers have missing features or bugs that using make WebRTC and WebTransport painful or unusable (some examples include ‣ and ‣, but there are more). While we’ve done work with groups like Igalia to work with browser vendors to remediate issues it appears to be a long road ahead until they’re reliably usable by developers.
As we continue working with browser vendors to improve the state of usable peer-to-peer communications in browsers having the ability for libp2p developers to leverage more hardened protocol implementations like HTTPS and Secure WebSockets would make their experience much easier.
While Let’s Encrypt currently makes it easy for anyone to obtain a certificate given a registered domain many users don’t have registered domains and don’t want to go through the process of obtaining one just to start using their application.
Goals
It should be possible for all common browser nodes to be able to communicate with non-browser nodes that are reachable with public IP addresses without users being required to buy or setup a domain name.
Non-goals
Ability for browser nodes to be able to connect to nodes with non-public IP addresses (e.g. behind NATs). This is out of scope due to the amount of effort required to deal with browser vendors to make WebRTC better and/or enable other protocols (e.g. WebTransport) to do holepunching. For the time be
Proposed solution
- Shipyard owns the domain name libp2p.direct
- Users’ applications will automatically be able to set their DNS01 ACME challenges for .libp2p.direct with Shipyard (note: a libp2p peerID is essentially a hash of a public key and so control can be verified statelessly)
- Users will be able to automatically get certificates for their domain via DNS01 ACME challenges to Let’s Encrypt for
*.<peerID>.libp2p.direct
- This requires Let’s Encrypt to be ok with the number of certificates we will be registering. Given that this mimics the arrangement they have with Plex for plex.direct this is hopefully not a problem.
- Shipyard will have a DNS resolver will resolve all IPs of the form
1-2-3-4.<peerID>.libp2p.direct
to an A record for 1.2.3.4 andxxxx-xxxx-xxxx-xxxx-xxxx-xxxx-xxxx-xxxx.<peerID>.libp2p.direct
to a AAAA record for the corresponding ipv6 address - Applications will be able to disseminate domain names that will be usable in browsers with protocols like HTTPS and Secure WebSockets without the user needing to set anything up
Risks
- In setting up a service for domain registration and setting the DNS01 ACME challenges there will be a need to handle takedown notices for abusers of a given domain name
- Shipyard already has experience with this kind of work as a result of running the ipfs.io public gateway
- The volume of peers wanting certificates grows high enough to cause problems for Shipyard’s service or for Let’s Encrypt
- Shipyard: Given that most of the server-side work is stateless this shouldn’t be an issue for quite a while and if it is then Shipyard will need to setup some sort of rate-limiting / spam prevention
- Let’s Encrypt: Given that Plex is already handling >4.5M certs of a similar nature for Plex it may not be an issue for a while. However, if it were Let’s Encrypt could ask Shipyard to institute rate-limits on setting DNS01 ACME challenges for new certificate issuances which would alleviate the pressure.
Prior Art
- Plex: They are helping users do DNS01 with Let’s Encrypt to get users certificates for
*.<identifier>.plex.direct
and sets up DNS to return an A record for1-2-3-4.<identifier>.plex.direct
to 1.2.3.4. To handle this they have increased limits with Let’s Encrypt - pubtls.org: Was a project to give people
<hash-of-publickey>.pubtls.org
domains and let them set DNS records for themselves. - Tailscale
- They are helping their users get custom subdomains and Let’s Encrypt certificates for them. To handle this they have increased limits with Let’s Encrypt
- Enabling HTTPS · Tailscale Docs we’ll have to settle with WebRTC and its limitations in a NAT’d environment.
- They are helping their users get custom subdomains and Let’s Encrypt certificates for them. To handle this they have increased limits with Let’s Encrypt
Alternative solutions
- Work with browser vendors to make it possible to use self-signed certificates when the certificate is known ahead of time → In progress but quite slow
- Propose a CA like Let’s Encrypt that they offer a generic service that could likely handle what libp2p and Plex both need (e.g. LE runs a domain name like
letsencrypt.direct
and give users certificates for*.<hash-of-public-key>.letsencrypt.direct
when they prove they have the corresponding private) → Would be convenient if they are interested, but want the increased burden on Let’s Encrypt to be as low as possible.- If there’s interest we’d certainly be interested to use it or to have our open service be a prototype for what LE might want to run in the future
- Use something like
1-2-3-4-<peerID>.libp2p.direct
rather than1-2-3-4.<peerID>.libp2p.direct
→ this means more certificates have to be issued since a given peer may have multiple IP addresses - Use something like a certificate hash instead of a peerID (e.g. to not encourage long-lived public-key based addresses that are painful to rotate) → potentially doable, although it seems would require more state on behalf of Shipyard’s side
Implementation and rollout plan
- If handling of the large number of certificates is approved by Let’s Encrypt, Shipyard would setup the DNS resolver and prototype the challenge registration protocol in go-libp2p (GitHub - libp2p/go-libp2p: libp2p implementation in Go) before specifying it more publicly and rolling it out
- It would likely start as experimental in go-libp2p for Secure WebSockets for more widespread use and testing and then a similar capability to support HTTPS would be added. It would likely roll out within kubo (GitHub - ipfs/kubo: An IPFS implementation in Go) and the IPFS ecosystem before being more widely adopted and deployed
- Get libp2p.direct onto the Public Suffix List
- Our use case is similar to Tailscale’s Add ts.net and beta.tailscale.net domains by danderson · Pull Request #1453 · publicsuffix/list · GitHub and better than the ones explicitly excluded by the PSL Guidelines · publicsuffix/list Wiki · GitHub in that we are leveraging cryptographic identifiers not just mapping the IP space to DNS and each users’ public key is genuinely independent user data that deserves it’s own namespace. However, as Tailscale did we’d like to make it clear to the PSL that we already have the rate limit increase from Let’s Encrypt and want the PSL inclusion because it has real value to us and is not just for circumventing Let’s Encrypt’s rate-limits.
Success Criteria
- A large enough percentage of non-NAT’d IPFS nodes are directly reachable from common web browsers such that they realistically can directly retrieve data from hosting nodes without needing a fallback/proxy.
- Adoption across other libp2p-based projects
- Sufficient adoption that will bolster our case to browser vendors that there should be native support for connecting to user applications even when the users haven’t registered for a domain name (e.g. via some self-certifying address).
FAQ
- What would a certificate like
*.<peerID>.libp2p.direct
mean for a consuming party?- It would be asserting that the controller of a given peer identity (e.g. private key) is also the controller of the given subdomain
- For something like
https://1-2-3-4.<peerID>.libp2p.direct
which has DNS returning an A record for 1.2.3.4 a consumer trusting the CA + domain owner of libp2p.direct can be sure that the address is either controlled by the owner of the corresponding private key or will result in a certificate error.