Decrediton on Tails

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

Decrediton on Tails
Decrediton on Tails

By Marcelo Martins - November 02, 2019

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

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 Linux 10 64-bit to install Tails 4.0 on a USB flash drive with 16GB of capacity. The other steps described in this article were executed inside this installation of Tails 4.0 to execute Decrediton 1.4.0.

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

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

a) Go to https://tails.boum.org/install/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 .img 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 and recommended if the browser extension wasn’t used.

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

a) Go to https://tails.boum.org/install/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 4.0 OpenPGP signature (the digital signature, which must reside in the same folder as Tails IMG 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-4.0.img.sig
gpg: assuming signed data in 'tails-amd64-4.0.img'
gpg: Signature made Mon Oct 21 12:30:06 2019 WEST
gpg:                using EDDSA key CD4D4351AFA6933F574A9AFB90B2B4BD7AED235F
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: CD4D 4351 AFA6 933F 574A  9AFB 90B2 B4BD 7AED 235F

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

$ gpg --import tails-signing.key
gpg: key DBB802B258ACD84F: 2170 signatures not checked due to missing keys
gpg: key DBB802B258ACD84F: public key "Tails developers <tails@boum.org>" imported
gpg: Total number processed: 1
gpg:               imported: 1
gpg: marginals needed: 3  completes needed: 1  trust model: pgp
gpg: depth: 0  valid:   1  signed:   0  trust: 0-, 0q, 0n, 0m, 0f, 1u
gpg: next trustdb check due at 2029-06-06

To learn more, read Verifying digital signatures

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

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


Figure 3 - Linux host 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/linux/usb/index.en.html

In this 16GB USB flash drive, a 8.6GB partition was created 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.

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 storage, 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 configure Tails for Decred usage


Figure 6 - Select both items to configure 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.

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 containing 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
(...)

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

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

amnesia@amnesia:~/Tor Browser$ gpg --keyserver keyserver.ubuntu.com --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:

$ gpg --verify manifest-decrediton-v1.4.0.txt.asc
gpg: assuming signed data in 'manifest-decrediton-v1.4.0.txt'
gpg: Signature made Tue Feb  5 22:07:04 2019 WET
gpg:                using RSA key 6D897EDF518A031D
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
$ grep `sha256sum decrediton-v1.4.0.tar.gz` manifest-decrediton-v1.4.0.txt
2e70094600731cbddc7261f3c6095edca525d1f87030d4a7d3bf1720cefb548c decrediton-v1.4.0.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.4.0.tar.gz 
amnesia@amnesia:~/Tor Browser$ mv decrediton-1.4.0/ ../Persistent/
amnesia@amnesia:~/Tor Browser$ cd ../Persistent/decrediton-1.4.0/
amnesia@amnesia:~/Persistent/decrediton-1.4.0$ ./decrediton -d

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

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

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

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

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

#!/bin/bash
# Decrediton-persistence
# This script includes persistence configuration for dcrd and Decrediton on Tails 3.7
# Author: Marcelo Martins (stakey.club)
# Must be run as root (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 read /etc/ferm/ferm.conf and check the correct position to insert the rule.
# Otherwise, change number 91 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

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 (stakey.club)
# Written for Tails 3.7
# Read all the comments before running this script.
# 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 $HOME
  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 then 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
DPKG_RESULT=$?
[[ $DPKG_RESULT -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 read /etc/ferm/ferm.conf and check the correct position to insert the rule.
# Otherwise, change 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