Decrediton on Tails

14 minute read

1. Introduction

Tails is an operating system based on Debian Linux that can be run directly from a USB flash drive.

It aims at preserving your privacy and anonymity, and helps you to:

  • use the Internet anonymously and circumvent censorship;
  • all connections to the Internet are forced to go through the Tor network;
  • leave no trace on the computer you are using unless you ask it explicitly; use state-of-the-art cryptographic tools to encrypt your files, emails and instant messaging.

Tails comes with Electrum installed, which is the one of the most well-known Bitcoin wallets. The operating system comes ready for Electrum. All we have to do is install Decrediton (and a few other things).

Figure 1 - A scheme as close as possible to anonymity
Figure 1 - A scheme as close as possible to anonymity

Figure 2 - A scheme as close as possible to anonymity, with a remote dcrd
Figure 2 - A scheme as close as possible to anonymity, with a remote dcrd

2. Installing Tails on USB flash drive

The solution is divided in the following steps:

  • Installation of Tails on USB flash drive (section 2)
  • Creation of encrypted persistent storage on the flash drive, where the blockchain and Decrediton configuration files will be stored (section 3)
  • Creation of a firewall rule to allow Decrediton to communicate with its internal dcrd (section 4)
  • Installation and configuration of Decrediton (section 5)

Section 6 brings two shell scripts to help with all those tasks, practically automating the whole process explained in sections 3 to 5. Those scripts are of utmost importance because Tails is an amnesic system that won’t keep any configuration after reboot.

Another way of saying this is, what remains after the reboot is:

  • the installation of Tails on USB flash drive on section 2
  • folder mapping to the persistent directory on section 3
  • the extraction and configuration of Decrediton on sections 5.2, 5.3 and 5.4 and the download of the blockchain

The rest of the configuration will be lost, more specifically:

  • the inclusion of Decred as an item of the application called “Configure a persistent volume” on section 3
  • the creation of the firewall rule on section 4
  • the installation of Decrediton dependencies on section 5.1

The scripts on section 6 will make the burden of these tasks go away and Decrediton usage on Tails viable. These scripts won’t install Tails and won’t partition the USB flash drive to create an encrypted persistent storage.

Tails complete installation instructions can be read at https://tails.boum.org/install/index.en.html

The steps described in this section were executed in a Debian 9 64-bit to install Tails 3.7 on a USB flash drive with 16GB of capacity. The other steps described in this article were executed inside this installation of Tails 3.7 to execute Decrediton 1.2.1.

Prerequisites

To install Tails on a USB flash drive another USB flash frive with Tails installed will be required or the installation should be started from a Linux host.

2.1. Security considerations

Running Tails inside a virtual machine has various security implications. Depending on the host operating system and your security needs, running Tails in a virtual machine might be dangerous.

Only run Tails in a virtual machine if both the host operating system and the virtualization software are trustworthy.

For security reasons, Tails will be installed on the USB flash drive from a Debian host. As Tails instructs, it would be necessary to have trustworthy software to run Tails (or any other OS) on the virtual machine. That includes the operating system being open source and also the virtualizer.

To learn more about virtualization risk, read https://tails.boum.org/doc/advanced_topics/virtualization/index.en.html

2.2. Direct download

a) Go to https://tails.boum.org/install/vm-download/index.en.html. b) Choose between direct download or download via torrent. In case of download via torrent it will be necessary to verify the digital signature using the steps shown in the next section. c) In case of direct download, start the download as shown in Step 1 of the website. Then, as shown in Step 2, install browser extension Tails Verification, available for Firefox, Chrome and Tor Browser, which will only access data sent to tails.boum.org. d) When the installation is finished, click a button on the same Step 2 of the website that reads “Verify Tails”. e) The web browser will open a window to select the ISO file downloaded before in step b). This verification takes about 10 seconds. f) After verifying the downloaded file using the browser extension, the extension may be removed. g) Manual verification shown in next section is optional.

2.3. Verification via OpenPGP (optional)

The digital signature can be manually verified for both direct and torrent downloads.

a) Go to https://tails.boum.org/install/vm-download/index.en.html. b) At the end of the page there is a section called “Verify using OpenPGP (optional)”, download the files Tails signing key (developers’ public key) and Tails 3.7 OpenPGP signature (the digital signature, which must reside in the same folder as Tails ISO file downloaded before). c) Verify the digital signature (in the verification process shown next, there was no need to import the public key manually because dirmngr intermediated the process, downloading the key from HKPS server via TCP/11371).

