Come avere un Fullnode Bitcoin con Raspberry Pi

Un lampone decentralizzato

Bitcoin In Action
17 min readSep 25, 2019

Nel libro Bitcoin dalla teoria alla pratica viene utilizzato un fullnode concesso gentilmente da Growbit, ma non è pubblico. Diamo come alternativa chainquery per fare determinate operazioni ma non è sufficiente a coprire tutti gli esempi che sono riportati.

Abbiamo quindi deciso di scrivere una guida per costruire e interagire con un proprio nodo Raspberry. Ovviamente il nodo può vivere anche nel vostro computer che solitamente usate, ma dovrebbe stare sempre connessi per essere up-to-date con la blockchain e dedicare un pò di spazio per il salvataggio della blockchain.
Oggi 2 Agosto 2018 la testnet pesa circa 25 gigabytes.

A questo indirizzo potete trovare informazioni interessanti per la mainnet, e a oggi sono all’incirca 270 gigabytes.

Componenti

I componenti che ho usato non sono miei, quindi non ho nessun interesse a pubblicizzarli. Elenco semplicemente il mio setup.

Invito chiunque a indicare un setup migliore del mio se è necessario :)

Setup finale: Raspberry + case + alimentatore + HDD + tappetino

Benissimo appena costruito il nostro dispositivo scarichiamo il software necessario.

Scaricare Raspberry Lite Image

Dal sito ufficiale scarica l’immagine lite.
Come vedete nel sito abbiamo lo SHA256 dello zip, che nel mio caso è

9e5cf24ce483bb96e7736ea75ca422e3560e7b455eee63dd28f66fa1825db70e

Quindi abbiamo la possibilità di verificare di aver scaricato il giusto archivio.

echo "9e5cf24ce483bb96e7736ea75ca422e3560e7b455eee63dd28f66fa1825db70e 2019–07–10-raspbian-buster-lite.zip" | shasum -a 256 -c -

NB: dovete essere nella stessa cartella dello zip appena scaricato, e tra lo SHA256 e il nome dello Zip ci devono essere due spazi

Con il comando shasum verifichiamo l’integrità e l’autenticità del file controllando il suo checksum creato con l’algoritmo SHA.

Se ottenete questo risultato:

2019–07–10-raspbian-buster-lite.zip: OK

la prova è andata a buon fine.

Formattare SD card (facoltativo)

Questo passaggio potrebbe essere facoltativo, ma per sicurezza io l’ho eseguito ugualmente. Dopo aver inserito la SD card, ho lanciato questo comando per individuarla.

diskutil list

nel mio caso era disk2, ho eseguito quindi questo comando:

sudo dd if=/dev/urandom of=/dev/disk2s2 bs=1000000

NB: questo comando non da output, quindi attendete fiduciosi :). Nei sistemi OSX con Ctrl+T possiamo sbirciare un pò…

Sui dispositivi mac potrebbe essere necessario lanciare questo comando prima e formattare.

$ sudo diskutil umountDisk /dev/disk2
Unmount of all volumes on disk2 was successful

Copiare l’immagine nella SD card

Bene è il momento di fare sul serio, spostiamo l’immagine nell’SD card.

Smontiamo SD card

diskutil unmountDisk /dev/disk2

copiamo quindi l’immagine al suo interno

sudo dd bs=1m if=2019–07–10-raspbian-buster-lite.img of=/dev/disk2

NB: questo comando non da output, quindi attendete fiduciosi² :). Nei sistemi OSX con Ctrl+T possiamo sbirciare un pò…

Quando l’immagine è stata copiata, abilitiamo ssh.
Come dimostra la guida di Raspberry, ci sono diversi modalità per accedere con il comando ssh. Uno di questi, il più semplice, è posizionare nel percorso dell’SD card /Volumes/boot/ un file ssh senza estensione

touch /Volumes/boot/ssh

SSH, secure shell, è un protocollo che permette di creare un canale sicuro tra due entità, cioè tra il client e il server (in questo caso Raspberry). Le comunicazioni sono crittate lato client e decrittate lato server automaticamente, così da poter trasferire le informazioni in modo sicuro. SSH risolve l’autenticazione, encryption (quindi cifrare messaggi) e l’integrità del messaggio testo.

