OpenSSH is a complete implementation of the SSH protocol (version 2) for secure remote login, command execution and file transfer. It includes a client ssh
and server sshd
, file transfer utilities scp
and sftp
as well as tools for key generation (ssh-keygen
), run-time key storage (ssh-agent
) and a number of supporting programs.
This is a port of OpenBSD's OpenSSH to most Unix-like operating systems, including Linux, OS X and Cygwin done by https://github.com/openssh/openssh-portable, and further tailored to limited Android environment (adb shell). Android shell does not provide user names and account information, such as /etc/passwd. Furthermore, this version limits encryption protocols to internal implementations. As a result, a complex dependency on libcrypto
is lifted off, and ed25519
becomes the only supported (and still - the best one!) encryption protocol (that is, no DSA or RSA support). The low-level installation process involves access to the base system and therefore requires a bootloader with permissive recovery mode, such as TWRP. Android-specific domain name resolution is delegated to an external nslookup
executable.
The official documentation for OpenSSH are the man pages for each tool:
The instructions below assume armv7. You may need to adjust the compiler to target armv8 (arm64) variant.
- Obtain GCC ARM cross toolchain:
sudo apt install gcc-arm-linux-gnueabi
- Build Musl:
git clone git://git.musl-libc.org/musl
cd musl
mkdir build
cd build
../configure --prefix=$(pwd)/../install
Make a small change into the system(char*)
implementation:
--- a/src/process/system.c
+++ b/src/process/system.c
@@ -32,7 +32,7 @@ int system(const char *cmd)
posix_spawnattr_setsigmask(&attr, &old);
posix_spawnattr_setsigdefault(&attr, &reset);
posix_spawnattr_setflags(&attr, POSIX_SPAWN_SETSIGDEF|POSIX_SPAWN_SETSIGMASK);
- ret = posix_spawn(&pid, "/bin/sh", 0, &attr,
+ ret = posix_spawn(&pid, "/system/bin/sh", 0, &attr,
(char *[]){"sh", "-c", (char *)cmd, 0}, __environ);
posix_spawnattr_destroy(&attr);
Then proceed to building and installation:
make -j12 && make install
-
Build and install Bash 5.0, which is going to be used for the login shell as show here: https://github.com/dmikushin/bash-anrdoid
-
Build and install simplistic nslookup equivalent to be used as an external domain name resolution utility: https://github.com/dmikushin/nslookup-android
-
Build OpenSSH with minimum dependencies, statically linking against Musl:
git clone https://github.com/dmikushin/openssh-android
cd openssh-android
autoconf
mkdir build
cd build
LDFLAGS=-static CFLAGS="-D__ANDROID__ -O3 -fomit-frame-pointer -ffast-math" CC=$(pwd)/../../musl/install/bin/musl-gcc ../configure --prefix=$(pwd)/../install --host=arm-linux-gnueabi --without-zlib --without-openssl
Reboot your phone into accessible recovery mode, such as TWRP. Mount /system partition as writable and use adb
to roll the compiled OpenSSH binaries:
adb push ./ssh /system/bin/
adb push ./sshd /system/bin/
adb push ./ssh-keygen /system/bin/
adb push ./sshd_config /system/etc/ssh/
Furthermore, we would want to generate the host SSH keys by manually calling ssh-keygen
:
adb shell
ssh-keygen -f /system/etc/ssh/ssh_host_ed25519_key -N '' -t ed25519
Generate another key pair to be used for remote authentication:
adb shell
ssh-keygen -f /system/etc/ssh/ssh_user_key -N '' -t ed25519
mv /system/etc/ssh/ssh_user_key.pub /system/etc/ssh/authorized_keys
exit
adb pull /system/etc/ssh/ssh_user_key ./
adb shell rm /system/etc/ssh/ssh_user_key
Reboot the phone into Android and launch the SSH server:
adb shell
/system/bin/sshd
exit
Given that the phone has a reachable IP address (e.g. the phone is connected to your home wireless router), connect to it directly:
$ ssh 192.168.12.202 -p 2222 -i ./ssh_user_key
shell@alto5_premium:/ $ uname -a
Linux localhost [email protected]_rb1.29-MIUI-Kernel #1 SMP PREEMPT Tue Jan 9 15:35:54 MSK 2018 armv7l GNU/Linux