2

I have already:

  • A rooted Android 5.0 device (Stock-ROM, Magisk 19.3), Termux installed (termux-v0.79-offline-bootstraps.apk) and root permissions granted.
  • Installed rclone through official repository in Termux pkg install rclone.
  • Created a rclone sftp configuration rclone config under the name "sshfs-srv-rasp1". Obviously, I have a RaspberryPi-Server with ssh-server already running. Other Linux machines can successfully connect through ssh and sftp/sshfs.
  • Checked if the rclone configuration works: rclone ls sshfs-srv-rasp1: I get the correct file-listing from srv-rasp1. So the connection works.
  • Downloaded fusermount binary from https://forum.xda-developers.com/t/exe-static-linux-binaries-for-arm-android-cryptsetup-encfs-f2fs-tools-testdisk-photorec.3709380/page-4#post-76462538 (Filename=gocryptfs_fusermount-ARMHF.zip -> extract fusermount for arm - not arm64).
  • Copied fusermount to /data/data/com.termux/files/usr/bin, and gave maximal permissions 777 (everybody can execute).
  • Checked with fusermount -V, that fusermount can be successfully launched.
  • Created an empty directory /storage/emulated/legacy/srv-rasp1 as mount-point.

When executing rclone in Termux as normal user:

$ rclone -vvv mount sshfs-srv-rasp1: /storage/emulated/legacy/srv-rasp1

I get the following permission error (fusermount failes on permissions in /dev/fuse):
2022/10/09 09:24:25 mount helper error: fusermount: failed to open /dev/fuse: Permission denied

When trying as root with tsudo:

$ tsudo rclone -vvv mount sshfs-srv-rasp1: /storage/emulated/legacy/srv-rasp1

or with tsu:

tsu -c "rclone -vvv mount sshfs-srv-rasp1: /storage/emulated/legacy/srv-rasp1"

I get past the /dev/fuse problem, but now it halts on some other permission error, regarding fork/exec:
2022/10/09 09:38:33 Fatal error: failed to mount FUSE fs: fusermount: fork/exec /data/data/com.termux/files/usr/bin/fusermount: permission denied

Another approach to get rclone executed with root privileges is to use (su -c "XXXX"). The problem is, with su we lose the enviromental variables $PATH, $HOME, which are needed for the shell to locate executables ($PATH), and for rclone to load $HOME/.config/rclone/rclone.conf. The workaround is to explicitly pass these variables to the command (emphasis on double quotation marks "", not ''):

su -c "PATH=$PATH HOME=$HOME rclone -vvv mount sshfs-srv-rasp1: /storage/emulated/legacy/srv-rasp1"

Result: rclone is correctly located and successfully executed in PATH=/data/data/com.termux/files/usr/bin, the configuration file /data/data/com.termux/files/home/.config/rclone/rclone.conf is, too, successfully loaded, BUT the error: "fork/exec ... permission denied" remains.

How can I get past these permissions errors?

1
  • Most probably related to mount namespace or SELinux. Already reported by others. Instead of using sudo or su -c or tsu -c, better open a root shell and run commands from there. You can also use strace to get the error more precisely. And I hope you've gone through this answer of mine. Oct 9, 2022 at 12:40

1 Answer 1

2

"Android permissions are a beast".

In desktop-Linux if you have root permissions you get spoiled to be able to do everything (good or bad). I found out, that in Android even if you execute something with root permissions, you are still not almighty, and need some tweaks. Maybe it is better this way ...

Below I will explain how I successfully mounted my sftp-share on a mount-point using Termux, and made it accessible to all users/apps/file explorers. Credits to MountainX: In his post How to automate rclone-mount without Termux or Magisk? he paved the way to break through the permissions-jungle for clone-mount without Magisk/Termux. I believe one can do it within Termux/Magisk as well. The obvious advantage is scriptability, cronjobs to regularly check/restore connections etc.

