dcrdata: executando o seu próprio explorador de blocos

10 minutos de leitura

1. Introdução

O dcrdata fornece uma interface web para analisar o conteúdo de blocos, transações e endereços de carteiras, além de tickets e votos. Para conferir o funcionamento do dcrdata acesse https://explorer.dcrdata.org/.

Antes de começar a instalação, faça seu planejamento: veja na seção 3, etapas o, p e q, o tempo gasto e o espaço em disco necessário.

1.1. Motivação

É comum, após realizar uma transação, colocar o txid (hash da transação) em um block explorer para ver se a transação já foi propagada e o seu número de confirmações. Com frequência, ao realizar uma transação p2p, a parte responsável por enviar as moedas envia um link de um block explorer apontando para o txid. Aqui começam os problemas do nosso herói.

Privacidade

Ao abrir esse link o usuário está se conectando a um web server, que registrará o seu endereço IP e muitas outras informações divulgadas pelo browser.

Ainda que possa usar uma VPN para mascarar sua origem, seria necessário ter certeza de que o serviço de VPN não armazena seu endereço IP e os destinos acessados e consulta a DNS (no log policy). O site PrivacyTools tem uma lista de provedores de VPN localizados fora dos EUA, com no log policy (apesar de não haver nenhuma garantia), que aceitam Bitcoin e suportam OpenVPN. Dê preferência a provedores localizados em países fora do grupo Fourteen Eyes.

Código malicioso

Além de ter sua informações e até a sua localização expostos, o usuário também se expõe a execução de código malicioso, principalmente via Javascript.

Transação forjada

Se a contraparte na transação detém o controle sobre o block explorer, ela poderá forjar uma transação que parece existir na blockchain mas existe apenas naquele banco de dados. É útil quando uma das partes espera que a outra confirme o envio para proceder com o negócio.

Conclusão

Rodando o seu próprio full node, com o seu próprio block explorer, o usuário não fica exposto a essas ameaças toda vez que verifica uma transação.

1.2. Diferenças entre nodes

É comum perceber diferenças entre nodes, mas todas as transações serão propagadas a todos os nodes, mesmo que leve um pouco mais de tempo até chegar ao seu.

O mempool do seu node provavelmente não será igual ao mempool dos outros nodes. As transações são propagadas entre os nodes que estão diretamente conectados e assim por diante. Além disso, a mempool é zerada toda vez que o dcrd é desligado. Então é normal que após reiniciar o dcrd a sua mempool não terá transações que outros nodes tem.

2. Arquitetura

Figura 1 - Alguns cenários possíveis para instalação do dcrdata
Figura 1 - Alguns cenários possíveis para instalação do dcrdata

3. Instalação

Os passos a seguir foram executados em um Debian 9 64-bit para a instalação do dcrdata 1.3.2.

Pré-requisitos

  • A linguagem Go 1.8.3 ou mais nova deve estar instalada. Para instalar, veja o artigo Instalando o Go (golang).
  • Executar o dcrd (>=1.1.0) sincronizado com o melhor bloco atual da rede. Para instalar, veja o artigo Instalando o dcrd.

a) Clone o repositório do dcrdata:

$ sudo git clone https://github.com/decred/dcrdata $HOME/go/src/github.com/decred/dcrdata

Se não possui o git instalado:

$ sudo apt-get install git

b) Entre no diretório que acabou de ser criado:

$ cd $HOME/go/src/github.com/decred/dcrdata

c) Execute o Dep para verificar as dependências:

$ dep ensure
ou
$ /usr/local/go/bin/dep ensure

d) Compile e instale:

$ go build
$ go install . ./cmd/..
ou
$ /usr/local/go/bin/go build
$ /usr/local/go/bin/go install . ./cmd/..

Se ao compilar encontrar o erro “exec: ‘gcc’: executable file not found in $PATH”, é possível que o gcc (compilador c) não esteja instalado.

$ sudo apt-get install gcc

e) Crie o arquivo de configuração a partir do default:

$ cp sample-dcrdata.conf dcrdata.conf

f) Ajuste os parâmetros dcrduser e dcrdpass com as informações do usuário RPC do dcrd. No arquivo dcrd.conf os parâmetros se chamam rpcuser e rpcpass:

g) Se o dcrd está sendo executado em outro host, altere também os parâmetros dcrdserv e dcrdcert.

h) Se o dcrdata será usado como explorador de blocos para uma rede local (e não apenas para o localhost), será necessário configurar o serviço web para escutar em um endereço IP local, além do localhost, usando o parâmetro apilisten. Essa configuração é fundamental para hosts headless (sem monitor).

apilisten=$(endereço IP da interface local)

i) O dcrdata pode usar como banco de dados o SQLite ou o PostgreSQL. Para usar o SQLite, configure no dcrdata.conf o parâmetro:

pg=false

Ou instale o PostgreSQL (recomendado):

$ sudo apt-get install postgresql

