Create a VM for running an Electrumx server which will connect to your bitcoind
VM. The electrumx
VM will be accessible from an Electrum Bitcoin wallet in an offline VM on the same host or remotely via a Tor onion service.
Electrumx is one of the possible server backends for the Electrum Bitcoin wallet. The other implementations covered in these guides are Electrs, and Electrum Personal Server (EPS).
Here are some of the differences between the different implementations:
- Electrs and Electrumx are more versatile.
- Electrs and Electrumx can serve any wallet once fully synchronized.
- EPS requires that each wallet's MPK is in its config file.
- Different disk space requirements.
- Electrs and Electrumx VM disk space: under 80G.
- EPS VM disk space: 1G.
- Different initial sync times.
- Initial Electrs Sync: 1-12 hours.
- Initial Electrumx Sync: 12-24 hours.
- Initial EPS Sync: 10-20 min.
- Electrumx can be configured to be part of a p2p network of servers that support random Electrum wallet users. That setup is out of scope for these guides.
This guide will set up a private server which will not broadcast it's onion address or connect to any peers. If a user wishes to serve other peers on the network, then they will be responsible for making the needed changes to the Electrumx configuration.
This will protect you from having to trust nodes ran by volunteers to provide you with vital information and services regarding your Electrum wallet and the Bitcoin stored therein.
There have already been multiple waves of attacks on Electrum users perpetrated by malicious Electrumx servers. These bad servers prevent users from sending transactions, instead sending back to them a bogus update requirement which actually leads to coin stealing malware.
In addition to preventing certain types of attacks, this setup also increases your privacy by not leaking information about your wallet to server operators. There are servers on the network which are using this information to build profiles on addresses and their interactions (eg. transaction surveillance companies).
- Read the README.
- To complete this guide you must have first completed:
Notes:
- This gateway should be independent of other Whonix gateways to isolate its onion service. See here.
- You must choose a label color, but it does not have to match this example.
- It is safe to lower the
maxmem
andvcpus
on this VM.
[user@dom0 ~]$ qvm-create --label purple --prop maxmem='400' --prop netvm='sys-firewall' \
--prop provides_network='True' --prop vcpus='1' --template whonix-gw-15 sys-electrumx
- Create the AppVM for Electrumx with the newly created gateway, using the
whonix-ws-15-bitcoin
TemplateVM.
Notes:
- You must choose a label color, but it does not have to match this example.
- It is safe to lower the
maxmem
andvcpus
on this VM.
[user@dom0 ~]$ qvm-create --label red --prop maxmem='800' --prop netvm='sys-electrumx' \
--prop vcpus='1' --template whonix-ws-15-bitcoin electrumx
- Increase private volume size.
[user@dom0 ~]$ qvm-volume resize electrumx:private 100G
[user@dom0 ~]$ echo 'electrumx bitcoind allow' | sudo tee -a /etc/qubes-rpc/policy/qubes.ConnectTCP
user@host:~$ sudo apt update && sudo apt install -y python-virtualenv python3-aiohttp
user@host:~$ sudo adduser --system electrumx
Adding system user `electrumx' (UID 117) ...
Adding new user `electrumx' (UID 117) with group `nogroup' ...
Creating home directory `/home/electrumx' ...
user@host:~$ sudo poweroff
- Create a random RPC username. Do not use the one shown.
Note: Save your username (7PXaFZ5DLG2alSeiGxnM
in this example) to replace <rpc-user>
in later examples.
user@host:~$ head -c 15 /dev/urandom | base64
7PXaFZ5DLG2alSeiGxnM
- Use Bitcoin's tool to create a random RPC password and config entry. Do not use the one shown.
Notes:
- Save the hased password (
9ffa7d78e1ddcb25ace4597bc31a1c8d$541c44f5d34044d532db47b74e9755ca4f0d87f805dd5895f0b36ea3a8d8c84c
in this example) to replace<hashed-pass>
in later examples. - Save your password (
GKkkKy-GAEDUw_6dp32O7Rh3DhHAnYhBUwNwNWUZPrI=
in this example) to replace<rpc-pass>
in later examples. - Replace
<rpc-user>
with the information noted earlier.
user@host:~$ ~/bitcoin/share/rpcauth/rpcauth.py <rpc-user>
String to be appended to bitcoin.conf:
rpcauth=7PXaFZ5DLG2alSeiGxnM:9ffa7d78e1ddcb25ace4597bc31a1c8d$541c44f5d34044d532db47b74e9755ca4f0d87f805dd5895f0b36ea3a8d8c84c
Your password:
GKkkKy-GAEDUw_6dp32O7Rh3DhHAnYhBUwNwNWUZPrI=
- Open
bitcoin.conf
.
user@host:~$ sudo -u bitcoin mousepad /home/bitcoin/.bitcoin/bitcoin.conf
- Paste the following at the bottom of the file.
Notes:
- Be sure not to alter any of the existing information.
- Replace
<rpc-user>
and<hashed-pass>
with the information noted earlier.
# Electrumx Auth
rpcauth=<rpc-user>:<hashed-pass>
- Save the file:
Ctrl-S
. - Switch back to the terminal:
Ctrl-Q
. - Restart the
bitcoind
service.
user@host:~$ sudo systemctl restart bitcoind.service
- Switch to user
electrumx
and enter home directory.
user@host:~$ sudo -H -u electrumx bash
electrumx@host:/home/user$ cd
- Download the latest Electrumx release.
Note: The current version of Electrumx is 1.15.0
, modify the following steps accordingly if the version has changed.
electrumx@host:~$ scurl-download https://github.com/spesmilo/electrumx/archive/1.15.0.tar.gz
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 126 100 126 0 0 60 0 0:00:02 0:00:02 --:--:-- 60
100 418k 0 418k 0 0 80980 0 --:--:-- 0:00:05 --:--:-- 142k
curl: Saved to filename 'electrumx-1.15.0.tar.gz'
- Verify download.
Notes:
- The developers of Electrumx do not currently sign or provide hash sums for releases.
- While it doesn't offer the same security, I have included the SHA256 sum of my
electrumx-1.15.0.tar.gz
download for your verification.
electrumx@host:~$ echo '2ff5efa9be1fbf8898e00ea2d9a31c38dd636d495fc222c29caa0cc36850185a electrumx-1.15.0.tar.gz' | shasum -c
electrumx-1.15.0.tar.gz: OK
- Extract.
electrumx@host:~$ tar -C ~ -xf electrumx-1.15.0.tar.gz
- Create virtual environment.
electrumx@host:~$ virtualenv -p python3 ~/exvenv
Already using interpreter /usr/bin/python3
Using base prefix '/usr'
New python executable in /home/electrumx/exvenv/bin/python3
Also creating executable in /home/electrumx/exvenv/bin/python
Installing setuptools, pkg_resources, pip, wheel...done.
- Link installed packages to virtual environment.
electrumx@host:~$ ln -s /usr/lib/python3/dist-packages/* ~/exvenv/lib/python3.7/site-packages/
- Source virtual environment.
electrumx@host:~$ source ~/exvenv/bin/activate
- Change directory.
(exvenv) electrumx@host:~$ cd ~/electrumx-1.15.0/
- Install Electrumx.
Note: This step will take some time and produce a lot of output. This is normal, be patient.
(exvenv) electrumx@host:~/electrumx-1.15.0$ python setup.py install
- Deactivate virtual environment and return to home dir.
(exvenv) electrumx@host:~/electrumx-1.15.0$ deactivate; cd
- Create Electrumx's data directory and subdirectories.
electrumx@host:~$ mkdir -m 0700 ~/.electrumx
electrumx@host:~$ mkdir -m 0700 ~/.electrumx/{certs,electrumx-db}
- Create configuration file.
electrumx@host:~$ mousepad ~/.electrumx/electrumx.conf
- Paste the following.
Notes:
- Be sure to replace
<rpc-user>
and<rpc-pass>
with the information noted earlier. - For a verbose desciption of these settings, look to the file:
~/electrumx-1.15.0/docs/environment.rst
.
## Required
COIN = Bitcoin
DB_DIRECTORY = /home/electrumx/.electrumx/electrumx-db
DAEMON_URL = http://<rpc-user>:<rpc-pass>@127.0.0.1:8332/
USERNAME = electrumx
## Services
SERVICES = ssl://:50002,rpc://
## Miscellaneous
NET = mainnet
DB_ENGINE = leveldb
SSL_CERTFILE = /home/electrumx/.electrumx/certs/server.crt
SSL_KEYFILE = /home/electrumx/.electrumx/certs/server.key
## Peer Discovery
PEER_DISCOVERY = self
PEER_ANNOUNCE = ''
## Cache
CACHE_MB = 400
## Python
PYTHONHOME = /home/electrumx/exvenv
- Save the file:
Ctrl-S
. - Switch back to the terminal:
Ctrl-Q
.
electrumx@host:~$ openssl req -x509 -sha256 -newkey rsa:4096 \
-keyout ~/.electrumx/certs/server.key -out ~/.electrumx/certs/server.crt -days 1825 \
-nodes -subj '/CN=localhost'
Generating a RSA private key
.........................................................................................++++
....++++
writing new private key to '/home/electrumx/.electrumx/certs/server.key'
-----
electrumx@host:~$ exit
- Create a persistent directory.
user@host:~$ sudo mkdir -m 0700 /rw/config/systemd
- Create the service file.
user@host:~$ lxsu mousepad /rw/config/systemd/electrumx.service
- Paste the following.
[Unit]
Description=Electrumx daemon
[Service]
EnvironmentFile=/home/electrumx/.electrumx/electrumx.conf
ExecStart=/home/electrumx/exvenv/bin/python /home/electrumx/exvenv/bin/electrumx_server
User=electrumx
Restart=on-failure
LimitNOFILE=8192
TimeoutStopSec=30min
PrivateTmp=true
ProtectSystem=full
NoNewPrivileges=true
PrivateDevices=true
MemoryDenyWriteExecute=true
[Install]
WantedBy=multi-user.target
- Save the file:
Ctrl-S
. - Switch back to the terminal:
Ctrl-Q
. - Fix permissions.
user@host:~$ chmod 0600 /rw/config/systemd/electrumx.service
- Edit the file
/rw/config/rc.local
.
user@host:~$ lxsu mousepad /rw/config/rc.local
- Paste the following at the bottom of the file.
cp /rw/config/systemd/electrumx.service /lib/systemd/system/
systemctl daemon-reload
systemctl start electrumx.service
- Save the file:
Ctrl-S
. - Switch back to the terminal:
Ctrl-Q
.
- Edit the file
/rw/config/rc.local
.
user@host:~$ sudo sh -c 'echo "qvm-connect-tcp 8332:bitcoind:8332" >> /rw/config/rc.local'
- Execute the file.
user@host:~$ sudo /rw/config/rc.local
- Make persistent directory for new firewall rules.
user@host:~$ sudo mkdir -m 0755 /rw/config/whonix_firewall.d
- Configure firewall.
user@host:~$ sudo sh -c 'echo "EXTERNAL_OPEN_PORTS+=\" 50002 \"" >> /rw/config/whonix_firewall.d/50_user.conf'
- Restart firewall service.
user@host:~$ sudo systemctl restart whonix-firewall.service
Note: Save the electrumx
IP (10.137.0.50
in this example) to replace <electrumx-ip>
in later examples.
user@host:~$ qubesdb-read /qubes-ip
10.137.0.50
user@host:~$ sudo systemctl start electrumx.service
- Edit the Tor configuration file.
user@host:~$ lxsu mousepad /rw/usrlocal/etc/torrc.d/50_user.conf
- Paste the following.
Note: Be sure to replace <electrumx-ip>
with the information noted earlier.
HiddenServiceDir /var/lib/tor/electrumx/
HiddenServicePort 50002 <electrumx-ip>:50002
- Save the file:
Ctrl-S
. - Switch back to the terminal:
Ctrl-Q
. - Reload
tor
.
user@host:~$ sudo systemctl reload tor.service
- Find out your onion hostname.
Note: Make a note of your server hostname for use with your remote Electrum wallet.
user@host:~$ sudo cat /var/lib/tor/electrumx/hostname
electrumxtoronionserviceaddressxxxxxxxxxxxxxxxxxxxxxxxxx.onion
- The intial sync can take anywhere from a day to multiple days depending on a number of factors including your hardware and resources dedicated to the
electrumx
VM. - Once the sync is finished you may connect your Electrum wallet via the Tor onion address.
- To check the status of the server:
sudo journalctl -fu electrumx
- To connect an offline Electrum wallet from a separate VM (split-electrum) use the guide:
2_electrum.md
.