Steps:

  • I prefer doing command-line stuff on Termux using my keyboard from a desktop through ssh, and not on the touchscreen (in case somebody is interested, summary for a quick-setup but not the most secure: $ pkg install openssh, create a password with $ passwd, launch $ sshd, find your android's ip with $ ifconfig, look under wlan0 the entry: inet 192.168.XXX.XXX, login to your android device from a desktop with $ ssh 192.168.XXX.XXX -p 8022). When inside Termux I also strongly suggest exploring directories with Midnight-Commander: $ pkg install mc. All the following steps were performed through ssh-connection(s) from the terminal-emulator of a desktop computer. Main advantage: one can have multiple ssh-connections, for example one as root-CLI, a second as normal-user-CLI, a third with 'midnight-commander' to check the results of mounting.
  • In Magisk-Manager-Settings of the android-device find the "Namespace" Option and choose "Global namespace" or "Inherited namespace" (for the time being it is working with both, if I find some problems in the future I will edit the answer).
  • The executables rclone and fusermount MUST be in /system/bin AND have ownership system:shell. NOT root:root. It seems, when launched that way they break through the permissions-jungle. Other combinations do not work (for example ownerships changed but launched from another directory). But it is not straightforward how to copy them in /system/bin because it is generally mounted read-only. Supposing both files are already installed in /data/data/com.termux/files/usr/bin, we must (a) make /system/bin writable, (b) copy them (c) change ownerships and mod, (d) restore /system/bin as read-only.

In Termux:

$ su
# mount -o rw,remount /system
# cp /data/data/com.termux/files/usr/bin/rclone /system/bin/
# cp /data/data/com.termux/files/usr/bin/fusermount  /system/bin/
# chown system:shell /system/bin/rclone
# chmod 775 /system/bin/rclone
# chown system:shell /system/bin/fusermount
# chmod 775 /system/bin/fusermount  
# mount -o ro,remount /system
# exit
$
  • Now we can launch rclone/fusermount through su -c "XXXX" again, but this time through their /system/bin/ copies. By the way, we do not need to pass $PATH variable any more. In my search I discovered the su --mount-master option as well.

su --mount-master -c "HOME=$HOME rclone -vvv mount sshfs-srv-rasp1: /storage/emulated/legacy/srv-rasp1 --allow-other"

As long as the above command is up and running, the mount-point /storage/emulated/legacy/srv-rasp1 is successfully linked to the sftp-share. The option "--allow-other" allows users other than root to have access. I could confirm access through a separate ssh-connection with 'midnight-commander'. But the moment the command is killed with Ctrl-c, the connection closes.

  • You can add the "--daemon" option to have it run in background. You can check anytime that rclone is still alive with pgrep rclone

  • In order to kill the connection gracefully: su -c "fusermount -u -z /storage/emulated/legacy/srv-rasp1". Note the -z ("lazy") option: it forces unmount even when someone is using the share. This command kills rclone in the background (check with pgrep).

  • What mount point to choose? My suggestion is, to create a mountpoint-directory in a place accessible from all apps. A good place is somewhere in internal-SD, typically /storage/emulated/0/XXXX or /storage/emulated/legacy/XXXX. You must check in your specific android variant where it lives. Beware, that that termux and su -c "XXXX" may see different things under /storage/emulated !. For example, on my Samsung Tab4:

    $ ls /storage/emulated
    0  legacy
    

    but

    $ su -c "ls /storage/emulated"
    legacy
    

    Interestingly, both /storage/emulated/0 and /storage/emulated/legacy refer to the same internal SD-Card. Since rclone command is executed through su -c "XXXX", I decided to use the common denominator "legacy". You have to check in your device the exact path through which su -c "XXXX" sees the internal SD-Card.

Until now, our sftp-share is accessible only within termux. Other apps (e.g. File-Explorer) don't have access. This has to do with ownerships/permission granted to the mount-point by rclone.

Check while rclone is running:

ls -l /storage/emulated/legacy/
drwxrwx--- 2 root sdcard_r 4096 Jan  1  2014 Alarms
drwxrwx--x 5 root sdcard_r 4096 Sep 22 17:47 Android
drwxrwx--- 2 root sdcard_r 4096 Jan  1  2014 DCIM
drwxrwx--- 3 root sdcard_r 4096 Oct  6 18:14 Documents
drwxrwx--- 3 root sdcard_r 4096 Oct  8 17:28 Download
...
drwxr-xr-x 1 root root        0 Oct  9 14:38 srv-rasp1

Ownership of mount-point srv-rasp1 is root:root. Changing the ownership out-of-connection has no effect: rclone grants again root:root. Even my rooted ES-Explorer could not see the content of srv-rasp1. The solution is to tweak the ownerships in rclone: --gid 9997 --dir-perms 0771 --file-perms 0660 --umask=0

The command so far:

su --mount-master -c "HOME=$HOME rclone -vvv mount sshfs-srv-rasp1: /storage/emulated/legacy/srv-rasp1 --gid 9997 --dir-perms 0771 --file-perms 0660 --umask=0 --allow-other --daemon"

Check ownerships/permissions again:

$ ls -l /storage/emulated/legacy
drwxrwx--- 2 root sdcard_r  4096 Jan  1  2014 Alarms
drwxrwx--x 5 root sdcard_r  4096 Sep 22 17:47 Android
drwxrwx--- 2 root sdcard_r  4096 Jan  1  2014 DCIM
drwxrwx--- 3 root sdcard_r  4096 Oct  6 18:14 Documents
drwxrwx--- 3 root sdcard_r  4096 Oct  8 17:28 Download
...
drwxrwx--x 1 root everybody    0 Oct  9 14:46 srv-rasp1

Voila. Mount-point srv-rasp1 was given group-ownership "everybody". ES-Explorer and all other apps can now access see the contents of srv-rasp1 mount.

Some comments, slightly unrelated to the question but still interesting:

  • rclone mounts as "root" directory by default not the actual root ("/") but the HOME directory ("/home/XXXX/") of the user who logs in the ssh/sftp server. In order to override this, I found a not-so-clear answer here: https://github.com/rclone/rclone/issues/4307. By experimenting, I discovered that rclone accepts the general syntax of Linux sshfs command: server:/path/to/mount/, with the remark that instead of "server" we give the configuration-name. So, if I want to mount srv-rasp1/mnt/ I simply have to type: ... rclone mount sshfs-srv-rasp1:/mnt /storage/emulated/legacy/srv-rasp1 .... The mount-point will be showing now the contents of srv-rasp1/mnt/
  • In his post MountainX adds some rclone options regarding vfs and cache stuff. This is beyond my knowledge but seems to achieve a seamless interaction between device <-> server, simultaneous writing/reading etc. I simply added them to the command line.

Below my final command:

su --mount-master -c "HOME=$HOME rclone -vvv mount sshfs-srv-rasp1:/mnt /storage/emulated/legacy/srv-rasp1 --gid 9997 --dir-perms 0771 --file-perms 0660 --umask=0 --cache-dir /storage/emulated/legacy/.cache --vfs-cache-mode full --vfs-cache-max-age 2h0m0s --vfs-cache-poll-interval 5m0s --allow-other --daemon"

In my setting, I didn't need:

  • to tweak anything regarding SELinux (see also the comment of MountainX in the above mentioned link).
  • to pass any Termux enviromental variable regarding libraries (e.g. LD_LIBRARY_PATH=$LD_LIBRARY_PATH). The executables rclone and fusermount are stand-alone, don't need any external libraries.
  • to tweak anything regarding namespaces (e.g. readlink or nsenter stuff), as Irfan Latif suggested (see How to mount rclone on Android? )

However, I can not exclude that the above mentioned tweaks could be needed in other settings. For this reason I mention them.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .