[ASUS ZenFone 8] bnsmb:
How to backup the data from the phone using rsync and ssh (including some hints for using sshd on an Android phone)

Like for all computer it's important to have a backup of the data on the phone.

For those who like me don't like to store their private data in one of the suspicious clouds there is a solution with standard Linux tools:

Use rsync and ssh to backup the data from the phone to your local workstation (see the man page for rsync for details regarding rsync and why it is useful for this task)

The neccessary tools for Android for this method can be installed with the Magisk Module MagiskSSH.

Download the Magisk Module with MagiskSSH from here

https://gitlab.com/d4rcm4rc/MagiskSSH_releases

Copy the ZIP file with the Magisk Module to the phone :

adb push magisk_ssh_v0.14.zip /sdcard/Download/

and install it via the module installation from within the Magisk App or manuell using :

adb shell su - -c /data/adb/magisk/magisk64 --install-module /sdcard/Download/magisk_ssh_v0.14.zip

Sample output of the installation:

ASUS_I006D:/ # /data/adb/magisk/magisk64 --install-module /sdcard/Download/magisk_ssh_v0.14.zip
- Current boot slot: _a
- Device is system-as-root
*******************************
OpenSSH for Android
*******************************
[0/7] Preparing module directory
[1/7] Extracting architecture unspecific module files
[2/7] Extracting libraries and binaries for arm64
[3/7] Configuring library path wrapper
[4/7] Recreating symlinks
[5/7] Creating SSH user directories
[6/7] Found sshd_config, will not copy a default one
[7/7] Cleaning up
- Setting permissions
- Done
ASUS_I006D:/ #

A reboot is required now.

adb shell reboot

For the next tasks open an adb shell and become root user.

Next create the authorized_keys file for the user root :

touch /data/ssh/root/.ssh/authorized_keys
chmod 600 /data/ssh/root/.ssh/authorized_keys

and add your public ssh key to the file /data/ssh/root/.ssh/authorized_keys.

To make sure that the keys and other data files for the MagiskSSH module are not removed while deinstalling the module you should create the file /data/ssh/KEEP_ON_UNINSTALL:

touch /data/ssh/KEEP_ON_UNINSTALL

The MagiskSSH module also installs a service to start sshd after each reboot: to disable this start create the file /data/ssh/no-autostart:

touch /data/ssh/no-autostart

To manually start or stop the sshd use the script /data/adb/modules/ssh/opensshd.init :

# start the sshd (as user root)
#
/data/adb/modules/ssh/opensshd.init start

# to stop the sshd (as user root)
#
/data/adb/modules/ssh/opensshd.init stop

Now test the access via ssh from your Linux workstation:

ssh -l root <phone_ip_address> id

Use this command to retrieve the current IP address of the phone:

PHONE_IP_ADDRESS=$( adb shell ifconfig wlan0 | grep "inet addr:" | sed -e "s/.*inet addr://g" -e "s/[[:space:]]*Bcast.*//g" )

example :

[xtrnaw7@t15g ~]$ ssh -l root ${PHONE_IP_ADDRESS} id
uid=0(root) gid=0(root) groups=0(root) context=u:r:magisk:s0
[xtrnaw7@t15g ~]$

Now you can use rsync to backup the data from the phone, e.g. to backup the photos from the phone do :

# on your local Linux workstation do:
# start the sshd on the phone via adb if not already running
#
adb shell su - -c /data/adb/modules/ssh/opensshd.init start

# retrieve the current IP address from the phone
#
PHONE_IP_ADDRESS=$( adb shell ifconfig wlan0 | grep "inet addr:" | sed -e "s/.*inet addr://g" -e "s/[[:space:]]*Bcast.*//g" )

# backup the new photos from the phone to the Linux workstation (rsync only copies new files from the phone)
# to the local directory /data/backup/ASUS_ZENFONE8/DCIM
#
rsync -av --rsync-path /data/adb/modules/ssh/usr/bin/rsync root@${PHONE_IP_ADDRESS}:/sdcard/DCIM/ /data/backup/ASUS_ZENFONE8/DCIM

# optional stop the sshd on the phone via adb
#
adb shell su - -c /data/adb/modules/ssh/opensshd.init stop

Note: The sshd configuration file used is /data/ssh/sshd_config

Sample Script to backup all data in the directory /sdcard

##!/bin/bash
#
# simple script to backup the data of an phone using adb, ssh, and rsync
#
# History
# 27.06.2022 /bs
# initial release
#

# for testing
#
#RSYNC_OPTIONS="${RSYNC_OPTIONS} --dry-run"

RSYNC_OPTIONS="${RSYNC_OPTIONS} --del "

