These resources are written by Freedom Lab members. Join our Freedom Lab server to be a part of the community and receive support directly.

ResourcesTalk to Your Node: Bitcoin Verification via SSH

Talk to Your Node: Bitcoin Verification via SSH

Tutorial Bitcoin Self-hosting

Audience: Intermediate — has a running StartOS node and basic terminal comfort

Duration: 90 min

Outcomes: By the end, you will:

Abstract

Your Bitcoin node validates every block and every transaction, but you have probably never asked it a direct question. This tutorial opens a secure SSH tunnel to your StartOS node and walks you through querying it: verifying the total money supply, reading the mempool, estimating fees, inspecting blocks, and monitoring the network. By the end, you will know how to get answers from your own copy of the blockchain instead of trusting a website.

The tutorial uses an AI agent (like Claude Code) as the primary interface for running commands, but every command is a standard bitcoin-cli call you can type yourself. Appendix A covers the full command reference so you can go direct whenever you want.

Concept Primer

What is SSH?

SSH (Secure Shell) is a way to remotely control a computer using text commands. Instead of sitting in front of your node, you type commands from your laptop and they execute on the node as if you were there. The connection is encrypted end-to-end, so nobody on your network can see what you are doing.

How Key Pairs Work

SSH uses a key pair for authentication: a private key on your laptop (like a password file) and a public key on your node (like a lock). When you connect, your computer proves it has the private key without ever sending it. The node checks this proof against the public key you registered. If they match, you are in.

This is more secure than a password:

Agenda

  1. Why Talk to Your Node (10 min) — motivation, what SSH is, course overview
  2. Setup (25 min) — key generation, StartOS registration, first connection, agent config
  3. Security (10 min) — threat model, key protection, checklist
  4. Your First Verification (25 min) — supply, mempool, fees, blocks, DIY command
  5. What Your Node Sees (15 min) — peers, fee dynamics, mining, bandwidth
  6. Buffer / Exploration (5 min) — try commands from Appendix A

Prerequisites

No programming experience required. No Linux experience required. If you can type and follow instructions, you can do this.

Section 1: Why Talk to Your Node

You bought a Bitcoin node. You plugged it in, synced the blockchain, and now it sits in your closet humming away. It is validating every transaction and every block — enforcing Bitcoin's rules without asking anyone for permission.

But right now, you are taking its word for it. You have not actually looked.

Bitcoin's entire value proposition rests on one idea: you do not have to trust anyone. Not a bank, not an exchange, not a block explorer website. You can verify everything yourself. But most node runners do not. They plug in the hardware, check the dashboard occasionally, and trust that it is working.

The blockchain data sitting on that device is the most complete, independently verified financial record in existence — and most people never look at it directly. When you check your balance on a block explorer, you are trusting that website to show you accurate data. None of that trust is necessary. Your node has the same data. It verified every byte of it.

What We Are Building Toward

Here is what it looks like when we are done. You open Claude (or any AI assistant with terminal access) and say:

"Check my node's block height and tell me what's in the mempool."

Claude connects to your node over SSH, runs the commands, and comes back with:

"Your node is at block 940,219 — fully synced. The mempool has 45,231 unconfirmed transactions totaling 23.8 MB, with a minimum relay fee of 1 sat/vbyte. Next-block fee estimate is about 12 sats/vbyte."

Or you ask:

"Verify the total bitcoin supply."

And a few minutes later:

"Your node counted every unspent output in the blockchain. Total supply: 20,000,457.41 BTC across 164.9 million UTXOs. This matches the expected issuance schedule — no extra bitcoin have been created."

A note on trust: A course about not trusting third parties asks you to trust an AI to talk to your node. Claude is a tool running on your machine, executing commands you can see and audit. It cannot move your bitcoin or change your node's configuration with the read-only commands used here. Every command Claude runs is a bitcoin-cli command you could type manually. Appendix A covers the full reference.

Section 2: Setup

This section gets you from zero to connected. By the end, you will have an SSH key, your node will recognize it, and you will have typed your first command on a remote machine.

Step 1: Generate an SSH Key

Open a terminal on your computer (Terminal on Mac/Linux, PowerShell or Git Bash on Windows).

ssh-keygen -t ed25519 -f ~/.ssh/id_ed25519_mynode

