Impossible de se connecter via SSH à des comptes utilisant le shell / bin / bash sur le Synology NAS


30

J'essaie d'installer bash comme shell par défaut sur un ARM Linux fonctionnant sur un périphérique intégré (Synology DS212 + NAS). Mais il y a vraiment quelque chose qui ne va pas et je ne peux pas comprendre ce que c'est.

Symptômes:

1) Root a / bin / bash comme shell par défaut, et peut se connecter normalement 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 a / bin / bash comme shell par défaut, et reçoit "Autorisation refusée" lors de la tentative de connexion 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) Changer le shell de Joeuser en / 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
$ 


Pour rendre les choses encore plus étranges, je peux me connecter en tant que joeuser en /bin/bashutilisant la console série (!). De plus, su - joeuseras as root fonctionne très bien, donc le binaire bash lui-même fonctionne bien.

Dans un acte de désespoir, j'ai changé l'uid de joeuser en 0 sur / etc / passwd, mais cela n'a pas fonctionné non plus, donc cela ne semble pas être lié à une autorisation.

Il semble que bash vérifie plus que sshd n'aimait pas et bloque les connexions pour les utilisateurs non root. Peut-être une sorte de vérification d'intégrité - ou d'émulation de terminal - qui déclenche le SIGCHLD, mais uniquement lorsqu'il est appelé via ssh.

J'ai déjà parcouru chaque élément sur sshd_config et j'ai également mis SSHD en mode débogage, mais je n'ai rien trouvé d'étrange. Voici mon /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


Et voici la sortie de /usr/syno/sbin/sshd -d, montrant l'échec de la tentative de connexion de joeuser, avec / bin / bash comme 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


Ici, vous avez la sortie complète de sshd -dd, avec ssh -vv .

Frapper:

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

Le binaire bash a été compilé de manière croisée à partir de la source. J'ai également essayé d'utiliser un binaire précompilé de la distribution Optware , mais j'ai eu exactement le même problème. J'ai vérifié l'absence de bibliothèques partagées à l'aide objdump -x, mais elles sont toutes là.

Toutes les idées qui pourraient être à l'origine de cette " autorisation refusée, veuillez réessayer. "? Je plonge presque dans le code source de bash pour enquêter, mais j'essaie d'éviter des heures à courir après quelque chose de stupide.

EDIT: ajout d'informations sur bash et le système

$ 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

2
ls -l /bin/bash
Michael Hampton

/ Bin / bash est-il répertorié dans / etc / shells?
tink

Oui, il est répertorié dans / etc / shells. Et les autorisations 0755, ajoutées ci-dessus.
Gui Ambros

Il est très probable que quelque chose soit exécuté dans son fichier .bashrc. Pouvez-vous cat ~ joeuser / .bashrc et fouiller dans ses scripts de profil? Vous pouvez également essayer d'exécuter / bin / bash lorsque vous êtes connecté en tant que lui.
vicfn

Aucun ~ joeuser / .ssh et aucun script de profil. C'est un utilisateur vide que je viens de créer pour tester.
Gui Ambros

Réponses:


39

Pour référence future: après trop d'heures de recherche et de débogage sur ce problème, j'ai finalement découvert la cause première.

La version OpenSSH utilisée par Synology est une version hautement personnalisée, qui ne se comporte pas comme le code d'origine. Il a beaucoup de hacks et de personnalisations ad hoc - par exemple, une vérification supplémentaire avant d'accepter une connexion pour voir si le service SSH est activé dans l'interface Web, ou supprimer les caractères spéciaux (;, |, ') des commandes rsync, ou .. attendez ... en évitant aux utilisateurs réguliers d'utiliser un shell différent de / bin / sh ou / bin / ash . Oui, codé en dur dans le binaire.

Voici le morceau de code d'OpenSSH 5.8p1, tel que distribué par Synology sur leur code source (DSM4.1 - branche 2636) , fichier 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 */
...
}


Comme vous pouvez l'imaginer, IsAllowShell(pw)c'était le coupable:

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


Pas étonnant que j'expérimente un comportement aussi étrange. Seuls les shells / bin / sh et / bin / ash seraient acceptés pour des utilisateurs différents de root ou admin . Et cela indépendamment de l'uid (j'avais testé aussi en faisant joeuser uid = 0, et cela n'a pas fonctionné. Maintenant, c'est évident pourquoi).

Une fois la cause identifiée, la correction a été simple: il suffit de supprimer l'appel à IsAllowShell () . Il m'a fallu un certain temps pour obtenir la bonne configuration pour compiler de manière croisée openssh et toutes ses dépendances, mais cela a bien fonctionné au final.

Si quelqu'un souhaite faire la même chose (ou essayer de compiler d'autres modules du noyau ou des binaires pour Synology), voici ma version de Makefile . Il a été testé avec la source OpenSSH-5.8p1 et fonctionne bien avec les modèles exécutant le processeur Marvell Kirkwood mv6281 / mv6282 (comme DS212 +). J'ai utilisé un hôte exécutant Ubuntu 12.10 x64.

Conclusion: mauvaise pratique, code terrible et un excellent exemple de ce qu'il ne faut pas faire. Je comprends que les OEM doivent parfois développer des personnalisations spéciales, mais ils devraient réfléchir à deux fois avant de creuser trop profondément. Non seulement cela se traduit par un code incontrôlable pour eux, mais crée également toutes sortes de problèmes imprévus en cours de route. Heureusement, GPL existe pour les garder honnêtes - et ouverts.


