This Magisk module contains OpenSSH 9.9p2 for Android

These OpenSSH binaries are compiled with SELinux support.

All binaries are dynamically linked for the default Android libraries only , e.g:

ASUS_I006D:/ # ldd /system/bin/ssh                                                                                                                                                                                                     
	linux-vdso.so.1 => [vdso] (0x7c388db000)
	libdl.so => /apex/com.android.runtime/lib64/bionic/libdl.so (0x7c376e4000)
	libc.so => /apex/com.android.runtime/lib64/bionic/libc.so (0x7c324f9000)
ASUS_I006D:/ # 


The configure options used are copied from the Termux Build script for OpenSSH:

    https://github.com/termux/termux-packages/blob/master/packages/openssh/build.sh

The configure command used to create the config for Compiling OpenSSH in Android is in the file

   source/myconfigure

in the Magisk Module

All patches for OpenSSH from Termux that are useful for a Magisk Module with OpenSSH are applied to the source code.

The patches for OpenSSH in Termux are available here:

    https://github.com/termux/termux-packages/tree/master/packages/openssh

The patches used are in the directory ./source/patches in the Magisk Module; the patches were copied from the repo at 2024-10-04.
The script source/patches/apply_patches.sh can be used to apply the patches.

An additional patch was necessary to get the OpenSSH binaries working for the user shell:

Source: https://stackoverflow.com/questions/76376942/openssh-9-3p-fails-to-build-for-android
(This is the patch misc.c.additional.patch in the directory source/patches in this Magisk Module)

 ----

2024-01-31 I've little idea if my post is of any help, but anyway, today I built LP64 version of ssh client and found that, LP64 version of struct passwd does have pw_gecos member (so you need to set ac_cv_member_struct_passwd_pw_gecos=yes for LP64 build), but, the value of it is set to NULL, causing SEGV, at least on Android 8.0 device with uid = AID_SHELL (2000). So you need to fix the source like this.

diff -rup openssh-9.6p1/misc.c openssh-9.6p1-droid-p01/misc.c
--- openssh-9.6p1/misc.c        2023-12-18 23:59:50.000000000 +0900
+++ openssh-9.6p1-droid-p01/misc.c      2024-01-31 17:10:46.530066587 +0900
@@ -488,7 +488,7 @@ pwcopy(struct passwd *pw)
        copy->pw_name = xstrdup(pw->pw_name);
        copy->pw_passwd = xstrdup(pw->pw_passwd == NULL ? "*" : pw->pw_passwd);
 #ifdef HAVE_STRUCT_PASSWD_PW_GECOS
-       copy->pw_gecos = xstrdup(pw->pw_gecos);
+       copy->pw_gecos = xstrdup(pw->pw_gecos == NULL ? "null" : pw->pw_gecos);
 #endif
        copy->pw_uid = pw->pw_uid;
        copy->pw_gid = pw->pw_gid;

 ---

OpenSSH has been configured with the following options:
                     User binaries: /system/usr/bin
                   System binaries: /system/usr/sbin
               Configuration files: /system/etc/ssh
                   Askpass program: /system/usr/libexec/ssh-askpass
                      Manual pages: /system/usr/man/manX
                          PID file: /data/local/tmp/var/run
  Privilege separation chroot path: /data/local/tmp/var/empty
            sshd default user PATH: /system/bin
                    Manpage format: doc
                       PAM support: no
                   OSF SIA support: no
                 KerberosV support: no
                   SELinux support: yes
                   libedit support: yes
                   libldns support: yes
  Solaris process contract support: no
           Solaris project support: no
         Solaris privilege support: no
       IP address in $DISPLAY hack: no
           Translate v4 in v6 hack: no
                  BSD Auth support: no
              Random number source: OpenSSL internal ONLY
             Privsep sandbox style: none
                   PKCS#11 support: yes
                  U2F/FIDO support: yes

              Host: aarch64-unknown-linux-android
          Compiler: /data/develop/android/android-ndk-r27b/toolchains/llvm/prebuilt/linux-x86_64/bin/aarch64-linux-android33-clang
    Compiler flags: --sysroot /data/develop/android/android-ndk-r27b/toolchains/llvm/prebuilt/linux-x86_64/sysroot/ -O2 -w -I/data/develop/android/sysroot/usr/include -I/data/develop/android/android-ndk-r27b/toolchains/llvm/prebuilt/linux-x86_64/sysroot//usr/include -Wno-implicit-function-declaration -Wno-int-conversion -fPIE -I/data/develop/android/sysroot/selinux/usr/include -DHAVE_SETRESGID=1 -pipe -Wunknown-warning-option -Wno-error=format-truncation -Qunused-arguments -Wall -Wextra -Wpointer-arith -Wuninitialized -Wsign-compare -Wformat-security -Wsizeof-pointer-memaccess -Wno-pointer-sign -Wno-unused-parameter -Wno-unused-result -Wimplicit-fallthrough -Wmisleading-indentation -Wbitwise-instead-of-logical -fno-strict-aliasing -D_FORTIFY_SOURCE=2 -ftrapv -fzero-call-used-regs=used -ftrivial-auto-var-init=zero -mretpoline -fno-builtin-memset -Dfd_mask=int  
Preprocessor flags: -I/data/develop/android/sysroot/usr/include  -DHAVE_ATTRIBUTE__SENTINEL__=1 -DBROKEN_SETRESGID  -I/system/usr/include -I/data/local/tmp/develop/sysroot/usr/include
      Linker flags: -L/data/develop/android/sysroot/usr/lib -L/data/local/tmp/develop/sysroot/usr/lib --sysroot /data/develop/android/android-ndk-r27b/toolchains/llvm/prebuilt/linux-x86_64/sysroot/  -s -ffunction-sections -fdata-sections -Wl,--gc-sections -L/data/develop/android/sysroot/usr/lib -L/data/develop/android/android-ndk-r27b/toolchains/llvm/prebuilt/linux-x86_64/sysroot//lib -L/data/develop/android/sysroot/selinux/usr/lib -ldl -lcrypto -lssl -lpcre2  -Wl,-z,relro -Wl,-z,now -Wl,-z,noexecstack -Wl,-z,retpolineplt -L/system/usr/lib 
         Libraries: -lldns  -lselinux
     +for channels: -lcrypto  -lz



Trouble Shooting

Due to the energy saving functions of Android, the wifi connection can be put into sleep mode too often, so that the ssh connection to the phone is very sluggish. To work around this problem, start a ping command in the background to use the WIfi connection continuously, e.g:

ping -i 0.2 192.168.1.1 >/dev/null & 


hostname resolution via DNS is not possible if the sshd was started via the Magisk service.sh script and the current user in the ssh session is NOT the root user. To work around this issue, either restart the sshd in an adb session or execute the commands that need hostname resolution via DNS in the ssh sessions as user root. The script

restart_ssh_daemon

can be used in an adb session to restart the sshd. 


To execute the customize script of the Magisk Module with "set -x" and write STDOUT and STDERR to the file /data/local/tmp/openssh_customize.log create the (probably empty) file /data/local/tmp/debug before installing the Magisk Module.


To execute the service script to start the sshd with "set -x" and write STDERR and STDLOG messages to the file /data/local/tmp/start_sshd.log create the file /data/local/tmp/debug before rebooting the phone.


 ---

History

21.02.2025 9.9p2.v1.0.0
  initial release

20.06.2025 9.9p2.v1.1.0
  the privilege separation user is now "nobody" -> the sshd can be started by the root user

