Create a VM for running Bitcoin Core, which will be built from source code and configured to:
- Allow other VMs to connect when given explicit permission from
dom0
. - Communicate only over Tor.
- Easily plugin other applications which require a
bitcoind
backend. - Index all transactions.
- Prefer hidden services, use them exclusively if possible.
- Use ephemeral hidden services when serving peers.
- Utilize Tor stream isolation.
The server daemon for the Bitcoin distributed cryptocurrency (bitcoind
), command line tools (bitcoin-cli
), and a gui wallet (bitcoin-qt
). These tools can be used to observe and interact with Bitcoin's blockchain.
Bitcoin Core is a full node, meaning it will verify that all incoming transactions and blocks are following Bitcoin's rules. This allows you to validate transactions without trusting third parties.
An indexed node can be used as a backend for other software which needs access to the blockchain, such as:
- BTCPay Server
- c-Lightning
- Electrum Personal Server
- Electrumx
- Guide:
1_electrumx.md
- Guide:
- JoinMarket
- Guide:
1_joinmarket.md
- Guide:
- LND
Using qrexec
we can connect any of these tools to bitcoind
from their own VM, making use of the Qubes security by isolation model.
- Read the README.
[user@dom0 ~]$ qvm-clone whonix-ws-15 whonix-ws-15-bitcoin
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-bitcoin
- Create AppVM.
Note: You must choose a label color, but it does not have to match this example.
[user@dom0 ~]$ qvm-create --label red --prop netvm='sys-bitcoin' \
--template whonix-ws-15-bitcoin bitcoind
- Increase the private volume size.
[user@dom0 ~]$ qvm-volume resize bitcoind:private 350G
user@host:~$ sudo apt update && sudo apt install -y automake autotools-dev build-essential git \
libboost-chrono-dev libboost-filesystem-dev libboost-system-dev libboost-test-dev \
libboost-thread-dev libevent-dev libprotobuf-dev libqrencode-dev libssl-dev libtool libzmq3-dev \
pkg-config protobuf-compiler qttools5-dev qttools5-dev-tools
user@host:~$ sudo adduser --system bitcoin
Adding system user `bitcoin' (UID 116) ...
Adding new user `bitcoin' (UID 116) with group `nogroup' ...
Creating home directory `/home/bitcoin' ...
user@host:~$ sudo poweroff
Note: Save your gateway IP (10.137.0.50
in this example) to replace <gateway-ip>
in later examples.
user@host:~$ qubesdb-read /qubes-ip
10.137.0.50
- Create directory.
user@host:~$ sudo mkdir -p /usr/local/etc/onion-grater-merger.d/
- Symlink the provided
bitcoind
profile.
user@host:~$ sudo ln -s /usr/share/doc/onion-grater-merger/examples/40_bitcoind.yml /usr/local/etc/onion-grater-merger.d/
- Restart
onion-grater
service.
user@host:~$ sudo systemctl restart onion-grater.service
- Switch to user
bitcoin
and change to home directory.
user@host:~$ sudo -H -u bitcoin bash
bitcoin@host:/home/user$ cd
- Clone the repository.
Note: At the time of writing the current release branch is 0.20
, modify the following steps accordingly if the version has changed.
bitcoin@host:~$ git clone --branch 0.20 \
https://github.com/bitcoin/bitcoin ~/bitcoin
Cloning into '/home/user/bitcoin'...
remote: Enumerating objects: 2, done.
remote: Counting objects: 100% (2/2), done.
remote: Total 168496 (delta 1), reused 1 (delta 1), pack-reused 168494
Receiving objects: 100% (168496/168496), 145.29 MiB | 338.00 KiB/s, done.
Resolving deltas: 100% (118758/118758), done.
- Enter the
~/bitcoin
directory and receive signing keys.
bitcoin@host:~$ cd ~/bitcoin/
bitcoin@host:~/bitcoin$ gpg --recv-keys $(<contrib/verify-commits/trusted-keys)
gpg: key 0x944D35F9AC3DB76A: public key "Michael Ford (bitcoin-otc) <[email protected]>" imported
gpg: key 0xD300116E1C875A3D: public key "MeshCollider <[email protected]>" imported
gpg: key 0x3648A882F4316B9B: public key "Marco Falke <[email protected]>" imported
gpg: key 0x29D4BCB6416F53EC: 1 duplicate signature removed
gpg: key 0x29D4BCB6416F53EC: 1 signature reordered
gpg: key 0x29D4BCB6416F53EC: public key "Jonas Schnelli <[email protected]>" imported
gpg: key 0x860FEB804E669320: public key "Pieter Wuille <[email protected]>" imported
gpg: key 0x74810B012346C9A6: public key "Wladimir J. van der Laan <[email protected]>" imported
gpg: Total number processed: 6
gpg: imported: 6
- Verify source code.
Note: Your output may not match the example. Just check that it says Good signature
.
bitcoin@host:~/bitcoin$ git verify-commit HEAD
gpg: Signature made Fri 10 Jul 2020 04:45:48 AM UTC
gpg: using RSA key CFB16E21C950F67FA95E558F2EEB9F5CC09526C1
gpg: Good signature from "Michael Ford (bitcoin-otc) <[email protected]>" [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: E777 299F C265 DD04 7930 70EB 944D 35F9 AC3D B76A
Subkey fingerprint: CFB1 6E21 C950 F67F A95E 558F 2EEB 9F5C C095 26C1
Note: This step will take some time and produce a lot of output. This is normal, be patient.
- Build Berkeley DB using the provided script.
bitcoin@host:~/bitcoin$ ./contrib/install_db4.sh `pwd`
- Generate Bitcoin Core configuration script.
bitcoin@host:~/bitcoin$ export BDB_PREFIX='/home/bitcoin/bitcoin/db4'; ./autogen.sh
Note: The next two steps will take some time and produce a lot of output. This is normal, be patient.
- Configure.
bitcoin@host:~/bitcoin$ ./configure BDB_LIBS="-L${BDB_PREFIX}/lib -ldb_cxx-4.8" \
BDB_CFLAGS="-I${BDB_PREFIX}/include" --prefix=/home/bitcoin
- Make and install.
bitcoin@host:~/bitcoin$ make check && make install
- Return to home directory.
bitcoin@host:~/bitcoin$ cd
- Create Bitcoin's data directory and configuration file.
bitcoin@host:~$ mkdir -m 0700 ~/.bitcoin
bitcoin@host:~$ mousepad ~/.bitcoin/bitcoin.conf
- Paste the following.
Note: Be sure to replace <gateway-ip>
with the information noted earlier.
listen=1
onion=<gateway-ip>:9111
onlynet=onion
proxy=<gateway-ip>:9111
txindex=1
- Save the file:
Ctrl-S
. - Switch back to the terminal:
Ctrl-Q
. - Fix permissions.
bitcoin@host:~$ chmod 0600 ~/.bitcoin/bitcoin.conf
bitcoin@host:~$ exit
- 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+=\" 8333 \"" >> /rw/config/whonix_firewall.d/50_user.conf'
- Restart firewall service.
user@host:~$ sudo systemctl restart whonix-firewall.service
- Create a persistent directory.
user@host:~$ sudo mkdir -m 0700 /rw/config/systemd
- Create the service file.
user@host:~$ lxsu mousepad /rw/config/systemd/bitcoind.service
- Paste the following.
[Unit]
Description=Bitcoin daemon
After=qubes-sysinit.service
[Service]
ExecStart=/home/bitcoin/bin/bitcoind \
-conf=/home/bitcoin/.bitcoin/bitcoin.conf \
-daemon \
-pid=/run/bitcoind/bitcoind.pid
ExecStop=/home/bitcoin/bin/bitcoin-cli stop
RuntimeDirectory=bitcoind
RuntimeDirectoryMode=0710
User=bitcoin
Type=forking
PIDFile=/run/bitcoind/bitcoind.pid
Restart=on-failure
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/bitcoind.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/bitcoind.service /lib/systemd/system/
systemctl daemon-reload
systemctl start bitcoind.service
- Save the file:
Ctrl-S
. - Switch back to the terminal:
Ctrl-Q
. - Execute the file.
user@host:~$ sudo /rw/config/rc.local
- Make an alias in order to control
bitcoind
easier.
user@host:~$ echo 'alias bitcoin-cli="sudo -u bitcoin /home/bitcoin/bin/bitcoin-cli"' >> ~/.bashrc
- Source the file.
user@host:~$ source ~/.bashrc
Note: Initial block download can take anywhere from a day to a week (or even more) depending on a number of factors including your hardware and internet connection.
user@host:~$ sudo systemctl start bitcoind
- Once the initial synchronization has finished you may begin using your Bitcoin node as a backend for other services.
- To check the status of the server:
sudo tail -f /home/bitcoin/.bitcoin/debug.log
- To interact with the server:
bitcoin-cli --help