#!/bin/bash echo ">>> Loading configuration file"; source clone.conf; echo "<<< done"; [ ! -e ./tmp -o ! -d ./tmp ] && mkdir ./tmp; [ ! -e ./server -o ! -d ./server ] && mkdir ./server; [ ! -e ./server/maintenance -o ! -d ./server/maintenance ] && mkdir ./server/maintenance; # [!] Check parameter : device file #========================================================# echo ">>> [!] Checking parameter : device"; # (1) Check parameter existence # test $# -lt 1 && echo "Missing parameter : device" && exit; # (2) Check USB and not a hard drive !!!!!!!!!! # device_type=$(udevadm info --query=all -n $1 | grep -E "ID_BUS" | awk '{print $2}' | sed 's/ID_BUS=//'); test $device_type != "usb" && echo ">>> ERROR: device type is $device_type, \"usb\" expected." && exit; echo "<<< done"; DEV="$1"; # [1] Init device layout (gpt table) #========================================================# step1(){ echo -e "\n>>> [1] Checking for mounted partitions ($DEV)"; # (1) List partitions of this device # mounted_partitions=$( cat /proc/mounts | awk '{print $1}' | grep "$DEV" ); # if nothing found -> next step test -z "$mounted_partitions" && echo "<<< done" && step2; for mounted in $mounted_partitions; do read -p " (!) umount $mounted (y/n) [n]" unmount; test -n "$unmount" && test $unmount = "y" && sudo umount $mounted 2> /dev/null > /dev/null && echo " > unmounted"; done; echo "<<< done"; step2; } # [2] Initialize GTP Table #========================================================# step2(){ echo -e "\n>>> [2] Formatting disk ($DEV)"; # (1) Confirmation # read -p" (!) Erase the whole disk ? it is irreversible! (y/n) [n]" confirm_format; test -z "$confirm_format" && echo "<<< aborting" && exit; test $confirm_format != "y" && echo "<<< aborting" && exit; # (2) Init gpt entry # echo -e "g\nw" | sudo fdisk $DEV 2> /dev/null > /dev/null; echo "<<< done"; step3; } # [3] Burn image to device #========================================================# step3(){ echo -e "\n>>> [3] Burning image into disk ($DEV)"; # (1) Confirmation # read -p" (!) Burn the whole disk ? it is irreversible! (y/n) [n]" confirm_burn; test -z "$confirm_burn" && echo "<<< aborting" && exit; test $confirm_burn != "y" && echo "<<< aborting" && exit; # (2) Burning image into disk # # if GZIP if [ "IMAGE_ZIP" = "1" ]; then echo " - using gunzip"; ( dd if=$IMAGE_FILE | pv -s $(du -bs $IMAGE_FILE | gunzip | awk '{print $1}') | sudo dd of=$DEV bs=4M ) \ || $( echo "<<< error: dd command failed" && exit ); else ( dd if=$IMAGE_FILE | pv -s $(du -bs $IMAGE_FILE | awk '{print $1}') | sudo dd of=$DEV bs=4M ) \ || $( echo "<<< error: dd command failed" && exit ); fi; echo "<<< done"; step4; } # [4] Mount partition #========================================================# step4(){ echo -e "\n>>> [4] Mounting partition ${DEV}2"; # [1] Mount device partition sudo mount ${DEV}2 /mnt || $( echo "<<< error: can't mount" && exit ); echo "<<< done"; step5; } # [5] Updating users #========================================================# step5(){ echo -e "\n>>> [5] Updating users' structure"; # (1) emulate `useradd sats` # echo " (.) emulate \`useradd sats\`"; echo " - /etc/shadow"; cat ./utility/shadow_append | sudo tee -a /mnt/etc/shadow > /dev/null; cat ./utility/shadow_append | sudo tee -a /mnt/etc/shadow- > /dev/null; echo " - /etc/passwd"; cat ./utility/passwd_append | sudo tee -a /mnt/etc/passwd > /dev/null; cat ./utility/passwd_append | sudo tee -a /mnt/etc/passwd- > /dev/null; # (2) Emulate `groupadd` then `usermod` # echo " (.) emulate \`groupadd sats\`"; echo " - /etc/group"; echo " (.) emulate \`groupadd ssh-key\`"; echo " - /etc/group"; echo " (.) emulate \`usermod -a -G ssh-key,sats sats\`"; echo " (.) emulate \`usermod -a -G ssh-key pi\`"; echo " - /etc/group"; cat ./utility/group_append | sudo tee -a /mnt/etc/group > /dev/null; cat ./utility/group_append | sudo tee -a /mnt/etc/group- > /dev/null; echo " (.) emulate \`usermod -a -G gpio,spi sats\`"; sudo cat /mnt/etc/group | sed 's/^gpio:x:997:pi$/\0,sats/' | sed 's/^spi:x:999:pi$/\0,sats/' | sudo tee /mnt/etc/group > /dev/null; echo "<<< done": step6; } # [6] Manage SSH keys # #========================================================# step6(){ echo -e "\n>>> [6] Manage ssh keys"; # (1) Create ssh key pair # echo " (.) Create ssh key [ecdsa:521]"; ssh-keygen -t ecdsa -b 521 -C "[ECDSA:521] SATS" -f ./tmp/id_ecdsa -P "" 2> /dev/null > /dev/null; # (2) Add public key to server's `authorized_keys` file # echo " (.) Add public key to server's list"; test ! -e ./server/authorized_keys && touch ./server/authorized_keys; cat ./tmp/id_ecdsa.pub >> ./server/authorized_keys; # (3) Create ssh file system # echo " (.) Init ssh folder (/home/sats/.ssh)"; sudo mkdir -p /mnt/home/sats/.ssh; # (4) Add both keys to sats files # echo " (.) Add keys to ssh folder"; sudo mv ./tmp/id_ecdsa /mnt/home/sats/.ssh/id_ecdsa; sudo mv ./tmp/id_ecdsa.pub /mnt/home/sats/.ssh/id_ecdsa.pub; # (5) Add maintenance keys # echo " (.) Add maintenance keys (for 'pi' user)"; sudo mkdir -p /mnt/home/pi/.ssh; sudo touch /mnt/home/pi/.ssh/authorized_keys; cat ./server/maintenance/*.pub | sudo tee /mnt/home/pi/.ssh/authorized_keys > /dev/null; # (6) Set up permissions # echo " (.) Set up permissions"; sudo chown -R 1000:1000 /mnt/home/pi/.ssh; sudo chmod 550 /mnt/home/pi/.ssh; sudo chmod 400 /mnt/home/pi/.ssh/authorized_keys; sudo chown -R 666:666 /mnt/home/sats/; sudo chmod 400 /mnt/home/sats/.ssh/*; # (7) Restrict access to pubkey only (no password) # echo " (.) Restrict access to pubkey"; cat ./utility/sshd_config_append | sudo tee -a /mnt/etc/ssh/sshd_config > /dev/null; # (8) Define config alias with ssh-key # echo " (.) Define alias config"; echo -e "Host\tsmmp-server\n\tHostname\t$SERVER_HOSTNAME\n\tUser\t$SERVER_USERNAME\n\tIdentityFile\t~/.ssh/id_ecdsa\n\tStrictHostKeyChecking\tno" | sudo tee /mnt/home/sats/.ssh/config > /dev/null; sudo chown 666:666 /mnt/home/sats/.ssh/config; sudo chmod 444 /mnt/home/sats/.ssh/config; echo "<<< done"; step7; } # [7] Set up systemd services #========================================================# step7(){ echo -e "\n>>> [7] Set up systemd units"; # (0) Create useful folders # echo " (.) Create useful folder"; echo " - /service"; sudo mkdir /mnt/service; echo " - /target"; sudo mkdir /mnt/target; # (1) Create link in order to be handled # echo " (.) Emulate \`systemctl set-default multi-user.target\`"; sudo ln -fs /lib/systemd/system/multi-user.target /mnt/etc/systemd/system/default.target; # (2) Install sats-install service # echo " (.) Create sats-install service"; echo " - /lib/systemd/system"; sudo cp ./utility/sats-install.service /mnt/lib/systemd/system/sats-install.service; # (3) Install sats-boot service # echo " (.) Create sats-update service"; echo " - /lib/systemd/system"; sudo cp ./utility/sats-update.service /mnt/lib/systemd/system/sats-update.service; # (4) Install sats-loop service # echo " (.) Create sats-loop service"; echo " - /lib/systemd/system"; sudo cp ./utility/sats-loop.service /mnt/lib/systemd/system/sats-loop.service; # (5) Enable startup service unit # echo " (.) Emulate \`systemctl enable sats-loop.service\`"; sudo mkdir -p /mnt/etc/systemd/system/multi-user.target.wants; sudo ln -fs /lib/systemd/system/sats-loop.service /mnt/etc/systemd/system/multi-user.target.wants/sats-loop.service; # (6) Create sats-install script # echo " (.) Create sats-install script"; sudo cp ./utility/sats-install /mnt/service/sats-install; # (8) Create sats-update script # echo " (.) Create sats-update script"; cat ./utility/sats-update | sudo tee /mnt/service/sats-update > /dev/null; # (8) Create sats-loop script # echo " (.) Create sats-loop script"; cat ./utility/sats-loop | sudo tee /mnt/service/sats-loop > /dev/null; # (9) Create sats-update timer # echo " (.) Create sats-update timer"; echo " - Create sats-loop.timer file"; cat ./utility/sats-update.timer | sudo tee /mnt/lib/systemd/system/sats-update.timer > /dev/null; echo " - Emulate \`systemctl enable sats-loop.timer\`"; sudo ln -fs /lib/systemd/system/sats-update.timer /mnt/etc/systemd/system/multi-user.target.wants/sats-update.timer; # (10) Set up permissions # echo " (.) Set up permissions"; echo " - sats-install @pi"; sudo chown 1000:1000 /mnt/service/sats-install; sudo chmod 770 /mnt/service/sats-install; echo " - sats-update @sats"; sudo chown 666:666 /mnt/service/sats-update; sudo chmod 770 /mnt/service/sats-update; echo " - sats-loop @sats"; sudo chown 666:666 /mnt/service/sats-loop; sudo chmod 770 /mnt/service/sats-loop; echo " - /service @sats"; sudo chown 666:666 /mnt/service/*; sudo chmod 777 /mnt/service/*; echo " - /target @sats"; sudo chown 666:666 /mnt/target; sudo chmod 777 /mnt/target; echo "<<< done"; step8; } # [8] Manage Network config #========================================================# step8(){ echo -e "\n>>> [8] Set up WiFi configuration"; # (1) Update interfaces configuration # echo " (.) Update /etc/network/interfaces configuration"; cat ./utility/interfaces | sudo tee /mnt/etc/network/interfaces > /dev/null; # (2) Set up wifi credentials # echo " (.) Set up WiFi credentials"; echo -e "network={\n\tssid=\"$WIFI_SSID\"\n\tpsk=\"$WIFI_PASS\"\n}" | sudo tee -a /mnt/etc/wpa_supplicant/wpa_supplicant.conf > /dev/null; # (3) Add cronjob to try to connect every hour # echo " (.) Adding connection try daemon"; echo -e "0 * * * *\troot\t/bin/systemctl start sats-update.service\n" | sudo tee -a /mnt/etc/crontab > /dev/null; echo "<<< done"; step9; } # [9] Set up SATS daemon #========================================================# step9(){ echo -e "\n>>> [9] Set up SATS operating folder"; # (1) Create operating folder # echo " (.) Create operating folder"; sudo mkdir -p /mnt/home/sats/satsd/source; sudo mkdir -p /mnt/home/sats/satsd/log; sudo mkdir -p /mnt/home/sats/satsd/conf; sudo mkdir -p /mnt/home/sats/satsd/data; sudo mkdir -p /mnt/home/sats/satsd/tmp; # (2) Create default configuration files # echo " (.) Create default configuration/log files"; echo $MACHINE_STATE | sudo tee /mnt/home/sats/satsd/conf/machine.state > /dev/null; echo $API_URL | sudo tee /mnt/home/sats/satsd/conf/api.url > /dev/null; echo $MACHINE_BRANCH | sudo tee /mnt/home/sats/satsd/conf/machine.branch > /dev/null; echo $MACHINE_ID | sudo tee /mnt/home/sats/satsd/conf/machine.id > /dev/null; echo "" | sudo tee /mnt/home/sats/satsd/conf/auth.list > /dev/null; echo "$MACHINE_SECRET:500:$NEXT_SECRET" | sudo tee /mnt/home/sats/satsd/conf/machine.secret > /dev/null; echo "$UNLOCK_CODE" | sudo tee /mnt/home/sats/satsd/conf/machine.unlock > /dev/null; echo "$WAREHOUSE_TOKEN" | sudo tee /mnt/home/sats/satsd/conf/warehouse.token > /dev/null; echo "$MACHINE_ID;$UNLOCK_CODE" | tee -a ./server/created > /dev/null; # (3) Adjust permissions # echo " (.) Adjust permissions"; sudo chown -R 666:666 /mnt/home/sats/satsd; sudo chmod -R 770 /mnt/home/sats/satsd; # (4) Add entry in /etc/hosts if LOCAL_TEST not empty # test -n "$LOCAL_TEST" && echo -e "\n$LOCAL_TEST\n" | sudo tee -a /mnt/etc/hosts > /dev/null; echo "<<< done"; step10; } # [10] Umount device and share data to server #========================================================# step10(){ echo "\n>>> Finishing properly"; echo " (.) Copying SATS public key to server's authorized_keys"; cat ./server/authorized_keys | tail -n 1 | ssh smmp-server "cat >> ~/authorized_keys" || echo " (!) Cannot share public key"; echo " (.) Copying SATS unlock code to server's database"; DB_PASS="e6mmCpx9Oks5BwS1rcPIrgRDIGLrmDQn9oqX0tqF2VhyiLDW6yKJFrafewwCZ63njYaDKiNjiAS11hrLYij7HaxTdHb33tEqby34vgVrUYaUnwPnCJHmkoyR3TfjcZNCPti8VZG0Oooq7qSHy4lcD6T4EFCcOQ_yHjVIfibvbuZqQcPTUvbDP_9910mRDBUADShIe4sjK2FLOTCz6usUKkNqTH3PldRfAgGl182Zw9tiSPJfvQZX3S2bKblNuZf1"; DB_USER="sats-set-unlock"; DB_DATABASE="logauth"; ssh smmp-server "echo \"UPDATE machine SET unlock_code='$UNLOCK_CODE' WHERE id_machine = $MACHINE_ID;\" | mysql -u$DB_USER -p$DB_PASS --database=$DB_DATABASE" || echo " (!) Cannot share unlock code"; echo " (.) Unmounting remote device"; sudo umount /mnt; echo "<<< done"; } # [0] Step choice #========================================================# echo -e "\nSTEPS"; echo "(1) Unmount mounted partitions"; echo "(2) Format disk (gpt table)"; echo "(3) Burn image into disk"; echo "(4) Mount / partition"; echo "(5) Update users and groups"; echo "(6) Manage ssh keys"; echo "(7) Set up systemd background"; echo "(8) Set up WiFi config"; echo "(9) Set up SATS daemon"; read -p "step: " step; case $step in "1") step1;; "2") step2;; "3") step3;; "4") step4;; "5") step5;; "6") step6;; "7") step7;; "8") step8;; "9") step9;; *) echo "wrong step"; exit;; esac;