Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Note

This document is inherited from nix-bitcoin, the predecessor project. It is a work in progress and may be outdated.

Nodeinfo

Run nodeinfo to see onion addresses and local addresses for enabled services.

Managing services

NixOS uses the systemd service manager.

Usage:

# Show service status
systemctl status bitcoind

# Show the last 100 log messages
journalctl -u bitcoind -n 100
# Show all log messages since the last system boot
journalctl -b -u bitcoind

# These commands require root permissions
systemctl stop bitcoind
systemctl start bitcoind
systemctl restart bitcoind

# Show the service definition
systemctl cat bitcoind
# Show all service parameters
systemctl show bitcoind

clightning database replication

The clightning database can be replicated to a local path or to a remote SSH target.
When remote replication is enabled, bitcoinix mounts a SSHFS to a local path.
Optionally, backups can be encrypted via gocryptfs.

Note: You should also backup the static file hsm_secret (located at /var/lib/clightning/bitcoin/hsm_secret by default), either manually or via the services.backups module.

Remote target via SSHFS

  1. Add this to your configuration.nix:

    services.clightning.replication = {
      enable = true;
      sshfs.destination = "user@hostname:directory";
      # This is optional
      encrypt = true;
    };
    programs.ssh.knownHosts."hostname".publicKey = "<ssh public key from running `ssh-keyscan` on the host>";
    

    Leave out the encrypt line if you want to store data on your destination in plaintext.
    Adjust user, hostname and directory as necessary.

  2. Deploy

  3. To allow SSH access from the bitcoinix node to the target node, either use the remote node config below, or copy the contents of $secretsDir/clightning-replication-ssh.pub to the authorized_keys file of user (or use ssh-copy-id).

  4. You can restrict the bitcoinix node’s capabilities on the SSHFS target using OpenSSH’s builtin features, as detailed here.

    To implement this on NixOS, add the following to the NixOS configuration of the SSHFS target node:

    systemd.tmpfiles.rules = [
      # Because this directory is chrooted by sshd, it must only be writable by user/group root
      "d /var/backup/nb-replication 0755 root root - -"
      "d /var/backup/nb-replication/writable 0700 nb-replication - - -"
    ];
    
    services.openssh = {
      extraConfig = ''
        Match user nb-replication
          ChrootDirectory /var/backup/nb-replication
          AllowTcpForwarding no
          AllowAgentForwarding no
          ForceCommand internal-sftp
          PasswordAuthentication no
          X11Forwarding no
      '';
    };
    
    users.users.nb-replication = {
      isSystemUser = true;
      group = "nb-replication";
      shell = "${pkgs.coreutils}/bin/false";
      openssh.authorizedKeys.keys = [ "<contents of $secretsDir/clightning-replication-ssh.pub>" ];
    };
    users.groups.nb-replication = {};
    

    With this setup, the corresponding sshfs.destination on the bitcoinix node is "nb-replication@hostname:writable".

Local directory target

  1. Add this to your configuration.nix

    services.clightning.replication = {
      enable = true;
      local.directory = "/var/backup/clightning";
      encrypt = true;
    };
    

    Leave out the encrypt line if you want to store data in local.directory in plaintext.

  2. Deploy

clightning will now replicate database files to local.directory. This can be used to replicate to an external HDD by mounting it at path local.directory.

Custom remote destination

Follow the steps in section “Local directory target” above and mount a custom remote destination (e.g., a NFS or SMB share) to local.directory.
You might want to disable local.setupDirectory in order to create the mount directory yourself with custom permissions.

Connect to RTL

Normally you would connect to RTL via SSH tunneling with a command like this

ssh -L 3000:127.0.0.1:3000 root@bitcoin-node

Or like this, if you are using netns-isolation

ssh -L 3000:169.254.1.29:3000 root@bitcoin-node

Otherwise, you can access it via Tor Browser at http://<onion-address>. You can find the <onion-address> with command nodeinfo. The default password location is $secretsDir/rtl-password. See: Secrets dir

Use Zeus (mobile lightning wallet) via Tor

  1. Install Zeus (version ≥ 0.9.0)

  2. Edit your configuration.nix

    For lnd

    Add the following config:

    services.lnd.lndconnect = {
      enable = true;
      onion = true;
    };
    
    For clightning

    Add the following config:

    services.clightning.plugins.clnrest = {
      enable = true;
      lnconnect = {
        enable = true;
        onion = true;
      };
    };
    
  3. Deploy your configuration

  4. Run the following command on your node (as user operator) to create a QR code with address and authentication information:

    For lnd
    lndconnect
    
    For clightning
    lnconnect-clnrest
    
  5. Configure Zeus

    • Add a new node and scan the QR code
    • Click Save node config
    • Start sending and stacking sats privately