Se abbiamo formattato la nostra SD card abbiamo due partizioni, una più piccola chiamata boot e una rootfs (almeno nel mio caso), il file deve essere posizionato nella partizione più piccola, ovvero in boot.
Per verificare quanto spazio abbiamo a disposizione possiamo utilizzare il comando df.

df -h

risultato:

Filesystem Size Used Avail Capacity iused ifree …../dev/disk2s2 1.8Gi 1.0Gi 776Mi 58% 42164 75196 36% /Volumes/rootfs
/dev/disk2s1 252Mi 40Mi 212Mi 16% 0 0 100% /Volumes/boot

posizionando il file ssh, quando il Raspberry si avvia, vede che c’e il file, lo cancella e abilita ssh.

Possiamo smontare il disco:

diskutil unmountDisk /dev/disk2

Siamo pronti a inserire l’SD card nel Raspberry!

Trovare il Raspberry nella rete

Dopo aver inserito l’SD card, acceso il Raspberry (davvero?) e collegato con il cavo ethernet, dobbiamo trovare il suo IP.
Possiamo collegarci al router e trovarlo dall’interfaccia grafica del router stesso, oppure possiamo usare il comando

arp -a

che restituisce tutti gli indirizzi dei dispositivi connessi.
Sappiamo che per convenzione l’indirzzo MAC del Raspberry inizia con b8:27:eb, quindi possiamo usare grep per filtrare il risultato.

arp -a | grep 'b8:27:eb'
? (192.168.1.221) at b8:27:eb:84:7b:a0 on en0 ifscope [ethernet]

Il MAC address (media access control) , chiamato anche physical address, individua con certezza l’interfaccia di rete. Ogni dispositivo ne ha una ed è univoca.

Nel mio caso l’ip designato per il Raspberry è 192.168.1.221
Dato che abbiamo abilitato ssh (vedi sopra) posso collegarmi con:

ssh pi@192.168.1.221

inserendo la password di default raspberry.
Per motivi di sicurezza è consigliato modificare la password ssh, dato che per tutto il mondo è raspberry :)
Con il comando:

passwd

è possibile cambiare la password per l’utente pi.
Cambiamo anche la password per l’utente root.

sudo passwd root

Io per comodità ho messo le stesse password.
Creiamo anche l’utente bitcoin che sarà l’utente designato alle operazioni sul nodo, in modo tale da creare anche una nuova home che, più avanti, linkeremo all’hard disk esterno.

sudo adduser bitcoin

Usare la chiave pubblica per loggarsi nel Raspberry

È molto comodo, oltre che sicuro, loggarsi con la chiave pubblica invece che con la password.
Creiamo quindi la coppia di chiave privata e pubblica.
Non sai se le hai già? Con questo comando verifichi le chiavi in tuo possesso.

ls -la ~/.ssh/*.pub

Se non la hai, puoi creare la tua chiave nel formato Ed25519.

Il formato Ed25519 è stato introdotto con OpenSSH versione 6.5. Utilizza la curva ellittica (https://en.wikipedia.org/wiki/Twisted_Edwards_curve) per derivare le chiavi ed è stata pensata per essere più veloce rispetto allo schema esistente della classica firma digitale. Per maggiori informazioni.

Per creare una nuova chiave:

ssh-keygen -o -a 100 -t ed25519 -f ~/.ssh/id_ed25519 -C "email@email.com"

~/.ssh/id_ed25519 rappresenta la nostra private key, “la nostra identità digitale”
~/.ssh/id_ed25519.pub rappresenta la nostra public key che dovremo mettere sul Raspberry per essere autenticati.

HINT: è buona norma mettere una password alla chiave privata. Cosi facendo ogni volta che ci autentichiamo, dobbiamo inserirla in modo da decrittare la chiave privata e loggarsi su Raspberry.
Come possiamo evitare di scrivere la password della chiave privata?
Lanciando ssh-add, il quale aggiunge la password a ssh-agent.
Per non dover scrivere ogni volta la password possiamo lanciare questo comando: ssh-add -K ~/.ssh/id_ed25519
Se invece vuoi cambiare la password della chiave privata: ssh-keygen -p -f id_ed25519

Copiamo la chiave appena creata nel nostro raspberry
ricordate che il vostro ip potrebbe essere differente

ssh-copy-id -i ~/.ssh/id_ed25519.pub pi@192.168.1.221

una volta copiata la chiave nel Raspberry, ci colleghiamo con ssh e togliamo la password.
Nel Raspberry è necessario fare questa procedura:

ssh pi@192.168.1.221
sudo nano /etc/ssh/sshd_config

cercate PasswordAuthentication, e settarla a no.

HINT: vuoi loggarti direttamente con l’utente bitcoin?
Con ssh bitcoin@192.168.1.221 puoi già loggarti inserendo la password, se invece vuoi loggarti con la chiave pubblica, fai la stessa operazione descritta sopra. Ogni utente ha le proprie chiavi, infatti vengono copiate nell home dell’utente /home/bitcoin/.ssh.
La cartella .ssh viene creata dal comando ssh-copy-id.
Se invece non potete creare la cartella .ssh nell’utente bitcoin, potete copiarla con il comando sudo con l’utente pi, e dopo cambiare l’owner
sudo chown -R bitcoin:bitcoin /home/bitcoin/.ssh

Note su SSH (facoltativo)

La prima volta che ci autentichiamo con SSH, riceveremo questo messaggio:

The authenticity of host ‘192.168.1.221 (192.168.1.221)’ can’t be established.
ECDSA key fingerprint is SHA256:XXXXXXXXXXXXXXX.
Are you sure you want to continue connecting (yes/no)?

Il fingerprint è l’impronta digitale del Raspberry. Lo potete trovare qui:

pi@raspberrypi:/etc/ssh $ ssh-keygen -lf ssh_host_ecdsa_key.pub
256 SHA256:IPYYELcHtVEmIVdZDswU4sgr991ZiPZOPyW9knKx4aY root@raspberrypi (ECDSA)

Quindi ci sta informando che ci stiamo collegando a tale dispositivo.
Scegliendo yes, l’indirizzo locale del Raspberry verrà aggiunto sul client nel file known_hosts (/Users/barno/.ssh).
Analizzando tale file vedrete che ci sarà l’IP del Raspberry e la sua chiave pubblica, come questa:

192.168.1.221 ecdsa-sha2-nistp256 chiave XXXX

La chiave è la chiave pubblica del Raspberry che trovate in

pi@raspberrypi:/etc/ssh $ cat /etc/ssh/ssh_host_ecdsa_key.pub

Mentre la chiave pubblica (creata e spostata in precedenza) del vostro client usata per l’autenticazione è salvata in:

pi@raspberrypi: $cat ~/.ssh/authorized_keys

Quindi se volete aggiungere un’altro utente, potete inserire la public key all’interno di quel file.

Router: IP Fisso, porte e IP pubblico

Se ogni volta che voglio accedere al Raspberry ha un indirizzo diverso diventa molto noioso se non controproducente. Quindi, stabiliamo un IP fisso locale per il nostro nodo configurandolo dal router.
Nel mio caso ho associato l’IP statico 192.168.1.221.
Un ulteriore passaggio fondamentale è aprire le opportune porte.
In questo caso apro sia la mainnet che la testnet e la porta 22 per SSH.

Configurazioni Porte.

Le porta 8333 (mainnet) e la porta 18333 (testnet) dobbiamo aprirle se vogliamo essere raggiunti dagli altri nodi.
La porta 8332 (mainnet) e la porta 18332 (testnet) che non sono state aperte permetterebbero di fare delle richieste RPC dall’esterno.
La porta 5100 è mappata sulla porta 22 del vostro router. Per collegarsi dall’esterno dobbiamo riferirsi alla porta 5100 (o una scelta da voi nel range di 1024–65535).

HINT: per verificare se le porte sono aperte correttamente potete utilizzare telnet IP_PUBBLICO PORTA e vedere se risponde.
Oppure potete utilizzare nmap (per installarlo su mac => brew install nmap) e inserire il vostro IP pubblico per verificare le porte aperte. (nmap — open IP PUB)

Potrebbe essere interessante collegarsi dall’esterno al nostro nodo.
Se non siete in possesso di un ip pubblico dovete contattare il vostro ISP.

GUI? no grazie.

Non vogliamo la GUI, quindi settiamo la RAM dedicata al minimo.
Dal vostro nodo digitate

sudo raspi-config

E vi troverete davanti a una schermata come questa

Come vedete ci sono un pò di opzioni.
Selezioniamo la voce 3 -> B1 -> B1.
Di fatto diciamo di volere la console come boot.
Poi possiamo scegliere locale e time-zone alla voce 4.
Ed infine spostandosi sulla voce 7 Advanced Options, e successivamente su A3 Memory split, settiamo la RAM a 16.
Buona cosa anche tenere il Raspberry aggiornato, quindi anche la voce numero 8 Update.
Fatto tutto, andate su finish.
Il Raspberry si riavvierà, appena torna raggiungibile possiamo fare gli aggiornamento dei pacchetti

sudo apt update
sudo apt -y upgrade

Riavviamo di nuovo il nostro Raspberry.

sudo shutdown -r now

Configurare l’hard disk esterno

Colleghiamo l’hard disk al nostro Raspberry e digitiamo il comando

sudo lsblk -o UUID,NAME,FSTYPE,SIZE,MOUNTPOINT,LABEL,MODEL

cosi da individuarlo, nel mio caso è sda.

Bene, siamo pronti a formattarlo!
Attenzione questa operazione elimina tutti i file dal proprio hard disk, quindi siate certi che non contenga le chiavi private di Satoshi!

sudo mkfs.ext4 /dev/sda -L LN

dove LN è la label dell’hard disk.

Per essere sicuri che tutto sia andato a buon fine possiamo richiamare il comando

sudo lsblk -o UUID,NAME,FSTYPE,SIZE,MOUNTPOINT,LABEL,MODEL

e dobbiamo leggere LN nella colonna LABEL del nostro hard disk.
Dato che il Raspberry lavorerà sempre con il nostro hard disk, montiamolo in automatico.
Prima di tutto creiamo la cartella hdd.

sudo mkdir /mnt/hdd

Poi individuiamo l’UUID dell’hard disk con il comando:

sudo blkid | grep /dev/sda

e una volta preso nota, apriamo il file necessario

sudo nano /etc/fstab

e aggiungiamo

UUID=XXXXXX /mnt/hdd ext4 defaults 0 0

dove XXXXX è l’UUID recuperato precedentemente.

e infine montiamo tutto!

sudo mount -a

In questo modo ogni volta che si riavvia il Raspberry l’HDD sarà già montato e pronto. Se riavviamo il Raspberry senza avere l’HDD collegato, potrebbe creare problemi.

Dato che abbiamo creato l’utente bitcoin che sarà l’addetto a interfacciarsi con il nodo, diamo i privilegi di scrittura alla cartella (ricorsivamente) appena creata

sudo chown -R bitcoin:bitcoin /mnt/hdd

In questo modo l’utente pi può solo leggere (a meno che non si usi sudo) e l’utente bitcoin leggere e scrivere.

Il percorso di default dove viene salvata la blockchain è ~/.bitcoin/ e questa non è dentro l’hdd esterno.
Per risolvere questo problema abbiamo due soluzioni.
O inseriamo datadir=/percorso/che/vogliamo nel file .conf, oppure facciamo una link simbolico.
Per cercare di lasciare più pulito possibile il file .conf, opteremo per il link simbolico che punta dentro alla cartella bitcoin nell’HDD.
Quindi creiamo la cartella con l’utente bitcoin.
PS: per cambiare utente: sudo su bitcoin

mkdir /mnt/hdd/bitcoin

creiamo quindi il link simbolico

ln -s /mnt/hdd/bitcoin /home/bitcoin/.bitcoin

per verificare che tutto sia andato a buon fine potete spostarvi in

cd /home/bitcoin/

e digitare

ls -al

dovreste vedere il collegamento evidenziato da ->

SWAP!
Che cosa è lo swap?
La definizione di Wikipedia è molto intuitiva:

Con il termine swap si intende, in informatica, l’estensione della capacità della memoria volatile complessiva del computer, oltre il limite imposto dalla quantità di RAM installata, attraverso l’utilizzo di uno spazio su un altro supporto fisico di memorizzazione, ad esempio il disco fisso. L’uso dello swap è una delle tecniche impiegate dal sistema operativo per la gestione della memoria virtuale.

La memoria complessiva del raspberry Pi 3 B+ è di 2 gigabyte, quindi cercheremo di aumentarla virtualmente.

Con l’utente pi digitare:

sudo dphys-swapfile swapoff
sudo dphys-swapfile uninstall
sudo nano /etc/dphys-swapfile

Quindi alla voce modificare come segue:

CONF_SWAPFILE=/mnt/hdd/swapfile
#CONF_SWAPSIZE=

Salvare e creare il file swapfile manualmente

sudo dd if=/dev/zero of=/mnt/hdd/swapfile count=1000 bs=1MiB
sudo chmod 600 /mnt/hdd/swapfile
sudo mkswap /mnt/hdd/swapfile

Quindi attivare lo swap

sudo dphys-swapfile setup
sudo dphys-swapfile swapon

Benissimo a questo punto possiamo installare qualche pacchetto interessante:

sudo apt install git build-essential libtool autotools-dev automake pkg-config libssl-dev libevent-dev bsdmainutils libboost-system-dev libboost-filesystem-dev libboost-chrono-dev libboost-program-options-dev libboost-test-dev libboost-thread-dev libminiupnpc-dev libzmq3-dev jq

È il momento di installare Bitcoin Core!

Bene è arrivato il momento!
Loggato come pi creiamo la cartella download che ospiterà il software.

mkdir /home/pi/download
cd /home/pi/download

Verifica l’ultima versione di bitcoin core disponibile: https://bitcoincore.org/en/download/ o qui https://github.com/bitcoin/bitcoin/releases

Qui invece è possibile vedere i change logs https://github.com/bitcoin/bitcoin/blob/master/doc/release-notes/release-notes-0.18.0.md

nel mio caso bitcoin core 0.18.0 e dobbiamo installare la versione linux arm 32 bit.

wget https://bitcoincore.org/bin/bitcoin-core-0.18.0/bitcoin-0.18.0-arm-linux-gnueabihf.tar.gz

Scarico anche le relative firme per verificare il pacchetto.

wget https://bitcoincore.org/bin/bitcoin-core-0.18.0/SHA256SUMS.asc
wget https://bitcoin.org/laanwj-releases.asc

controllo il pacchetto ignorando i Warning

sha256sum --check SHA256SUMS.asc --ignore-missing

risultato:

bitcoin-0.18.0-arm-linux-gnueabihf.tar.gz: OK
sha256sum: WARNING: 20 lines are improperly formatted

L’importante è che ci sia un bell’OK!

Controlliamo anche le chiavi.

gpg --import ./laanwj-releases.asc
gpg --refresh-keys
gpg --verify SHA256SUMS.asc

risultato:

gpg: Good signature from “Wladimir J. van der Laan …”
Primary key fingerprint: 01EA 5486 DE18 A882 D4C2 6845 90C8 019E 36C2 E964

Bene, siamo sicuri di avere quello che vogliamo, possiamo finalmente installarlo. Decomprimiamo l’archivio e spostiamo i file bin all’interno di /usr/local/bin cosi da renderlo globale.

tar -xvf bitcoin-0.18.0-arm-linux-gnueabihf.tar.gzsudo install -m 0755 -o root -g root -t /usr/local/bin bitcoin-0.18.0/bin/*

Per verificare che tutto sia andato a buon fine, possiamo digitare:

bitcoind -version> Bitcoin Core Daemon version v0.18.0

Bene, momento di pulizia, assicuratevi di essere nella cartella /home/pi/download

rm -Rf *

Ottimo, siamo pronti a creare il file .conf che leggerà Bitcoin core.
Con l’utente bitcoin (sudo su bitcoin) spostarsi in /mnt/hdd/bitcoin e digitare

nano bitcoin.conf

e aggiungere:

# Generated by https://jlopp.github.io/bitcoin-core-config-generator/# This config should be placed in following path:
# ~/.bitcoin/bitcoin.conf
# [core]
# Run in the background as a daemon and accept commands.
daemon=1
# Set database cache size in megabytes; machines sync faster with a larger cache. Recommend setting as high as possible based upon machine’s available RAM.
dbcache=100
# Keep at most <n> unconnectable transactions in memory.
maxorphantx=10
# Keep the transaction memory pool below <n> megabytes.
maxmempool=50
# Maintain a full transaction index, used by the getrawtransaction rpc call.
txindex=1
# Maintain at most N connections to peers.
maxconnections=40
# Tries to keep outbound traffic under the given target (in MiB per 24h), 0 = no limit.
maxuploadtarget=5000
# Run this node on the Bitcoin Test Network.
testnet=1
# Accept command line and JSON-RPC commands.
server=1
# Options only for mainnet
[main]
# Options only for testnet
[test]
# Options only for regtest
[regtest]

Per creare la configurazione ho usato comodo servizio https://jlopp.github.io/bitcoin-core-config-generator/ .
Per sapere tutti i parametri ci basterà comunque digitare bitcoind -h.
Per avere una demo di configurazione possiamo visitare il GitHub ufficiale di Bitcoin https://github.com/bitcoin/bitcoin/blob/master/share/examples/bitcoin.conf

Il file contiene testnet=1, quindi scaricheremo la blockchain testnet. Gli esempi riportati nel libro Bitcoin dalla teoria alla pratica, utilizzando la testnet e poi per fare degli esperimenti direi che è meglio non perdere btc.

Siamo pronti a partire! 🚀
Digitiamo

bitcoind

e il nodo inizia a scaricare la blockchain.
Per vedere i log possiamo usare tail.

tail -f /home/bitcoin/.bitcoin/testnet3/debug.log

e per avere delle informazioni più dettagliate

bitcoin-cli getblockchaininfo | jq

Vuoi conoscere tutti i comandi possibili?

bitcoin-cli help

Vuoi sapere che significato hanno i valori ottenuti con la chiamata getblockchaininfo?

bitcoin-cli help getblockchaininfo

Vuoi stoppare il nodo?

bitcoin-cli stop

HINT:

Dato che con Raspberry abbiamo delle limitazione del numero peers e altri parametri, un metodo per sincronizzare la blockchain più velocemente è quello di scaricare il core sul proprio computer, collegare l’hard disk esterno che stiamo utilizzando sul Raspberry e lanciare il demone facendo scaricare la blockchain all’interno dell’unità esterna. il file bitcoin.conf lo potete generare da qui https://jlopp.github.io/bitcoin-core-config-generator.

Come fare a far scaricare la blockchain nell’hard disk esterno?
Dopo aver scaricato bitcoin core, come mostrato poco sopra, mi sposto nella cartella bin

/Users/barno/Documents/btc/bitcoin-0.18.0/bin

e lancio il comando

./bitcoind -datadir=/Volumes/LN/bitcoin

dove /Volumes/LN/bitcoin è la cartella del disco esterno.

Per leggere i log vale quanto spiegato sopra, ovviamente cambiando il path.

tail -f /Volumes/LN/bitcoin/testnet3/debug.log

check blockchain

/Users/barno/Documents/btc/bitcoin-0.18.0/bin/bitcoin-cli getblockchaininfo

Ho inserito i percorsi assoluti per far capire dove sono posizionato.

Utilizzare il nodo Raspberry dal proprio client (opzionale)

Potremmo avere la necessità di fare delle chiamate al nostro nodo da non dentro il Raspberry.
Se siamo nella rete locale possiamo fare un tunnel ssh facendo il forward della porta 18333 locale sulla porta 18333 del Raspberry.
In questo modo è come se dicessimo: Ehi, tutte le chiamate che faccio sul mio localhost (client) sulla porta 18333 inoltrale in questo tunnel.
Dall’altro lato del tunnel è presente il Raspberry.
Colleghiamoci al Raspberry con questo comando ssh:

ssh -L 18332:127.0.0.1:18332 pi@192.168.1.221

Sul nostro client, spostiamoci in bitcoin core, nel mio caso il percorso è quello riportato poco sopra

/Users/barno/Documents/btc/bitcoin-0.18.0/bin/bitcoin-cli

Facciamo una chiamata per interrogare il nodo

./bitcoin-cli getblockchaininfo | jq

riceviamo però questo errore:

error: Could not connect to the server 127.0.0.1:8332Make sure the bitcoind server is running and that you are connecting to the correct RPC port.

ok, dobbiamo essere autenticati.
Per fare questo ci sono tre modi,

  • username e password come parametri dalla chiamata.
  • rpcauth
  • copiare il cookie dal Bitcoin core del Raspberry nel nostro client.

Soluzione 1 (username e password)
In Raspberry con l’utente bitcoin stoppiamo il nodo Bitcoin

bitcoin-cli stop

Adesso editiamo il .conf

vi /mnt/hdd/bitcoin/bitcoin.conf

e aggiungiamo

[test]
rpcuser=barno
rpcpassword=barnopass

e riavviamo il nodo con il comando bitcoind (se avete implementato la soluzione che avvia il nodo in automatico, potrebbe essersi già riavviato).

Adesso dal nostro client possiamo fare la nostra chiamata, passando anche rpcport nelle opzioni.

./bitcoin-cli -rpcuser=barno -rpcpassword=barnopass -testnet=1 getblockchaininfo | jq

Soluzione 2 rpcauth
A differenza della prima soluzione, non scriveremo in chiaro la username e la password nel file di .conf ma utilizzeremo questo script in python per aggiungere il salt e offuscare la nostra password.
Una volta scaricato lo script python lanciatelo passando username e password che volete utilizzare

./rpcauth.py barno barnopass
String to be appended to bitcoin.conf:
rpcauth=barno:bf92263dcf78afbf74c69af146a5f5df$ec8d07c7952ad57b616f3af7898074c286f0b5151f6aeaf840248c0945405801
Your password:
barnopass

Come si capisce dall’output, dobbiamo aggiungere la stringa rpcauth nel nostro file .conf
Stoppiamo il nodo e inseriamo la riga suggerita.

[test]
rpcauth=barno:bf92263dcf78afbf74c69af146a5
8074c286f0b5151f6aeaf840248c0945405801

e riavviamo il nodo con il comando bitcoind (se avete implementato la soluzione che avvia il nodo in automatico, potrebbe essersi già riavviato).

Adesso dal nostro client possiamo fare la nostra chiamata, passando anche rpcport nelle opzioni.

./bitcoin-cli -rpcuser=barno -rpcpassword=barnopass -testnet=1 getblockchaininfo | jq

Il vantaggio di questa procedura è che la username e la password sono hashati con HMAC-SHA-256, e possiamo creare più utenti, aggiungendo un altro rpcauth in bitcoin.conf.

Soluzione 3 cookie
il file .cookie è la via più comoda cosi da evitare di non dover mettere username e password se siamo interessati ad un utente solo. Si trova all’interno della datadir, che nel nostro caso avendo scaricato la blockchain di test, è all’interno di testnet3.

Anche nel client deve essere dentro la cartella testnet3, oppure possiamo specificare un percorso.
Usando il comando scp, copiamo il cookie dal Raspberry al nostro client.
Il percorso di default sul Mac per la datadir è ~/Library/Application Support/Bitcoin, su Linux è ~/.bitcoin/

Il comando da eseguire dal client per copiare il .cookie è:

scp bitcoin@192.168.1.221:/mnt/hdd/bitcoin/testnet3/.cookie /Users/barno/Library/Application\ Support/Bitcoin/testnet3

Adesso abbiamo a disposizione il .cookie che ci autentica più velocemente senza inserire username e password.
Dal client possiamo quindi eseguire il nostro comando RPC.

./bitcoin-cli -testnet=1 getblockchaininfo | jq

Se vogliamo posizionare il .cookie in un altro percorso dobbiamo passare l’opzione -rpccookiefile.

Avviare il demone bitcoind in automatico

Creiamo un servizio in modo tale che se il demone bitcoind dovesse crashare, oppure per qualsiasi motivo si dovesse spengere il Raspberry, al suo riavvio siamo in grado di sincronizzare la blockchain senza eseguire nessun comando manuale.
Con l’utente pi, creiamo il servizio

sudo nano /etc/systemd/system/bitcoind.service

E scriviamo:

[Unit]Description=Bitcoin daemonAfter=network.target[Service]ExecStartPre=/bin/sh -c 'sleep 30'ExecStart=/usr/local/bin/bitcoind -daemon -conf=/home/bitcoin/.bitcoin/bitcoin.conf -pid=/home/bitcoin/.bitcoin/bitcoind.pidPIDFile=/home/bitcoin/.bitcoin/bitcoind.pidUser=bitcoinGroup=bitcoinType=forkingKillMode=processRestart=alwaysTimeoutSec=120RestartSec=30[Install]WantedBy=multi-user.target

Salviamo e abilitiamo il servizio

sudo systemctl enable bitcoind.service

Riavviamo il Raspberry

sudo shutdown -r now

Adesso al vostro login dovreste avere già il nodo attivo!

Comandi utili per i servizi

enable

sudo systemctl enable bitcoind.service

restart

sudo systemctl restart bitcoind.service

start

sudo systemctl start bitcoind.service

stop

sudo systemctl stop bitcoind.service

status

sudo systemctl status bitcoind.service

Sicurezza

ufw

Bene cerchiamo di mettere in sicurezza il nostro Raspberry.
Utilizzeremo ufw (firewall) come suggerito anche dalla guida Raspberry https://www.raspberrypi.org/documentation/configuration/security.md.

Installiamolo con

sudo apt install ufw

ufw blocca le connessioni in entrata e lascia libere quelle in uscita.
Ecco la configurazione che ho usato io.

ATTENZIONE siate sicuri dell’indirizzi ip Interno ed esterno, altrimenti vi chiudete fuori!

sudo su
ufw default deny incoming
ufw default allow outgoing
ufw allow from 192.168.1.0/24 to any port 22 comment 'allow SSH from local LAN'
ufw allow sshufw allow proto udp from 192.168.1.0/24 port 1900 to any comment 'allow local LAN SSDP for UPnP discovery'
ufw allow 9735 comment 'allow Lightning'
ufw allow 8333 comment 'allow Bitcoin mainnet'
ufw allow 18333 comment 'allow Bitcoin testnet'
ufw enable
systemctl enable ufw
ufw status
exit

e per verificare le regole attive

sudo ufw status verbose

Le configurazioni sono salvate in:

/etc/ufw/

HINT: avete inserito una regola per errore?
con il comando sudo ufw status numbered potete individuare l’indice della regola errata e con il comando sudo ufw delete [numero] potete cancellarla.
Clicca qui per maggiori informazioni sui comandi ufw.

fail2ban

https://www.raspberrypi.org/documentation/configuration/security.md

Altro tool consigliato dalla guida Raspberry, che analizza il log per verificare delle attività sospette, ad esempio attacchi di tipo bruteforce.

sudo apt-get install fail2ban

Bene adesso avete tutto a disposizione per tenere attivo il vostro nodo.

Potete tranquillamente fare esperimenti, oppure seguire senza problemi il libro Bitcoin dalla teoria alla pratica :)

Bitcoin Fullnode Raspberry Bitcoin dalla teoria alla pratica
Il mio nodo in funzione.

Ogni suggerimento o modifica è sempre benvenuta.
Le fonti che ho utilizzato per questo articolo sono:
- https://medium.com/@meeDamian/bitcoin-full-node-on-rbp3-revised-88bb7c8ef1d1
- https://stadicus.github.io/RaspiBolt/

--

--

Responses (3)