j) Crie no PostgreSQL a credencial de acesso e o banco de dados de acordo com a configuração feita em dcrdata.conf:

pgdbname=dcrdata
pguser=dcrdata
pgpass=

Para criar a credencial e o banco de dados no PostgreSQL, substitua as váriáveis abaixo pelos nomes escolhidos para os parâmetros acima:

$ sudo su - postgres
$ createuser $pguser
$ createdb -O $pguser $pgdbname
$ psql
postgres=# \password $pguser
postgres=# \q

k) O script rebuilddb2 é o aplicativo que cria e dá manutenção no banco de dados PostgreSQL. Entre no diretório $HOME/go/src/github.com/dcrdata/dcrdata/cmd/rebuilddb2/ e crie o arquivo de configuração com base no sample:

$ cd $HOME/go/src/github.com/decred/dcrdata/cmd/rebuilddb2
$ cp sample-rebuilddb2.conf rebuilddb2.conf

Se fosse usado apenas o banco de dados SQLite, o aplicativo usado seria o rebuilddb.

l) Edite os parâmetros de conexão RPC (dcrduser, dcrdpass, dcrdserv e dcrdcert) e PostgreSQL (dbname, dbuser e dbpass) com os mesmos valores de dcrdata.conf.

m) Altere em rebuilddb2.conf o parâmetro nodaemontls que contém o valor true. O default do rebuilddb2 é iniciar um cliente RPC e tentar se conectar ao dcrd sem criptografia. O dcrd recusará a conexão informando que o cliente não parece estar tentando um handshake TLS. No terminal do rebuilddb2 haverá um erro fatal de resposta HTTP malformada.

nodaemontls=false

n) Compile o rebuilddb2:

$ go build
ou
$ /usr/local/go/bin/go build

o) Deve haver espaço suficiente na partição onde se encontra o diretório de dados do PostgreSQL (default: /var/lib/postgresql). Escolha uma partição ou disco que tenha no mínimo 80 GB livres (para 200.000 blocos) mais um espaço para crescimento, e faça a inicialização.

p) Se o dcrd já estiver com todos os blocos copiados localmente, execute o rebuilddb2, que irá criar as tabelas no PostgreSQL. Se o dcrd ainda estiver sendo atualizado a conexão RPC será recusada.

$ ./rebuilddb2 -C rebuilddb2.conf

O dcrdata passará cerca de cinco horas importando informações de todos os blocos conhecidos pelo dcrd para dentro do PostgreSQL. Depois, 30 minutos indexando o banco. No final, gastará mais de 20 horas atualizando as transações não gastas na memória (variando de 30 a 60 minutos para cada conjunto de 250.000; havia mais de 9.200.000).

q) Quando a importação terminar… não inicie o dcrdata, ainda.

Para que o dcrdata possa consultar as transações individualmente, será necessário iniciar o dcrd com a opção --txindex ou --addrindex. Vá na janela onde o dcrd está sendo executado, encerre-o com [Ctrl+C] e execute-o novamente:

$ ./dcrd [--txindex | --addrindex]

--txindex: mantém um index baseado no hash das transações para pesquisa através do comando RPC getrawtransaction (mínimo necessário para o dcrdata)
--addrindex: mantém um index baseado no endereço das transações para pesquisa através do comando RPC searchrawtransactions (engloba o --txindex)

Após aproximadamente 25 minutos indexando as transações, o dcrd estará pronto. Vá ao diretório principal e inicie o dcrdata:

$ cd ../..
$ ./dcrdata -C dcrdata.conf

O dcrdata precisará de aproximadamente duas horas para varrer os blocos em busca das transações (para aproximadamente 200.000 blocos).

Ao final o dcrdata indicará no terminal: ‘Now serving on http://127.0.0.1:7777/’. Acesse o dcrdata pelo browser neste endereço:

Figura 2 - O dcrdata está instalado e pronto para uso
Figura 2 - O dcrdata está instalado e pronto para uso

3.1. Acesso via HTTPS

Agora que tudo está funcionando como esperado, é possível fazer uma última modificação: configurar o acesso HTTPS para o explorador de blocos. O acesso via HTTPS tem o objetivo de evitar que a rede local possa capturar os endereços de transações e carteiras que um usuário pesquisa, o que pode levar a descoberta de suas compras, tickets ou saldo, por inferência ou correlação. Se o dcrdata está sendo acessado via browser a partir do localhost, configurar o acesso HTTPS não trará nenhum benefício.

O readme do dcrdata sugere que esse acesso seja feito via proxy reverso nginx conforme a figura a seguir, exceto pela separação em três dispositivos diferentes:

Figura 3 - Outro cenário para uso do dcrdata, agora via nginx
Figura 3 - Outro cenário para uso do dcrdata, agora via nginx

O arquivo sample-nginx.conf no diretório principal do dcrdata já está pré-configurado com a aplicação que roda em http://127.0.0.1:7777/. O que fica faltando é um ajuste de configuração e o certificado digital para fazer a criptografia entre o nginx e o browser do cliente. As instruções abaixo assumem o cenário da Figura 3, exceto pela divisão entre os dispositivos.

