diff --git a/1A_-_Setting_up_a_Bitcoin-Core_VPS_by_Hand.md b/1A_-_Setting_up_a_Bitcoin-Core_VPS_by_Hand.md deleted file mode 100644 index fac53b0..0000000 --- a/1A_-_Setting_up_a_Bitcoin-Core_VPS_by_Hand.md +++ /dev/null @@ -1,168 +0,0 @@ -# Learning Bitcoin from the Command-Line # - -> NOTE: This is a draft in progress, so that I can get some feedback from early reviewers. It is not yet ready for learning. - -The best way to learn to learn deeply about bitcoin is to avoid GUIs (even bitcoin-qt), and instead learn it from the command line. This tutorial assumes that you have some minimal background of how to use a command line. If not, there are many tutorials available, and I have one for Mac users at https://github.com/ChristopherA/intro-mac-command-line - -## Installing a PRUNED Bitcoin Node on a VPS ## - -A pruned bitcoin node is a full node (in particular, a pruned node is NOT an SPV node), but it is smaller as doesn’t have all the history. - -In addition, the bitcoin.conf settings suggested here will minimalize the initial and ongoing bandwidth requirements, allow a $5 a month VPS to be great for learning and testing with bitcoin. - -This info works with both Linode and Digital Ocean, so should work with more VPSs and local virtual machines. - -> NOTE: Don’t use a VPS for a bitcoin wallet with significant real funds— see http://blog.thestateofme.com/2012/03/03/lessons-to-be-learned-from-the-linode-bitcoin-incident/ — it is just very nice to be able experiment with real bitcoin transactions on a live full node without tying up a self-hosted server on a home network. I’ve also found it useful to be able to use an iPhone or iPad to communicate via SSH to my VPS to do some simple bitcoin tasks. -> - -If you don’t have a Linode or DG account, signup using these codes will give you roughly a month of free time. - -* Linode Referral Code: https://www.linode.com/?r=3c7fa15a78407c9a3d4aefb027539db2557b3765 -* Digital Ocean: http://www.digitalocean.com/?refcode=a6060686b88a - -I slightly prefer Linode, because there is a scripting capability called a "StackScript" for creating VPS'es that I plan to use to automate some of these installation functions. - -> IMPORTANT: First, you’ll should to copy the httpS URL for most recent bitcoin linux distribution from https://bitcoin.org/en/download as well the most recently httpS URL for the signatures for that release, and you will need the URL for the bitcoin signing keys for versionpast v0.11.+ . I have included what they were as of writing this tutorial, but you should not rely on them — always verify your bitcoin distribution! - -On the the VPS, create the minimal (~$5/m) VPS with Debian 8. Startup the VPS and use the IP address that your VPS dashboard shows you. - -``` -ssh root@162.243.130.224 - -uname -a # Should be "Linux debian", and give distribution release "4.8.6-x86_64-linode78" -lsb_release -a #Should report 8.6 or better (this script tested on debian 8.6) - - -hostnamectl set-hostname bitcoincore-pruned.local # You may not need to do this on Digital Ocean - -nano /etc/hosts #add "127.0.0.1 bitcoincore-pruned.local" to hosts file. - -dpkg-reconfigure tzdata - -date # confirm that this shows your correct time zone - -# we should update debian to latest security fixes - -apt-get update; apt-get upgrade; apt-get dist-upgrade - -# keep debian updates -echo "unattended-upgrades unattended-upgrades/enable_auto_updates boolean true" | debconf-set-selections -apt-get -y install unattended-upgrades - -# we need to update iptables to use bitcoin ports - -iptables -A INPUT -p tcp --dport 22 -m conntrack --ctstate NEW,ESTABLISHED -j ACCEPT -iptables -A INPUT -p tcp --dport 8333 -j ACCEPT -iptables -A INPUT -m conntrack --ctstate ESTABLISHED -j ACCEPT -iptables -A INPUT -i lo -j ACCEPT -iptables -P INPUT DROP -iptables -P FORWARD DROP - -ip6tables -A INPUT -p tcp --dport 22 -m conntrack --ctstate NEW,ESTABLISHED -j ACCEPT -ip6tables -A INPUT -p tcp --dport 8333 -j ACCEPT -ip6tables -A INPUT -m conntrack --ctstate ESTABLISHED -j ACCEPT -ip6tables -A INPUT -i lo -j ACCEPT -ip6tables -P INPUT DROP -ip6tables -P FORWARD DROP - -echo "iptables-persistent iptables-persistent/autosave_v4 boolean true" | debconf-set-selections -echo "iptables-persistent iptables-persistent/autosave_v6 boolean true" | debconf-set-selections -apt-get -y install iptables-persistent - -adduser user1 - -adduser user1 sudo - -reboot - -ssh user1@45.33.46.147 - -sudo apt-get install haveged # Installs random number tools — otherwise gpg will not have enough randomness on a VPS - -## TODO: rng-tools may be installed by haveged -- if working remove these -#sudo apt-get install rng-tools -#/etc/init.d/rng-tools start -#sudo /usr/sbin/rngd -r /dev/urandom # Initialize randomness pool -#cat /dev/urandom | rngtest -c 1000 # check randomness pool - -## TODO: make sure haveged is properly initialized, and that it will be started on boot - -gpg --gen-key # create a key for this VPS (I don't the name of this machine as the email address — all other questions I press return - #TODO: I'm not absolutely sure that we need to do this — it is only required for fully qualified --verify if an --lsign is done of the import. - -# get current values for these URLs from https://bitcoin.org/en/download — make sure that they are HTTPS not HTTP urls. - -wget https://bitcoin.org/bin/bitcoin-core-0.13.2/bitcoin-0.13.2-x86_64-linux-gnu.tar.gz -wget https://bitcoin.org/bin/bitcoin-core-0.13.2/SHA256SUMS.asc -wget https://bitcoin.org/laanwj-releases.asc - ## TODO: validate the release key, for instance, it is the same as in the keyserver i.e. gpg --recv-keys 0x01EA5486DE18A882D4C2684590C8019E36C2E964 -gpg --import laanwj-releases.asc - gpg --list-keys - gpg --lsign 36C2E964 # laanwj's bitcoin release key just imported ## -gpg --verify SHA256SUMS.asc -# You should see a 'good signature', for example: -# gpg: Signature made Tue 03 Jan 2017 12:20:59 AM PST using RSA key ID 36C2E964 -# gpg: Good signature from "Wladimir J. van der Laan (Bitcoin Core binary release signing key) " - -cat SHA256SUMS.asc -sha256sum bitcoin-0.13.2-x86_64-linux-gnu.tar.gz -# SHA256 hashes should match - -tar xzf bitcoin-0.13.2-x86_64-linux-gnu.tar.gz -sudo install -m 0755 -o root -g root -t /usr/local/bin bitcoin-0.13.2/bin/* -rm bitcoin-0.13.2-x86_64-linux-gnu.tar.gz -rm -rf bitcoin-0.13.2/ - -mkdir ~/.bitcoin -echo -e "server=1\ndbcache=1536\npar=1\nblocksonly=1\nprune=550\nmaxuploadtarget=137\nmaxconnections=16\nrpcuser=bitcoinrpc\nrpcpassword=$(xxd -l 16 -p /dev/urandom)" > ~/.bitcoin/bitcoin.conf -chmod 600 ~/.bitcoin/bitcoin.conf -more ~/.bitcoin/bitcoin.conf - -bitcoind -daemon #start bitcoin - -``` -Note: it may take up to several minutes for Bitcoin Core to start, during which it will display the following message whenever you use bitcoin-cli: - `error: {"code":-28,"message":"Verifying blocks..."}` - -Also useful is this command, the same number (your local getblockcount = the remote blockchain.info's getblockcount) then your pruned node is ready (about a day). - -``` -echo `bitcoin-cli getblockcount 2>&1`/`wget -O - http://blockchain.info/q/getblockcount 2>/dev/null` -``` - -### Useful aliases to add to .bash_profile - -``` -alias btcdir="cd ~/.bitcoin/" #linux default bitcoind path - # alias btcdir="cd ~/Library/Application\ Support/Bitcoin/" #mac default bitcoind path -alias bc="bitcoin-cli" -alias bd="bitcoind" -alias btcinfo='bitcoin-cli getinfo | egrep "\"version\"|balance|blocks|connections|errors"' -alias btcblock="echo `bitcoin-cli getblockcount 2>&1`/`wget -O - http://blockchain.info/q/getblockcount 2>/dev/null`" -``` - -### Useful commands - -``` -bc help -bc getblockchaininfo -bc getnetworkinfo -bc getnettotals -bc getwalletinfo -bc stop -``` - - -### Some tutorials once you've got bitcoin installed and up-to-date - -- Bitcoin.org's developer examples https://bitcoin.org/en/developer-examples#transactions -- Jonas Nick's "How to Run a Bitcoin Node" https://github.com/jonasnick/bitcoin-node -- David DeRosa's "A Developer Oriented Series about Bitcoin" http://davidederosa.com/basic-blockchain-programming/ - -Videos - -- Bitcoin JSON-RPC Tutorial 1 https://www.youtube.com/watch?v=ygNit44dQHA -- Bitcoin JSON-RPC Tutorial 2 - VPS Setup https://www.youtube.com/watch?v=ygNit44dQHA -- Bitcoin JSON-RPC Tutorial 3 - bitcoin.conf https://www.youtube.com/watch?v=W54aRszkEOI&t=65s -- Bitcoin JSON-RPC Tutorial 4 - Command Line Interface https://www.youtube.com/watch?v=vmdYD7vutTI -- Bitcoin JSON-RPC Tutorial 5 - Your First Calls https://www.youtube.com/watch?v=ARL_PvDEBtU diff --git a/Linode_Bitcoin-Core_VPS_Setup.stackscript b/Linode_Bitcoin-Core_VPS_Setup.stackscript new file mode 100644 index 0000000..034dce4 --- /dev/null +++ b/Linode_Bitcoin-Core_VPS_Setup.stackscript @@ -0,0 +1,364 @@ +#!/bin/bash + +#### +# This is a Linode StackScript https://www.linode.com/stackscripts/ for deploying +# a Bitcoin node optimized for use on a VPS, for learning or testing purposes. +# +# WARNING: Don’t use a VPS for a bitcoin wallet with significant real funds — see +# http://blog.thestateofme.com/2012/03/03/lessons-to-be-learned-from-the-linode-bitcoin-incident/ +# it is just very nice to be able experiment with real bitcoin transactions on +# a live node without tying up a self-hosted server on a local network. I’ve +# also found it useful to be able to use an iPhone or iPad to communicate via +# SSH to my VPS to do some simple bitcoin tasks. +#### + +# This block defines the variables the user of the script needs to input +# when deploying using this script. +# +# +# BTCTYPE= +# +# HOSTNAME= +# +# FQDN= +# +# USERPASSWORD= +# +# SSH_KEY= +# +# SYS_SSH_IP= + +#### +# 0. Set Initial Variables +#### + +# CURRENT BITCOIN RELEASE: +# Change as necessary + +export BITCOIN=bitcoin-core-0.13.2 + +# Set the variable $IPADDR to the IP address the new Linode receives. +IPADDR=$(/sbin/ifconfig eth0 | awk '/inet / { print $2 }' | sed 's/addr://') + +# Output stdout and stderr to ~root files + +exec > >(tee -a /root/stackscript.log) 2> >(tee -a /root/stackscript.log /root/stackscript.err >&2) + +echo "$0 - BEGINNING NEW MACHINE SETUP STACKSCRIPT" + +#### +# 1. Update Hostname +#### + +echo $HOSTNAME > /etc/hostname +/etc/init.d/hostname.sh start +/bin/hostname $HOSTNAME + +echo "$0 - Set hostname as $FQDN ($IPADDR)" +echo "$0 - TODO: Put $FQDN with IP $IPADDR in your main DNS file." + +# Add localhost aliases + +echo "127.0.0.1 localhost" > /etc/hosts +echo "127.0.1.1 $FQDN $HOSTNAME" >> /etc/hosts + +echo "$0 - Set localhost" + +#### +# 2. Update Timezone +#### + +# Set Timezone to America/LA + +TIMEZONE="America/Los_Angeles" +echo $TIMEZONE > /etc/timezone +cp /usr/share/zoneinfo/${TIMEZONE} /etc/localtime + +echo "$0 - Set Time Zone to Lost Angeles" + +#### +# 3. Protect the Server +#### + +# Add firewall rules to block everything that's not Bitcoin, Ping, or SSH + +cat > /etc/iptables.firewall.rules < /etc/ip6tables.firewall.rules + +# Make a startup file that runs IPv4 and IPv6 rules + +cat > /etc/network/if-pre-up.d/firewall <> /etc/hosts.allow + +else + echo "$0 - There were no SSH IPs to set: $SYS_SSH_IP; you will not be able to SSH in!" +fi + +# Block SSH access from everywhere else + +# Yes, this means that if you don't have an IP address for SSH, you can only login +# from Linode's Lish Console + +echo "sshd: ALL" >> /etc/hosts.deny +echo "$0 - Limited SSH access." + + +#### +# 4. Set Up User +#### + +# Create "user1" with optional password and give them sudo capability + +/usr/sbin/useradd -m -p `perl -e 'printf("%s\n",crypt($ARGV[0],"password"))' "$USERPASSWORD"` -g sudo -s /bin/bash user1 +/usr/sbin/adduser user1 sudo + +echo "$0 - Setup user1 with sudo access." + +# Set up SSH Key + +if [ -n "$SSH_KEY" ]; then + + mkdir ~user1/.ssh + echo "$SSH_KEY" >> ~user1/.ssh/authorized_keys + chown -R user1 ~user1/.ssh + + echo "$0 - Added .ssh key to user1." + +fi + +# Give user some helpful bitcoin aliases + +sudo -u user1 cat >> ~user1/.bash_profile <&1 | grep "Good signature"` + +if [[ $SHASIG ]]; then + echo "VERIFICATION SUCCESS / SIG: $SHASIG" +else + (>&2 echo "VERIFICATION ERROR: Signature for Bitcoin did not verify!") +fi + +# Verify Bitcoin: SHA + +export TARSHA256=`/usr/bin/sha256sum ~user1/$BITCOINPLAIN-x86_64-linux-gnu.tar.gz | awk '{print $1}'` +export EXPECTEDSHA256=`cat ~user1/SHA256SUMS.asc | grep $BITCOINPLAIN-x86_64-linux-gnu.tar.gz | awk '{print $1}'` + +if [ "$TARSHA256" == "$EXPECTEDSHA256" ]; then + echo "VERIFICATION SUCCESS / SHA: $TARSHA256" +else + (>&2 echo "VERIFICATION ERROR: SHA for Bitcoin did not match!") +fi + +# Install Bitcoin + +echo "$0 - Installinging Bitcoin." + +sudo -u user1 /bin/tar xzf ~user1/$BITCOINPLAIN-x86_64-linux-gnu.tar.gz -C ~user1 +/usr/bin/install -m 0755 -o root -g root -t /usr/local/bin ~user1/$BITCOINPLAIN/bin/* +/bin/rm -rf ~user1/$BITCOINPLAIN/ + +# Start Up Bitcoin + +echo "$0 - Starting Bitcoin." + +sudo -u user1 /bin/mkdir ~user1/.bitcoin + +# The only variation between Mainnet and Testnet is that Testnet has the "testnet=1" variable +# The only variation between Regular and Pruned is that Pruned has the "prune=550" variable, which is the smallest possible prune + +# TODO: need to test rpcpassword random below using EOF technique + +# TODO: since these are largely the same, maybe another technique? + +if [ "$BTCTYPE" == "Mainnet" ]; then + +cat >> ~user1/.bitcoin/bitcoin.conf << EOF +server=1 +dbcache=1536 +par=1 +blocksonly=1 +maxuploadtarget=137 +maxconnections=16 +rpcuser=bitcoinrpc +rpcpassword=$(xxd -l 16 -p /dev/urandom) +EOF + +elif [ "$BTCTYPE" == "Pruned Mainnet" ]; then + +cat >> ~user1/.bitcoin/bitcoin.conf << EOF +server=1 +dbcache=1536 +par=1 +blocksonly=1 +prune=550 +maxuploadtarget=137 +maxconnections=16 +rpcuser=bitcoinrpc +rpcpassword=$(xxd -l 16 -p /dev/urandom) +EOF + +elif [ "$BTCTYPE" == "Testnet" ]; then + +cat >> ~user1/.bitcoin/bitcoin.conf << EOF +server=1 +dbcache=1536 +par=1 +blocksonly=1 +maxuploadtarget=137 +maxconnections=16 +testnet=1 +rpcuser=bitcoinrpc +rpcpassword=$(xxd -l 16 -p /dev/urandom) +EOF + +elif [ "$BTCTYPE" == "Pruned Testnet" ]; then + +cat >> ~user1/.bitcoin/bitcoin.conf << EOF +server=1 +dbcache=1536 +par=1 +blocksonly=1 +prune=550 +maxuploadtarget=137 +maxconnections=16 +testnet=1 +rpcuser=bitcoinrpc +rpcpassword=$(xxd -l 16 -p /dev/urandom) +EOF + +elif [ "$BTCTYPE" == "Private Regtest" ]; then + + (>&2 echo "$0 - ERROR: Private Regtest is not setup yet.") + +else + + (>&2 echo "$0 - ERROR: Somehow you managed to select no Bitcoin Installation Type, so Bitcoin hasn't been properly setup. Whoops!") + +fi + +/bin/chown user1 ~user1/.bitcoin/bitcoin.conf +/bin/chmod 600 ~user1/.bitcoin/bitcoin.conf + +sudo -u user1 /usr/local/bin/bitcoind -daemon + +# Add Bitcoin Startup to Crontab for User1 + +sudo -u user1 sh -c '( /usr/bin/crontab -l -u user1 2>/dev/null; echo "@reboot /usr/local/bin/bitcoind -daemon" ) | /usr/bin/crontab -u user1 -' + +# Alert User! + +sudo -u user1 touch ~user1/BITCOIN-IS-READY + +echo "$0 - ENDING NEW MACHINE SETUP STACKSCRIPT"