$ gpg --verify tails-amd64-3.7.iso.sig
gpg: assuming signed data in 'tails-amd64-3.7.iso'
gpg: Signature made Tue May  8 02:18:06 2018 WEST
gpg:                using RSA key 2FAF9BA0D65BB371F0BC2D463020A7A9C2B72733
gpg: requesting key 3020A7A9C2B72733 from hkps server hkps.pool.sks-keyservers.net
gpg: key DBB802B258ACD84F: 4 duplicate signatures removed
gpg: key DBB802B258ACD84F: 1770 signatures not checked due to missing keys
gpg: key DBB802B258ACD84F: 1 signature reordered
gpg: key DBB802B258ACD84F: public key "Tails developers <tails@boum.org>" imported
gpg: no ultimately trusted keys found
gpg: Total number processed: 1
gpg:               imported: 1
gpg: Good signature from "Tails developers <tails@boum.org>" [unknown]
gpg:                 aka "Tails developers (offline long-term identity key) <tails@boum.org>" [unknown]
gpg: WARNING: This key is not certified with a trusted signature!
gpg:          There is no indication that the signature belongs to the owner.
Primary key fingerprint: A490 D0F4 D311 A415 3E2B  B7CA DBB8 02B2 58AC D84F
     Subkey fingerprint: 2FAF 9BA0 D65B B371 F0BC  2D46 3020 A7A9 C2B7 2733

If the public key must be imported (the public key downloaded from the website):

$ gpg --import tails-signing.key

To learn more, read Verifying digital signatures

2.4. Installing via tails-installer

The easiest way of installing Tails on a USB flash drive is using a Linux host.

Figure 3 - Linux host with tails-installer installs an image of Tails on a USB flash drive
Figure 3 - Linux host with tails-installer installs an image of Tails on a USB flash drive

To learn more about this scenario, read installation instructions at https://tails.boum.org/install/debian/usb/index.en.html

In this 16GB USB flash drive, tails-installer created a 8.6GB partition formatted with FAT32 for Tails and left the remaining 7.4GB free.

Figure 4 - The volumes in the USB flash drive after partitioning
Figure 4 - The volumes in the USB flash drive after partitioning

Restart the device using the USB flash drive containing Tails. The next steps will be executed from Tails.

3. Creating an encrypted persistent storage

The encrypted persistent storage is not hidden. An attacker in possession of the USB stick can know whether it has an encrypted persistent storage. Take into consideration that you can be forced or tricked to give out its passphrase.

Before using persistent storages, read the warnings at https://tails.boum.org/doc/first_steps/persistence/warnings/index.en.html.

Edit file /usr/share/perl5/Tails/Persistence/Configuration/Presets.pm using root privileges and include the code snippet shown next, after the Electrum block in the file, for example.

        {
            name        => $self->encoding->decode(gettext(q{Decred client})),
            description => $self->encoding->decode(gettext(
                q{Decrediton wallet and configuration}
            )),
            destination => '/home/amnesia/.config/decrediton',
            options     => [ 'source=decrediton' ],
            enabled     => 0,
            icon_name   => 'package-x-generic',
        },
        {
            name        => $self->encoding->decode(gettext(q{Decred server})),
            description => $self->encoding->decode(gettext(
                q{Decred's blockchain server}
            )),
            destination => '/home/amnesia/.dcrd',
            options     => [ 'source=dcrd' ],
            enabled     => 0,
            icon_name   => 'package-x-generic',
        },

From the Applications menu, select Tails, and start application “Configure persistent volume”. Select the new items in the list: “Decred client” and “Decred server”. Click on button “Save”.

Figure 5 - The application that configures persistent storage
Figure 5 - The application that configures persistent storage

Figure 6 - Select both items to confgure Tails for Decred usage
Figure 6 - Select both items to confgure Tails for Decred usage

Restart the device using Tails USB flash drive. Folder mappings for ~/.dcrd and ~/.config/decrediton, which will reside in the USB flash drive, will be automatically created.

4. Firewall

Tails firewall has a rigid control over its traffic, including localhost access. Very specific rules must be created so that processes can talk to each other within Tails. This helps avoid traffic bypassing Tor.

Tails uses iptables for network access control, but the rules are managed using a front-end called ferm, a service that configures the rules in its own language and then generates a file in iptables format containg the rules.

First, the cache file generated by ferm must be deleted:

# mv /var/cache/ferm/start.sh /var/cache/ferm/start-oldrules.sh

Then, edit the file /etc/ferm/ferm.conf using root privileges and search for the following rule:

                # White-list access to OnionShare
                daddr 127.0.0.1 proto tcp syn dport 17600:17650 {
                    mod owner uid-owner $amnesia_uid ACCEPT;
                }

Insert the rule for dcrd and dcrwallet right below it:

                # White-list access to dcrd and dcrwallet
                daddr 127.0.0.1 proto tcp dport 9109:9112 {
                    mod owner uid-owner $amnesia_uid ACCEPT;
                }

This rule allows localhost access to TCP destination ports 9109 to 9112, made by a process run by the amnesia user.

Save the file, reload ferm rules and check iptables for the new rule as shown next. Root privileges will be necessary.

# service ferm reload
# iptables -L -v
(...)
    0     0 ACCEPT     tcp  --  any    lo      anywhere             localhost            tcp dpts:9109:9112 owner UID match amnesia
(...)

5. Installing Decrediton

5.1. Dependencies

Decrediton depends on libgconf2-4 library, which is not installed by default on Debian (Tails is Debian-based). The following command installs libgconf2-4 and its dependencies. The package net-tools was included in the command because it installs netstat tool, which we will use later.

$ sudo -i
# apt update
# apt install gconf2-common gconf-service libgconf-2-4 libgconf2-4 net-tools

5.2. Download and verification of digital signatures

a) Import Decred developers’ public key (as shown here):