OpenSSL self-signed certificate

Como um certificado self-signed é um certificado como outro qualquer exceto pela relação de confiança, vamos gerar um certificado self-signed no dcrdata para fazer a criptografia da comunicação.

a) Crie o diretório, o certificado e a chave privada e configure as permissões do diretório:

$ sudo mkdir -p /etc/ssl/dcrdata
$ sudo openssl req -new -x509 -days 365 -nodes -out /etc/ssl/dcrdata/dcrdata-cert.pem -keyout /etc/ssl/dcrdata/dcrdata-key.key
$ sudo chmod -R 600 /etc/ssl/dcrdata

b) Copie o arquivo sample-nginx.conf para /etc/nginx/nginx.conf e edite o arquivo para incluir o caminho correto do certificado e da chave privada:

$ sudo mv /etc/nginx/nginx.conf /etc/nginx/nginx.conf.old
$ sudo cp sample-nginx.conf /etc/nginx/nginx.conf

Altere os parâmetros ssl_certificate e ssl_certificate_key para que apontem para o certificado e a chave gerados na primeira etapa:

ssl_certificate       /etc/ssl/dcrdata/dcrdata-cert.pem
ssl_certificate_key   /etc/ssl/dcrdata/dcrdata-key.key

c) Remova as versões anteriores do TLS e deixe apenas a atual, 1.2. Use apenas métodos criptográficos mais seguros, o que vai impedir o acesso a partir de dispositivos desatualizados.

ssl_protocols         TLSv1.2;
ssl_ciphers           ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256;

d) Reinicie o serviço do nginx:

$ sudo service nginx restart

e) Acesse o endereço https://127.0.0.1/. O browser avisará que o certificado não faz parte de uma cadeia de confiança.

Figura 4 - Exceção de segurança no Firefox
Figura 4 - Exceção de segurança no Firefox

e) Crie uma exceção permanente e recarregue a página. O alerta permanecerá sendo mostrado na barra de endereços.

Figura 5 - dcrdata acessado por https
Figura 5 - dcrdata acessado por https

3.2. Acesso HTTPS via Tor

Além da criptografia ponta-a-ponta configurada na seção anterior, também podemos encapsular o acesso HTTPS via Tor, pelo menos na ponta do servidor dcrdata.

Figura 6 - dcrdata acessado por https via Tor
Figura 6 - dcrdata acessado por https via Tor

Configuração do nginx

Altere o parâmetro listen dentro da seção server:

    server {
        listen       443 default_server;
        server_name  _;

para:

    server {
        listen       127.0.0.1:9070 default_server;
        server_name _;

Configuração do Tor

Para instalar o Onion Service, será necessário editar o arquivo torrc.

a) Procure no diretório Browser/TorBrowser/Data/Tor/torrc no diretório do Tor Browser.

b) Abra o arquivo torrc e procure pela linha: ### This section is just for location-hidden services ###

c) Adicione as seguintes linhas ao torrc:

HiddenServiceDir /var/tor/dcrdata
HiddenServicePort 443 127.0.0.1:9070

d) Recarrege a configuração do Tor:

$ sudo service tor reload

No diretório especificado em HiddenServiceDir serão criados os arquivos hostname e private_key, que contém o hostname .onion e a chave privada respectivamente.

hostname

O arquivo hostname é criado pelo Tor é contém o nome com o qual o serviço se anuncia na rede Tor, que é uma versão curta da chave pública e se parece com duskgytldkxiuqc6.onion. Esse é o nome público do seu serviço e será usado para acessar o dcrdata.

private_key

Outro arquivo criado no mesmo diretório é o private_key. Mantenha-o em segurança. Ele contém a chave privada gerada para esse onion service e se cair em mão erradas permitirá que terceiros se passem pelo serviço na rede do Tor.

e) Reinicie o nginx:

$ sudo service nginx restart

Para saber mais, leia sobre o uso do Decred através da rede Tor.

4. Atualização

Encerre o processo dcrdata através de [Ctrl+C] no terminal onde está sendo executado ou termine o processo através do comando kill:

$ kill `ps ax | grep ./dcrdata | head -1 | cut -d' ' -f2`

Para atualizar o dcrdata:

$ cd $HOME/go/src/github.com/decred/dcrdata
$ git pull origin master

$ dep ensure
ou
$ /usr/local/bin/go/dep ensure

$ go build
ou
$ /usr/local/bin/go/go build

Execute novamente o dcrdata:

$ ./dcrdata -C dcrdata.conf

Se encontrar o erro “[ERR]: DATD: table maintenance required”, execute novamente o script rebuilddb2:

$ ./rebuilddb2 -C rebuilddb2.conf

Ao término acesse novamente o endereço https://127.0.0.1/ e verifique que o dcrdata funciona normalmente.