- Make sure your phone is accessible from internet as explained here.
- You need a rooted device.
Android phones nowadays aren't those old low-end devices, they can run a full-featured SSH server happily. And it's an easy recipe:
- Get fully static
sshd binary for your phone's architecture. See details below.
/etc/shadow. To add a new user with password like we do on a Linux OS:
~# mount -o rw,remount /system; mount -o rw,remount /
~# touch /etc/passwd /etc/shadow
~# busybox adduser -D -H -h /dev/null -s /system/bin/false -u 900 sshd
~# busybox adduser -D -H -h /home/user1 -s /system/bin/sh -u 901 user1
~# toybox passwd user1
~# mkdir -p /data/home/user1/Documents /home /sdcard/home /etc/ssh
~# mount -o bind /data/home /home
~# mount -o bind /data/home /mnt/runtime/default/emulated/0/home
~# chmod 0750 /data/home/user1; chown 0.901 /data/home/user1
bind mount is required because otherwise SFTP's
chroot won't work with
/data's bad ownership. Second is to easily access shared files from
/sdcard/home. To set non-root permissions on
/sdcard/home, use bindfs instead.
sshd user is for Privilege Separation.
user1 is our first user that'll be able to login through SSH. In the same way more users can be added.
Add required configurations to
/etc/ssh/sshd_config (defaults suffice in most cases):
Subsystem sftp internal-sftp
Match User user1
Run SSH server, may use
logwrapper to get log in
~# ssh-keygen -A # generate host keys on first use
~# /system/bin/sshd -4 -E /sdcard/home/.sshd.log
Now you can access server through SFTP / SSHFS.
SSHD can also be run as an
init service that's handled by Android's
init. See this answer for explanation.
SSH server lets you login remotely after proper authentication. Additionally it serves sharing of files and many other resource sharing securely. But there is no concept of
Linux console login on Android (1) because it boots directly to GUI. However it makes use of Discretionary Access Control (DAC) of Linux kernel which is based on UIDs / GIDs and permission mode. Every installed app is considers as a *NIX user and is assigned a unique UID at install time. See this answer for more details on this.
HOW USER LOGIN AND AUTHENTICATION WORK:
/etc/passwd contained username vs. UID/GID mapping, while supplementary GIDs were added to
/etc/group. Password was also added to
/etc/passwd which was later moved to
/etc/shadow with the introduction of shadow password suite. Similarly
/etc/gshadow contains Secure Group Account Information. These files are read by privilege granting programs such as
sshd etc. and managed by administering programs such as
Most of these programs are part of shadow and util-linux package and their behavior is controlled by defining a number of configuration items in
/etc/login.defs, for instance logging of different events, password expiry, environment variables etc. Also there are many files that are required or updated by these utilities, including
limits files under
/var/run/wtmp and possibly others.
To centralize the functionality of these privilege granting and administering programs, a more sophisticated authentication mechanism PAM was introduced. Instead of directly handling the user login and authentication stuff, programs link to PAM libraries (called modules) which in turn respond accordingly depending on its configuration files mainly under
Other than PAM, a complicated name resolution mechanism NSS also (a set of modules) exists on Linux distros which controls - among many other things - how
shadow databases are read depending on its configuration file
/etc/nsswitch.conf. Both PAM and NSS can be configured to use remote database service like LDAP / NIS. And then there are centralized caching daemons like NSCD and SSSD. Working together, they complete the puzzle of user logins (identification and authentication) on Linux.
HOW TO SETUP LOGIN ENVIRONMENT ON ANDROID:
None of the above described configuration files and libraries exist on Android because user logins don't happen at all. But the programs built with Linux's standard libc APIs require all these files and services - including PAM - on Android too, which is near to impossible. PAM can be disabled for
sshd by setting
UsePAM no in
sshd_config so that it directly reads files
PAM be gone, still we need to provide a minimal environment that meets the least requirements of login process.
ssh binary for instance, needs
/etc/passwd to exist necessarily because it sets
$HOME from there to read
id_* key. Also if host is a domain name and not an IP address,
/etc/resolv.conf must exist with
nameserver for DNS to work. It's a different story explained here.
So we need to create the relevant files on Android manually. Or use the non-PAM counterparts of
shadow-utils such as
passwd to update these files. We can get a minimal set of these utilities on Android, e.g. with busybox or toybox.
RUNNING LINUX PROGRAMS ON ANDROID:
Ideally you should write / modify the source code of a program in accordance with Android environment and then build dynamic binaries / libraries using Android's NDK and Bionic libc. But due to differences among Linux distros and Android such as in filesystem hierarchy, kernel configuration, implementation of libc and other libraries (2), code written for Linux distros need heavy modification on Android, otherwise don't mind failed attempts. In case of
openssh, see the list of modification patches in AOSP and on Termux. Two of these patches are no password authentication (3) and no multiple users (4, 5). Former was worked around on Termux by introducing new APIs in termux-auth (6, 7), but the later can't be achieved without setting up login environment on Android.
Other options is to build fully static binary with Linux's libc such as
uClibc. While it's easy to statically build small libraries, libc itself links to many other libraries. In case of glibc, all of them can't be built statically, such as dynamically-loaded modules. I'm not sure how effective
--enable-static-nss is, but, e.g.
gconv can't be linked statically (8). So
sshd binary must not be built with
glibc, otherwise it won't work without NSS modules.
Also set Privilege Separation Path to some existing directory like
/data/local/tmp and disable any other unnecessary features like
lastlog etc. Or you would need to create
/var directory in