It will ask you to set a passphrase. Do it. This encrypts the key file so that even if someone copies it off your machine, they cannot use it without the passphrase.

This creates two files:

Windows note: ~ means C:\Users\YourUsername. The .ssh folder should already exist. If not, create it.

Step 2: Add Your Public Key to StartOS

View your public key:

# Mac/Linux
cat ~/.ssh/id_ed25519_mynode.pub

# Windows (PowerShell)
type C:\Users\YourUsername\.ssh\id_ed25519_mynode.pub
  1. Copy the entire output (it starts with ssh-ed25519 and ends with your username)
  2. Open your StartOS dashboard in a browser
  3. Go to System > SSH Keys
  4. Paste the public key and save

That is it. Your node now recognizes your laptop.

Step 3: Find Your Node's Address

You need your node's IP address on your local network. Check one of these:

Step 4: Connect

ssh -i ~/.ssh/id_ed25519_mynode start9@192.168.1.50

Replace 192.168.1.50 with your node's actual IP.

First connection: You will see a message asking if you trust the server's fingerprint. Type yes. This only happens once — SSH remembers the server after that.

If everything worked, your terminal prompt changes to something like:

start9@wood-opals:~$

You are on your node. Type exit to disconnect and return to your laptop's terminal.

Step 5: Create a Shortcut

Create or edit ~/.ssh/config on your laptop so you never have to type the full connection string again:

Host mynode
    HostName 192.168.1.50
    User start9
    IdentityFile ~/.ssh/id_ed25519_mynode
    IdentitiesOnly yes

Replace the IP with your node's address. Now connecting is just:

ssh mynode

Step 6: Set Up for Your AI Agent

Your AI agent cannot type passphrases interactively, so you need to load your key into an SSH agent first.

Mac/Linux:

ssh-add ~/.ssh/id_ed25519_mynode

Enter your passphrase once. The agent holds the decrypted key in memory until you log out.

Windows (PowerShell as Administrator):

# Check if the agent is running
Get-Service ssh-agent

# If it says "Stopped", start it and set it to auto-start:
Set-Service -Name ssh-agent -StartupType Automatic
Start-Service ssh-agent

# Add your key (prompts for passphrase once)
C:\Windows\System32\OpenSSH\ssh-add.exe C:\Users\YourUsername\.ssh\id_ed25519_mynode

Git Bash users: Git Bash ships its own SSH binary that does not talk to the Windows agent. Add these aliases to your ~/.bashrc:

export GIT_SSH="/c/Windows/System32/OpenSSH/ssh.exe"
alias ssh='/c/Windows/System32/OpenSSH/ssh.exe'
alias scp='/c/Windows/System32/OpenSSH/scp.exe'

Then reload: source ~/.bashrc

Verify your agent can connect:

ssh mynode "echo connected"

If it prints connected without asking for a passphrase, your AI agent can use it too.

When you are done for the day: Flush the keys from the agent:

# Mac/Linux
ssh-add -D

# Windows
C:\Windows\System32\OpenSSH\ssh-add.exe -D

Section 3: Security

You now have remote access to your Bitcoin node. That is a powerful thing, and it is worth understanding exactly what it means before you start using it.

What You Just Opened

SSH gives you a command-line terminal on your server. On StartOS, the SSH user (start9) has passwordless sudo — meaning there is no second gate between "logged in" and "full control." For this tutorial, we only use read-only commands. But the access itself is broader than what we use it for.

Who Can Reach Your Node?

SetupRiskWho can attempt to connect
LAN-only (your setup)LowerOnly devices on your home network
Port 22 forwarded on routerHighAnyone on the internet
SSH over Tor hidden serviceMediumAnyone who discovers the .onion address

Never forward port 22 on your router. Automated bots scan the entire internet for open SSH ports around the clock. If you need remote access, use a VPN or Tor — never raw SSH over the open internet.

What Is at Stake

If someone obtained your SSH key and passphrase, they could:

What they cannot do:

Key distinction: Your node is a verification tool, not a custody tool. If you use a hardware wallet, SSH access is a privacy and convenience concern, not a funds-at-risk concern.

The SSH Agent Trade-Off

If you loaded your key into the SSH agent (Step 6), the agent holds your decrypted key in memory. Any process running as your user can silently ask the agent to sign an authentication challenge — meaning malware or a rogue script could SSH to your server without your knowledge. The agent does not prompt you.

