Photograph by Rama, Wikimedia Commons, Cc-by-sa-2.0-fr


So I had some phone problems last week. Okay, not like the phone shown above. Rather my LG Nexus 5X mobile phone that I bought a while back, running CyanogenMod. I’ve been very happy with this phone. Until one day a week ago Friday it just went dead. Very dead.

Dead as in it wouldn’t turn on. Dead as in when I plugged in the phone to charge, the charge light didn’t come on and the screen was still black. I tried holding the power button to turn it on for 10 seconds. 20 seconds. 30 seconds. I tried combinations of power and volume up or down. Nothing.

It had been raining that day, so I worried somehow it got fried. But other than a little drizzle, I never went outside in the wet.

So I was quite worried that I fried it. I’ve been using Titanium Backup to backup the phone, but it is a bit of a pain to copy these files over to my laptop so that I have them in the event the phone completely dies. (I did it about a month prior.) I’ve also been reluctant to upload this stuff to the cloud because it is pretty sensitive stuff. I don’t really wan’t Google or anyone else having access to that much info about me. I mean they already know what I search about, what I wrote in my blog, etc. But my phone has private notes to myself (which I don’t sync), financial info, etc. that I’d rather not pass out of my possession. And I know that Titanium Backup has some encryption support, but I don’t know how well the encryption is written. And even perfect encryption is still subject to brute force attacks. Sure, it probably would be fine, but I’d still rather keep the backup copies of my personal data in my personal possession and not tempt fate.

Which is what led me to that sick feeling in my stomach when the phone wouldn’t turn on. My backups weren’t that up-to-date.

The good news is that after another day of messing with it, I found that holding the power button down for over a minute caused it to boot up. And it has been happy ever since.

Phew! Close call.

(Note to self: I always thought that holding a power button down for 10-15 seconds was long enough to get whatever effect that button was designed for. Apparently not! Something was designed to happen if you hold the button down for about a minute.)

So I don’t really want to go through that again. Which led to the question of a better backup system.

Which led me to this site:
https://blog.josefsson.org/2015/11/28/automatic-android-replicant-backup-over-usb-using-rsync/

It demonstrates a number of very good ideas for how to use the standard Unix rsync command to synchronize everything on your phone between your phone and a backup directory on your PC. The author designed the script to startup at USB plugin, but I’m okay just running the script manually when I plug in the phone for now.

I did make a number of mods to the script though. In particular, there was no security at all on the device to prevent any other program on the device from accessing the rsync daemon to gain access to all of your data. So I added a randomly generated shared secret that is only accessible to root on the device (and if anyone already has root access to your device, they don’t need to hack your rsyncd to read your data). Additionally, I improved the clean-up at the end of the script, excluded a bunch of cache directories that don’t need to be backed up (among other things), and fixed some temporary file permissions.

So here is the script as I use it:

#!/bin/bash

BASEDIR=/var/backups
PREFIX=$BASEDIR/android
export ANDROID_SERIAL="$1"

# generate random secret
secret=$(dd if=/dev/urandom bs=1 count=32 2>/dev/null | base64 -w 0 | rev | cut -b 2- | rev)

#log to logger
#exec 2>&1 | logger

#log to logfile
#exec >$BASEDIR/log/android_backup.`date +%Y%m%d-%H%M%S`.log 2>&1
exec >>$BASEDIR/log/android_backup.log 2>&1

if ! test -d "$PREFIX-$ANDROID_SERIAL"; then
echo "could not find directory: $PREFIX-$ANDROID_SERIAL"
exit 1
fi

set -x

adb wait-for-device
adb root
adb wait-for-device
adb shell "umask 077 && printf 'backup:$secretn' > /mnt/secure/rsyncd.secrets"
adb shell "umask 077 && printf 'address = 127.0.0.1npid file = /mnt/secure/rsyncd.pidnuid = rootngid = rootn[root]ntpath = /nthosts allow = 127.0.0.1ntauth users = backupntsecrets file = /mnt/secure/rsyncd.secretsn' > /mnt/secure/rsyncd.conf"
adb shell "umask 077 && rsync --daemon --no-detach --log-file=/data/media/0/rsyncd/rsyncd.log --config=/mnt/secure/rsyncd.conf" &
adb forward tcp:6010 tcp:873
sleep 2
RSYNC_PASSWORD=$secret rsync -av --delete --exclude /mnt --exclude /dev --exclude /acct --exclude /sys --exclude /proc --exclude /storage/emulated --exclude cache rsync://backup@localhost:6010/root/ $PREFIX-$ANDROID_SERIAL/
: rc $?
adb forward --remove tcp:6010

# kill rsyncd
adb shell 'kill `cat /mnt/secure/rsyncd.pid`'

# remove temporary files
adb shell rm -f /mnt/secure/rsyncd.conf /mnt/secure/rsyncd.pid /mnt/secure/rsyncd.secrets

I named this script “android_backup.sh”. Now I just go to the directory this file is in and type “./android_backup.sh android-XXXX” where XXXX is the serial number of the phone (as listed by “adb devices”). Just make sure you have a directory named “/var/backups/android-XXXX”.

That’s it.

Now if only I could figure out what happened to the phone in the first place…