- nix - a language
- nix - a packaging system
- nixOS - a linux distribution
- nix-bitcoin - packages and modules which turn a
nixOS
host into a bitcoin node
Setting up a nix-bitcoin
node is divided into two phases:
- Preparing host machine and installing the
nixOS
Linux distribution to it - Creating a
nix
deployment environment on a different machine, and then deploying thenix-bitcoin
packages and modules to thenixOS
host machine. Going forward, this machine will act as your terminal from which you will administrate your bitcoin node.
On a separate machine:
$ ssh-keygen -t ed25519
$ cat ~/.ssh/id_ed25519.pub
Save the generated private and public keys for use in the nix configuration and the remote deployment machine
Download the image from https://nixos.org/download.html#nixos-iso
Burn it to a USB drive or disc: sudo dd if=nix.iso of=/dev/rdiskN
Edit your BIOS UEFI / Boot order settings accordingly
Depending on number of drives, performance needs, and risk tolerance for failure scenarios, other setups may vary wildly. You can pool multiple disks together with no redundancy, mirror
for replication, or use parity options like raidz1
/raidz2
/raidz3
.
This setup will make use of 6 disks in a raidz2
configuration.
Set up environment variables
$ $DISK1=/dev/disk/by-id/ata-WDC_WD40EFZX-68AWUN0_WD-WX12DUUUUUUU
$ $DISK2=/dev/disk/by-id/ata-WDC_WD40EFZX-68AWUN0_WD-WX12DVVVVVVV
$ $DISK3=/dev/disk/by-id/ata-WDC_WD40EFZX-68AWUN0_WD-WX12DWWWWWWW
$ $DISK4=/dev/disk/by-id/ata-WDC_WD40EFZX-68AWUN0_WD-WX12DXXXXXXX
$ $DISK5=/dev/disk/by-id/ata-WDC_WD40EFZX-68AWUN0_WD-WX12DYYYYYYY
$ $DISK6=/dev/disk/by-id/ata-WDC_WD40EFZX-68AWUN0_WD-WX12DZZZZZZZ
Create the EFI
boot partition
$ sgdisk -n3:1M:+512M -t3:EF00 $DISK1
Create the OS partition
$ sgdisk -n1:0:0 -t1:BF01 $DISK1
Copy the partition table across all devices
$ sfdisk --dump $DISK1 | sfdisk $DISK2
$ sfdisk --dump $DISK1 | sfdisk $DISK3
$ sfdisk --dump $DISK1 | sfdisk $DISK4
$ sfdisk --dump $DISK1 | sfdisk $DISK5
$ sfdisk --dump $DISK1 | sfdisk $DISK6
Format the boot partitions:
$ mkfs.vfat $DISK1-part3
$ mkfs.vfat $DISK2-part3
$ mkfs.vfat $DISK3-part3
$ mkfs.vfat $DISK4-part3
$ mkfs.vfat $DISK5-part3
$ mkfs.vfat $DISK6-part3
$ zpool create -o ashift=12 -O atime=off -O encryption=aes-256-gcm \
-O acltype=posixacl -O keyformat=passphrase -O xattr=sa \
-O mountpoint=none -O compression=lz4 \
zroot raidz2 \
$DISK1-part1 $DISK2-part1 $DISK3-part1 \
$DISK4-part1 $DISK5-part1 $DISK6-part1
(At this point, you will be prompted for a disk encryption passphrase)
Create the zfs
filesystems:
$ zfs create -o mountpoint=none zroot/root
$ zfs create -o mountpoint=legacy zroot/root/nixos
$ zfs create -o mountpoint=legacy zroot/var
$ zfs create -o mountpoint=legacy zroot/home
Mount the Nixos
root and create child mountpoints:
$ mount -t zfs zroot/root/nixos /mnt
$ mkdir /mnt/home
$ mkdir /mnt/var
$ mkdir /mnt/boot
Mount the child filesystem mountpoints and EFI
boot partition:
$ mount -t zfs zroot/home /mnt/home
$ mount -t zfs zroot/var /mnt/var
$ mount /mnt/boot $DISK1-part3
$ nixos-generate-config --root /mnt
Get the HOST ID of the machine, save it for later:
$ head -c 8 /etc/machine-id
Note that openssh.authorizedKeys.keys
item value is the contents of your ssh public key file (id_ed25519.pub
)
boot.loader.systemd-boot.enable = true;
boot.loader.efi.canTouchEfiVariables = true;
boot.supportedFilesystems = [ "zfs" ];
boot.zfs.requestEncryptionCredentials = true;
networking.hostName = "nixnode";
networking.hostId = "[HOST ID GOES HERE]";
time.timeZone = "UTC";
users.users.root = {
openssh.authorizedKeys.keys=[
"ssh-ed25519 AAAA... user@nix-bitcoin-deploy"
];
}
environment.systemPackages = with pkgs; [
vim
wget
curl
git
];
services.openssh.enable = true;
services.openssh.permitRootLogin="yes";
services.zfs.autoSnapshot.enable = true;
services.zfs.autoScrub.enable = true;
$ nixos-install
(You will be prompted to create the root password)
$ ifconfig
$ sudo apt install curl git gnupg2 dirmgr
$ curl -o install-nix-2.7.0 https://releases.nixos.org/nix/nix-2.7.0/install
$ curl -o install-nix-2.7.0.asc https://releases.nixos.org/nix/nix-2.7.0/install.asc
$ gpg2 --keyserver hkps://keyserver.ubuntu.com --recv-keys B541D55301270E0BCF15CA5D8170B4726D7198DE
$ gpg2 --verify ./install-nix-2.7.0.asc
$ sh ./install-nix-2.7.0 --daemon
$ git clone https://github.com/fort-nix/nix-bitcoin
$ cd nix-bitcoin/examples
$ nix-shell
$ fetch-release > nix-bitcoin-release.nix
$ cd ../../
$ mkdir nix-bitcoin-node
$ cd nix-bitcoin-node
$ cp -r ../nix-bitcoin/examples/{nix-bitcoin-release.nix,configuration.nix,shell.nix,krops,.gitignore} .
Copy the id_ed25519
ssh private key to ~/.ssh
Change the permissions of the private key:
$ chmod go-rwx ~/.ssh/id_ed25519
in ~/.ssh/config
:
Host bitcoin-node
Hostname [NIXOS HOST IP ADDRESS GOES HERE]
IdentityFile ~/.ssh/id_ed25519
User operator
PubkeyAuthentication yes
AddKeysToAgent yes
Edit nix-bitcoin-node/krops/deploy.nix
:
target = "root@bitcoin-node";
Retrieve remote nixOS hardware-configuration.nix and configuration.nix:
$ scp bitcoin-node:/etc/nixos/hardware-configuration.nix hardware-configuration.nix
$ scp bitcoin-node:/etc/nixos/configuration.nix remote-configuration.nix
Edit the nix-bitcoin-node/configuration.nix
{ config, pkgs, lib, ... }: {
imports = [
<nix-bitcoin/modules/presets/secure-node.nix>
<nix-bitcoin/modules/presets/hardened.nix>
./hardware-configuration.nix
./remote-configuration.nix
];
### CLIGHTNING
services.clightning.enable = true;
services.clightning.plugins.clboss.enable = true;
services.clightning.plugins.summary.enable = true;
services.clightning.extraConfig = ''
alias=my_nix_node
'';
### RIDE THE LIGHTNING
services.rtl.enable = true;
services.rtl.nodes.clightning = true;
### ELECTRS
services.electrs.enable = true;
nix-bitcoin.configVersion = "0.0.65";
}
Enter deployment environment:
$ nix-shell
$ deploy
Following deployment, you will have a bitcoin node. Do not be surprised if resource use is intensive for hours or perhaps a couple days. bitcoind
will perform its download and validation of the entire blockchain (less than half a terabyte, given pruning wasn't enabled), and c-lightning
will also take some time to bootstrap following bitcoind
's initial block download (IBD).
To access your node:
ssh bitcoin-node
By default, the node will not allow connections over the local network or the internet (tor is allowed). If you don't want to change this, you can still tunnel traffic to RTL via your SSH connection.
Alter your ~/.ssh/config
to add port forwarding to the bitcoin-node Host
configuration:
Host bitcoin-node
Hostname [NIXOS HOST IP ADDRESS GOES HERE]
...
LocalForward 3000 localhost:3000
Once you've configured forwarding, connect to your node from your deployment machine:
ssh bitcoin-node
While you're in an SSH terminal session, grab the RTL password:
cat /var/src/secrets/rtl-password
on the deployment machine, open a browser and navigate to http://localhost:3000
.
Use the RTL password to log in
- Your local subnet is
192.168.1.1
through192.168.1.255
- You have enabled Core Lightning (
clightning
) and Ride the Lightning (rtl
) in your deploymentconfiguration.nix
:services.clightning.enable = true; services.rtl.enable = true; services.rtl.nodes.clightning = true;
In your deployment configuration.nix
file, either add or edit the networking.firewall.extraCommands settings:
networking.firewall.extraCommands = ''
iptables -A nixos-fw -p tcp --source 192.168.1.0/24 --dport 3001 -j nixos-fw-accept
iptables -A nixos-fw -p udp --source 192.168.1.0/24 --dport 3001 -j nixos-fw-accept
iptables -A nixos-fw -p tcp --source 192.168.1.0/24 --dport 4001 -j nixos-fw-accept
iptables -A nixos-fw -p udp --source 192.168.1.0/24 --dport 4001 -j nixos-fw-accept
'';
and widen up the cl-rest
service's allowed IP addresses. :
systemd.services.cl-rest.serviceConfig.IPAddressAllow = lib.mkForce "127.0.0.1/32 ::1/128 169.254.0.0/16 192.168.1.0/24";
In your deployment environment's configuration.nix
file, either add or edit the clightning extraConfig
setting:
services.clightning.extraConfig = ''
alias=bad_for_education
'';