Skip to content

Commit

Permalink
Check in a baseline so that we don't worry about losing files.
Browse files Browse the repository at this point in the history
  • Loading branch information
monkey-jsun committed Oct 17, 2020
1 parent e7feeef commit 27fc4d2
Show file tree
Hide file tree
Showing 5 changed files with 567 additions and 2 deletions.
66 changes: 64 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,64 @@
# eroas
Electrum-running-on-a-stick (Eroas) runs Electrum wallet on a fingerprint protected USB disk securely and easily
# EROAS

EROAS stands for "Electrum Running On A Stick".
EROAS runs Electrum wallet on fingerprint-protected USB disk to achieve
cold-wallet security and warm-wallet convenience at a budget price.
It is meant to
operate like a safe or saving account for infrequent transactions (perhaps <1 transaction per day),
and is suitable to protect assets from anywhere from $1K to $10M USD.

To use EROAS, simply insert EROAS USB drive into PC/MacBook and boot
from it. Press your fingerprint to unlock the secure drive. Afterwards,
Electrum will start and guide you through the transactions.
Afterwards you shut down the machine, unplug the drive and store it
securely.


### Operating modes:

- Use EROAS with Tor to connect to open Electrum netowrk
- Use EROAS with a single designated Electrum server for better security and privacy

### Security features

- The system image is an unmutable ISO image, resistent to all persistent attacks.
- Data partition
- is password-protected crypto file system
- is on a hidden, secondary partiton
- is on a fingerprint-protect secure drive
- Networking
- In Tor mode, no incoming traffic is allowed
- In dedicated electrum server mode, no incoming traffic is allowed, and
only outgoing traffic allowed is for the dedicated server at dedicated
port
- Usual security measures in Electrum (e.g, wallet password)
- Every byte of code is generated from open source software and you can build from scratch
- Only use general purposed and open architecture hardware (PC/Mac/USB disks)

### Other features

