Skip to content

Instantly share code, notes, and snippets.

@pryce-turner
Last active December 25, 2022 14:33
Show Gist options
  • Save pryce-turner/cd407416a5023d78d2a3b0fb8aaa089a to your computer and use it in GitHub Desktop.
Save pryce-turner/cd407416a5023d78d2a3b0fb8aaa089a to your computer and use it in GitHub Desktop.
Air-gapped Raspberry Pi for eth2-deposit-cli

Motivation

The greatest strength of an airgapped machine is also it's biggest headache - no way out! This is a short guide for configuring an old Raspberry Pi 2 (no radio cards!) to securely use the eth2-deposit-cli tool. Whether using an existing mnemonic or generating a new one, the security conscious will appreciate doing so on a machine which never has and never will touch any network.


Requirements

  • Raspberry Pi
  • min 16Gb microSD
  • Raspberry Pi OS
  • USB drive
  • An internet connected device (preferably Debian based e.g. Ubuntu)

Steps

Install OS

There are a million guides for installing an OS on a Pi, the official documentation is a good place to start. You can also use any OS supported by your Pi, I simply chose Raspbian Lite because it's lightweight and Debian based. You'll also want to make your life easier by choosing an OS that ships with an appropriate Python version (>=3.7 at the time of writing).

Install Pip

(If your system ships with Pip installed, skip ahead to the note in the CLI dependencies section!)

Raspbian Lite doesn't ship with pip, the most common python packaging/dependency manager, so we'll need to install it. I chose to do so using the official .deb files distributed by the official archive. A good way to fetch pip and it's dependencies is via apt-cache, if your internet connected device supports it. Running $ apt-cache depends --recurse --no-recommends --no-suggests --no-conflicts --no-breaks --no-replaces --no-enhances python3-pip | grep "^\w" | sort -u (from this helpful article) will return a whole mess of dependencies, most of which will already be met on your Pi. This is where things get tricky.. Since you're gathering these dependencies on your networked device, it most likely will not be running the same architecture or OS. However, with the names of the dependencies and a bit of patience you can get it to work. In my case, I ran lsb-release -a on my Pi to reveal it's based on Debian 10 (Buster) which allowed me to find compatible packages in the aforementioned packaging archive. In my case they were:

  • python3-pip_20.0.2-5ubuntu1.6_all.deb
  • python3-setuptools_45.2.0-1_all.deb
  • python-pip-whl_20.0.2-5ubuntu1.6_all.deb
  • python3-pkg-resources_45.2.0-1_all.deb
  • python3-wheel_0.34.2-1_all.deb

Once you download these, transfer them to your USB stick and then onto your Pi. (You may need to manually mount your drive). Once mounted, they can be installed via sudo dpkg -i *.deb from the USB drive mount directory. This is where you'll likely encounter your first error and will need to do some back-and-forth until you get the right packages. You can verify pip is correctly installed by simply running pip3 or python3-pip.

Fetch eth2-cli-source

Download the cli source to your networked machine via git clone https://github.com/ethereum/eth2.0-deposit-cli.git. You'll also want to copy this to your USB stick and onto your Pi.

Install CLI dependencies

Once pip is installed on the Pi, we can use it to manually install the Python dependencies for the CLI. On your networked device, cd to the eth2-deposit-cli directory you just cloned and run pip download -r requirements.txt (more info here). This will download (but not install) the dependencies required for the project. However, once again these deps will be specific to your system, not the Pi! I recommend reading this excellent primer on Python wheels to make sense of the files downloaded. Once again, some fiddling will be needed. I relied on this PR to find my way. Pay special attention to the cp37 and armv7 parts of the filenames when fetching them from PiWheels. Mine ended up being:

  • cached_property-1.5.2-py2.py3-none-any.whl
  • click-7.1.2-py2.py3-none-any.whl
  • cytoolz-0.11.0-cp37-cp37m-linux_armv7l.whl
  • eth_hash-0.2.0-py3-none-any.whl
  • eth_typing-2.2.2-py3-none-any.whl
  • pyrsistent-0.16.1.tar.gz
  • six-1.15.0-py2.py3-none-any.whl
  • ssz-0.2.4-py3-none-any.whl
  • toolz-0.10.0-py3-none-any.whl
  • typed_ast-1.4.1-cp37-cp37m-linux_armv7l.whl
  • eth_utils-1.9.5-py3-none-any.whl
  • lru_dict-1.1.6-cp37-cp37m-linux_armv7l.whl
  • mypy_extensions-0.4.3-py2.py3-none-any.whl
  • pycryptodome-3.9.8-cp37-cp37m-linux_armv7l.whl
  • py_ecc-5.1.0-py3-none-any.whl

Once you've collected them all and put them on the Pi, they can be installed with pip install --no-index --find-links /path/to/download/dir/ -r requirements.txt. This is another point where you'll encounter errors, likely related to an incompatible Python version or architecture.

Note:

If your system shipped with Pip, you'll run into permission errors running setup.py. Resist the urge to sudo pip install - who knows, maybe your system relies on some incompatible crypto packages. You don't want to break out the sledge hammer only to realize you're trying to knock down a load bearing wall. Instead create a virtual env with python3 -m venv deposit_cli_env followed by source deposit_cli_env/bin/activate. Most OS' will let you know the env is active by adding a tag to the left of your prompt. Now pip install your dependencies, followed by ./deposit.sh install.

That's it!

Once all dependencies are met you should be able to run the CLI via ./deposit.sh or python3 eth2deposit/deposit.py. I realize there are likely more efficient/elegant ways of accomplishing this - but this worked for me and not once did an RJ45 desecrate my airgapped machine! Please note that you can accomplish very similar results much more easily by networking the Pi after first boot-up and installing dependencies from the web. As long as it never touches the network after a mnemonic has been generated/entered, you should have a virtually identical security posture - call me a purist.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment