Não é possível efetuar login via SSH em nenhuma conta usando o shell / bin / bash no Synology NAS

30

Estou tentando instalar o bash como o shell padrão em um ARM Linux em execução em um dispositivo incorporado (Synology DS212 + NAS). Mas há algo realmente errado e não consigo descobrir o que é isso.

Sintomas:

1) A raiz tem / bin / bash como shell padrão e pode efetuar login normalmente via SSH:

$ grep root /etc/passwd
root:x:0:0:root:/root:/bin/bash

$ ssh root@NAS
root@NAS's password:
Last login: Sun Dec 16 14:06:56 2012 from desktop
# 


2) joeuser possui / bin / bash como shell padrão e recebe "Permission denied" ao tentar efetuar login via SSH:

$ grep joeuser /etc/passwd
joeuser:x:1029:100:Joe User:/home/joeuser:/bin/bash

$ ssh joeuser@localhost
joeuser@NAS's password:
Last login: Sun Dec 16 14:07:22 2012 from desktop
Permission denied, please try again.
Connection to localhost closed.


3) mudando o shell do joeuser para / bin / sh:

$ grep joeuser /etc/passwd
joeuser:x:1029:100:Joe User:/home/joeuser:/bin/sh

$ ssh joeuser@localhost
Last login: Sun Dec 16 15:50:52 2012 from localhost
$ 


Para tornar as coisas ainda mais estranhas, posso logar como joeuser usando /bin/bash usando o console serial (!). Também um su - joeuser as root funciona bem, então o próprio binário bash está funcionando bem.

Em um ato de desespero, eu mudei o uid de joeuser para 0 em / etc / passwd, mas também não funcionou, então não parece ser algo relacionado a permissão.

Parece que o bash está fazendo alguma verificação extra que o sshd não gostou e bloqueando as conexões para usuários não-root. Talvez algum tipo de verificação de sanidade - ou emulação de terminal - esteja acionando o SIGCHLD, mas apenas quando chamado via ssh.

Eu já passei por todos os itens do sshd_config e também coloquei o SSHD no modo de depuração, mas não achei nada estranho. Aqui está o meu /etc/ssh/sshd_config :

LogLevel DEBUG
LoginGraceTime 2m
PermitRootLogin yes
RSAAuthentication yes
PubkeyAuthentication yes
AuthorizedKeysFile      %h/.ssh/authorized_keys
ChallengeResponseAuthentication no
UsePAM yes
AllowTcpForwarding no
ChrootDirectory none
Subsystem       sftp    internal-sftp -f DAEMON -u 000


E aqui está a saída de /usr/syno/sbin/sshd -d , mostrando a tentativa falhada de joeuser tentando efetuar login, com / bin / bash como o shell:

debug1: Config token is loglevel
debug1: Config token is logingracetime
debug1: Config token is permitrootlogin
debug1: Config token is rsaauthentication
debug1: Config token is pubkeyauthentication
debug1: Config token is authorizedkeysfile
debug1: Config token is challengeresponseauthentication
debug1: Config token is usepam
debug1: Config token is allowtcpforwarding
debug1: Config token is chrootdirectory
debug1: Config token is subsystem
debug1: HPN Buffer Size: 87380
debug1: sshd version OpenSSH_5.8p1-hpn13v11
debug1: read PEM private key done: type RSA
debug1: private host key: #0 type 1 RSA
debug1: read PEM private key done: type DSA
debug1: private host key: #1 type 2 DSA
debug1: read PEM private key done: type ECDSA
debug1: private host key: #2 type 3 ECDSA
debug1: rexec_argv[0]='/usr/syno/sbin/sshd'
debug1: rexec_argv[1]='-d'
Set /proc/self/oom_adj from 0 to -17
debug1: Bind to port 22 on ::.
debug1: Server TCP RWIN socket size: 87380
debug1: HPN Buffer Size: 87380
Server listening on :: port 22.
debug1: Bind to port 22 on 0.0.0.0.
debug1: Server TCP RWIN socket size: 87380
debug1: HPN Buffer Size: 87380
Server listening on 0.0.0.0 port 22.

debug1: Server will not fork when running in debugging mode.
debug1: rexec start in 6 out 6 newsock 6 pipe -1 sock 9
debug1: inetd sockets after dupping: 4, 4
Connection from 127.0.0.1 port 52212
debug1: HPN Disabled: 0, HPN Buffer Size: 87380
debug1: Client protocol version 2.0; client software version OpenSSH_5.8p1-hpn13v11
SSH: Server;Ltype: Version;Remote: 127.0.0.1-52212;Protocol: 2.0;Client: OpenSSH_5.8p1-hpn13v11
debug1: match: OpenSSH_5.8p1-hpn13v11 pat OpenSSH*
debug1: Enabling compatibility mode for protocol 2.0
debug1: Local version string SSH-2.0-OpenSSH_5.8p1-hpn13v11
debug1: permanently_set_uid: 1024/100
debug1: MYFLAG IS 1
debug1: list_hostkey_types: ssh-rsa,ssh-dss,ecdsa-sha2-nistp256
debug1: SSH2_MSG_KEXINIT sent
debug1: SSH2_MSG_KEXINIT received
debug1: AUTH STATE IS 0
debug1: REQUESTED ENC.NAME is 'aes128-ctr'
debug1: kex: client->server aes128-ctr hmac-md5 none
SSH: Server;Ltype: Kex;Remote: 127.0.0.1-52212;Enc: aes128-ctr;MAC: hmac-md5;Comp: none
debug1: REQUESTED ENC.NAME is 'aes128-ctr'
debug1: kex: server->client aes128-ctr hmac-md5 none
debug1: expecting SSH2_MSG_KEX_ECDH_INIT
debug1: SSH2_MSG_NEWKEYS sent
debug1: expecting SSH2_MSG_NEWKEYS
debug1: SSH2_MSG_NEWKEYS received
debug1: KEX done
debug1: userauth-request for user joeuser service ssh-connection method none
SSH: Server;Ltype: Authname;Remote: 127.0.0.1-52212;Name: joeuser
debug1: attempt 0 failures 0
debug1: Config token is loglevel
debug1: Config token is logingracetime
debug1: Config token is permitrootlogin
debug1: Config token is rsaauthentication
debug1: Config token is pubkeyauthentication
debug1: Config token is authorizedkeysfile
debug1: Config token is challengeresponseauthentication
debug1: Config token is usepam
debug1: Config token is allowtcpforwarding
debug1: Config token is chrootdirectory
debug1: Config token is subsystem
debug1: PAM: initializing for "joeuser"
debug1: PAM: setting PAM_RHOST to "localhost"
debug1: PAM: setting PAM_TTY to "ssh"
debug1: userauth-request for user joeuser service ssh-connection method password
debug1: attempt 1 failures 0
debug1: do_pam_account: called
Accepted password for joeuser from 127.0.0.1 port 52212 ssh2
debug1: monitor_child_preauth: joeuser has been authenticated by privileged process
debug1: PAM: establishing credentials
User child is on pid 9129
debug1: Entering interactive session for SSH2.
debug1: server_init_dispatch_20
debug1: server_input_channel_open: ctype session rchan 0 win 65536 max 16384
debug1: input_session_request
debug1: channel 0: new [server-session]
debug1: session_new: session 0
debug1: session_open: channel 0
debug1: session_open: session 0: link with channel 0
debug1: server_input_channel_open: confirm session
debug1: server_input_global_request: rtype [email protected] want_reply 0
debug1: server_input_channel_req: channel 0 request pty-req reply 1
debug1: session_by_channel: session 0 channel 0
debug1: session_input_channel_req: session 0 req pty-req
debug1: Allocating pty.
debug1: session_new: session 0
debug1: session_pty_req: session 0 alloc /dev/pts/1
debug1: server_input_channel_req: channel 0 request shell reply 1
debug1: session_by_channel: session 0 channel 0
debug1: session_input_channel_req: session 0 req shell
debug1: Setting controlling tty using TIOCSCTTY.

debug1: Received SIGCHLD.
debug1: session_by_pid: pid 9130
debug1: session_exit_message: session 0 channel 0 pid 9130
debug1: session_exit_message: release channel 0
debug1: session_by_tty: session 0 tty /dev/pts/1
debug1: session_pty_cleanup: session 0 release /dev/pts/1
Received disconnect from 127.0.0.1: 11: disconnected by user
debug1: do_cleanup
debug1: do_cleanup
debug1: PAM: cleanup
debug1: PAM: closing session
debug1: PAM: deleting credentials


Aqui você tem a saída completa do sshd -dd, junto com o ssh -vv .

Bash:

# bash --version
GNU bash, version 3.2.49(1)-release (arm-none-linux-gnueabi)
Copyright (C) 2007 Free Software Foundation, Inc.

O binário bash foi compilado da origem. Eu também tentei usar um binário pré-compilado da distribuição do Optware , mas tive a exatamente o mesmo problema. Eu verifiquei a falta de bibliotecas compartilhadas usando objdump -x , mas elas estão todas lá.

Alguma idéia do que poderia estar causando isso " Permissão negada, por favor tente novamente. "? Estou quase mergulhando no código-fonte para investigar, mas tentando evitar horas correndo atrás de algo que pode ser bobo.

EDITAR: adicionando mais informações sobre o bash e o sistema

$ ls -la /bin/bash
-rwxr-xr-x    1 root     root        724676 Dec 15 23:57 /bin/bash