amnesia@amnesia:~/Tor Browser$ gpg --keyserver pgp.mit.edu --recv-keys 0x518A031D
gpg: key 0x6DF634AA7608AF04: public key "Decred Release <release@decred.org>" imported
gpg: Total number processed: 1
gpg:               imported: 1

b) Go to https://github.com/decred/decred-binaries/releases/ and download the files decrediton-$VERSION.tar.gz, manifest-decrediton-$VERSION.txt and manifest-decrediton-$VERSION.txt.asc.

c) Verify the integrity of file manifest-decrediton-$VERSION.txt using the digital signature contained in manifest-decrediton-$VERSION.txt.asc. Next, verify if the hash of file decrediton-$VERSION.tar.gz matches the hash contained in manifest-decrediton-$VERSION.txt:

amnesia@amnesia:~/Tor Browser$ gpg --verify manifest-decrediton-v1.2.1.txt.asc 
gpg: assuming signed data in 'manifest-decrediton-v1.2.1.txt'
gpg: Signature made Tue 01 May 2018 06:41:34 PM UTC
gpg:                using RSA key 0x6D897EDF518A031D
gpg: Good signature from "Decred Release <release@decred.org>" [unknown]
gpg: WARNING: This key is not certified with a trusted signature!
gpg:          There is no indication that the signature belongs to the owner.
Primary key fingerprint: FD13 B683 5E24 8FAF 4BD1  838D 6DF6 34AA 7608 AF04
     Subkey fingerprint: F516 ADB7 A069 852C 7C28  A02D 6D89 7EDF 518A 031D
amnesia@amnesia:~/Tor Browser$ sha256sum decrediton-v1.2.1.tar.gz 
a2535fc4d789486850ac66b1de3b45a013c937bfd8509e0396f1863fe41ed535  decrediton-v1.2.1.tar.gz
amnesia@amnesia:~/Tor Browser$ grep tar.gz manifest-decrediton-v1.2.1.txt
a2535fc4d789486850ac66b1de3b45a013c937bfd8509e0396f1863fe41ed535 decrediton-v1.2.1.tar.gz

To learn more, read Verifying digital signatures

Extract Decrediton to ~/Persistent directory and run it for the first time to create the configuration files. Decrediton won’t be able to communicate with external hosts because it hasn’t been configured to use Tor proxy (any other network traffic is prohibited by the firewall).

amnesia@amnesia:~/Tor Browser$ tar -xzf decrediton-v1.2.1.tar.gz 
amnesia@amnesia:~/Tor Browser$ mv decrediton-1.2.1/ ../Persistent/
amnesia@amnesia:~/Tor Browser$ cd ../Persistent/decrediton-1.2.1/
amnesia@amnesia:~/Persistent/decrediton-1.2.1$ ./decrediton -d

Close the window or terminate the execution using [Ctrl+C].

5.3. Configuring Tor as proxy

Edit configuration file $HOME/.config/decrediton/dcrd.conf. Include the following line at the end of the file and save it.

proxy=127.0.0.1:9150

5.4. Configuring dcrwallet

Start Decrediton.

$ ./decrediton -d

Create a wallet using a new seed or an existing one. The wallet will be created inside the structure ~/.config/decrediton/wallets/mainnet/$WALLET_NAME/mainnet/wallet.db.

