#!/usr/bin/env bash set -e export LOG_FILE=/tmp/install.log CERT_DIR=/etc/ssl/certs KEY_DIR=/etc/ssl/private CONFIG_DIR=/etc/lamassu MIGRATE_STATE_PATH=$CONFIG_DIR/.migrate LAMASSU_CA_PATH=$CERT_DIR/Lamassu_CA.pem CA_KEY_PATH=$KEY_DIR/Lamassu_OP_Root_CA.key CA_PATH=$CERT_DIR/Lamassu_OP_Root_CA.pem SERVER_KEY_PATH=$KEY_DIR/Lamassu_OP.key SERVER_CERT_PATH=$CERT_DIR/Lamassu_OP.pem MNEMONIC_DIR=$CONFIG_DIR/mnemonics MNEMONIC_FILE=$MNEMONIC_DIR/mnemonic.txt BACKUP_DIR=/var/backups/postgresql BLOCKCHAIN_DIR=/mnt/blockchains OFAC_DATA_DIR=/var/lamassu/ofac ID_PHOTO_CARD_DIR=/opt/lamassu-server/idphotocard FRONTCAMERA_DIR=/opt/lamassu-server/frontcamera OPERATOR_DIR=/opt/lamassu-server/operatordata # Look into http://unix.stackexchange.com/questions/140734/configure-localtime-dpkg-reconfigure-tzdata decho () { echo `date +"%H:%M:%S"` $1 echo `date +"%H:%M:%S"` $1 >> $LOG_FILE } retry() { local -r -i max_attempts="$1"; shift local -r cmd="$@" local -i attempt_num=1 until $cmd do if (( attempt_num == max_attempts )) then echo echo "****************************************************************" echo "Attempt $attempt_num failed and there are no more attempts left! ($cmd)" return 1 else echo echo "****************************************************************" echo "Attempt $attempt_num failed! Trying again in $attempt_num seconds..." sleep $(( attempt_num++ )) fi done } rm -f $LOG_FILE cat <<'FIG' _ | | __ _ _ __ ___ __ _ ___ ___ _ _ ___ ___ _ ____ _____ _ __ | |/ _` | '_ ` _ \ / _` / __/ __| | | |_____/ __|/ _ \ '__\ \ / / _ \ '__| | | (_| | | | | | | (_| \__ \__ \ |_| |_____\__ \ __/ | \ V / __/ | |_|\__,_|_| |_| |_|\__,_|___/___/\__,_| |___/\___|_| \_/ \___|_| FIG echo -e "\nStarting \033[1mlamassu-server\033[0m install. This will take a few minutes...\n" if [ "$(whoami)" != "root" ]; then echo -e "This script has to be run as \033[1mroot\033[0m user" exit 3 fi release=$(lsb_release -rs) processor=$(uname -i) if [ "$release" != "16.04" ] || [ "$processor" != "x86_64" ]; then echo "You're attempting to install on an unsupported Linux distribution or release ("$release $processor")." echo uname -a echo echo "Please return to DigitalOcean and create a droplet running Ubuntu 16.04 x64 instead." exit 1 fi # So we don't run out of memory decho "Enabling swap file for install only..." fallocate -l 1G /swapfile >> $LOG_FILE 2>&1 chmod 600 /swapfile >> $LOG_FILE 2>&1 mkswap /swapfile >> $LOG_FILE 2>&1 swapon /swapfile >> $LOG_FILE 2>&1 IP=$(ifconfig eth0 | grep "inet" | grep -v "inet6" | awk -F: '{print $2}' | awk '{print $1}') decho "Updating system..." sleep 10 curl -sL https://deb.nodesource.com/setup_8.x | sudo -E bash - >> $LOG_FILE 2>&1 apt update >> $LOG_FILE 2>&1 decho "Installing necessary packages..." apt install nodejs python-minimal build-essential supervisor postgresql libpq-dev -y -q >> $LOG_FILE 2>&1 decho "Installing latest npm package manager for node..." retry 3 npm -g --unsafe-perm install npm@5 >> $LOG_FILE 2>&1 NODE_MODULES=$(npm -g root) NPM_BIN=$(npm -g bin) decho "Installing lamassu-server..." retry 3 npm -g --unsafe-perm install lamassu/lamassu-server#${1-master} >> $LOG_FILE 2>&1 decho "Generating mnemonic..." mkdir -p $MNEMONIC_DIR >> $LOG_FILE 2>&1 SEED=$(openssl rand -hex 32) MNEMONIC=$(bip39 $SEED) echo "$MNEMONIC" > $MNEMONIC_FILE decho "Creating postgres user..." POSTGRES_PW=$(hkdf postgres-pw $SEED) su -l postgres >> $LOG_FILE 2>&1 <> $LOG_FILE 2>&1 mkdir -p $CONFIG_DIR >> $LOG_FILE 2>&1 decho "Generating SSL certificates..." openssl genrsa \ -out $CA_KEY_PATH \ 4096 >> $LOG_FILE 2>&1 openssl req \ -x509 \ -sha256 \ -new \ -nodes \ -key $CA_KEY_PATH \ -days 3650 \ -out $CA_PATH \ -subj "/C=IS/ST=/L=Reykjavik/O=Lamassu Operator CA/CN=lamassu-operator.is" \ >> $LOG_FILE 2>&1 openssl genrsa \ -out $SERVER_KEY_PATH \ 4096 >> $LOG_FILE 2>&1 openssl req -new \ -key $SERVER_KEY_PATH \ -out /tmp/Lamassu_OP.csr.pem \ -subj "/C=IS/ST=/L=Reykjavik/O=Lamassu Operator/CN=$IP" \ -reqexts SAN \ -sha256 \ -config <(cat /etc/ssl/openssl.cnf \ <(printf "[SAN]\nsubjectAltName=IP.1:$IP")) \ >> $LOG_FILE 2>&1 openssl x509 \ -req -in /tmp/Lamassu_OP.csr.pem \ -CA $CA_PATH \ -CAkey $CA_KEY_PATH \ -CAcreateserial \ -out $SERVER_CERT_PATH \ -extfile <(cat /etc/ssl/openssl.cnf \ <(printf "[SAN]\nsubjectAltName=IP.1:$IP")) \ -extensions SAN \ -days 3650 >> $LOG_FILE 2>&1 rm /tmp/Lamassu_OP.csr.pem decho "Copying Lamassu certificate authority..." LAMASSU_CA_FILE=$NODE_MODULES/lamassu-server/Lamassu_CA.pem cp $LAMASSU_CA_FILE $LAMASSU_CA_PATH mkdir -p $OFAC_DATA_DIR cat < $CONFIG_DIR/lamassu.json { "postgresql": "postgres://lamassu_pg:$POSTGRES_PW@localhost/lamassu", "mnemonicPath": "$MNEMONIC_FILE", "lamassuCaPath": "$LAMASSU_CA_PATH", "caPath": "$CA_PATH", "certPath": "$SERVER_CERT_PATH", "keyPath": "$SERVER_KEY_PATH", "hostname": "$IP", "logLevel": "info", "migrateStatePath": "$MIGRATE_STATE_PATH", "blockchainDir": "$BLOCKCHAIN_DIR", "ofacDataDir": "$OFAC_DATA_DIR", "idPhotoCardDir": "$ID_PHOTO_CARD_DIR", "frontCameraDir": "$FRONTCAMERA_DIR", "operatorDataDir": "$OPERATOR_DIR" "strike": { "baseUrl": "https://api.strike.acinq.co/api/" }, "coinAtmRadar": { "url": "https://coinatmradar.info/api/lamassu/" }, "ofacSources": [ { "name": "sdn_advanced", "url": "https://www.treasury.gov/ofac/downloads/sanctions/1.0/sdn_advanced.xml" }, { "name": "cons_advanced", "url": "https://www.treasury.gov/ofac/downloads/sanctions/1.0/cons_advanced.xml" } ] } EOF decho "Setting up database tables..." lamassu-migrate >> $LOG_FILE 2>&1 decho "Setting up lamassu-admin..." ADMIN_REGISTRATION_URL=`lamassu-register admin 2>> $LOG_FILE` decho "Setting up backups..." BIN=$(npm -g bin) BACKUP_CMD=$BIN/lamassu-backup-pg mkdir -p $BACKUP_DIR BACKUP_CRON="@daily $BACKUP_CMD > /dev/null" (crontab -l 2>/dev/null || echo -n ""; echo "$BACKUP_CRON") | crontab - >> $LOG_FILE 2>&1 $BACKUP_CMD >> $LOG_FILE 2>&1 decho "Setting up firewall..." ufw allow ssh >> $LOG_FILE 2>&1 ufw allow 443/tcp >> $LOG_FILE 2>&1 # Admin ufw allow 3000/tcp >> $LOG_FILE 2>&1 # Server ufw allow 8071/tcp >> $LOG_FILE 2>&1 # Lamassu support ufw -f enable >> $LOG_FILE 2>&1 decho "Setting up supervisor..." cat < /etc/supervisor/conf.d/lamassu-server.conf [program:lamassu-server] command=${NPM_BIN}/lamassu-server autostart=true autorestart=true stderr_logfile=/var/log/supervisor/lamassu-server.err.log stdout_logfile=/var/log/supervisor/lamassu-server.out.log environment=HOME="/root" EOF cat < /etc/supervisor/conf.d/lamassu-admin-server.conf [program:lamassu-admin-server] command=${NPM_BIN}/lamassu-admin-server autostart=true autorestart=true stderr_logfile=/var/log/supervisor/lamassu-admin-server.err.log stdout_logfile=/var/log/supervisor/lamassu-admin-server.out.log environment=HOME="/root" EOF service supervisor restart >> $LOG_FILE 2>&1 decho "Disabling swap file..." swapoff /swapfile >> $LOG_FILE 2>&1 # disable exitting on error in case DO changes motd scripts set +e chmod -x /etc/update-motd.d/*-release-upgrade chmod -x /etc/update-motd.d/*-updates-available chmod -x /etc/update-motd.d/*-reboot-required chmod -x /etc/update-motd.d/*-help-text chmod -x /etc/update-motd.d/*-cloudguest set -e # reset terminal to link new executables hash -r echo decho "Done! Now it's time to configure Lamassu stack." echo echo -e "\n*** IMPORTANT ***" echo "In a private space, run lamassu-mnemonic, write down the words" echo "and keep them in a safe place." echo echo "This secret will allow you to retrieve system passwords, such " echo "as the keys to your Ethereum account. However, you must still " echo "backup your wallets separately. Visit support.lamassu.is for " echo "details on regularly backing up your wallets and coins." echo echo echo "Activation URL for lamassu-admin:" echo $ADMIN_REGISTRATION_URL