Skip to content

bitcoin-dev-tools/usdt-dash

Repository files navigation

Bitcoin Core USDT Tracing Dashboard

A NixOS configuration that deploys a Bitcoin Core node with USDT tracepoint monitoring. A BCC/eBPF script hooks into bitcoind's 16 USDT tracepoints, exports metrics to Prometheus, and visualizes them on a public Grafana dashboard over HTTPS.

Architecture

bitcoind (USDT tracepoints)
    |
    v  eBPF/BCC hooks
Python tracing exporter (root, systemd)  :9435
    |
    v  Prometheus scrape
Prometheus  :9090
    |
    v  data source
Grafana  :3000 (anonymous read-only)
    |
    v  reverse proxy
Caddy  :443 (Cloudflare DNS ACME)

Tracepoints

The exporter hooks into 16 of bitcoind's 20 USDT tracepoints (excluding coin_selection:*):

  • Mempool (4): added, removed, replaced, rejected
  • Network (7): inbound/outbound messages, inbound/outbound/closed connections, evicted, misbehaving
  • Validation (1): block_connected
  • UTXO Cache (4): flush, add, spent, uncache

Deploying Your Own

Prerequisites

  • A VPS running NixOS (tested on Hetzner Cloud CX22)
  • sops and age installed locally
  • A Cloudflare API token with DNS edit permissions for your domain
  • just command runner

1. Clone and configure

git clone <this-repo>
cd usdt-dash

2. Update deployment settings

Edit the settings block in flake.nix to match your server:

  • hostName -- your hostname
  • domain -- your domain (used for Caddy and Grafana)
  • networkInterface -- your server's network interface
  • ipAddress / prefixLength -- your server's IP
  • gateway -- your provider's gateway
  • sshKeys -- your SSH public key(s)

3. Update justfile

In justfile, set host to your server's IP or hostname.

4. Set up secrets

The included secrets.yaml is encrypted with keys you can't decrypt. Delete it and create your own:

# Generate a local age key (skip if you already have one)
age-keygen -o ~/.config/sops/age/keys.txt

# Get your local public key
age-keygen -y ~/.config/sops/age/keys.txt

Edit .sops.yaml and replace both keys:

  • &local -- your local age public key
  • &server -- leave as placeholder for now (filled after first deploy)
keys:
  - &local age1your-local-key-here
  - &server age1your-server-key-here
creation_rules:
  - path_regex: secrets\.yaml$
    key_groups:
      - age:
          - *local
          - *server

For the initial deploy, temporarily comment out the &server key and its reference so you can encrypt with just your local key:

rm secrets.yaml

# Create plaintext, then encrypt in-place
cat > secrets.yaml <<'EOF'
caddy-cloudflare-token: your-cloudflare-api-token
grafana-secret-key: some-random-hex-string
EOF
sops --encrypt --in-place secrets.yaml

5. Initial deploy

just deploy

This uses nixos-anywhere to wipe and install NixOS on the target.

6. Add server key to sops

sops-nix automatically derives an age key from the server's SSH host key for decryption -- no manual key generation needed on the server. But you need the corresponding public key in .sops.yaml so that sops can encrypt secrets the server can read.

Get the age public key from the server's SSH host key:

ssh root@<your-server> "cat /etc/ssh/ssh_host_ed25519_key.pub" | nix-shell -p ssh-to-age --run ssh-to-age

Paste the output into .sops.yaml as the &server key, uncomment it, then re-encrypt:

echo y | sops updatekeys secrets.yaml

7. Deploy the full configuration

just switch

This rsyncs the config to the server and runs nixos-rebuild switch remotely.

8. Reboot

The first deploy with kernel header changes needs a reboot for BCC to find them:

ssh root@<your-server> reboot

After reboot, verify:

# Check tracing service
ssh root@<your-server> systemctl status bitcoind-tracing

# Check metrics endpoint
ssh root@<your-server> curl -s localhost:9435/metrics | head -20

File Overview

File Purpose
flake.nix Nix flake with nixpkgs, disko, sops-nix inputs, and deployment settings
configuration.nix All NixOS services: bitcoind, tor, prometheus, grafana, caddy, sops
disk-config.nix Disk partitioning layout (disko)
hardware-configuration.nix Hardware-specific config (generated by nixos-anywhere)
tracing/bitcoind_exporter.py BCC/eBPF script hooking USDT tracepoints, Prometheus exporter
tracing/service.nix NixOS module for the tracing systemd service
grafana/dashboard.json Grafana dashboard with mempool, network, block, and UTXO cache panels
.sops.yaml sops encryption key configuration
secrets.yaml Encrypted secrets (Cloudflare token, Grafana secret key)
justfile Command runner recipes for deploy, switch, sync, etc.

About

nix configuration for usdt bitcoind monitoring and dashboard

Topics

Resources

Stars

Watchers

Forks