Scratchbox remote shell with sshfs
Introduction
This document describes how to set up Scratchbox remote shell between Nokia Internet Tablet running OS2008 and host Linux machine running either the Scratchbox 1 or Scratchbox 2 build environments.
Scratchbox Remote Shell (sbrsh) is used to provide CPU Transparency for cross-compiling with Scratchbox. CPU Transparency means foreign architecture binaries are executed in a way that is transparent in the build environment, thus foreign architecture binaries can be executed alike native binaries. Scratchbox 1 uses binfmt_misc mechanism to register a misc_runner helper command in the Linux kernel. Scratchbox 2 implements this using run_cputransparency function in the libsb2 preload library. These in turn call a helper command to execute the foreign architecture binary. The current default installation in both systems use QEMU user mode emulation.
Instead of emulating the target environment, sbrsh runs binaries seamlessly on the actual target hardware. This is useful when QEMU user space emulation doesn't support some functionality properly. The sbrsh client program connects to a remote machine running sbrshd server. When the server has authorized the connection, the client first requests it to mount a remote filesystem. When the filesystem has been mounted over network connection, the sbrshd server executes a binary given as argument to sbrsh client. The client sbrsh is typically run on host Linux machine where cross-compiling takes place. The server process sbrshd runs on target hardware.
Earlier versions of sbrsh used NFS network filesystem for remote mounts. The latest versions support sshfs, which is easier to set up because most SSH servers support the protocol and there is no need for additional daemons on the host and target Linux machines. sshfs is a network filesystem based on the SSH File Transfer Protocol. sshfs is implemented using FUSE, which provides a library and a kernel module to implement filesystems in Linux userspace. See sshfs and FUSE project pages on more information.
See the current README or the (somewhat outdated) Scratchbox Remote Shell user documentation for more information on sbrsh.
Scratchbox Remote Shell is licensed under the terms of the GNU General Public License version 2.
Known limitations
With Scratchbox 2: The configuration used for sbrsh doesn't see the same path mappings that are present under Scratchbox. For this reason, it is necessary to run the compilation in a directory under the active rootstrap. Currently you can't use sbrsh if you are compiling under your home directory.
With Scratchbox 1 and Scratchbox 2: The sbrsh configuration file must have the fully-specified path mappings for your Scratchbox mounts (with target and rootstrap encoded), meaning that you need a separate configuration for each target, specifying its SDK. The -t and -c options can be used to select alternate configurations when using multiple devices or rootstraps.
The sbrsh communication happens on a TCP/IP connection and is not encrypted. The Scratchbox remote shell is meant to be used only on trusted networks, such as a company's LAN or an USB network between a PC and a handheld device.
sbrsh does not support user authentication. Again, only use it on trusted networks.
Packages and modifications
The Busybox 1.6.1 (version used in OS2008) mount applet doesn't have support for calling external mount helpers, such as /sbin/mount.fuse, when mounting a filesystem. Later versions of Busybox have this functionality, but the Busybox package cannot be updated with the Application Manager. Application Manager is set to upgrade system packages only from system update repository. Instead of upgrading Busybox or backporting the functionality, the mount command from util-linux is used instead. The command has been packaged in mount-full package and installs binaries to /bin/mount.full and /bin/umount.full.
FUSE has been modified to call these binaries by changing hardcoded references to /bin/mount and /bin/umount to PROG_MOUNT and PROG_UMOUNT defines, which are defined at configure-time to point to /bin/mount.full and /bin/umount.full.
Scratchbox Remote Shell (sbrsh) with sshfs support is now part of the upstream sbrsh git repository and is also available in Debian source package sbrsh version 7.6.
Requirements
This document assumes Nokia N8x0 Internet Tablet target with freshly installed OS2008 image (diablo) on the device side and Scratchbox 1 or Scratchbox 2 build environment running on the host Linux machine's side. You will also need root access on the Internet Tablet device. See How Do I Become Root on maemo.org wiki.
Install required packages on a host Linux machine
For Scratchbox 1:
Support of sbrsh is included in Scratchbox CPU transparency devkit versions 1.0.7 and later. On a Debian-based system add the following lines to your system /etc/apt/sources.list file and run sudo apt-get update:
deb http://scratchbox.org/debian/ apophis main
Upgrade the scratchbox-devkit-cputransp package on the host by running sudo apt-get install scratchbox-devkit-cputransp .
For non-Debian based systems, see the Scratchbox Apophis download page.
For Scratchbox 2:
On a Debian-based system, add the following lines to your system /etc/apt/sources.list file and run sudo apt-get update:
deb http://maemo-sdk.garage.maemo.org/download/host experimental free
Install the sbrsh package on the host by running sudo apt-get install sbrsh .
On non-Debian based systems, pull source from sbrsh git repository from source and run sudo make install.
Install required packages on Internet Tablet
Run task-sbrshd.install on the device to install the required packages using the Application Manager. This will install the following packages on Internet Tablet:
libfuse2 fuse-modules-rx-34 fuse-utils libblkid1 libuuid1 mount-full ssh sshfs sbrshd
Setup networking between the Internet Tablet and host Linux machine
The Internet tablet and host Linux machine can be connected via USB. The simplest way to establish networking between the host and the tablet is to install the maemo PC connectivity metapackage on the device:
maemo-pc-connectivity.install This provides a control panel applet, USB Networking, for setting up USB networking. The applet is configured to use static IP address 192.168.2.15 for the tablet and 192.168.2.14 for the host. This document also uses these IP addresses. The host in the Internet Tablet /etc/hosts has also been modified to point to the IP of the host computer using tablet as hostname instead of the IP address.By default, the USB connection provides USB mass storage access to the memory card, and needs to be switched to USB networking. The control panel applet USB Networking allows changing to USB networking mode, but the applet has a few quirks:
- When USB networking is in use, USB cable disconnections are not properly detected by Linux HAL.
- Any memory card mounts are unmounted while USB cable connection is detected, even in USB networking mode.
- Does not integrate with Internet Connectivity Daemon, other than providing a dummy entry.
- Not possible to use USB networking with Hildon applications that use Internet Connectivity, such as browsers, due to missing name resoving. USB networking uses static IP address and cannot have information about DNS, except when manually configured, thus DNS name resolving doesn't work.
- Multiple default routes might appear in the routing table if many networking connections are in place.
If you want to configure networking manually:
You will need a network between Internet tablet and host Linux machine. If you don't have a private network set up, you may for example follow USB networking HOWTO to setup USB networking.
Add user
Add your username as a user to the Internet Tablet (replace you with your username) and uid/gid on your uid/gid on the host Linux machine. Example commands run on Internet Tablet:
~ > groupadd -g 1000 you ~ > useradd -u 1000 -g you -d /home/you -s /bin/sh you ~ > mkdir /home/you ~ > chown you:you /home/you
Configure Secure Shell
sshfs requires passwordless login to ssh server running on the host Linux machine. This is so that sshfs won't stop to ask for password and fail.
Note: this is removing password validation when using ssh to connect from the device to the host, and not the usual passwordless login you may desire in the other direction, which is a separate step (but pretty much identical, except with switched target and host).
You can set this by creating public/private key pair and by sharing this key between the devices. Create a ssh key using ssh-keygen on the Internet Tablet, leaving the passphrase empty. Add the generated to authorized keys under your home directory ~/.ssh/authorized_keys on the host Linux machine.
Run these commands on the tablet, replacing you with your username:
~ > su - you ~ $ ssh-keygen -t rsa Generating public/private rsa key pair. Enter file in which to save the key (/home/you/.ssh/id_rsa): Created directory '/home/you/.ssh'. Enter passphrase (empty for no passphrase): Enter same passphrase again: Your identification has been saved in /home/you/.ssh/id_rsa. Your public key has been saved in /home/you/.ssh/id_rsa.pub. The key fingerprint is: ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff you@Nokia-N810-51-3
Add the key-generated ssh key in the Internet Tablet user's home directory ~/.ssh/id_rsa.pub to your Linux host user's home directory ~/.ssh/authorized_keys . Change permissions of .ssh and authorized_keys to only readable by user.
Log in to host Linux machine side to add host to list of known hosts and to test the ssh connection. Example commands run on Internet Tablet. Match your username (replace you with your username):
~ > su - you ~ $ ssh host The authenticity of host 'host (192.168.2.14)' can't be established. RSA key fingerprint is ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff. Are you sure you want to continue connecting (yes/no)? yes Warning: Permanently added 'host,192.168.2.14' (RSA) to the list of known hosts.
Again, if you're newly configuring your tablet, you will probably want to repeat this process in the opposite direction (Run ssh-keygen on host, copied to authorized_keys on device), for passwordless login to the device.
Configure sbrshd on Internet Tablet
Scratchbox remote shell is meant to be used only on trusted networks
Warning: The settings shown in this section are now default configurations in packages with maemo tag in version string. This is enabled by default.
Edit /etc/default/sbrshd on Internet Tablet to enable sbrshd. Change ENABLE option to true and MOUNT_BIN and UMOUNT_BIN to point in util-linux versions of mount and umount:
ENABLE=true MOUNT_BIN=/bin/mount.full UMOUNT_BIN=/bin/umount.full
sbrshd only accepts connections from an IP listed in /etc/sbrshd.conf. Add your host Linux machine's IP as a trusted host to this file, one IP address per line. For example:
192.168.2.14
Start fuse and sbrshd on Internet Tablet:
~ > /etc/init.d/fuse start Starting filesystem in userspace: fuse. ~ > /etc/init.d/sbrshd start Starting sbrshd: done.
Configure sbrsh on host Linux machine
sbrsh is configured in $HOME/.sbrsh (in Scratchbox 2) and /scratchbox/users/you/targets/CHINOOK_ARMEL.sbrsh (in Scratchbox 1 target CHINOOK_ARMEL username you) Format of ~/.sbrsh file follows:
# Format: # # <name> <hostname>[:<port>] # nfs|bind|sshfs <filesystem> <mountpoint> [<options>] # ...
Example configuration for Scratchbox 1:
Example sbrsh configuration file /scratchbox/users/you/targets/CHINOOK_ARMEL.sbrsh for username you and target CHINOOK_ARMEL :
sshfs-target tablet ssh you@host:/scratchbox/users/you/targets/CHINOOK_ARMEL/ / rw,nonempty,allow_other ssh you@host:/scratchbox/users/you/home/you/ /home/you rw,nonempty,allow_other bind /tmp /tmp bind /dev /dev bind /dev/pts /dev/pts bind /proc /proc bind /sys /sys
Edit CHINOOK_ARMEL target configuration in /scratchbox/users/you/targets/CHINOOK_ARMEL.config configuration file. Change SBOX_CPUTRANSPARENCY_METHOD to read:
SBOX_CPUTRANSPARENCY_METHOD=/scratchbox/devkits/cputransp/bin/sbrsh
Example Configuration for Scratchbox 2:
Example configuration file ~/.scratchbox2/chinook40_armel/sbrsh.config for maemo SDK+ chinook rootstrap target chinook40_armel:
sshfs-target tablet ssh you@host:/home/you/.maemo-sdk/rootstraps/armel/chinook40_armel/ / rw,nonempty,allow_other ssh you@host:/home/you/ /home/you rw,nonempty,allow_other bind /tmp /tmp bind /dev /dev bind /dev/pts /dev/pts bind /proc /proc bind /sys /sys
To use sbrsh as the CPU transparency method in Scratchbox 2 on your target, create a new target using sb2-init or edit existing Scratchbox 2 target configuration e.g. ~/.scratchbox2/chinook40_armel/sb2.config . Edit the setting SBOX_CPUTRANSPARENCY_METHOD in that file:
export SBOX_CPUTRANSPARENCY_METHOD=/usr/bin/sbrsh
Test the CPU transparency method by running an armel binary.
Editing configuration files
To allow the host computer's IP to point to the tablet hostname of the Internet Tablet, rather than its IP address, add host to /etc/hosts on the Internet Tablet. List sshfs entries first as unmounting takes place in reverse order.
When changing the sbrsh configuration file, sbrsh --umount should be done first, followed by edits, then an optional sbrsh --mount , because these commands read the current sbrsh configuration and don't remember previous mounts. Otherwise you might get strange errors or failures to mount.
The mounts must appear in order of increasing depth. In other words, the root must be mounted first, followed by entries that live inside the root, and so on.
A bind entry will substitute the target's original filesystem directory into the mapped filesystem using bind mounts. Thus the actual /proc from the target and not the host's or Scratchbox target's /proc will be reflected in the target.
Now you should be able to use sbrsh to run a command on the Internet Tablet.
Running sbrsh
Try running the following command on host Linux PC to see if the mount works:
~ $ sbrsh /bin/sh sh-2.05b$
If you instead get an error like this:
~ $ sbrsh /bin/sh sbrsh server: Can't execute command: /bin/sh (Permission denied)
In this case, the issue is likely not that there is an access error or that permissions are wrong. Instead, this may be the result of a failure to run chroot command on the target – which would happen if you're missing a mount for root / mount is in your .sbrsh and the sandbox mode is enabled (this is the default).
If your rootstrap doesn't have a shell, like the case in maemo SDK+ with chinook rootstrap, you will need one. Build busybox using Scratchbox 2 and extract the resulting Debian package it with dpkg-deb -x ~/.maemo-sdk/rootstraps/armel/chinook40_armel to your target. Note that the package is not installable because of conflicts with different tools which expect GNU tools to be in use.
If you're able to launch the shell, you should now see a shell inside the Internet Tablet. In case there are any problems, configure debugging output in /etc/default/sbrshd configuration (DEBUG=true) and restart the server. Sample parts of a log file resulting from successful execution (timestamps removed for clarity):
2487 DAEMON New connection 2487 DAEMON Client IP address is 192.168.2.14 [...] 2487 DAEMON Searching for host 192.168.2.14 in /etc/sbrshd.conf 2487 DAEMON Found matching line: 192.168.2.14 [...] 2487 DAEMON Sandbox root is /var/sbrshd/you@192.168.2.14/sshfs-target 2487 DAEMON /var/sbrshd/you@192.168.2.14/sshfs-target/ is not mounted 2487 DAEMON Creating directory /var/sbrshd/you@192.168.2.14/sshfs-target/ 2487 DAEMON Executing: /usr/bin/sshfs [...] 2513 EXECUTE Changing to group ID 1000 2513 EXECUTE Changing to user ID 1000 2487 DAEMON /var/sbrshd/you@192.168.2.14/sshfs-target/dev is not mounted 2487 DAEMON Creating directory /var/sbrshd/you@192.168.2.14/sshfs-target/dev 2487 DAEMON Executing: /bin/mount.full [...] [...] 2526 COMMAND Changing root directory to /var/sbrshd/you@192.168.2.14/sshfs-target 2525 HANDLER Managing process 2526 [...] 2487 DAEMON Process 2525 returned: 0 2487 DAEMON Found mounts for pid 2525 2487 DAEMON Releasing mount /var/sbrshd/you@192.168.2.14/sshfs-target/ (0 users remain) 2487 DAEMON Releasing mount /var/sbrshd/you@192.168.2.14/sshfs-target/dev (0 users remain) [...] 2487 DAEMON Checking for expired mounts 2487 DAEMON Waiting for connection
Known problems
Building packages with Scratchbox 2
Files that are run under sbrsh do not see the path mappings that are present under Scratchbox 2. For this reason, it is necessary to run the compilation in a directory under the active rootstrap. Currently you cannot use sbrsh with Scratchbox 2 when compiling under your home directory. For example, target chinook40_armel rootstrap root is located under this directory:
~/.maemo-sdk/rootstraps/armel/chinook40_armel
Note that in the example of sbrsh mounting rules, the directory/tmp is bind mounted from the target and thus the directory /tmp under the rootstrap root is not visible.
Rejected SSH host key or rejected authentication is not reported
sbrsh and sshfs do not properly propagate error messages from ssh if host key has changed, or if remote authentication fails. The following error message is a known symptom:
read: connection reset by peer
If sbrsh is unable to mount, follow these steps to detect the exact problem:
- Invoke sshfs from command line the device to host (as user). With debugging enabled, the exact command is shown in /var/log/sbrshd.log .
- Invoke ssh from command line on the device to host (as user). Try adding more verbosity levels to detect if there is a key exchange problem.
- Finally, see that all the keys are in place and match. If the host key has changed, redo the entries in .ssh/authorized_keys (host), .ssh/known_hosts (host), .ssh/id_rsa (device) and .ssh/id_rsa.pub (device).
Launching Hildon applications via sbrsh
If you receive the error message "osso_initialize() failed" when launching Hildon applications via sbrsh, the problem is likely due to the dbus client (from libdbus library) failing to connect to a dbus server. The DBUS_SESSION_BUS_ADDRESS environment variable is passed (like unix:abstract=/tmp/dbus-J2ijFdz9wV,guid=a617635b16cb8ba899fc2500480377e4) and this is referred to a socket that does not exist on the tablet due to bind mount pointing to the tablet's /tmp . Manually set DBUS_SESSION_BUS_ADDRESS to the tablet-side value (e.g. unix:path=/tmp/session_bus_socket), and ensure /tmp is a bind mount. After this maemo applications can be started.