Decrediton will show an error message while connecting to dcrwallet. Terminate the execution closing the window or by issuing [Ctrl+C] on the terminal window.

In order for Decrediton to connect to dcrwallet it is necessary to specify a TCP port where dcrwallet will listen for connections, otherwise all TCP ports would have to be allowed on the firewall, on the rule created in section 4.

Edit file ~/.config/decrediton/wallets/mainnet/$WALLET_NAME/dcrwallet.conf and change the port specified by the parameter grpclisten to 9112.

grpclisten=127.0.0.1:9112

Start Decrediton again.

Check the connections using netstat.

$ netstat -atp

6. Scripts

To avoid going to war with Tails on every execution, I created two shell scripts. The first one must only be executed one after the creation of the persistent storage. The second will have to be executed after every reboot.

Copy both code snippets to ~/Persistent directory on USB flash drive and mark the execution attribute:

$ chmod +x decrediton-dep.sh decrediton-persistence.sh

6.1. decrediton-persistence.sh

Enter the directory where the script is located and execute it with command sudo -E ./decrediton-persistence.sh.

#!/bin/bash
# Decrediton-persistence
# Author: Marcelo Martins
# Written for Tails 3.7
# Persistence configuration for dcrd and Decrediton on Tails 3.7
# Requires root privileges (sudo)
# Ref: https://gist.github.com/mc2pw/aeb4ca3972fea54d4858

if [[ $EUID -ne 0 ]]; then
  echo "$0: Please run as root: sudo -E $0."
  exit 1
fi

if [ $HOME = "/root" ]; then
  echo $HOME
  echo "$0: Use sudo with option -E to keep amnesia profile."
  exit 1
fi

PERSIST_PRESET="/usr/share/perl5/Tails/Persistence/Configuration/Presets.pm"
GREP_RESULT=`grep -c Decred $PERSIST_PRESET`
if [ $GREP_RESULT -gt 0 ]; then
  echo "$0: Persistence configured. Now open menu Applications -> Tails -> Configure persistent volume."
  exit 0
fi

# Make sure you check /usr/share/perl5/Tails/Persistence/Configuration/Presets.pm for the correct position to insert the rule.
# Then change number 146 below inside `sed` to reflect the correct position.
sed -i "146 a #\n\t{\n\t    name        => \$self->encoding->decode(gettext(q{Decred client})),\n\t    description => \$self->encoding->decode(gettext(\n\t        q{Decrediton wallet and configuration}\n\t    )),\n\t    destination => '/home/amnesia/.config/decrediton\',\n\t    options     => [ \'source=decrediton\' ],\n\t    enabled     => 0,\n\t    icon_name   => \'package-x-generic\',\n\t},\n\t{\n\t    name        => \$self->encoding->decode(gettext(q{Decred server})),\n\t    description => \$self->encoding->decode(gettext(\n\t        q{Decred\'s blockchain server}\n\t    )),\n\t    destination => \'/home/amnesia/.dcrd\',\n\t    options     => [ \'source=dcrd\' ],\n\t    enabled     => 0,\n\t    icon_name   => \'package-x-generic\',\n\t}," $PERSIST_PRESET

GREP_RESULT=`grep -c Decred $PERSIST_PRESET`
if [ $GREP_RESULT -gt 0 ]; then
  echo "$0: Persistence configured. Now open menu Applications -> Tails -> Configure persistent volume."
  exit 0
fi

# End of script

6.2. decrediton-dep.sh

Enter the directory where the script is located and execute it with command sudo -E ./decrediton-dep.sh.

#!/bin/bash
# Decrediton-dep
# Author: Marcelo Martins
# Written for Tails 3.7
# Read all the comments before running this script.
# Reconfigures Tails after inicialization and
# must be run after every reboot to prepare the environment for Decrediton.
# Requires root privileges (sudo)

if [[ $EUID -ne 0 ]]; then
  echo "$0: Please run as root: sudo -E $0."
  exit 1
fi

if [ $HOME = "/root" ]; then
  echo "$0: Use sudo with option -E to keep amnesia user environment."
  exit 1
fi

GREP_RESULT=`grep -c Decred /usr/share/perl5/Tails/Persistence/Configuration/Presets.pm`
if [[ $GREP_RESULT -lt 2 && (! -d $HOME/.dcrd || ! -d $HOME/.config/decrediton) ]]; then
  echo "$0: decrediton-persistence.sh must be run to configure persistent storage."
  exit 1
fi

if [ ! -f $HOME/.config/decrediton/dcrd.conf ]; then
  echo "$0: There is no dcrd.conf. Open Decrediton to create config files. Then close it and run this script again."
  exit 1
fi

# Download all packages locally to persistent storage
# so we won't waste time with apt update and download more than once
# Why net-tools? Because I like to verify the connections with netstat before using a service via Tor.
if [ ! -f gconf-service*.deb ]; then
  apt update
  echo "Downloading gconf2-common..."
  GCONF2=`apt-get download gconf2-common | awk '{print $5"_"$7"_"$6".deb"}' | head -1`
  echo "Downloading gconf-service..."
  GCONFSVC=`apt-get download gconf-service | awk '{print $5"_"$7"_"$6".deb"}' | head -1`
  echo "Downloading libgconf-2-4..."
  LIBGCONF=`apt-get download libgconf-2-4 | awk '{print $5"_"$7"_"$6".deb"}' | head -1`
  echo "Downloading libgconf2-4..."
  LIBGCONF2=`apt-get download libgconf2-4 | awk '{print $5"_"$7"_"$6".deb"}' | head -1`
  echo "Downloading net-tools..."
  NETTOOLS=`apt-get download net-tools | awk '{print $5"_"$7"_"$6".deb"}' | head -1`
else
  GCONF2=`find . -name gconf2* | awk -F "/" '{ print $2 }'`
  GCONFSVC=`find . -name gconf-service* | awk -F "/" '{ print $2 }'`
  LIBGCONF=`find . -name libgconf-2-4* | awk -F "/" '{ print $2 }'`
  LIBGCONF2=`find . -name libgconf2-4* | awk -F "/" '{ print $2 }'`
  NETTOOLS=`find . -name net-tools* | awk -F "/" '{ print $2 }'`
fi

# Install the packages
dpkg -i $GCONF2 $GCONFSVC $LIBGCONF $LIBGCONF2 $NETTOOLS > /dev/null 2>&1
[ $? -eq 0 ] && echo "$0: Dependencies were successfully installed."

# Because of the way dcrwallet was setup to allow multiple simultaneous wallets,
# I had to change a setting in dcrwallet.conf to be able to narrow down TCP port range.
# Ref: https://github.com/decred/decrediton/pull/1163

# Make sure you check /etc/ferm/ferm.conf for the correct position to insert the rule.
# Then change the number 91 below inside `sed` to reflect the correct position.
if [ `grep -c 9109:9112 /etc/ferm/ferm.conf` -eq 0 ]; then
  sed -i '91 a #\n\t\t# White-list access to dcrd and dcrwallet\n\t\tdaddr 127.0.0.1 proto tcp dport 9109:9112 {\n\t\t    mod owner uid-owner $amnesia_uid ACCEPT;\n\t\t}' /etc/ferm/ferm.conf
  [ -f /var/cache/ferm/start.sh ] && mv /var/cache/ferm/start.sh /var/cache/ferm/start.sh.old
  service ferm reload
fi

IPT_RESULT=`iptables -L -v | grep -c 9109:9112`
[ $IPT_RESULT -gt 0 ] && echo "$0: Firewall rules were set."

# Check dcrwallet.conf for TCP port configuration.
# The problem here is, now dcrwallet.conf resides inside the wallet directory.
# I'm assuming there is only one wallet in this Persistent storage.
WALLET_FULLPATH=`find $HOME/.config/decrediton/ -name dcrwallet.conf`
DCRW_RESULT=`grep -c grpclisten=127.0.0.1:9112 $WALLET_FULLPATH`
if [ $DCRW_RESULT -eq 0 ]; then
  sed -i "s/grpclisten=127.0.0.1:0/grpclisten=127.0.0.1:9112/" $WALLET_FULLPATH
  DCRW_RESULT=`grep -c grpclisten=127.0.0.1:9112 $WALLET_FULLPATH`
fi
[ $DCRW_RESULT -gt 0 ] && echo "$0: dcrwallet is configured to use a single TCP port."

# Check dcrd is configured to proxy the traffic through Tor.
DCRD_RESULT=`grep -c proxy=127.0.0.1:9150 $HOME/.config/decrediton/dcrd.conf`
if [ $DCRD_RESULT -eq 0 ]; then
  echo "proxy=127.0.0.1:9150" >> $HOME/.config/decrediton/dcrd.conf
  DCRD_RESULT=`grep -c proxy=127.0.0.1:9150 $HOME/.config/decrediton/dcrd.conf`
fi
[ $DCRD_RESULT -gt 0 ] && echo "$0: dcrd is configured to proxy through Tor."

# End of script