¿Cómo ejecutar el servidor SSH/SFTP para múltiples inicios de sesión de usuario con autenticación de contraseña en Android?

Quiero ejecutar un servidor SSH en mi teléfono Android para que mis clientes (que varían entre 10 y 20) puedan compartir datos conmigo de manera fácil y segura cuando estoy en movimiento, sin usar servicios de alojamiento de terceros como correo electrónico, archivo compartir, etc. Cada usuario debe tener su propio directorio (forzado mediante el chroot de SFTP) y debe poder iniciar sesión con su propia contraseña (no el archivo de clave) que yo les proporcione, opcionalmente compartiendo credenciales con otros usuarios si uno necesita

No encontré ninguna solución tan flexible, especialmente FOSS. Así que construí sshdel programa a partir del código fuente de openssh , usando gcc-linux-aarch64el compilador cruzado en Ubuntu. Sin embargo, cuando lo ejecuto en mi teléfono, arroja un error:

~# sshd -d
Privilege Separation user sshd does not exist

¿Cómo puedo agregar sshdy otros usuarios en Android? Mi teléfono está rooteado.

PD: Estoy anotando una respuesta a mi propia pregunta sobre las limitaciones que enfrenté y cómo he estado logrando esto durante los últimos años. Se agradecería cualquier otro método, particularmente una solución no root a través de GUI para facilitar a un usuario común.

Respuestas (1)

Nota:

  • Asegúrese de que su teléfono sea accesible desde Internet como se explica aquí .
  • Necesitas un dispositivo rooteado.

Los teléfonos Android de hoy en día no son esos viejos dispositivos de gama baja, pueden ejecutar felizmente un servidor SSH con todas las funciones. Y es una receta fácil:

  • Obtenga binario completamente estático sshdpara la arquitectura de su teléfono. Vea los detalles abajo.
  • Crear /etc/passwdy /etc/shadow. Para agregar un nuevo usuario con contraseña como lo hacemos en un sistema operativo Linux:

    ~# 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
    

    Se requiere el primer bindmontaje porque, de lo contrario, los SFTP chrootno funcionarán con /datala mala propiedad de . El segundo es acceder fácilmente a los archivos compartidos desde /sdcard/home. Para establecer permisos no root en /sdcard/home, use bindfs en su lugar.
    sshdusuario es para Privilege Separation . user1es nuestro primer usuario que podrá iniciar sesión a través de SSH. De la misma manera se pueden agregar más usuarios.

  • Agregue las configuraciones requeridas a /etc/ssh/sshd_config(los valores predeterminados son suficientes en la mayoría de los casos):

    UsePAM no
    PasswordAuthentication yes
    Subsystem sftp internal-sftp
    Match User user1
      ChrootDirectory /home/user1
    
  • Ejecute el servidor SSH, puede usarlo logwrapperpara iniciar sesión logcat:

    ~# ssh-keygen -A    # generate host keys on first use
    ~# /system/bin/sshd -4 -E /sdcard/home/.sshd.log
    

    Ahora puede acceder al servidor a través de SFTP/SSHFS. SSHDtambién se puede ejecutar como un initservicio administrado por Android init. Vea esta respuesta para una explicación.


DETALLES:

El servidor SSH le permite iniciar sesión de forma remota después de la autenticación adecuada. Además, sirve para compartir archivos y muchos otros recursos para compartir de forma segura. Pero no existe el concepto de Linux console loginen Android ( 1 ) porque se inicia directamente en la GUI. Sin embargo, utiliza el control de acceso discrecional (DAC) del kernel de Linux que se basa en UID/GID y modo de permiso. Cada aplicación instalada se considera un usuario *NIX y se le asigna un UID único en el momento de la instalación. Ver esta respuesta para más detalles sobre esto.

CÓMO FUNCIONAN EL INICIO DE SESIÓN Y LA AUTENTICACIÓN DEL USUARIO:

Tradicionalmente, el nombre de usuario /etc/passwdcontenido frente al mapeo de UID/GID, mientras que los GID complementarios se agregaron a /etc/group. También se agregó una contraseña a /etc/passwdla que luego se trasladó /etc/shadowcon la introducción de la suite de contraseñas ocultas . De manera similar, /etc/gshadowcontiene información de cuenta de grupo seguro . Estos archivos son leídos por programas que otorgan privilegios como login, su, sshdetc. y administrados por programas de administración como passwdy useradd.