4
Un travail remarquable, monsieur, pour enquêter sur ce problème et retirer le rideau de la scène Synology. Je dois admettre que je pensais très bien à mon Diskstation jusqu'à présent, car il a été très utile et une fois démarré, il exécute maintenant même des scripts pour moi sous le nouveau planificateur de tâches. Mais vous avez révélé ici quelques défauts de conception à courte vue. Je suis toujours satisfait du Diskstation, mais je garderai votre message à l'esprit. A voté pour le message et la réponse.
Bernard Dy

Voté pour l'effort. Si je ne veux pas prendre la peine de faire des connexions de céréales, je veux juste changer le shell par défaut en /bin/sh, y a-t-il un moyen de le faire?
Vicary

Pourquoi la synologie ferait cela me dépasse totalement :(
Gerhard Burger

Je renomme /bin/ashà /bin/ash.realLIEES zshà /bin/ash... jusqu'à présent , tout semble bien ... o_o
x1a0

7

Pour contourner le problème, et puisque j'ai installé bash via ipkg et que je ne peux pas être sûr que / opt sera toujours disponible (monté correctement), je mets simplement ce qui suit dans mon .profile

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

tandis que / etc / passwd contient / bin / ash comme shell.


1

Voyons voir. Il est isolé d'un seul shell, et vous regardez la sortie de débogage sshd, donc ce ne sont pas des problèmes d'autorisation en écriture avec ~ joeuser / .ssh. C'est celui qui attire le plus de monde.

Avez-vous essayé de créer un utilisateur normal supplémentaire (c'est-à-dire pas joeuser) pour vous assurer qu'il rencontre le même problème? Cela l'isolerait dans la configuration de l'utilisateur par rapport à la configuration à l'échelle du système.

S'il s'agit d'un problème à l'échelle du système, la prochaine chose que j'examinerais sont les fichiers de configuration partagés comme / etc / profile qui proviennent de tout le monde. Il peut y avoir un bloc conditionnel qui ne se déclenche pas si le nom d'utilisateur est root. (ID utilisateur non efficace, car vous l'avez déjà testé)

Vérifiez dmesg pour les rapports de défaut de segmentation si vous ne l'avez pas déjà fait, juste au cas où quelque chose serait encore plus étrange.


Merci Andrew. Aussi vérifié dmesg, et absolument rien. La création d'un nouvel utilisateur n'a pas non plus aidé, il s'agit donc clairement d'un problème à l'échelle du système. Et joeuser peut se connecter normalement si je remets le shell à / bin / ash, ce qui exclut tout / etc / profile ou autre (que j'ai également vérifié, btw). C'est juste avec non-root, en utilisant bash, via ssh. Comme ce point n'est même pas un vrai problème (je peux le vivre tel qu'il est maintenant), mais cela m'ennuie d'admettre que je n'ai pas pu trouver la cause de ce comportement étrange. C'est un système déterministe après tout; il doit y avoir une sorte d'explication ...
Gui Ambros

1

essayez la recherche / etc / ssh / sshd_config
pour AllowUsers

s'il est là, essayez d'y ajouter joeuser, juste le nom d'utilisateur

aussi il peut être bloqué dans pam ... je ne me souviens plus de quel fichier il s'agit ...


Pas le cas. Si c'était un problème avec AllowUsers, cela ne me permettrait pas de me connecter avec joeuser lorsque je changerais le shell en / bin / ash. Cela ne semble pas être lié à quoi que ce soit lié à la sécurité ou à toute autre configuration. C'est probablement une sorte de comment bash gère les pseudo-terminaux via ssh, contre ash, csh, etc.
Gui Ambros

1

Leur version modifiée de openssh cherche un /bin/shshell?

Solution facile alors:

ln -fs / bin / bash / bin / sh


Cela changerait le shell pour tous les utilisateurs, et pas seulement ceux qui avaient besoin de bash. De plus, toute nouvelle mise à niveau supprimerait le lien symbolique (même si la réparation d'OpenSH a également le même problème). Quoi qu'il en soit, cela a été résolu, comme décrit ci-dessus.
Gui Ambros

D'accord, mais comme je suis le seul utilisateur de mon NAS, cette solution fonctionne pour moi. Quoi qu'il en soit, merci d'avoir souligné ce que vous avez découvert.
Ponytech

0

Essayez de réinstaller Bash et voyez si cela aide.


Non, j'ai eu bash de deux sources différentes (une de la distribution Optware, et j'ai aussi compilé 3.2 à partir de la source moi-même), et même problème. Je suis allé à l'extrême pour obtenir bash 4.2 et appliquer les correctifs (tous les 39), et la compilation croisée. Exactement le même comportement. Fonctionne avec root, autorisation refusée pour les autres. Ma dernière supposition est le binaire OpenSSH, qui est le même installé par défaut par le firmware de Synology. C'est le seul morceau que je n'ai pas encore touché. Je vais essayer de télécharger la dernière source et la compilation croisée, pour voir ce qui se passe.
Gui Ambros

2
Étrange, pas sûr, mais cela semble être un problème d'authconfig. LDAP s'exécute-t-il également sur le serveur? Pouvez-vous m'envoyer une sortie de journal en temps réel de fichier sécurisé et de message au moment de l'échec de la connexion.
Pratap

2
Connectez-vous également en tant que root au serveur et laissez le shell utilisateur être / bin / bash et essayez de basculer vers l'utilisateur en utilisant su-username. Montrez-moi la sortie de cela aussi.
Pratap

0

Au cas où quelqu'un tomberait dessus parce qu'il a fait la même erreur que moi:

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

non: $ sudo usermod -s bash your_username

Le 2e se traduira par une autorisation refusée lors de la connexion.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.