This is the same security model used by every developer with GitHub SSH keys. It is standard practice. But you should:

Hot Wallet Check

Check if any wallets are loaded on your node:

ssh mynode "sudo podman exec bitcoind.embassy bitcoin-cli listwallets"

If wallets are loaded and unencrypted, anyone with SSH access can spend from them. The standard recommendation: use a hardware wallet, and let the node handle validation only.

Security Checklist

Before moving on, confirm:

Section 4: Your First Verification

This is the section the setup was for. You are about to independently verify facts about Bitcoin using your own node — no websites, no APIs, no trust required.

Tell your AI agent what you want to know and it will run the commands over SSH. If you want to understand what is happening under the hood, Appendix A covers every command in detail.

Is Your Node Synced?

Before verifying anything, make sure your node is caught up with the network. Ask your agent:

"Check if my node is fully synced."

The agent runs getblockchaininfo and checks that blocks equals headers (all known blocks downloaded and validated) and verificationprogress is at or near 1 (100% verified).

What "synced" actually means: your node downloaded every block ever produced — starting from the genesis block in January 2009 — and independently validated every transaction in every one of them. It checked every signature, verified every input was unspent, confirmed every coinbase reward was correct, and enforced every consensus rule.

Verify the Money Supply

This is the command that makes running a node worth it.

"Verify the total bitcoin supply on my node."

The agent runs gettxoutsetinfo, which scans every unspent transaction output (UTXO) in the entire blockchain. This takes several minutes — it is counting over 160 million individual outputs and summing them.

FieldValueMeaning
Total supply~20,000,457 BTCEvery bitcoin that currently exists
UTXO count~164.9 millionIndividual unspent outputs
Transactions~114.4 millionTotal transactions ever processed
UTXO set size~11.3 GBHow much space the state takes on disk

The UTXO set hash: The result includes a hash_serialized_3 field — a cryptographic fingerprint of the entire UTXO set. If your hash matches another node's hash at the same block height, you have both independently proven you agree on the exact state of every bitcoin in existence. No coordination needed. No trust required. Just math.

Check the Mempool

The mempool is where unconfirmed transactions wait to be included in a block. Every node maintains its own mempool.

"What's in my node's mempool right now?"
FieldWhat it tells you
Transaction countHow many transactions are waiting for confirmation
Total sizeCombined size in bytes — relates to how many blocks it would take to clear
Total feesSum of all fees waiting to be collected by miners
Minimum feeThe lowest fee rate your mempool will accept (rises when the mempool is full)

Estimate Fees

"What's the fee estimate for next-block confirmation? And for within an hour?"

The fee rate is expressed in sats/vbyte — satoshis per virtual byte of transaction data. A typical transaction is about 140 vbytes, so multiply the rate by 140 to estimate your total fee in satoshis.

Inspect a Block

"Show me the latest block."
FieldWhat it tells you
HeightPosition in the chain (0 = genesis block)
Transaction countHow many transactions the miner included
TimestampWhen the miner started working on it
DifficultyMining difficulty when this block was found
ConfirmationsHow many blocks have been built on top of it
Previous block hashThe block before this one — this is what makes it a chain

The Genesis Block: Block 0, mined by Satoshi Nakamoto on January 3, 2009. It contains the famous coinbase message: "The Times 03/Jan/2009 Chancellor on brink of second bailout for banks." Every block since then links back to this one through an unbroken chain of hashes. Your node verified all of them.

Look Up a Transaction

If you have a transaction ID (txid), your node can decode it:

"Look up this transaction: [paste txid]"

You will see the inputs (where the bitcoin came from), outputs (where it went and how much), fee (how much the sender paid the miner), and which block confirmed it.

Do It Yourself

You have been letting your agent handle the commands. Now try one yourself. Open your terminal and type this exactly:

ssh mynode "sudo podman exec bitcoind.embassy bitcoin-cli getblockcount"

That is it. One command. Your laptop connects to your node over SSH, reaches into the Bitcoin Core container, asks for the current block height, and prints the number.

No AI. No website. No intermediary. Your laptop asked your node a question and got a direct answer. The number you see is the block height your node has verified — every block from genesis to that number, independently validated by your hardware.

Section 5: What Your Node Sees