La mayoría de estos programas son parte del paquete shadow y util-linux y su comportamiento se controla definiendo una serie de elementos de configuración en /etc/login.defs, por ejemplo, registro de diferentes eventos, caducidad de contraseña, variables de entorno, etc. También hay muchos archivos que son necesarios o actualizado por estas utilidades, incluidos nologin, default/useradd, adduser.conf, skel/, shells, subuid, subgid, limitsarchivos en /etc/, /var/log/faillog, /var/log/lastlog, y posiblemente otros./var/run/utmp/var/run/wtmp

Para centralizar la funcionalidad de estos programas de concesión y administración de privilegios, se introdujo un mecanismo de autenticación PAM más sofisticado. En lugar de manejar directamente el inicio de sesión del usuario y las cosas de autenticación, los programas se vinculan a las bibliotecas PAM (llamadas módulos ) que a su vez responden en consecuencia dependiendo de sus archivos de configuración principalmente bajo /etc/pam.dy /etc/security.

Además de PAM, también existe un complicado mecanismo de resolución de nombres NSS (un conjunto de módulos ) en las distribuciones de Linux que controla, entre muchas otras cosas, cómo passwdse leen las bases de datos groupy shadowlas bases de datos según su archivo de configuración /etc/nsswitch.conf. Tanto PAM como NSS se pueden configurar para usar un servicio de base de datos remota como LDAP / NIS . Y luego están los demonios de almacenamiento en caché centralizados como NSCD y SSSD . Trabajando juntos, completan el rompecabezas de los inicios de sesión de los usuarios (identificación y autenticación) en Linux.

CÓMO CONFIGURAR EL ENTORNO DE INICIO DE SESIÓN EN ANDROID:

Ninguno de los archivos de configuración y bibliotecas descritos anteriormente existe en Android porque los inicios de sesión de los usuarios no ocurren en absoluto. Pero los programas creados con las API libc estándar de Linux requieren todos estos archivos y servicios, incluido PAM, también en Android, lo que es casi imposible. PAM se puede deshabilitar sshdconfigurándolo UsePAM nopara sshd_configque lea archivos directamente /etc/passwdy /etc/group./etc/shadow

PAM se ha ido, aún necesitamos proporcionar un entorno mínimo que cumpla con los requisitos mínimos del proceso de inicio de sesión. sshbinary, por ejemplo, debe /etc/passwdexistir necesariamente porque se establece $HOMEdesde allí para leer known_hosts, configy id_* key. Además, si el host es un nombre de dominio y no una dirección IP, /etc/resolv.confdebe existir nameserverpara que DNS funcione. Es una historia diferente explicada aquí .

Entonces necesitamos crear los archivos relevantes en Android manualmente. O use las contrapartes no PAMshadow-utils de tales como useraddy passwdpara actualizar estos archivos. Podemos obtener un conjunto mínimo de estas utilidades en Android, por ejemplo, con busybox o toybox.

EJECUTAR PROGRAMAS DE LINUX EN ANDROID:

Idealmente, debe escribir/modificar el código fuente de un programa de acuerdo con el entorno de Android y luego crear archivos binarios/bibliotecas dinámicos utilizando el NDK de Android y Bionic libc. Pero debido a las diferencias entre las distribuciones de Linux y Android, como la jerarquía del sistema de archivos, la configuración del kernel, la implementación de libc y otras bibliotecas ( 2 ) , el código escrito para las distribuciones de Linux necesita una gran modificación en Android; de lo contrario, no se preocupe por los intentos fallidos . En caso de openssh, consulte la lista de parches de modificación en AOSP y en Termux . Dos de estos parches son sin autenticación de contraseña ( 3 ) y sin múltiples usuarios ( 4, 5 ) . El primero se solucionó en Termux mediante la introducción de nuevas API en termux-auth ( 6 , 7 ) , pero el último no se puede lograr sin configurar el entorno de inicio de sesión en Android.

Otras opciones son construir un binario completamente estático con la libc de Linux, como glibc, muslo uClibc. Si bien es fácil construir estáticamente pequeñas bibliotecas, libc se vincula a muchas otras bibliotecas. En el caso de glibc , todos ellos no se pueden construir estáticamente, como módulos cargados dinámicamente. No estoy seguro de cuán efectivo --enable-static-nsses, pero, por ejemplo, gconvno se puede vincular estáticamente ( 8 ) . Por lo tanto sshd, el binario no debe construirse con glibc, de lo contrario, no funcionará sin los módulos NSS.
También configure la ruta de separación de privilegios en algún directorio existente /data/local/tmpy deshabilite cualquier otra característica innecesaria como utmp, wtmpetc. lastlogO necesitaría crear /varun directorio enrootfs.

OTRAS LECTURAS: