Deploy a private IPFS network in 5 steps

IPFS (InterPlanetary File System) is a peer-to-peer distributed file system that stores and retrieves files in a BitTorrent-like way. The default installation of IPFS connects your machine to the global distributed network. In some cases (privacy, confidentiality) a private IPFS network is preferred over connecting to the public IPFS network.

This article describes the steps to create a private IPFS network on different Ubuntu machines within the same network. Make sure the machines can ping each other.

No connection to the public network will be made, so all the data on this private network will only be accessible to known peers on the network.

For Mac OS, the installation steps are almost identical, just download the Mac versions of Go and IPFS. To install on Windows, you could install Ubuntu from the Microsoft store and follow the steps below.

Step 1 — Install IPFS

Go installation

To install the latest version of IPFS, first Go needs to be installed from https://golang.org/doc/install.

Download the archive to your disk. Then extract the file into /usr/local, creating a Go tree in /usr/local/go with the following example statement. Change the filename in the statement below to the name of your local file.

sudo tar -C /usr/local -xzf go1.11.4.linux-amd64.tar.gz

Add /usr/local/go/bin to the PATH environment variable, by executing:

export PATH=$PATH:/usr/local/go/bin

and apply changes with

source $HOME/.profile

IPFS installation

To install ipfs, go to https://dist.ipfs.io/#go-ipfs and copy the link (see picture below) of the latest Go implementation of IPFS. At the time of writing, the latest version is Version v0.4.18 for Ubuntu.

Copy the link of go-ipfs

Run the following commands (update the third and fourth line to the latest version with the copied link).

sudo apt-get update
wget https://dist.ipfs.io/go-ipfs/v0.4.18/go-ipfs_v0.4.18_linux-amd64.tar.gz
tar xvfz go-ipfs_v0.4.18_linux-amd64.tar.gz
sudo mv go-ipfs/ipfs /usr/local/bin/ipfs

optional cleanup:

rm go-ipfs_v0.4.18_linux-amd64.tar.gz
rm -R ./go-ipfs

To verify your installation, type

ipfs version

with the following result

Installing IPFS won’t start the IPFS filesystem right away, so no connection to the public IPFS network will be made.

Step 2 — Initialize nodes

For the purpose of this tutorial, we will install two nodes: a bootstrap node and a client node. The bootstrap node is an IPFS node that other nodes can connect to in order to find other peers. Since we are creating our own private network, we cannot use the bootstrap nodes from the public IPFS network, so we will change these settings later. Select one of your machines as bootstrap node and one as client node.

IPFS is initialized in a hidden directory in your user home directory: ~/.ipfs. This directory will be used to initialize the nodes. On both machines, bootstrap node and client node, run the following.

IPFS_PATH=~/.ipfs ipfs init

Result:

Note: we use IPFS_PATH=~/.ipfs to force IPFS to use the directory with the config file (and swarm file, see step 3) of our private network. If you already have IPFS installed on your machine that connects to a public network, the ipfs add statement might use this installation and thus publishing a document on the public network. If this installation is the first installation of ipfs, IPFS_PATH=~/.ipfs can be omitted.

Step 3 — Create a private network

We have now installed two IPFS nodes, which could easily connect to the public IPFS network, but that’s not what we need. To create a private network, we will use a swarm key. This swarm key will be referenced by all the nodes in this private network.

The swarm key generator is executed on the bootstrap node only and runs on the Go programming language. To install the swarm key generator, we use go get, which uses git. If you have not installed git yet on your bootstrap node, do so with

sudo apt-get install git

Run the following command to install the swarm key generator:

go get -u github.com/Kubuxu/go-ipfs-swarm-key-gen/ipfs-swarm-key-gen

Run the swarm key generator to create the swarm file in your .ipfs directory:

./go/bin/ipfs-swarm-key-gen > ~/.ipfs/swarm.key

Copy the generated swarm file to the .ipfs directory of all client nodes.

Step 4 — Bootstrap IPFS nodes

A bootstrap node is used by client nodes to connect to the private IPFS network. The bootstrap connects clients to other nodes available on the network. In our private network we cannot use the bootstrap of the public IPFS network, so in this section we will replace the existing bootstrap with the ip address and peer identity of the bootstrap node.
 
 First, remove the default entries of bootstrap nodes from both the bootnode and the client node. Use the command on both machines:

IPFS_PATH=~/.ipfs ipfs bootstrap rm --all

Check the result to see the bootstrap is empty with:

IPFS_PATH=~/.ipfs ipfs config show

Result:

Now add the ip address and the Peer Identity (hash address) of your bootstrap node to each of the nodes including the bootstrap node.

The ip address of the bootnode can be found with hostname -I.

The Peer Identity was created during the initialisation of IPFS and can be found with the following statement.

IPFS_PATH=~/.ipfs ipfs config show | grep "PeerID"

Result:

Assemble the add bootstrapstatement as follows.

IPFS_PATH=~/.ipfs ipfs bootstrap add /ip4/<ip address of bootnode>/tcp/4001/ipfs/<peer identity hash of bootnode>

Example:

IPFS_PATH=~/.ipfs ipfs bootstrap add /ip4/172.25.10.5/tcp/4001/ipfs/QmdbaLZsKA94tsYeKJEPyLThWARFCtWyJWuudBUd4z9KBU

Run your statement on both the bootstrap node and the client node.

Step 5— Start the network

The private network is installed, so we can test this network. We will use an environment variable to make sure that if there is a mistake in our configuration or the private network is not fully configured, the nodes don’t connect to the public IPFS network and the daemons just fail.
 The environment variable for the same is “LIBP2P_FORCE_PNET” and to start the IPFS nodes you just need to start the daemon using theipfs daemon command with the following statements.

export LIBP2P_FORCE_PNET=1
IPFS_PATH=~/.ipfs ipfs daemon &

export LIBP2P_FORCE_PNET=1 means that you force your node to be private. If no private network is configured, the daemon will fail to start.

In our case the command and the output look like this:

Do note the message log stating Swarm is limited to private network of peers with the swarm key which means that our private network is working perfectly. Now add a file to our private network on one node and try to access it from the other node.

mkdir ipfstest
cd ipfstest
echo "Hello World!" > file1.txt
IPFS_PATH=~/.ipfs ipfs add file1.txt
IPFS_PATH=~/.ipfs ipfs cat <hash of the file>

Result:

The ipfs add statement returned a hash code of the uploaded file. This hash code can be used from the other nodes to retrieve the file. If the same file is uploaded on an other node, the same hash is generated, so the file is not stored twice on the network.

To upload a complete directory, add the directory name and the -r option (recursive). The directory and the files in it are hashed:

The files can be accessed via a browser as well. Open a browser and enter:

http://127.0.0.1:8080/ipfs/QmfM2r8seH2GiRaC4esTjeraXEachRt8ZsSeGaWTPLyMoG
Result:

This concludes the tutorial to build a private peer-to-peer IPFS network. In this network all documents are private and confidential to the participants of this network.


This article was written after research about private distributed storage solutions for a blockchain project we at SynTouch were working on. At SynTouch we provide blockchain solutions for the Dutch market. For more information about our services, please contact sander.van.laar@syntouch.nl.

Special thanks to Koen Wartenberg, Mignon Gakuba and Sibe van Etten for their input.