js-IPFS 0.54.0 brings UPnP NAT Hole Punching to your js-IPFS node

by Alex Potsides on 2021-02-03

🔦 Highlights

NAT UPnP Hole Punching

js-IPFS@0.54.0 enables NAT traversal with UPnP enabled routers for improved connectivity, but also requires a repo upgrade in the browser

↔️ NAT UPnP Hole Punching

When you run an IPFS node on your home network you are commonly behind a NAT firewall. These types of firewalls are commonly used on home networks to work around the shortage of IPv4 addresses in the world.

Normally, it’s not possible for computers external to your network to make connections to your node when this sort of infrastructure is between you and the remote computer. It’s essential for external computers to be able to connect to your computer when using IPFS, otherwise there is no way for remote nodes to fetch content stored on your node.

This problem is not unique to IPFS, it also extends to any P2P network and a lot of online games. Thankfully there is a solution: if your router supported UPnP and you have it enabled, a process on your computer can communicate with the router and ask it to open an external port and forward all traffic sent to that port to your machine. Once the port has been opened, we are then free to inform our connected peers that they can open connections on this external port as and when required via the libp2p identify protocol.

js-IPFS@0.54.0 enables UPnP NAT hole punching by default, but it will only work if UPnP is enabled on your router; instructions for enabling this will vary by manufacturer so please see your router’s documentation for more information on how to enable.

If everything works as expected, you should start to see externally addressable multiaddrs in the output of jsipfs id a short time after daemon startup without any extra configuration:

$ jsipfs id
  "id": "QmT2aN...",
  "publicKey": "CAASpgIwggEiMA0...",
  "addresses": [
    "/ip4/"  // <-- externally addressable!
  // ...other fields here

If you do not wish to enable hole punching, you can set the Swarm.DisableNatPortMap config key to true:

$ jsipfs config --json Swarm.DisableNatPortMap true

level-js upgrade

js-IPFS@0.54.0 uses the latest version of level-js in the browser. level-js@4.x.x and below support storing keys as either strings or Uint8Arrays, but level-js@5.x.x only supports Uint8Arrays in line with leveldown on Node.js.

This means a database migration will be necessary for those running js-IPFS in the browser (Node.js is unaffected).

This migration should take place automatically the first time you load js-IPFS@0.54.0 on a web page that has previously used js-IPFS@0.53.0 and below.

You can disable this feature by passing repoAutoMigrate: false to the IPFS constructor:

const node = await IPFS.create({
  repoAutoMigrate: false

Though if you do this, you should give your users some way of upgrading because level-js@5.x.x cannot see any database keys that are not Uint8Arrays.

✨New features

🔨 Breaking changes

🕷️ Bug fixes

🗺️ What’s next?

Check out the js-IPFS Project Roadmap which contains headline features organised in the order we hope them to land.

Only large features are called out in the roadmap, expect lots of small bugfix releases between the roadmapped items!

😍 Huge thank you to everyone that made this release possible

🙌🏽 Want to contribute?

Would you like to contribute to the IPFS project and don’t know how? Well, there are a few places you can get started:

⁉️ Do you have questions?

The best place to ask your questions about IPFS, how it works, and what you can do with it is at discuss.ipfs.io. We are also available at the #ipfs channel on Freenode.