Backup Your iOS Devices to a Private IPFS Node

Update 2020-04-07: This has now been built into a single command line tool. Installation and usage can be found on Github.


There are various reasons you may want to backup your iOS device somewhere other than iCloud.

This post describes how to perform manual backups of your iOS device over USB or WiFi to a local IPFS node via the command line.

Script available: A script is available on Github that automates much of this process.

You will need

  • Knowledge of basic IPFS concepts
  • Basic command line knowledge
  • An iOS device
  • Locally running IPFS node
  • Mac, Linux, or Windows computer*

*This has only been tested on Mac, but the dependencies should work across all platforms

Setting up a private IPFS node

IPFS Desktop is what I use to run a local IPFS. But there are many other ways to do this as well.

IMPORTANT: It is highly recommended to use a private IPFS node. Following this tutorial will encrypt your backup, but it will not encrypt metadata for your backup. This metadata contains potentially sensitive information, including the phone number and list of apps installed on your device. See this issue for more information.

Ensuring your IPFS node will only connect to peers that you trust will prevent this unencrypted metadata from being available to others on the public IPFS network. For more information about private networks, see this.

You can simply generate a swarm key

1
2
go get github.com/Kubuxu/go-ipfs-swarm-key-gen/ipfs-swarm-key-gen
ipfs-swarm-key-gen > ~/.ipfs/swarm.key

And remove all peers from the bootstrap list

1
ipfs bootstrap rm --all

This will create a private network where your local node is the sole member. In future tutorials, I will show how this network may be expanded so your backups may be stored on multiple computers that you own.

1. Install Dependencies

The only dependency needed is libimobiledevice, a cross-platform library that enables communication with iOS devices.

Homebrew

The easiest installation method for macOS is using Homebrew. This package has not had a formal release for quite some time. I recommend installing from the latest HEAD to avoid issues that have been fixed.

1
brew install libimobiledevice --HEAD

Compiling from source

If the Homebrew solution does not work for you on macOS or you are installing on Linux or Windows, you will need to compile the package from source. Build instructions can be found here.

Enable WiFi backups

At the time of writing, HEAD does not support performing backups over WiFi. I have opened a PR with a simple change to enable this. If this is still not merged and you would like to use WiFi, try building from this fork.

2. Pair your device

Once you have installed libimobiledevice, the first step is to see if your device can be discovered.

1
idevice_id -l -n

This will search and list the device identifiers for all devices connected via USB or WiFi.

If you have never connected this device to your computer, you may need to pair it first. See if the device is already paired by running

1
idevicepair -u $DEVICE_UDID validate

If it is not paired, initiate the pairing process

1
idevicepair -u $DEVICE_UDID pair

You should see a dialog show up on your device asking to “trust this computer”. Choose “Trust” and enter in your passcode if prompted.

If you need to distinguish between multiple connected devices, try getting more info about a device using ideviceinfo. For example,

1
ideviceinfo -u $DEVICE_UDID -k DeviceName

will print out the device name.

3. Enable encryption

Before performing a backup, it is highly recommended to enable encryption.

1
idevicebackup2 -u $DEVICE_UDID encryption on -i

You should be prompted to enter a password for the backup. This encryption is using the standard iTunes backup encryption provided by Apple. See the Apple Platform Security Guide for more details.

4. Perform backup

We will now perform the backup to the local filesystem. You will need to specify a BACKUP_PATH. There are two different methods here to choose from:

  1. Backup to BACKUP_PATH temporarily and copy to IPFS as blocks (slower)
  2. Backup to BACKUP_PATH permanently and add to IPFS via filestore (faster)

Option 1 is a simple solution that uses the normal IPFS usage patterns you are probably familiar with. However, this will result in the entire backup being saved to the local filesystem and then copied into IPFS. I have found performance significantly increases if you use the filestore instead.

Option 2 uses the filestore, an experimental feature that allows IPFS to reference files being added instead of copying them. Because we are dealing with such large files, this will significantly improve performance. However, be aware that the backup must live somewhere permanently on the local filesystem. If these files are modified in any way, things will break.

You can enable the filestore by making a change to your IPFS config:

1
ipfs config --json Experimental.FilestoreEnabled true

Now, perform the backup

1
idevicebackup2 -u $DEVICE_UDID backup $BACKUP_PATH

This may take some time.

5. Save backup to IPFS

Once the backup is complete, we can now add it to IPFS. As mentioned previously, there are two options.

Option 1

Copy the backup to IPFS

1
ipfs add -r "${BACKUP_PATH}/${DEVICE_UDID}"

Clean up the temporary backup

1
rm -r $BACKUP_PATH

Option 2

Add the backup to the IPFS filestore using --nocopy

1
ipfs add --nocopy -r "${BACKUP_PATH}/${DEVICE_UDID}"

6. Keep track of your backups

Once the backup has been added to IPFS, I find it useful to keep track of different backups using MFS (Mutable File System). I keep a directory called ios-backups at the root of MFS.

1
ipfs files mkdir /ios-backups

This directory contains a list of files named by DEVICE_UDID with the contents being the CID of the latest backup for that device.

1
echo "${CID}" | ipfs files write --create /ios-backups/${DEVICE_UDID}

That’s it!

If you have any issues or questions, feel free to reach out and create an issue.

Also check out Github to find a script that automates most of this process.