GNU/Linux >> Tutoriales Linux >  >> Linux

No puedo iniciar sesión a través de SSH en ninguna cuenta que utilice /bin/bash shell en Synology NAS

Solución 1:

Para referencia futura:después de demasiadas horas investigando y depurando este problema, finalmente descubrí la causa raíz.

La versión OpenSSH utilizada por Synology es una versión altamente personalizada, que no comportarse como el código original. Tiene muchos trucos y personalizaciones ad-hoc, por ejemplo, verificación adicional antes de aceptar un inicio de sesión para ver si el servicio SSH está habilitado dentro de la interfaz web, o eliminar caracteres especiales (;, |, ') de los comandos rsync, o... .espérelo... evitar que los usuarios regulares usen un shell diferente a /bin/sh o /bin/ash . Sí, codificado de forma rígida dentro del binario.

Aquí está el fragmento de código de OpenSSH 5.8p1, distribuido por Synology en su código fuente (DSM4.1 - rama 2636), archivo session.c :

void do_child(Session *s, const char *command)
{
...

#ifdef MY_ABC_HERE
   char szValue[8];
   int RunSSH = 0;
   SSH_CMD SSHCmd = REQ_UNKNOWN;

   if (1 == GetKeyValue("/etc/synoinfo.conf", "runssh", szValue, sizeof(szValue))) {
           if (strcasecmp(szValue, "yes") == 0) {
                   RunSSH = 1;
           }
   }

   if (IsSFTPReq(command)){
           SSHCmd = REQ_SFTP;
   } else if (IsRsyncReq(command)){
           SSHCmd = REQ_RSYNC;
   } else if (IsTimebkpRequest(command)){
           SSHCmd = REQ_TIMEBKP;
   } else if (RunSSH && IsAllowShell(pw)){
           SSHCmd = REQ_SHELL;
   } else {
           goto Err;
   }

   if (REQ_RSYNC == SSHCmd) {
           pw = SYNOChgValForRsync(pw);
   }
   if (!SSHCanLogin(SSHCmd, pw)) {
           goto Err;
   }
   goto Pass;

 Err:
   fprintf(stderr, "Permission denied, please try again.\n");
   exit(1);

 Pass:
   #endif /* MY_ABC_HERE */
...
}


Como puedes imaginar, el IsAllowShell(pw) fue el culpable:

static int IsAllowShell(const struct passwd *pw)
{
     struct passwd *pUnPrivilege = NULL;
     char *szUserName = NULL;
     if (!pw || !pw->pw_name) {
             return 0;
     }
     szUserName = pw->pw_name;
     if(!strcmp(szUserName, "root") || !strcmp(szUserName, "admin")){
             return 1;
     }
     if (NULL != (pUnPrivilege = getpwnam(szUserName))){
             if (!strcmp(pUnPrivilege->pw_shell, "/bin/sh") || 
                     !strcmp(pUnPrivilege->pw_shell, "/bin/ash")) {
                     return 1;
             }
     }
     return 0;
}


No es de extrañar por qué estaba experimentando un comportamiento tan extraño. Solo se aceptarán shells /bin/sh y /bin/ash para usuarios distintos de root o administrador . Y esto independientemente del uid (lo había probado también haciendo joeuser uid=0, y no funcionó. Ahora es obvio por qué).

Una vez identificada la causa, la solución fue fácil:simplemente elimine la llamada a IsAllowShell() . Me tomó un tiempo obtener la configuración correcta para realizar una compilación cruzada de openssh y todas sus dependencias, pero al final funcionó bien.

Si alguien está interesado en hacer lo mismo (o intentar compilar de forma cruzada otros módulos del kernel o archivos binarios para Synology), esta es mi versión de Makefile . Se probó con fuente OpenSSH-5.8p1 y funciona bien con modelos que ejecutan CPU Marvell Kirkwood mv6281/mv6282 (como DS212+). Usé un host con Ubuntu 12.10 x64.

En pocas palabras:mala práctica, código terrible y un gran ejemplo de lo que no que hacer. Entiendo que a veces los OEM necesitan desarrollar personalizaciones especiales, pero deberían pensarlo dos veces antes de profundizar demasiado. Esto no solo da como resultado un código imposible de mantener para ellos, sino que también crea todo tipo de problemas imprevistos en el futuro. Afortunadamente, GPL existe para mantenerlos honestos y abiertos.

Solución 2:

Para sortear el problema, y ​​dado que instalé bash a través de ipkg y no puedo estar seguro de que /opt siempre esté disponible (montado correctamente), simplemente pongo lo siguiente en mi .profile

[ -x /opt/bin/bash ] && exec /opt/bin/bash

mientras que /etc/passwd contiene /bin/ash como shell.


Linux
  1. /usr/bin Vs /usr/local/bin ¿En Linux?

  2. Bash =~ Regex y Https://regex101.com/?

  3. ¿Alguna razón para tener un Shebang apuntando a /bin/sh en lugar de /bin/bash?

  4. CentOS / RHEL:Cómo rotar el archivo /var/log/wtmp y /var/log/btmp usando logrotate

  5. ¿Cuál es la diferencia entre #!/usr/bin/env bash y #!/usr/bin/bash?

Linux – ¿Fusionar /usr/bin y /usr/sbin en /bin (gnu/linux)?

¿Diferencia entre /var/log/messages, /var/log/syslog y /var/log/kern.log?

¿Por qué /bin/sh apunta a /bin/dash y no a /bin/bash?

fundamentos de grep

Instalar binarios en /bin, /sbin, /usr/bin y /usr/sbin, interacciones con --prefix y DESTDIR

#!/bin/sh vs #!/bin/bash para máxima portabilidad