$  file /bin/bash
/bin/bash: ELF 32-bit LSB executable, ARM, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.14, stripped

$  uname -a
Linux NAS 2.6.32.12 #2661 Mon Nov 12 23:10:15 CST 2012 armv5tel GNU/Linux synology_88f6282_212+

$ grep bash /etc/shells
/bin/bash
/bin/bash2
    
por Gui Ambros 16.12.2012 / 22:34

7 respostas

38

Para referência futura: após muitas horas pesquisando e depurando esse problema, eu finalmente descobri a causa raiz.

A versão do OpenSSH usada pela Synology é uma versão altamente personalizada, que não se comporta como o código original. Ele possui vários hacks e personalizações ad-hoc - por exemplo, verificação adicional antes de aceitar um login para ver se o serviço SSH está habilitado na interface da Web ou descartar caracteres especiais (;, |, ') dos comandos rsync ou .. Espere por isso ... evitando que usuários regulares usem um shell diferente de / bin / sh ou / bin / ash . Sim, codificado dentro do binário.

Aqui está o trecho do código do OpenSSH 5.8p1, distribuído pela Synology em seu código fonte (DSM4.1 - branch 2636) , arquivo 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 você pode imaginar, o IsAllowShell(pw) foi o culpado:

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;
}


Não é de admirar por que eu estava experimentando um comportamento tão estranho. Somente shells / bin / sh e / bin / ash seriam aceitos para usuários diferentes de root ou admin . E isso, independentemente do uid (eu tinha testado também fazendo joeuser uid = 0, e não funcionou. Agora é óbvio porquê).

Uma vez identificada a causa, a correção foi fácil: basta remover a chamada para IsAllowShell () . Levei um tempo para obter a configuração certa para compilar o openssh e todas as suas dependências, mas funcionou bem no final.

Se alguém estiver interessado em fazer o mesmo (ou tentar cross-compilar outros módulos do kernel ou binários para o Synology), aqui está minha versão do < em> Makefile . Foi testado com fonte OpenSSH-5.8p1 e funciona bem com modelos executando CPU Marvell Kirkwood mv6281 / mv6282 (como DS212 +). Eu usei um host rodando o Ubuntu 12.10 x64.

Resultado: prática ruim, código terrível e um ótimo exemplo do que não deve ser feito. Eu entendo que os OEMs precisam desenvolver personalizações especiais, mas devem pensar duas vezes antes de cavar muito fundo. Isso não apenas resulta em um código inatingível para eles, mas também cria todos os tipos de problemas imprevistos no futuro. Felizmente a GPL existe para mantê-los honestos - e abertos.

    
por 21.01.2013 / 01:35
7

Para contornar o problema, e já que instalei o bash via ipkg e não posso ter certeza / opt sempre estará disponível (montado corretamente), eu simplesmente coloco o seguinte no meu .profile

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

enquanto / etc / passwd contém / bin / ash como shell.

    
por 11.03.2013 / 10:21
1

Vamos ver. Ele é isolado para um único shell, e você está olhando para a saída de depuração do sshd, portanto, não é um problema de permissão gravável do mundo com o ~ joeuser / .ssh. Essa é a que mais atrai as pessoas.

Você já tentou criar um usuário normal adicional (ou seja, não joeuser) para garantir que o mesmo problema ocorra? Isso isolaria a configuração do usuário em relação à configuração do sistema.

Se for um problema de todo o sistema, a próxima coisa que eu darei uma olhada são os arquivos de configuração compartilhados, como / etc / profile, que são fornecidos por todos. Pode haver um bloco condicional que não está sendo acionado se o nome de usuário for root. (não eficaz userid, desde que você já testou para isso)

Verifique o dmesg para obter relatórios de falhas de segmentação, se ainda não o fez, caso haja algo ainda mais estranho acontecendo.

    
por 06.01.2013 / 07:40
1

tente / etc / ssh / sshd_config
pesquisar por AllowUsers

se estiver lá, tente adicionar joeuser lá, apenas username

também pode ser bloqueado em pam ... não me lembro qual arquivo é ...

    
por 09.01.2013 / 13:21
1

Sua versão modificada do openssh procura um /bin/sh shell?

Solução fácil então:

ln -fs /bin/bash /bin/sh

    
por 08.04.2013 / 23:44
0

Tente reinstalar o Bash e veja se isso ajuda.

    
por 17.12.2012 / 09:02
0

No caso de alguém se deparar com isso porque cometeu o mesmo erro que eu:

sim: $ sudo usermod -s /bin/bash your_username

não: $ sudo usermod -s bash your_username

O segundo resultará em uma permissão negada quando o ssh'ing entrar.

    
por 11.12.2015 / 20:53