Additional lndconnect features

  • Create a plain text URL:
    lndconnect --url
    
  • Set a custom host. By default, lndconnect detects the system’s external IP and uses it as the host.
    lndconnect --host myhost
    

Connecting without Tor or WireGuard

Enabling lndconnect or lnconnect does not change the address that the REST server listens on. By default, the lnd and clnrest REST servers only listen on localhost.

The REST API grants full control over your lightning node, so only expose it to networks you trust. To reach it directly (e.g. via your local network or your own VPN), opt in explicitly. In the examples below, 192.168.1.10 is the address of your node and eth0 is the interface of the trusted network.
These examples don’t apply when using netns-isolation.

For lnd
services.lnd = {
  restAddress = "0.0.0.0";
  # Add the node address to the TLS certificate
  certificate.extraIPs = [ "192.168.1.10" ];
  # Only needed when using `secure-node.nix` or `enable-tor.nix`
  tor.enforce = false;
};
networking.firewall.interfaces.eth0.allowedTCPPorts = [ config.services.lnd.restPort ];
For clightning
services.clightning = {
  plugins.clnrest.address = "0.0.0.0";
  # Only needed when using `secure-node.nix` or `enable-tor.nix`
  tor.enforce = false;
};
networking.firewall.interfaces.eth0.allowedTCPPorts = [ config.services.clightning.plugins.clnrest.port ];

Then create the QR code with your node address as the host:

lndconnect --host 192.168.1.10
lnconnect-clnrest --host 192.168.1.10

Use Zeus (mobile lightning wallet) via WireGuard

Connecting Zeus directly to your node is much faster than using Tor, but a bit more complex to setup.

There are two ways to establish a secure, direct connection:

  • Connecting via TLS. This requires installing your lightning app’s TLS Certificate on your mobile device.

  • Connecting via WireGuard. This approach is simpler and more versatile, and is described in this guide.

  1. Install Zeus (version ≥ 0.9.0) and WireGuard on your mobile device.

  2. Add the following to your configuration.nix:

    imports = [
      # Use this line when using the default deployment method
      <nix-bitcoin/modules/presets/wireguard.nix>
    
      # Use this line when using Flakes
      (nix-bitcoin + /modules/presets/wireguard.nix)
    ]
    
    # For lnd
    services.lnd.lndconnect.enable = true;
    
    # For clightning
    services.clightning = {
      plugins.clnrest = {
        enable = true;
        lnconnect.enable = true;
      };
    };
    
  3. Deploy your configuration.

  4. If your node is behind an external firewall or NAT (e.g. a router), add the following port forwarding rule to the external device:

    • Port: 51820 (the default value of option networking.wireguard.interfaces.wg-nb.listenPort)
    • Protocol: UDP
    • Destination: IP of your node
  5. Setup WireGuard on your mobile device.

    Run the following command on your node (as user operator) to create a QR code for WireGuard:

    nix-bitcoin-wg-connect
    
    # For debugging: Show the WireGuard config as text
    nix-bitcoin-wg-connect --text
    

    The above commands automatically detect your node’s external IP.
    To set a custom IP or hostname, run the following:

    nix-bitcoin-wg-connect 93.184.216.34
    nix-bitcoin-wg-connect mynode.org
    

    Configure WireGuard:

    • Press the + button in the bottom right corner
    • Scan the QR code
    • Add the tunnel
  6. Setup Zeus

    Run the following command on your node (as user operator) to create a QR code for Zeus:

    For lnd
    lndconnect-wg
    
    For clightning
    lnconnect-clnrest-wg
    

    Configure Zeus:

    • Add a new node and scan the QR code
    • Click Save node config
    • On the certificate warning screen, click I understand, save node config.
      Certificates are not needed when connecting via WireGuard.
    • Start sending and stacking sats privately

Additional lndconnect features

Create a plain text URL:

lndconnect-wg --url

Connect to electrs

Requirements Android