Your node is not just a database of old blocks. It is an active participant in the Bitcoin network — connected to other nodes, relaying transactions, validating new blocks as they arrive, and maintaining its own view of the network's current state.

Your Peers

Your node is connected to a handful of other nodes around the world. A healthy node typically has 8–10 outbound connections and may accept inbound connections too. The total is usually between 8 and 125.

"How many peers is my node connected to? Are any on Tor?"

Things to look for in peer details:

The Mempool in Motion

Every time someone broadcasts a transaction, it ripples through the network from node to node. Your node receives it from a peer, validates it (checks that the inputs are unspent, the signatures are valid, the fee meets the minimum), and adds it to its mempool. Then it relays the transaction to its other peers.

Your mempool is your node's view of unconfirmed transactions. It is not identical to every other node's mempool — transactions propagate at different speeds, nodes have different minimum fee policies, and mempool size limits vary.

When the Mempool Gets Full

Your node allocates 300 MB by default for the mempool. When it fills up, the node drops the lowest-fee transactions to make room for higher-fee ones. The mempoolminfee field rises — your node is being selective about what it keeps.

"Is the mempool full right now? What's the minimum fee to get in?"

Fee Dynamics

Bitcoin Core looks at the last several hundred blocks and tracks which fee rates got confirmed in how many blocks. From this, it builds a statistical model. This is more sophisticated than most fee estimation websites, which often just look at the current mempool.

"What are the fee estimates for 1 block, 6 blocks, and 144 blocks?"

If the gap between next-block and next-day is large, the network is congested. If they are close together, the network is quiet and patience does not save much.

Mining and Difficulty

Mining difficulty adjusts every 2,016 blocks (roughly two weeks) to keep the average block time at 10 minutes regardless of how much computing power is on the network.

"What's the current mining difficulty? When was the last adjustment?"

Your node estimates the total hash rate by looking at how quickly blocks are being found relative to the difficulty target. As of early 2026, the Bitcoin network computes hundreds of exahashes per second — more computational work per second than any other system in human history.

Bandwidth and Identity

"How much data has my node sent and received since it last started?"

A fully synced node with default settings typically uses 50–200 GB per month. Your node also broadcasts a version string to its peers and shows which networks it is reachable over (IPv4, IPv6, Tor, I2P). StartOS nodes are typically Tor-connected, so peers see your .onion address, not your home IP.

Appendix A: Under the Hood

This appendix covers what your agent does behind the scenes when it queries your node. If you want to run commands manually, understand the container model, or look up a specific command, this is the reference.

The Container Model

StartOS does not run Bitcoin Core directly on the server. It runs inside a Podman container — an isolated environment that packages the software with everything it needs. Think of your server as an apartment building. Each service (Bitcoin Core, Electrum Server, Lightning) lives in its own apartment.

This means you cannot just type bitcoin-cli on the server. You need to reach into the container first:

sudo podman exec bitcoind.embassy bitcoin-cli <command>

To open an interactive shell inside the container:

sudo podman exec -it bitcoind.embassy bash

Now you can type bitcoin-cli commands without the podman exec prefix. Type exit to leave.

Container Management

CommandWhat it does
sudo podman psList running containers
sudo podman logs bitcoind.embassy --tail 50Last 50 lines of Bitcoin Core logs
sudo podman logs bitcoind.embassy --followFollow logs in real time (Ctrl+C to stop)
sudo podman restart bitcoind.embassyRestart Bitcoin Core (safe)

Create a Shortcut

Add an alias to your server's .bashrc to skip the podman exec prefix:

ssh mynode
echo 'alias btc="sudo podman exec bitcoind.embassy bitcoin-cli"' >> ~/.bashrc
source ~/.bashrc

Now commands are just:

btc getblockcount
btc getmempoolinfo
btc estimatesmartfee 6

Command Reference

All commands are read-only. You cannot break your node by running these.

Blockchain:

CommandWhat it returns
getblockchaininfoChain, height, sync status, pruning, disk size
getblockcountCurrent block height (just the number)
getbestblockhashHash of the latest block
getblock "hash"Full details of a specific block
getblockhash <height>Block hash by height
getdifficultyCurrent mining difficulty
getchaintxstatsTransaction rate over time

UTXO Set:

