diff --git a/modules/extroot b/modules/extroot new file mode 100644 index 0000000..27d2594 --- /dev/null +++ b/modules/extroot @@ -0,0 +1,230 @@ +#!/bin/bash /usr/lib/turtle/turtle_module +# Title: LANTurtle OpenWRT Extroot configuration +# Description: Simplified SD card storage +# Author: jrwimmer +# Props: The OpenWrt community +# Version: 1.0 +# Category: General +# Target: N/A +# Attackmodes: N/A + +# Constants +VERSION="1.0" +DESCRIPTION="Simplified SD card storage" +REQUIRED_PACKAGES="block-mount kmod-fs-ext4 e2fsprogs fdisk" +CONF=/tmp/extroot.form + +# All "dialog" functionality is related to the Turtle shell +: ${DIALOG_OK=0} +: ${DIALOG_CANCEL=1} +: ${DIALOG_HELP=2} +: ${DIALOG_EXTRA=3} +: ${DIALOG_ITEM_HELP=4} +: ${DIALOG_ESC=255} + +function configure { + dialog --title "Extroot: Info" --msgbox "::: NOTICE :::\n\nThis module is intended for use on freshly-imaged devices. Any customizations already made are not guaranteed to persist through extroot configuration." 14 72 + + dialog --title "Extroot: WARNING" --defaultno --yesno "::: WARNING :::\n\n\nThis Operation WILL ERASE THE ATTACHED SD CARD \n\nAre you sure you wish to continue?" 14 72 + + return=$? + case $return in + "$DIALOG_OK") + perform_migration;; + "$DIALOG_CANCEL") + dialog --title "Extroot" --msgbox "Operation cancelled" 14 72 + exit 0;; + "$DIALOG_ESC") + dialog --title "Extroot" --msgbox "Operation cancelled" 14 72 + exit 0;; + esac +} + +function check_space { + # Get block size for the root partition + rootfs_blocksize=$(df -P / | awk '{print $2}' | tail -n+2) + rootfs_humansize=$(df -h / | awk '{print $2}' | tail -n+2) + + # Check if the root partition is larger than 256 MB + if (( $rootfs_blocksize > 256000 )); then + dialog --title "Extroot: WARNING" --defaultno --yesno "::: WARNING :::\n\n\nThe root partition appears to be larger than 256MB in size (Seen: $rootfs_humansize)\n\nThis may indicate that the overlay configuration process has already been performed on this installation.\n\nAre you sure you wish to continue?" 14 72 + + return=$? + case $return in + "$DIALOG_OK") + return 0;; + "$DIALOG_CANCEL") + dialog --title "Extroot" --msgbox "Operation cancelled" 14 72 + exit 0;; + "$DIALOG_ESC") + dialog --title "Extroot" --msgbox "Operation cancelled" 14 72 + exit 0;; + esac + fi +} + +function check_network { + # Check for Internet connection by attempting to contact an opkg repository server + + # First, extract a server URL from distfeeds.conf + opkg_baseurl=$(sed -E -n "s/^[^#]*(http:\/\/[^\/]*)\/.*/\1/p;q" /etc/opkg/distfeeds.conf) &> /dev/null + if [[ $? -ne 0 ]]; then + echo "\nCould not extract an opkg repo from distfeeds.conf\n\nIf this is unexpected, you may need to upgrade or restore the firmware." > $1 + return 1 + fi + + # ...then, use wget to determine if the server can be reached + wget -q --tries 3 --spider "$opkg_baseurl" &> /dev/null + wget_returncode=$? + if [[ $wget_returncode -ne 0 ]]; then + echo "\nLAN Turtle could not connect to $opkg_baseurl\nVerify the device's internet connection and try again (wget error $wget_returncode)" > $1 + return 1 + fi + + sleep 3 +} + +function install_dependencies { + echo "Updating opkg" + opkg update + + echo "Checking/installing dependencies" + opkg install $REQUIRED_PACKAGES + + sleep 3 +} + +function remount_rootfsdata { + # Identify flash memory device containing current overlay + rootfsdata_dev="$(sed -n -e "/\s\/overlay\s.*$/s///p" /etc/mtab)" + + # Create remount entry + uci -q delete fstab.rwm + uci set fstab.rwm="mount" + uci set fstab.rwm.device="${rootfsdata_dev}" + uci set fstab.rwm.target="/rwm" + uci commit fstab + + sleep 3 +} + +function format_sdcard { + echo "Checking SD card presence" + [[ "$(ls /dev/sd* 2> /dev/null | wc -l)" == "0" ]] && { + echo "\nError: No SD card is inserted or the card is not supported\n\nAdditional Details:\nCould not find a device with prefix 'sd'" > $1 + return 1 + } + + sdcard_device=$(ls /dev/sd* 2> /dev/null | head -n1) + echo "New overlay device identified as: $sdcard_device" + + echo "Unmounting any active external storage" + block umount &> /dev/null + + echo "Partitioning SD card" + echo -e "o\nn\np\n2\n\n+1024M\nn\np\n1\n\np\n\nw\n" | fdisk "$sdcard_device" 2>/dev/null + mkfs.ext4 -F "${sdcard_device}1" + mkswap "${sdcard_device}2" + + echo "Restarting the storage bus" + echo "1-0:1.0" > /sys/bus/usb/drivers/hub/unbind 2>/dev/null + echo "1-0:1.0" > /sys/bus/usb/drivers/hub/bind 2>/dev/null + sleep 3 + + echo "Commit/activate swap and remove existing SD card mounts" + block detect > /etc/config/fstab + uci -q delete fstab.@mount[0] + uci commit fstab + block mount &> /dev/null + + sleep 3 +} + +function make_extroot { + sdcard_device=$(ls /dev/sd* 2> /dev/null | head -n1)1 + echo "New overlay partition identified as: $sdcard_device" + + eval $(block info "${sdcard_device}" | grep -o -e "UUID=\S*") + echo "New overlay partition has a UUID of: $UUID" + + echo "Recreating overlay fstab entry" + uci -q delete fstab.overlay + uci set fstab.overlay="mount" + uci set fstab.overlay.uuid="${UUID}" + uci set fstab.overlay.target="/overlay" + uci commit fstab + + sleep 3 +} + +function migrate_overlay { + sdcard_device=$(ls /dev/sd* 2> /dev/null | head -n1)1 + echo "New overlay partition identified as: $sdcard_device" + + echo "Creating temporary mount point directory at: /tmp/cproot" + mkdir -p /tmp/cproot + + echo "Binding active overlay to: /tmp/cproot" + mount --bind /overlay /tmp/cproot + + echo "Mounting new overlay parition at: /mnt" + mount "${sdcard_device}" /mnt + + echo "Copying data; please wait..." + tar -C /tmp/cproot -cvf - . 2>/dev/null | tar -C /mnt -xf - 2>/dev/null + echo "Copy process complete" + + echo "Unmounting new overlay and removing bind" + umount /tmp/cproot /mnt + + sleep 3 +} + +function finalize { + dialog --title "Extroot: Info" --msgbox "::: NOTICE :::\n\nOperation complete. To finalize changes, the system will now reboot." 14 72 + reboot +} + +function perform_step { + # Create a tmpfile in which we can store error data + active_tmpfile=$(mktemp) + # Default error data to 0 + echo 0 > "$active_tmpfile" + + # Perform the requested step + eval "$1" "$active_tmpfile" | dialog --progressbox "$2" 14 72 + + # Retrieve the last error written to the tmpfile + last_return_code=$(cat "$active_tmpfile") + # Delete the tmpfile + rm "$active_tmpfile" + + # Determine if an error occurred + if [[ "$last_return_code" != 0 ]]; then + # Notify the user of the problem + dialog --title "Extroot: Error" --msgbox "$last_return_code" 9 72 + exit 1 + fi +} + +function perform_migration { + check_space + + perform_step "check_network" "Checking network connectivity" + + perform_step "install_dependencies" "Installing requried dependencies" + + perform_step "remount_rootfsdata" "Creating backup mount for current overlay" + + perform_step "format_sdcard" "Formatting SD card" + + perform_step "make_extroot" "Configuring new overlay" + + perform_step "migrate_overlay" "Migrating overlay data" + + finalize +} + +function start { + echo "This module is used via the 'Configure' option" +} \ No newline at end of file diff --git a/modules/module_list b/modules/module_list index 9a96136..4a96b34 100644 --- a/modules/module_list +++ b/modules/module_list @@ -4,6 +4,7 @@ cron Schedule tasks ddnsc Dynamic Domain Name Service dns-spoof Forges replies to arbitrary DNS address dnsmasq-spoof DNSSpoof using DNSMasq +extroot Simplified SD card storage follow-file Follow log printing data as file grows iodine Creates a DNS Tunnel using iodine keymanager SSH Key Manager