- supported usb drives include:
- Lexar JumpDrive Fingerprint (https://www.lexar.com/portfolio_page/jumpdrive-fingerprint-f35-usb-3-0-flash-drive/)
- Eaget fingerprint pendrive
- support 2 ways to backup and restore
backup data partition as a backup file.
backup Electrum Mnemonic phrases
- support both mac and PC


### User experience

One-time preparation
- (optional) Build EROAS ISO image from source
- Flash ISO image to the USB public drive

Running
- Insert USB into any PC or Mac and boot from the USB drive.
- Press finger to unlock secure drive
- if it is first time running
- Upon prompt, select and enter password for encrypted filesystem
- Select Electrum network options: using Tor or using a trusted server.
- Otherwise
- Upon prompt, enter password for encrypted filesystem
- Electrum wallet will start automatically. Follow its UI to create wallet and start transactions.
- Power down machine after every use.
231 changes: 231 additions & 0 deletions build_eros.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,231 @@
#!/bin/bash

set -e # exit on error
set -o pipefail # exit on pipeline error
set -u # treat unset variable as error
#set -x

SCRIPT_DIR="$(dirname "$(readlink -f "$0")")"
CHROOT_DIR=$SCRIPT_DIR/chroot

CMD=(setup_host debootstrap run_chroot build_iso)

DATE=`TZ="UTC" date +"%y%m%d-%H%M%S"`

function help() {
# if $1 is set, use $1 as headline message in help()
if [ -z ${1+x} ]; then
echo -e "This script builds EROAS (Electrum-Running-On-A-Stick)"
echo -e
else
echo -e $1
echo
fi
echo -e "Supported commands : ${CMD[*]}"
echo -e
echo -e "Syntax: $0 [start_cmd] [-] [end_cmd]"
echo -e "\trun from start_cmd to end_end"
echo -e "\tif start_cmd is omitted, start from first command"
echo -e "\tif end_cmd is omitted, end with last command"
echo -e "\tenter single cmd to run the specific command"
echo -e "\tenter '-' as only argument to run all commands"
echo -e
exit 0
}

function find_index() {
local ret;
local i;
for ((i=0; i<${#CMD[*]}; i++)); do
if [ "${CMD[i]}" == "$1" ]; then
index=$i;
return;
fi
done
help "Command not found : $1"
}

function check_host() {
local os_ver;
os_ver=`lsb_release -d | grep "Ubuntu 20.04"`
if [[ $os_ver == "" ]]; then
echo "WARNING : OS is not Ubuntu 20.04 and is untested"
fi

if [ $(id -u) -eq 0 ]; then
echo "This script should not be run as 'root'"
exit 1
fi
}

function setup_host() {
echo "=====> running setup_host ..."
sudo apt update
sudo apt install -y binutils debootstrap squashfs-tools xorriso grub-pc-bin grub-efi-amd64-bin mtools
sudo mkdir -p $CHROOT_DIR
}

function debootstrap() {
echo "=====> running debootstrap ... will take a couple of minutes ..."
sudo debootstrap --arch=amd64 --variant=minbase focal $CHROOT_DIR http://us.archive.ubuntu.com/ubuntu/
}

function run_chroot() {
echo "=====> running run_chroot ..."
sudo mount --bind /dev $CHROOT_DIR/dev
sudo mount --bind /run $CHROOT_DIR/run

sudo ln -f $SCRIPT_DIR/chroot_build.sh $CHROOT_DIR/root/chroot_build.sh
sudo chroot $CHROOT_DIR /root/chroot_build.sh -

sudo umount $CHROOT_DIR/dev
sudo umount $CHROOT_DIR/run
}

function build_iso() {
echo "=====> running build_iso ..."

mkdir -p image/{casper,isolinux,install}

# copy kernel files
sudo cp chroot/boot/vmlinuz-**-**-generic image/casper/vmlinuz
sudo cp chroot/boot/initrd.img-**-**-generic image/casper/initrd

# grub
touch image/ubuntu
cat <<EOF > image/isolinux/grub.cfg
search --set=root --file /ubuntu
insmod all_video
set default="0"
set timeout=30
menuentry "Run EROAS (Electrum Running On A Stick)" {
linux /casper/vmlinuz boot=casper nopersistent toram quiet splash ---
initrd /casper/initrd
}
menuentry "Check disc for defects" {
linux /casper/vmlinuz boot=casper integrity-check quiet splash ---
initrd /casper/initrd
}
EOF

# generate manifest
sudo chroot chroot dpkg-query -W --showformat='${Package} ${Version}\n' | sudo tee image/casper/filesystem.manifest
sudo cp -v image/casper/filesystem.manifest image/casper/filesystem.manifest-desktop
sudo sed -i '/ubiquity/d' image/casper/filesystem.manifest-desktop
sudo sed -i '/casper/d' image/casper/filesystem.manifest-desktop
sudo sed -i '/discover/d' image/casper/filesystem.manifest-desktop
sudo sed -i '/laptop-detect/d' image/casper/filesystem.manifest-desktop
sudo sed -i '/os-prober/d' image/casper/filesystem.manifest-desktop

# compress rootfs
sudo mksquashfs chroot image/casper/filesystem.squashfs
printf $(sudo du -sx --block-size=1 chroot | cut -f1) > image/casper/filesystem.size

# create diskdefines
cat <<EOF > image/README.diskdefines
#define DISKNAME Electrum Running on Stick
#define TYPE binary
#define TYPEbinary 1
#define ARCH amd64
#define ARCHamd64 1
#define DISKNUM 1
#define DISKNUM1 1
#define TOTALNUM 0
#define TOTALNUM0 1
EOF

# create iso image
cd $SCRIPT_DIR/image
grub-mkstandalone \
--format=x86_64-efi \
--output=isolinux/bootx64.efi \
--locales="" \
--fonts="" \
"boot/grub/grub.cfg=isolinux/grub.cfg"

(
cd isolinux && \
dd if=/dev/zero of=efiboot.img bs=1M count=10 && \
sudo mkfs.vfat efiboot.img && \
LC_CTYPE=C mmd -i efiboot.img efi efi/boot && \
LC_CTYPE=C mcopy -i efiboot.img ./bootx64.efi ::efi/boot/
)

grub-mkstandalone \
--format=i386-pc \
--output=isolinux/core.img \
--install-modules="linux16 linux normal iso9660 biosdisk memdisk search tar ls" \
--modules="linux16 linux normal iso9660 biosdisk search" \
--locales="" \
--fonts="" \
"boot/grub/grub.cfg=isolinux/grub.cfg"

cat /usr/lib/grub/i386-pc/cdboot.img isolinux/core.img > isolinux/bios.img

sudo /bin/bash -c "(find . -type f -print0 | xargs -0 md5sum | grep -v -e 'md5sum.txt' -e 'bios.img' -e 'efiboot.img' > md5sum.txt)"

sudo xorriso \
-as mkisofs \
-iso-level 3 \
-full-iso9660-filenames \
-volid "Electrum Running On Stick" \
-eltorito-boot boot/grub/bios.img \
-no-emul-boot \
-boot-load-size 4 \
-boot-info-table \
--eltorito-catalog boot/grub/boot.cat \
--grub2-boot-info \
--grub2-mbr /usr/lib/grub/i386-pc/boot_hybrid.img \
-eltorito-alt-boot \
-e EFI/efiboot.img \
-no-emul-boot \
-append_partition 2 0xef isolinux/efiboot.img \
-output "../eros-$DATE.iso" \
-m "isolinux/efiboot.img" \
-m "isolinux/bios.img" \
-graft-points \
"/EFI/efiboot.img=isolinux/efiboot.img" \
"/boot/grub/bios.img=isolinux/bios.img" \
"."
}

# ============= main ================

check_host

# check number of args
if [[ $# == 0 || $# > 3 ]]; then help; fi

# loop through args
dash_flag=false
start_index=0
end_index=${#CMD[*]}
for ii in "$@";
do
if [[ $ii == "-" ]]; then
dash_flag=true
continue
fi
find_index $ii
if [[ $dash_flag == false ]]; then
start_index=$index
else
end_index=$(($index+1))
fi
done
if [[ $dash_flag == false ]]; then
end_index=$(($start_index + 1))
fi

#loop through the commands
for ((ii=$start_index; ii<$end_index; ii++)); do
${CMD[ii]}
done

echo "$0 - Initial build is done!"

Loading

0 comments on commit 27fc4d2

Please sign in to comment.