CommandWhat it returns
gettxoutsetinfoTotal supply, UTXO count, set size (takes minutes)
gettxout "txid" nWhether a specific output is unspent

Mempool:

CommandWhat it returns
getmempoolinfoSize, tx count, memory usage, min fee
getrawmempoolList of all unconfirmed transaction IDs
estimatesmartfee <blocks>Fee rate for confirmation in N blocks

Network:

CommandWhat it returns
getnetworkinfoVersion, protocol, connections, networks
getpeerinfoDetailed info on every connected peer
getconnectioncountNumber of peers (just the number)
getnettotalsTotal bytes sent and received

Mining:

CommandWhat it returns
getmininginfoDifficulty, hash rate, current block
getnetworkhashpsEstimated network hash rate

Reading JSON Output

Most commands return JSON. Here is an example from getblockchaininfo:

{
  "chain": "main",
  "blocks": 940219,
  "headers": 940219,
  "bestblockhash": "00000000000000000000ba29...",
  "difficulty": 145042165424853.3,
  "verificationprogress": 1,
  "pruned": false,
  "size_on_disk": 826789612252
}

Key things to check: "chain": "main" (you are on mainnet), "blocks" equals "headers" (fully synced), "verificationprogress": 1 (100% verified), "pruned": false (full node).

Appendix B: Tips & Troubleshooting

Quick Status Check

Three commands give you a fast snapshot:

ssh mynode "sudo podman exec bitcoind.embassy bitcoin-cli getblockcount"
ssh mynode "sudo podman exec bitcoind.embassy bitcoin-cli getconnectioncount"
ssh mynode "sudo podman exec bitcoind.embassy bitcoin-cli getmempoolinfo"

Block height, peer count, mempool size. If all three return reasonable numbers, your node is synced, connected, and healthy. Or just ask your agent: "Is my node healthy?"

Common Errors

"Connection refused" when SSHing

ssh: connect to host 192.168.1.50 port 22: Connection refused

Cause: SSH server is not running, or the IP address is wrong.

Fix: Check your node's IP address — IPs can change if you do not have a static lease on your router. Look up the current address in your router's device list or the StartOS dashboard. Confirm SSH is enabled under System > SSH.

"Permission denied (publickey)"

start9@192.168.1.50: Permission denied (publickey).

Cause: The server does not recognize your key.

Fix: Confirm you added the public key (.pub file), not the private key, to StartOS. Check that you are pointing to the right private key with -i. Verify the username is start9. Check file permissions: chmod 600 ~/.ssh/id_ed25519_mynode

"Could not open a connection to your authentication agent"

Could not open a connection to your authentication agent.

Cause: ssh-add cannot find a running SSH agent.

Fix: On Windows, use the full path: C:\Windows\System32\OpenSSH\ssh-add.exe. On Mac/Linux, start the agent first: eval $(ssh-agent -s)

"Host key verification failed"

WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!

Cause: Your node's fingerprint changed since your last connection (reinstall, hardware swap).

If you know why it changed, remove the old entry: ssh-keygen -R 192.168.1.50. If you do not know why, investigate before connecting. This warning protects you from man-in-the-middle attacks.

"error: Could not connect to the server 127.0.0.1:8332"

Cause: Bitcoin Core is not running, or you ran bitcoin-cli outside the container.

Fix: Make sure you are using the podman exec prefix. Check if the container is running: sudo podman ps. Check Bitcoin Core's logs: sudo podman logs bitcoind.embassy --tail 20

"bitcoin-cli: command not found"

Cause: You are on the server shell, not inside the container.

Fix: Either exec into the container first (sudo podman exec -it bitcoind.embassy bash) or use the full podman exec command from the server shell.

Server Maintenance

# Check disk space
ssh mynode "df -h"

# Check running services
ssh mynode "sudo podman ps"

# View Bitcoin Core logs (last 20 lines)
ssh mynode "sudo podman logs bitcoind.embassy --tail 20"

# Restart Bitcoin Core (safe -- picks up where it left off)
ssh mynode "sudo podman restart bitcoind.embassy"

A full (unpruned) node uses 800+ GB and growing. If your drive fills up, Bitcoin Core will stop syncing.

When to Ask for Help

If you see errors about database corruption, unexpected shutdowns, or "block validation failed," do not try to fix these yourself. These are rare but serious.

Reference Links