three utilities that i wrote from scratch; they are provided here
without restriction in the hope someone finds them useful.

* duplicate primary USB to identical or larger USB drive
* backup persistent contents to the Persistent Folder
* restore from backup above

i find the duplicate utility essential and recommend it be included in
Tails. I've had a few instances where my computer halted (battery ran
out) and the usb drive was completely ruined with all data
unrecoverable, my only luck was that i had actually run my duplicate
previously! phew!!!

also, installing these under ~/.local/share/applications helps too.


Install [note, i've only done this once and it worked; so the setup
procedures should be tested with other systems.]

Manually add the following mapping to the
/live/persistence/TailsData_unlocked/persistence.conf file:

/home/amnesia/.local    source=local

Then reboot to establish persistence for these "local" customizations.

Next drop the attached files in the
/home/amnesia/.local/share/applications/ folder and the utilities will
magically show up in the menus under "Accessories"! The *.bash files
must have execute permission.

INFO:

The duplicate.bash script checks to see if the two USB's are identical,
and if so it does a dd copy of the entire drive; if not identical it
attempts to create matching partitions on the target drive and dd's the
two partitions separately. That way you SHOULD be able to duplicate a
drive to another usb that isn't identical, but is at least a little bigger.

The backup.bash and restore.bash scripts are identical and use the
filename to determine which function to perform; backup puts the backup
file in the /home/amnesia/Persistent folder then i manually move it to a
cloud or another computer and then i wipe the backup file to free up the
space. Ideally, it would prompt for a target network destination, maybe
i'll add that in the future.

These have been working for me, but more testing is surely necessary.

