Skip to main content

Private Network

Background

We are using IPFS as our file system. But IPFS is built to use for public data, and it does not support ACL, So we need to find a way to keep users safe until our security layer becomes mature. And also ipfs-cluster docs recommended to have a secret.

Current Network

Our current network topology is too simple, its only base on webrtc-start and peer discovery is disabled.

Server

Node with roll of server is a js-libp2p node with our protocol's and server side implementations (use js-ipfs as fs) that listen on webrtc-start.

Client

Node with the roll of client (phone,webapp) are listening on webrtc-start and when user provide the string peer id (B58String) of the box with connect API, the api create multiAddress based on webrtc signaling server add it to libp2p peer store and keep the connection alive with the box. also have to mention inbound connections are blocked.

Problem Statement

We need to protect users and their data from harms and risks of public networks and also cover the multi box scenario. The public network risks are:

  • Anyone on the internet can connect to the box.
  • Anyone on the internet that is connected to the box can use bitswap to get data from the box.
  • Peer routing and Content discovery can leak what you are doing to the public.
  • deficiency in our encryption algorithm or key management can leak all user data to the public.
  • clusters running without a secret may discover and connect to the main IPFS network, which is mostly useless for the cluster peers (and for the IPFS network).

Motivation

Isolating users from public networks can help us reduce the scope of work while maintaining the usefulness of our product, and testing our security layer without putting users in harm's way.

Proposal

We can use built-in libp2p components to create a private network with encrypted communication. The components are:

  • Libp2p built-in private network. It uses a private shared key for creating an isolated network with encrypted communication.
  • Libp2p bootstrap for bootstrapping the network of boxes:

In this way when a node comes online, Libp2p uses the key and the list of other node's to join the network.

Scope of work

Box

For box setup users provide an environment variable FULA_NET_SECRET which they should remember. and provide a list of node as config.json

FULA-Client

user calls createClient they should also provide the secret they used for setting up the boxes. and when he calls connect it should pass the list of string peerId's

Implementation

The box and client already support private-key but need to add test and fixes namings.

Box

In the Config we should change the name PKEY to FULA_NET_SECRET

We need to add js-libp2p-bootstrap and In the Config we should add to support to load config.json in this format:

{
"nodes": [
"/ip4/104.131.131.82/tcp/4001/ipfs/QmaCpDMGvV2BGHeYERUEnRQAwe3N8SzbUtfsmvsqQLuvuJ",
"/dnsaddr/bootstrap.libp2p.io/ipfs/QmNnooDu7bfjPFoTZYxMNLWUQJyrVwtbZg5gBMjTezGAJN",
"/dnsaddr/bootstrap.libp2p.io/ipfs/QmQCU2EcMqAqQPR2i9bChDtGNJchTbq5TbXJJ16u19uLTa"
]
}

Which will be used for creating js-libp2p-bootstrap config.

FULA-client

In fula-client We have to change pkey to fulaSecret so:

createClient(config?: Partial<Libp2pOptions & constructorOptions>, pKey = undefined): Promise<Fula>

to

createClient(config?: Partial<Libp2pOptions & constructorOptions>, fulaSecret = undefined): Promise<Fula>

and change connect interface to get a list of peerId`s from:

connect: (peerId: string) => Connection

to

 connect: (peerId: [string]) => Connection

We need to change Connection in the way that:

  • Connection Status
    • If we connect to at least one box we are Online.
    • When we are not connected to any box and try to connect we are at Connecting.
    • When connection fails to all the serverPeerIds we Are Offline.
  • Connection should have a list of serverPeerId.
  • Connect to all the serverPeerId and keep the connection alive.

Case Study

For dogfooding of new changes we can use a copy of react-gallery and change the BoxConfig to get list of comma seperated peerIds and App should change to pass the list of peerId's to fula-client.

Note: if example repo would be outside mono-repo we can just use branch for describing every functionality.

Alternative approaches

VPN

Using VPN for creating the private network.

Disadvantage:

  • It adds another point of failure to the system.
  • It is also not that decentralized.