Não é possível efetuar login via SSH em nenhuma conta usando / bin / bash shell 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 é.

Sintomas:

1) A raiz possui / 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 "Permissão negada" 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 de volta 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 efetuar login como joeuser /bin/bashusando o console serial (!). Além disso su - joeuser, o as root funciona bem, então o próprio binário bash está funcionando bem.

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

Parece que o bash está fazendo uma 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 fracassada de joeuser tentando efetuar login, com / bin / bash como 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 no-more-sessions@openssh.com 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 .

Bater:

# 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 em cruz da fonte. Também tentei usar um binário pré-compilado da distribuição Optware , mas tive 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 essa " Permissão negada, tente novamente. "? Estou quase mergulhando no código-fonte do bash para investigar, mas tentando evitar horas perseguindo algo que pode ser bobo.

EDIT: 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
Gui Ambros
fonte
2
ls -l /bin/bash
Michael Hampton
/ Bin / bash está listado em / etc / shells?
tink
Sim, está listado em / etc / shells. E permissões 0755, adicionadas acima.
Gui Ambros
Provavelmente, algo está sendo executado em seu arquivo .bashrc. Você pode brincar com ~ joeuser / .bashrc e vasculhar os scripts de perfil? Você também pode tentar executar / bin / bash enquanto estiver logado como ele.
vicfn
Nenhum ~ joeuser / .ssh e nenhum script de perfil. É um usuário em branco que acabei de criar para testar.
Gui Ambros

Respostas:

39

Para referência futura: depois de muitas horas pesquisando e depurando esse problema, 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. Possui muitos hacks e personalizações ad-hoc - por exemplo, verificação adicional antes de aceitar um logon para ver se o serviço SSH está ativado na interface da web ou remover caracteres especiais (;, |, ') dos comandos rsync, ou .. aguarde ... evitando que usuários comuns usem um shell diferente de / bin / sh ou / bin / ash . Sim, codificado no binário.

Aqui está o trecho de código do OpenSSH 5.8p1, conforme distribuído pela Synology em seu código-fonte (DSM4.1 - filial 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, esse 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 é à toa 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 testei também fazendo joeuser uid = 0, e não funcionou. Agora é óbvio o porquê).

Uma vez identificada a causa, a correção foi fácil: basta remover a chamada para IsAllowShell () . Demorei um pouco para obter a configuração correta 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 compilar outros módulos ou binários do kernel para Synology), aqui está minha versão do Makefile . Foi testado com a fonte OpenSSH-5.8p1 e funciona bem com modelos executando a CPU Marvell Kirkwood mv6281 / mv6282 (como DS212 +). Eu usei um host executando o Ubuntu 12.10 x64.

Conclusão: más práticas, código terrível e um ótimo exemplo do que não fazer. Entendo que algumas vezes os OEMs precisam desenvolver personalizações especiais, mas devem pensar duas vezes antes de se aprofundar demais. Não apenas isso resulta em código impossível de manter para eles, mas também cria todo tipo de problemas imprevistos no caminho. Felizmente, a GPL existe para mantê-los honestos - e abertos.

Gui Ambros
fonte
4
Trabalho estelar, senhor, ao investigar esta questão e afastar a cortina do estágio de Synology. Devo admitir que tinha pensado muito bem no meu Diskstation até agora, pois ele tem sido muito útil e, uma vez iniciado, o bootstrap está executando alguns scripts para mim no novo agendador de tarefas. Mas você revelou algumas falhas no design míope aqui. Ainda estou satisfeito com o Diskstation, mas manterá sua postagem em mente. Votou na postagem e na resposta.
10133 Bernard Dy
Votado pelo esforço. Se não quero me preocupar em fazer conexões de cereais, só quero mudar o shell padrão para /bin/sh, existe uma maneira de fazer isso?
Vicary
Por Synology faria isso é totalmente além de mim :(
Gerhard Burger
I renomeado /bin/ashpara /bin/ash.reale ligados zshem /bin/ash... até agora tudo parece bem ... o_o
x1a0
7

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

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

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

Tom Regner
fonte
1

Vamos ver. Ele está isolado em um único shell, além de você estar olhando para a saída de depuração sshd, para que não haja problemas de permissão de gravação mundial com ~ joeuser / .ssh. Essa é a que atrai a maioria das pessoas.

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

Se for um problema em todo o sistema, a próxima coisa que eu daria uma olhada são os arquivos de configuração compartilhados, como o / etc / profile, que são obtidos por todos. Pode haver um bloco condicional que não está sendo disparado se o nome de usuário for root. (ID do usuário não eficaz, já que você já fez o teste)

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

Andrew B
fonte
Obrigado Andrew. Também verificado dmesg, e absolutamente nada. Criar um usuário novinho em folha também não ajudou, por isso é claramente um problema em todo o sistema. E o joeuser pode efetuar login normalmente se eu mudar o shell de volta para / bin / ash, o que exclui qualquer / etc / profile ou outro (que eu também verifiquei, btw). É apenas com não raiz, usando o bash, via ssh. Neste ponto, nem sequer é um problema real (eu posso viver com ele como é agora), mas me incomoda admitir que não fui capaz de encontrar a causa desse comportamento estranho. Afinal, é um sistema determinístico; lá deve ser algum tipo de explicação ...
Gui Ambros
1

tente / etc / ssh / sshd_config
procurar AllowUsers

se estiver lá, tente adicionar joeuser lá, apenas nome de usuário

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

BiG_NoBoDy
fonte
Não é o caso. Se houvesse um problema com AllowUsers, não me deixaria entrar com joeuser quando eu alterasse o shell para / bin / ash. Isso não parece estar relacionado a nada relacionado à segurança ou a qualquer outra configuração. Provavelmente é algum tipo de como o bash lida com pseudo-terminais via ssh, versus ash, csh, etc. #
Gui Ambros
1

A versão modificada do openssh procura um /bin/shshell?

Solução fácil, então:

ln -fs / bin / bash / bin / sh

Ponytech
fonte
Isso mudaria o shell para todos os usuários, e não apenas para os que precisavam do bash. Além disso, qualquer nova atualização removeria o link simbólico (mesmo que a correção do openssh também tenha o mesmo problema). Enfim, isso foi resolvido, como descrito acima.
Gui Ambros #
OK verdade, mas como eu sou o único usuário no meu NAS, esta solução funciona para mim. De qualquer forma, obrigado por apontar o que você descobriu.
Ponytech #
0

Tente reinstalar o Bash e veja se isso ajuda.

Pratap
fonte
Não, eu obtive o bash de duas fontes diferentes (uma da distribuição Optware e também compilei o 3.2 da fonte) e o mesmo problema. Eu cheguei ao extremo de obter o bash 4.2 e aplicar os patches (todos os 39) e fazer a compilação cruzada. Exatamente o mesmo comportamento. Funciona com raiz, permissão negada para outros. Meu último palpite é o binário OpenSSH, que é o mesmo instalado por padrão pelo firmware da Synology. Esta é a única peça que ainda não toquei. Vou tentar baixar a fonte mais recente e fazer a compilação cruzada, para ver o que acontece.
Gui Ambros
2
Estranho, não tenho certeza, mas isso parece ser um problema authconfig. O ldap também está sendo executado no servidor? Você pode me enviar a saída de log em tempo real do arquivo seguro e de mensagem no momento da falha no login.
Pratap
2
Faça o login como root no servidor e deixe o shell do usuário ser / bin / bash e tente mudar para o usuário usando su - username. Mostre-me a saída disso também.
Pratap
0

Caso alguém se depare 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 ao ser ativada.

Christy
fonte