The dup utility has saved my ass more than once! one of my usb drives
was completely destroyed (can't even format it) when my PC ran out of
battery power and shutdown abruptly.  i highly recommend a duplicate
feature be added to tails!!

let me know if you find these useful. good luck.

-a2




-------------------------------------------------

ONLY AT VFEmail! - Use our Metadata Mitigator to keep your email out of the 
NSA's hands!
$24.95 ONETIME Lifetime accounts with Privacy Features!  
15GB disk! No bandwidth quotas!
Commercial and Bulk Mail Options!  
#!/bin/bash

# TESTMODE, comment out the following line to disable TESTMODE
# backup and restore will NOT run when TESTMODE=TRUE
#TESTMODE=TRUE

P=`basename $0`
D="`echo ~amnesia/Persistent`"
PATTERN="-backup.tbz2.gpg"
#SRC="~amnesia"
SRC=/live/persistence/TailsData_unlocked

#
# only root can run 
#
if [ `whoami` != "root" ];then
    zenity --title="Insufficient Permission" \
        --info \
        --text="Only root can run this command; aborting." \
        --timeout=5 2>/dev/null
    exit 1
fi

if [ "$P" = "backup.bash" ];then
    MODE=BACKUP
else
    MODE=RESTORE
fi

zenity --title="Close all programs" \
        --info \
        --text="It is strongly recommended you close all programs before 
running a ${MODE}.\nIt can take up to 30 minutes or more to complete.\n\nPlease 
close any running programs now and Click OK to continue." 2>/dev/null


if [ "$MODE" = "BACKUP" ];then
    TODAY=`date +%Y-%m-%d`
    BAKFILE="$D/${TODAY}${PATTERN}"
    if [ -f "$BAKFILE" ];then
        zenity --title="Overwrite Backup File?" \
            --question \
            --text="WARNING: backup file already exists!\nPlease confirm you 
want to overwrite the file:\n`ls \"$BAKFILE\"`" 2>/dev/null 
        if [ $? -ne 0 ];then
            zenity --title="Backup Aborted." \
                --info \
                --text="Backup aborted, did NOT overwrite existing file." \
                --timeout=5 2>/dev/null
            exit 1
        fi
    fi

    zenity --info \
        --text="You are about to be prompted, twice, for a 
passphrase.\nRemember it because you will need it to restore from backup.\n\n 
... be patient the backup takes several minutes ..." 2>/dev/null

    if [ "$TESTMODE" = "TRUE" ];then
        zenity --info --text="TEST Mode, $MODE skipped." 2>/dev/null
    else
        echo "Enter password (twice) and then wait for the $MODE to complete."
        cd ${SRC}
        tar --exclude "*${PATTERN}" -cjf - . |
            gpg --cipher-algo AES -c - > "$BAKFILE"
        chown amnesia.amnesia $BAKFILE

        zenity --info \
                --text="Backup complete.\n `ls \"$BAKFILE\"`" 2>/dev/null
    fi
    exit 0

elif [ "$MODE" = "RESTORE" ];then
   cd ${D}
   F=""
   for f in `find . -name "*${PATTERN}" -print|tr ' ' '#'`;do
        if [ "$F" = "" ];then
            F="TRUE $f"
        else
            # If there are more than two USB drives, create a list
            F="$F FALSE $f"
        fi
   done

   if [ "$F" = "" ];then
        zenity --title="Restore Aborted." \
            --info \
            --text="Restore aborted, could not find any backup files." \
            --timeout=5 2>/dev/null
        exit 1
   fi

    # select the restore file, set BAKFILE
    BAKFILE=`zenity --title="Select Backup File" \
        --list \
        --separator=" " \
        --radiolist \
        --text="Select file to restore:" \
        --column="Select" \
        --column="Device" \
        $F 2>/dev/null`

    if [ $? -ne 0 ];then
        zenity --title="Aborting..." \
            --info \
            --text="Restore Aborted, no restore file selected" \
            --timeout=5 2>/dev/null
        exit 1;
    fi

    BAKFILE="`echo "$BAKFILE"|tr '#' ' '`"
    if [ -f "$BAKFILE" ];then
        zenity --info --title="Starting Restore." \
            --text="Restore: you will be prompted for the passphrase you 
provided when you created this backup.\nPlease be patient, the restore will 
take several minutes.\nClick OK to continue..." 2>/dev/null

        if [ "$TESTMODE" = "TRUE" ];then
            zenity --info --text="TEST Mode, $MODE skipped." 2>/dev/null
        else
            echo "Enter password and then wait for the $MODE to complete."
            cd ${SRC}
            gpg --cipher-algo AES -d "$BAKFILE" | tar -xjvf - 
            zenity --info \
                --text="Restore Complete." 2>/dev/null
        fi
        exit 0

    else
        zenity --info \
            --text="Invalid file: $BAKFILE. Restore aborted." 2>/dev/null
        exit 1
    fi
fi
#!/bin/bash

I_DEV=""
O_DEV=""
OUSB=""
IUSB=""

#
# only root can run 
#
if [ `whoami` != "root" ];then
    zenity --title="Insufficient Permission" \
        --info --text="Only root can run this command; aborting." --timeout=5 
2>/dev/null
    exit 1
fi

zenity --title="Close all programs" \
        --info \
        --text="It is strongly recommended you close all programs before 
starting the duplication process.\nIt typically takes 30 minutes or more to 
complete.\n\nPlease close any running programs now and Click OK to continue." 
2>/dev/null


#
# Find USB drives.  
# default first one is the INPUT and the SECOND is backup
#
for d in `readlink -e /dev/disk/by-id/usb*0:0|sort`; do
    if [ "$I_DEV" = "" ];then
        I_DEV="TRUE $d"
    else
        # If there are more than two USB drives, create a list
        I_DEV="$I_DEV FALSE $d"
    fi
done

#
# select the input device, set IUSB
IUSB=`zenity --title="Select Source Device" \
        --list \
        --radiolist \
        --text="Select Source USB Device" \
        --column="Select" \
        --column="Device" \
        $I_DEV 2>/dev/null`

if [ $? -ne 0 ];then
    zenity --title="Aborting..." \
        --info \
        --text="Duplication Aborted, no source device selected." --timeout=5 
2>/dev/null
    exit 1;
fi

# 
# Confirm IUSB is the boot device!
#
udevadm info $IUSB |grep -q "^S: TailsBootDev"
if [ $? -ne 0 ];then
    zenity --title="Invalid Source" \
        --question \
        --text="WARNING: Source Device, $IUSB, is not bootable.\nPlease confirm 
you want to duplicate another USB drive." 2>/dev/null 
    if [ $? -ne 0 ];then
        zenity --title="Aborting..." \
            --info --text="Aborted, did not confirm source device: $IUSB" 
--timeout=5 2>/dev/null
        exit 1
    fi
fi

## Now, get the Output device list
## excluding the selected one from the target
for d in `readlink -e /dev/disk/by-id/usb*0:0|sort`; do
    if [ "$d" = "$IUSB" ];then
        : ;
    elif [ "$O_DEV" = "" ];then
        O_DEV="TRUE $d"
    else
        # If there are more than two USB drives, create a list
        O_DEV="$O_DEV FALSE $d"
    fi
done
if [ "$O_DEV" = "" ];then
    zenity --title="Aborting..." \
        --info \
        --text="Aborted, no valid target device found." \
        --timeout=10 2>/dev/null
    exit 1
fi


OUSB=`zenity --title="Select Target Device" \
        --list \
        --radiolist \
        --text="Select Target USB Device" \
        --column="Select" \
        --column="Device" \
        $O_DEV 2>/dev/null`

if [ $? -ne 0 ];then
    zenity --title="Aborting..." \
        --info \
        --text="Duplication Aborted, no target device selected." \
        --timeout=5 2>/dev/null
    exit 1;
fi

##
## Check the SOURCE drive size, boot and data partition
##
ISIZ=`lsblk -dnb -o size ${IUSB}`
ISIZboot=`lsblk -dnb -osize ${IUSB}1 2>/dev/null`
ISIZdata=`lsblk -dnb -osize ${IUSB}2 2>/dev/null`
if [ "${ISIZboot}" = "" -o "${ISIZdata}" = "" ];then
    zenity --title="Aborting... invalid Source." \
           --info \
           --text="Aborted, Missing boot or data partition on $IUSB" \
            --timeout=10 2>/dev/null
    exit 1;
fi

##
## Check the TARGET drive size, boot and data partitions
##
OSIZ=`lsblk -dnb -o size ${OUSB}`
OSIZboot=`lsblk -dnb -osize ${OUSB}1 2>/dev/null`
OSIZdata=`lsblk -dnb -osize ${OUSB}2 2>/dev/null`
if [ "${OSIZ}" = "" ];then
    zenity --title="Aborting... invalid Target." \
           --info \
           --text="Aborted, Cannot determine size of Target: $IUSB" \
            --timeout=10 2>/dev/null
    exit 1
fi

udevadm info $OUSB |grep -q "^S: TailsBootDev"
if [ $? -eq 0 ];then
    zenity --title="WARNING: Invalid Target" --question \
        --text="WARNING: Target Device, $OUSB, is the current boot 
device.\nPlease confirm you want to clobber your current boot 
device!!!\n\nWARNING: NOT RECOMMENDED! Abort Recommended (click No)." 
2>/dev/null 
    if [ $? -ne 0 ];then
        zenity --title="Aborting..." --info \
            --text="Aborted, did not confirm Target: $OUSB" \
            --timeout=5 2>/dev/null
        exit 1
    fi
fi

## OK here we go
## First, USB Drives vary in exact size.
##
if [ 0${ISIZ} -ne 0${OSIZ} ];then
    if [ 0${ISIZboot} -ne 0${OSIZboot} -o \
         0${ISIZdata} -ne 0${OSIZdata} ];then

        zenity --title="WARNING: Target Partitions" --question \
            --text="WARNING! WARNING!! WARNING!!!\nBoot and data partitions do 
not match.\n\nClick 'Yes' to Create new boot and data Partitions on the 
${OUSB}. All contents on ${OUSB} will be lost." 2>/dev/null 
        if [ $? -ne 0 ];then
            zenity --title="Aborting..." --info \
                --text="Aborted, did not confirm partitions." \
                --timeout=10 2>/dev/null
            exit 1
        fi
        ##
        ## dump SOURCE partitions, apply to TARGET
        ##
        PTAB=`sfdisk --dump ${IUSB} 2>/dev/null |
                grep "^${IUSB}" |
                sed "s;${IUSB};${OUSB};g"`
        echo -e "label: gpt\n${PTAB}" | sfdisk ${OUSB}
        if [ $? -ne 0 ];then
            zenity --title="Aborting... partition error." --info \
               --text="Aborted, failed to create boot and data partitions on 
${OUSB}" \
               --timeout=30 2>/dev/null
            exit 1
        fi
    fi
    CMD="dd status=progress if=${IUSB}1 of=${OUSB}1 bs=8M;dd status=progress 
if=${IUSB}2 of=${OUSB}2 bs=8M"
else
    CMD="dd status=progress if=${IUSB} of=${OUSB} bs=8M"
fi
#
# Confirm , are you sure you want to proceed?  really?
#
zenity  --title="WARNING: Please confirm" \
        --question \
        --default-cancel \
        --text="WARNING! WARNING!! WARNING!!! \n\nAll contents on $OUSB will be 
lost!\n\nClick 'Yes' to start duplication of $IUSB to $OUSB!\n" 2>/dev/null

if [ $? -ne 0 ];then
    zenity --info \
        --text="Duplication Aborted, no changes were made." \
        --timeout=10 2>/dev/null
    exit 1
fi

###
### Well, well, well. OK, HERE WE GO! Let the backup begin!!!
###
sync;
s=`date`
(sleep 3;eval ${CMD}) |
    zenity --progress \
    --title="Duplicating $IUSB to $OUSB in progress..." \
    --pulsate \
    --text="Please be patient.\nThe Duplication can take 30 minutes or 
more.\nStarted at: ${s}" \
    --auto-kill --auto-close 2>/dev/null
DDRESULT=$?
e=`date`

###
### all done!
###
if [ ${DDRESULT} -eq 0 ];then
    result="Succeeded."
else
    result="Aborted, $OUSB very likely corrupted."
fi
# report the resulrts...
zenity --title="Duplication Complete" --info \
    --text="Duplication ${result}\nStarted: ${s}\nEnded: ${e}"  2>/dev/null

exit 0

#!/bin/bash

# TESTMODE, comment out the following line to disable TESTMODE
# backup and restore will NOT run when TESTMODE=TRUE
#TESTMODE=TRUE

P=`basename $0`
D="`echo ~amnesia/Persistent`"
PATTERN="-backup.tbz2.gpg"
#SRC="~amnesia"
SRC=/live/persistence/TailsData_unlocked

#
# only root can run 
#
if [ `whoami` != "root" ];then
    zenity --title="Insufficient Permission" \
        --info \
        --text="Only root can run this command; aborting." \
        --timeout=5 2>/dev/null
    exit 1
fi

if [ "$P" = "backup.bash" ];then
    MODE=BACKUP
else
    MODE=RESTORE
fi

zenity --title="Close all programs" \
        --info \
        --text="It is strongly recommended you close all programs before 
running a ${MODE}.\nIt can take up to 30 minutes or more to complete.\n\nPlease 
close any running programs now and Click OK to continue." 2>/dev/null


if [ "$MODE" = "BACKUP" ];then
    TODAY=`date +%Y-%m-%d`
    BAKFILE="$D/${TODAY}${PATTERN}"
    if [ -f "$BAKFILE" ];then
        zenity --title="Overwrite Backup File?" \
            --question \
            --text="WARNING: backup file already exists!\nPlease confirm you 
want to overwrite the file:\n`ls \"$BAKFILE\"`" 2>/dev/null 
        if [ $? -ne 0 ];then
            zenity --title="Backup Aborted." \
                --info \
                --text="Backup aborted, did NOT overwrite existing file." \
                --timeout=5 2>/dev/null
            exit 1
        fi
    fi

    zenity --info \
        --text="You are about to be prompted, twice, for a 
passphrase.\nRemember it because you will need it to restore from backup.\n\n 
... be patient the backup takes several minutes ..." 2>/dev/null

    if [ "$TESTMODE" = "TRUE" ];then
        zenity --info --text="TEST Mode, $MODE skipped." 2>/dev/null
    else
        echo "Enter password (twice) and then wait for the $MODE to complete."
        cd ${SRC}
        tar --exclude "*${PATTERN}" -cjf - . |
            gpg --cipher-algo AES -c - > "$BAKFILE"
        chown amnesia.amnesia $BAKFILE

        zenity --info \
                --text="Backup complete.\n `ls \"$BAKFILE\"`" 2>/dev/null
    fi
    exit 0

elif [ "$MODE" = "RESTORE" ];then
   cd ${D}
   F=""
   for f in `find . -name "*${PATTERN}" -print|tr ' ' '#'`;do
        if [ "$F" = "" ];then
            F="TRUE $f"
        else
            # If there are more than two USB drives, create a list
            F="$F FALSE $f"
        fi
   done

   if [ "$F" = "" ];then
        zenity --title="Restore Aborted." \
            --info \
            --text="Restore aborted, could not find any backup files." \
            --timeout=5 2>/dev/null
        exit 1
   fi

    # select the restore file, set BAKFILE
    BAKFILE=`zenity --title="Select Backup File" \
        --list \
        --separator=" " \
        --radiolist \
        --text="Select file to restore:" \
        --column="Select" \
        --column="Device" \
        $F 2>/dev/null`

    if [ $? -ne 0 ];then
        zenity --title="Aborting..." \
            --info \
            --text="Restore Aborted, no restore file selected" \
            --timeout=5 2>/dev/null
        exit 1;
    fi

    BAKFILE="`echo "$BAKFILE"|tr '#' ' '`"
    if [ -f "$BAKFILE" ];then
        zenity --info --title="Starting Restore." \
            --text="Restore: you will be prompted for the passphrase you 
provided when you created this backup.\nPlease be patient, the restore will 
take several minutes.\nClick OK to continue..." 2>/dev/null

        if [ "$TESTMODE" = "TRUE" ];then
            zenity --info --text="TEST Mode, $MODE skipped." 2>/dev/null
        else
            echo "Enter password and then wait for the $MODE to complete."
            cd ${SRC}
            gpg --cipher-algo AES -d "$BAKFILE" | tar -xjvf - 
            zenity --info \
                --text="Restore Complete." 2>/dev/null
        fi
        exit 0

    else
        zenity --info \
            --text="Invalid file: $BAKFILE. Restore aborted." 2>/dev/null
        exit 1
    fi
fi

Attachment: Backup-Persistent-Data.desktop
Description: application/desktop

Attachment: Duplicate.desktop
Description: application/desktop

Attachment: Restore-Persistent-Data.desktop
Description: application/desktop

_______________________________________________
Tails-dev mailing list
[email protected]
https://mailman.boum.org/listinfo/tails-dev
To unsubscribe from this list, send an empty email to 
[email protected].

Reply via email to