-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Check in a baseline so that we don't worry about losing files.
- Loading branch information
1 parent
e7feeef
commit 27fc4d2
Showing
5 changed files
with
567 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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!" | ||
|
Oops, something went wrong.