# default is to backup the phone connected via adb over LAN
#
[ $# -ne 0 ] && ADB_OPTIONS="$*" || ADB_OPTIONS="-e"

# retrieve the serial number of the attached phone
#
SERIAL_NO="$( adb ${ADB_OPTIONS} shell getprop ro.serialno )"
if [ "${SERIAL_NO}"x = ""x ] ; then
echo "ERROR: Can not read the serial number of the connected phone"
exit 89
fi

VENDOR_MODEL="$( adb ${ADB_OPTIONS} shell getprop ro.product.vendor.model )"

# directory for the backup
#
BACKUP_DIR="/data/backup/ASUS_ZENFONE8/data_backup/${VENDOR_MODEL}_${SERIAL_NO}"

if [ ! -d "${BACKUP_DIR}" ] ; then
echo "ERROR: The directory \"${BACKUP_DIR}\" does not exist"
exit 99
fi

PHONE_IP_ADDRESS="$( adb ${ADB_OPTIONS} shell ifconfig wlan0 | grep "inet addr:" | sed -e "s/.*inet addr://g" -e "s/[[:space:]]*Bcast.*//g" )"
if [ "${PHONE_IP_ADDRESS}"x = ""x ] ; then
echo "ERROR: Can not detect the IP address of the phone"
exit 100
fi

echo "Updating a backup of the data on the phone with the serial number \"${SERIAL_NO}\" and the IP \"${PHONE_IP_ADDRESS}\" to the directory \"${BACKUP_DIR}\" ..."

set -x

# start the sshd if neccessary
#
adb ${ADB_OPTIONS} shell su - -c /data/adb/modules/ssh/opensshd.init start

# do the backup
#
time rsync ${RSYNC_OPTIONS} -av --rsync-path /data/adb/modules/ssh/usr/bin/rsync root@${PHONE_IP_ADDRESS}:/sdcard/ "${BACKUP_DIR}/"

# stop the sshd
#
adb ${ADB_OPTIONS} shell su - -c /data/adb/modules/ssh/opensshd.init stop
set +x

How to enable access via ssh for non-root user

In the standard configuration installed by MagiskSSH ssh access is only allowed as user root because the ssh keys are in the directory /data and all non-root user can not read files in the directory /data. Therefor some efforts are neccessary to add ssh access for non-root user.

e.g. To enable the ssh access for the user shell do:

To configure ssh access for the user shell we must create a .ssh directory for the user shell in a directory tree owned by the user shell. The only directory on the phone owned by the user shell that can be used for this purpose is /storage :

ASUS_I006D:/ # ls -ld /storage
drwx--x--- 4 shell everybody 80 2022-06-26 18:37 /storage
ASUS_I006D:/ #

But unfortunately all files and directories in this directory are temporary and will be deleted after a reboot of the phone.

Therefor we configure a startup script in Magisk to create this directory tree after each reboot, e.g.

/data/adb/service.d/create_ssh_dir_for_shell.sh:

# /data/adb/service.d/create_ssh_dir_for_shell.sh
#
mkdir -p /storage/shell/.ssh

chmod -R 700 /storage/shell/

touch /storage/shell/.ssh/authorized_keys

echo "<ssh_public_key>" > /storage/shell/.ssh/authorized_keys

chmod 600 /storage/shell/.ssh/authorized_keys

chown -R shell:shell /storage/shell

Make the script executable:

su - -c chmod +x data/adb/service.d/create_ssh_dir_for_shell.sh

To test the script just execute it one time manually as user root.

su - -c sh data/adb/service.d/create_ssh_dir_for_shell.sh

Now create a backup of the sshd config file

su - -c cp /data/ssh/sshd_config /storage/ssh/sshd_config.org.$$

and add these lines at the end of the file /data/ssh/sshd_config

Match User shell
AuthorizedKeysFile /storage/shell/.ssh/authorized_keys

Restart the sshd if it's already running

Now test the access as user shell, example:

[xtrnaw7@t15g ~]$ ssh -l shell 192.168.1.148 id
uid=2000(shell) gid=2000(shell) groups=2000(shell) context=u:r:magisk:s0
[xtrnaw7@t15g ~]$

The reason for this config is the setting "StrictMode yes" in the sshd config file /data/ssh/sshd_config (see the man page for sshd_config for details). So another "solution" is to change this setting:

With the setting "StrictModes no" in the file sshd_config the directory with the authorized_keys file for the non-root users can be anywhere (for example in /sdcard/shell)

Execute as user root:

sed -i -e "s/.*StrictModes.*//g" -e "s/UsePrivilegeSeparation/StrictModes no\nUsePrivilegeSeparation/g" /data/ssh/sshd_config

and change the entry in the file /data/ssh/sshd_config for the authorized_keys file for the user shell, for example:

Match User shell
AuthorizedKeysFile /sdcard/shell/.ssh/authorized_keys

Afterwards restart the sshd:

/data/adb/modules/ssh/opensshd.init stop
/data/adb/modules/ssh/opensshd.init start

Now create the directories and files neccessary for the ssh access (see above) in the directory /sdcard/shell:

SUS_I006D:/ # find /sdcard/shell -exec ls -ld {} \;
drwxrws--- 3 u0_a118 media_rw 3452 2022-06-26 18:32 /sdcard/shell
drwxrws--- 2 u0_a118 media_rw 3452 2022-06-26 18:32 /sdcard/shell/.ssh
-rw-rw---- 1 u0_a118 media_rw 408 2022-06-26 18:32 /sdcard/shell/.ssh/authorized_keys
ASUS_I006D:/ #

and the access as user shell via ssh should work