Requirements Desktop

  1. Enable electrs in configuration.nix

    Change

    # services.electrs.enable = true;
    

    to

    services.electrs.enable = true;
    
  2. Deploy new configuration.nix

  3. Get electrs onion address with format <onion-address>:<port>

    nodeinfo | jq -r .electrs.onion_address
    
  4. Connect to electrs

    Make sure Tor is running on Desktop or as Orbot on Android.

    On Desktop

    electrum --oneserver -1 -s "<electrs onion address>:t" -p socks5:127.0.0.1:9050
    

    On Android

    Three dots in the upper-right-hand corner
    Network > Proxy mode: socks5, Host: 127.0.0.1, Port: 9050
    Network > Auto-connect: OFF
    Network > One-server mode: ON
    Network > Server: <electrs onion address>:t
    

Connect to bitcoinix node through the SSH onion service

  1. Get the SSH onion address (excluding the port suffix)

    ssh operator@bitcoin-node
    nodeinfo | jq -r .sshd.onion_address | sed 's/:.*//'
    
  2. Create a SSH key

    ssh-keygen -t ed25519 -f ~/.ssh/id_ed25519
    
  3. Place the ed25519 key’s fingerprint in the configuration.nix openssh.authorizedKeys.keys field like so

    # FIXME: Add your SSH pubkey
    services.openssh.enable = true;
    users.users.root = {
      openssh.authorizedKeys.keys = [ "<contents of ~/.ssh/id_ed25519.pub>" ];
    };
    
  4. Connect to your bitcoinix node’s SSH onion service, forwarding a local port to the bitcoinix node’s SSH server

    ssh -i ~/.ssh/id_ed25519 -L <random port of your choosing>:127.0.0.1:22 root@<SSH onion address>
    
  5. Edit your deployment tool’s configuration and change the node’s address to 127.0.0.1 and the ssh port to <random port of your choosing>. If you use krops as described in the installation tutorial, set target = "127.0.0.1:<random port of your choosing>"; in krops/deploy.nix.

  6. After deploying the new configuration, it will connect through the SSH tunnel you established in step iv. This also allows you to do more complex SSH setups that some deployment tools don’t support. An example would be authenticating with Trezor’s SSH agent, which provides extra security.

Initialize a Trezor for Bitcoin Core’s Hardware Wallet Interface

  1. Enable Trezor in configuration.nix

    Change

    # services.hardware-wallets.trezor = true;
    

    to

    services.hardware-wallets.trezor = true;
    
  2. Deploy new configuration.nix

  3. Check that your bitcoinix node recognizes your Trezor

    ssh operator@bitcoin-node
    lsusb
    

    Should show something relating to your Trezor

  4. If your Trezor has outdated firmware or is not yet initialized: Start your Trezor in bootloader mode

    Trezor v1

    Plug in your Trezor with both buttons depressed
    

    Trezor v2

    Start swiping your finger across your Trezor's touchscreen and plug in the USB cable when your finger is halfway through
    
  5. If your Trezor’s firmware is outdated: Update your Trezor’s firmware

    trezorctl firmware-update
    

    Follow the on-screen instructions

    Caution: This command will wipe your Trezor. If you already store Bitcoin on it, only do this with the recovery seed nearby.

  6. If your Trezor is not yet initialized: Set up your Trezor

    trezorctl reset-device -p
    

    Follow the on-screen instructions

  7. Find your Trezor

    hwi enumerate
    hwi -t trezor -d <path from previous command> promptpin
    hwi -t trezor -d <path> sendpin <number positions for the PIN as displayed on your device's screen>
    hwi enumerate
    
  8. Follow Bitcoin Core’s instructions on Using Bitcoin Core with Hardware Wallets to use your Trezor with bitcoin-cli on your bitcoinix node

clightning

Plugins

There is a number of plugins available for clightning. See Readme: Features → clightning or search.nixos.org for a complete list.

You can activate and configure these plugins like so:

services.clightning = {
    enable = true;
    plugins = {
        clboss.enable = true;
        clboss.min-onchain = 40000;
    };
};

Please have a look at the module for a plugin (e.g. clboss.nix) to learn its configuration options.

Trustedcoin

When services.clightning.tor.proxy is enabled, trustedcoin also uses Tor for all external connections by default. In this case, connections to block explorers can sometimes get blocked.

An example of clightning log error output when connections are getting blocked:

lightningd[5138]: plugin-trustedcoin estimatefees error: https://blockstream.info/api error: 403 Forbidden
lightningd[4933]: plugin-trustedcoin getblock error: got something that isn't a block hash: <html><head>...

To work around this and connect via clearnet instead, set this option:

services.clightning.plugins.trustedcoin.tor.proxy = false;