Hi, is there a reference implementation using js-libp2p with Helia and friends to publish a website through an IPFS gateway from a desktop/laptop behind consumer internet (NAT/UPNP/PMP/etc)?
From first looks, many parts are there, but they don’t seem fully tested or working together for a desktop p2p app - similar to bittorrent clients
I only have my networking config, and it’s taken a lot of fussing to get it to work. But I want to build things I’m confident work on everyone’s networking config.
I’m thinking about features in bittorrent clients:
change ports at runtime
configure and detect UPNP/PMP/NAT
Bundled as a proof of concept for publishing a static website through an ipfs gateway.
If I had to start from scratch, I’d build it like this:
Node and Typescript using Vite
A one-page web UI
An Express server with access to the libp2p stack
A REST API because it’s easy for web devs to reason about
POST /publish - Publish local folder → get CID → html makes link to gateway
GET /publish - list of published folders
GET /status - to poll for network status
GET/POST /config - change networking (ports, enable/disable features, etc)
Logging and status so it’s easy to reason about bugs and features
@danieln and @bumblefudge what do you think?
@dhuseby can you think of a “just add water” way to deliver the torrent-style NAT-circumvention outlined in this post? or an exemplary js-libp2p config on github that could be turned into a tutorial or made part of a “just add water” tutorial/example project of the kind being proposed? apologies for having to tag you in and not just tracking your own tutorial/example project repo progress passively.
1 Like
Hi bumblefudge, thanks for the reply. I’m totally willing to be wrong about it, but it looks like the current AutoNAT and uPnP modules can’t do this OOTB:
opened 08:31PM - 27 Mar 24 UTC
need/triage
- **Version**:
├── @libp2p/autonat@1.0.13
├── @libp2p/upnp-nat@1.0.14
├── lib… p2p@1.3.0
- **Platform**:
linux
- **Subsystem**:
addressManager, AutoNAT, and UPNP.
#### Severity:
Considering js-libp2p as the transport layer for a peer-to-peer app running on a personal computer, and how users expect to configure p2p apps like bittorrent.
High - The main functionality of the application does not work, API breakage, repo format breakage, etc.
Medium - A non-essential functionality does not work, performance issues, etc.
#### Description:
Most peer-to-peer apps are run on personal computers instead of servers. Consider Bittorrent clients like qbittorrent, utorrent, vuze, etc.
These allow users to change the address, port, and upnp settings while the application is running.
Both autonat and upnp-nat detect a nodes public ip, but neither update the announce addresses in addressManager or candidates used by autonat.
This means an application using js-libp2p must detect these through other means or manage a restart of libp2p.
autonat detects them from peers and updates [addressManager's observedAddrs](https://github.com/libp2p/js-libp2p/blob/59a97b61b3e46f6d4b459ae94f7a6db534d4bca2/packages/interface-internal/src/address-manager/index.ts#L18), but it doesn't appear to update the candidates with the new IP address.
upnp-nat gets [client.externaIp()](https://github.com/libp2p/js-libp2p/blob/59a97b61b3e46f6d4b459ae94f7a6db534d4bca2/packages/upnp-nat/src/upnp-nat.ts#L97) and [updates observed addrs](https://github.com/libp2p/js-libp2p/blob/59a97b61b3e46f6d4b459ae94f7a6db534d4bca2/packages/upnp-nat/src/upnp-nat.ts#L119) but my client's `libp2p.getMultiaddrs()` never update.
Maybe I'm missing something but I don't see a way to use this information to reconfigure the js-libp2p other than to:
1. start it with a known incomplete config
2. add a timer to let these async processes complete (60s timeout for upnp-nat)
3. interrogate the libp2p client using undeclared interfaces to get addressManager
4. stop the client and reconfigure listen addresses and restart.
The statically configured listen addresses are already templates 0.0.0.0 and port 0 are replaced with local interfaces. It would be great if libp2p could do this with announce addresses as well.
What I'd like is to configure libp2p with these options:
```
services: {
autoNAT: autoNAT({ autoAnnounce true }),
upnp: uPnPNAT({ autoAnnounce true })
}
```
When autoNAT observes an externalIP, it calls `addressManager.autoAnnounce(ip)`.
addressManager iterates transports to create addresses. These are then verified by autoNAT.
When uPnPNAT observes an externalIP/port it calls `addressManager.autoAnnounce(ip, port)`
addressManager iterates transports to create addresses. These are then verified by autoNAT.
If addressManager remembers it's announced IP's, it could also do a port change with `addressManager.autoAnnounce(undefined, port)`
This would be a large change and may or may not be wanted.
#### Steps to reproduce the error:
Look at how other peer-to-peer applications configure their networking
https://vpn.ac/images/tutorials/socks5/qbittorrent1.png
https://www.bolehvpn.net/images/utorrent1.jpg
https://imgur.com/MQ4zkcA
It’s also discussed a bit here:
# Address Manager
The Address manager is responsible for keeping an updated register of the peer's addresses. It includes 2 different types of Addresses: `Listen Addresses` and `Announce Addresses`.
These Addresses should be specified in your libp2p [configuration](../../../../doc/CONFIGURATION.md) when you create your node.
## Listen Addresses
A libp2p node should have a set of listen addresses, which will be used by libp2p underlying transports to listen for dials from other nodes in the network.
Before a libp2p node starts, its configured listen addresses will be passed to the AddressManager, so that during startup the libp2p transports can use them to listen for connections. Accordingly, listen addresses should be specified through the libp2p configuration, in order to have the `AddressManager` created with them.
It is important pointing out that libp2p accepts ephemeral listening addresses. In this context, the provided listen addresses might not be exactly the same as the ones used by the transports. For example TCP may replace `/ip4/0.0.0.0/tcp/0` with something like `/ip4/127.0.0.1/tcp/8989`. As a consequence, libp2p should take into account this when determining its advertised addresses.
## Announce Addresses
In some scenarios, a libp2p node will need to announce addresses that it is not listening on. In other words, Announce Addresses are an amendment to the Listen Addresses that aim to enable other nodes to achieve connectivity to this node.
Scenarios for Announce Addresses include:
- when you setup a libp2p node in your private network at home, but you need to announce your public IP Address to the outside world;
This file has been truncated. show original
To get an idea of what users expect, here are some reference images of bittorrent configs:
Imgur: The magic of the Internet - 10 years old
1 Like