Ich kann mich mit / bin / bash shell auf Synology NAS nicht über SSH bei Konten anmelden

30

Ich versuche, bash als Standardshell auf einem ARM-Linux zu installieren, das auf einem eingebetteten Gerät (Synology DS212 + NAS) ausgeführt wird. Aber irgendetwas stimmt wirklich nicht und ich kann nicht herausfinden, was es ist.

Symptome:

1) Root hat / bin / bash als Standardshell und kann sich normal über SSH anmelden:

$ 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 hat / bin / bash als Standard-Shell und erhält die Meldung "Permission denied", wenn er versucht, sich über SSH anzumelden:

$ 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) Ändern der joeuser-Shell zurück zu / 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
$ 


Um die Sache noch merkwürdiger zu machen, kann ich mich /bin/bashüber die serielle Konsole (!) Als joeuser anmelden . Auch ein su - joeuserals root funktioniert gut, so dass die Bash-Binärdatei selbst gut funktioniert.

In einem Akt der Verzweiflung habe ich die UID von Joeuser in / etc / passwd auf 0 geändert, aber es hat auch nicht funktioniert.

Es sieht so aus, als ob Bash zusätzliche Überprüfungen durchführt, die sshd nicht mochte, und die Verbindungen für Nicht-Root-Benutzer blockiert. Vielleicht eine Art von Sanity-Check oder Terminal-Emulation, die die SIGCHLD auslöst, aber nur, wenn sie über ssh aufgerufen wird.

Ich habe bereits jedes einzelne Element in sshd_config durchgesehen und SSHD auch in den Debug-Modus versetzt, fand aber nichts Seltsames. Hier ist mein /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


Und hier ist die Ausgabe von /usr/syno/sbin/sshd -d, die den fehlgeschlagenen Versuch von Joeuser zeigt, sich anzumelden, mit / bin / bash als 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


Hier haben Sie die volle Ausgabe von sshd -dd zusammen mit ssh -vv .

Bash:

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

Die Bash-Binärdatei wurde aus dem Quellcode querkompiliert. Ich habe auch versucht, eine vorkompilierte Binärdatei aus der Optware-Distribution zu verwenden , hatte aber genau das gleiche Problem. Ich habe mithilfe von nach fehlenden gemeinsam genutzten Bibliotheken gesucht objdump -x, aber sie sind alle da.

Irgendwelche Ideen, was dazu führen könnte, dass "die Erlaubnis verweigert wurde, bitte versuchen Sie es noch einmal. "? Ich bin fast dabei, in den Bash-Quellcode einzutauchen, um nachzuforschen, aber ich versuche Stunden zu vermeiden, um etwas zu jagen, das albern sein könnte.

BEARBEITEN: Hinzufügen weiterer Informationen zu Bash und dem System

$ 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
quelle
2
ls -l /bin/bash
Michael Hampton
Ist / bin / bash in / etc / shells aufgeführt?
Tink
Ja, es ist in / etc / shells aufgelistet. Und Berechtigungen 0755, oben hinzugefügt.
Gui Ambros
Höchstwahrscheinlich wird in seiner .bashrc-Datei etwas ausgeführt. Können Sie ~ joeuser / .bashrc katzen und in seinen Profilskripten stöbern? Sie können auch versuchen, / bin / bash auszuführen, während Sie als er angemeldet sind.
Vicfn
Kein ~ joeuser / .ssh und keine Profilskripte. Es ist ein leerer Benutzer, den ich gerade zum Testen erstellt habe.
Gui Ambros

Antworten:

39

Zum späteren Nachschlagen: Nach viel zu vielen Stunden Recherche und Debugging dieses Problems habe ich endlich die Ursache entdeckt.

Die von Synology verwendete OpenSSH-Version ist eine stark angepasste Version, die sich nicht wie der Originalcode verhält. Es enthält viele Hacks und Ad-hoc-Anpassungen - z. B. zusätzliche Überprüfungen vor dem Akzeptieren einer Anmeldung, um festzustellen, ob der SSH-Dienst in der Webschnittstelle aktiviert ist, oder das Entfernen von Sonderzeichen (;, |, ') aus rsync-Befehlen oder .. warte darauf ... vermeide, dass normale Benutzer eine andere Shell als / bin / sh oder / bin / ash verwenden . Ja, fest in der Binärdatei codiert.

Hier ist der Code aus OpenSSH 5.8p1, wie er von Synology im Quellcode (DSM4.1 - Zweig 2636) veröffentlicht wurde 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 */
...
}


Wie Sie sich vorstellen können, IsAllowShell(pw)war das der Schuldige:

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


Kein Wunder, warum ich so ein merkwürdiges Verhalten erlebte. Für andere Benutzer als root oder admin werden nur die Shells / bin / sh und / bin / ash akzeptiert . Und das unabhängig von der UID (ich hatte auch getestet, wie man joeuser uid = 0 macht, und es hat nicht funktioniert. Jetzt ist klar, warum).

Sobald die Ursache identifiziert wurde, war die Lösung einfach: Entfernen Sie einfach den Aufruf von IsAllowShell () . Es hat eine Weile gedauert, bis ich die richtige Konfiguration für das Cross-Compilieren von openssh und all seinen Abhängigkeiten gefunden hatte, aber am Ende hat es gut funktioniert.

Wenn jemand daran interessiert ist, dasselbe zu tun (oder zu versuchen, andere Kernelmodule oder Binärdateien für Synology zu kompilieren), ist hier meine Version von Makefile . Es wurde mit OpenSSH-5.8p1 getestet und funktioniert gut mit Modellen mit Marvell Kirkwood mv6281 / mv6282-CPU (wie DS212 +). Ich habe einen Host mit Ubuntu 12.10 x64 verwendet.

Fazit: schlechte Praxis, schrecklicher Code und ein gutes Beispiel dafür, was nicht zu tun ist. Ich verstehe, dass OEMs manchmal spezielle Anpassungen entwickeln müssen, aber sie sollten es sich zweimal überlegen, bevor sie zu tief graben. Dies führt nicht nur zu nicht wartbarem Code für sie, sondern schafft auch alle möglichen unvorhergesehenen Probleme. Zum Glück gibt es eine GPL, um sie ehrlich und offen zu halten.

Gui Ambros
quelle
4
Hervorragende Arbeit, Sir, bei der Untersuchung dieses Problems und beim Zurückziehen des Vorhangs von der Synology-Bühne. Ich muss zugeben, dass ich bis jetzt sehr viel von meiner Diskstation gehalten habe, da sie sehr nützlich war und einmal gebootet, jetzt sogar einige Skripte für mich unter dem neuen Taskplaner ausführt. Aber Sie haben hier einige Mängel im kurzsichtigen Design aufgedeckt. Ich bin immer noch zufrieden mit der Diskstation, werde mich aber an Ihren Beitrag erinnern. Hat sowohl den Beitrag als auch die Antwort positiv bewertet.
Bernard Dy
Upvoted für die Mühe. Wenn ich keine Müsliverbindungen herstellen möchte, möchte ich nur die Standard-Shell in ändern. Gibt /bin/shes eine Möglichkeit, dies zu tun?
Vicary
Warum Synology dies tun würde, ist mir völlig unverständlich :(
Gerhard Burger
Ich umbenannt /bin/ashzu /bin/ash.realund verknüpft zshauf /bin/ash... so weit alles in Ordnung scheint ... o_o
x1a0
7

Um das Problem zu umgehen und da ich bash über ipkg installiert habe und nicht sicher bin, ob / opt immer verfügbar sein wird (korrekt eingehängt), füge ich einfach Folgendes in mein .profile ein

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

während / etc / passwd / bin / ash als Shell enthält.

Tom Regner
quelle
1

Wir werden sehen. Es ist isoliert auf eine einzelne Shell, und Sie sehen sich die Ausgabe von sshd debug an, so dass es keine Probleme mit schreibgeschützten Berechtigungen für ~ joeuser / .ssh gibt. Das ist derjenige, der die meisten Leute bekommt.

Haben Sie versucht, einen zusätzlichen normalen Benutzer (dh nicht joeuser) zu erstellen, um sicherzustellen, dass das gleiche Problem auftritt? Das würde es auf die Konfiguration des Benutzers im Vergleich zur systemweiten Konfiguration beschränken.

Wenn es sich um ein systemweites Problem handelt, sollten Sie sich als Nächstes gemeinsam genutzte Konfigurationsdateien wie / etc / profile ansehen, die von allen verwendet werden. Möglicherweise gibt es einen bedingten Block, der nicht ausgelöst wird, wenn der Benutzername root ist. (nicht effektive userid, da du das schon getestet hast)

Überprüfen Sie dmesg auf Segmentierungsfehlerberichte, falls dies noch nicht geschehen ist, für den Fall, dass etwas noch seltsameres vor sich geht.

Andrew B
quelle
Vielen Dank Andrew. Auch überprüft dmesg und absolut nichts. Es hat auch nicht geholfen, einen brandneuen Benutzer zu erstellen. Es handelt sich also eindeutig um ein systemweites Problem. Und Joeuser kann sich normal anmelden, wenn ich die Shell zurück in / bin / ash ändere, was jegliche / etc / profile oder andere ausschließt (die ich auch überprüft habe, übrigens). Es ist nur mit non-root, mit bash, via ssh. In diesem Punkt ist es nicht einmal ein wirkliches Problem (ich kann damit leben, wie es jetzt ist), aber es ärgert mich zuzugeben, dass ich die Ursache für dieses seltsame Verhalten nicht finden konnte. Es ist schließlich ein deterministisches System; Es muss eine Erklärung geben ...
Gui Ambros
1

Versuchen Sie, in / etc / ssh / sshd_config
nach AllowUsers zu suchen

wenn es da ist, versuche dort joeuser hinzuzufügen, nur username

es kann auch in pam gesperrt sein ... ich erinnere mich nicht welche datei es ist ...

BiG_NoBoDy
quelle
Nicht der Fall. Wenn es ein Problem mit AllowUsers gab, konnte ich mich nicht bei Joeuser anmelden, wenn ich die Shell in / bin / ash änderte. Dies scheint nichts mit Sicherheit zu tun zu haben oder mit einer anderen Konfiguration. Es ist wahrscheinlich eine Art, wie Bash Pseudo-Terminals über ssh, versus Asche, csh, etc. behandelt.
Gui Ambros
1

Ihre modifizierte Version von openssh sucht nach einer /bin/shShell?

Einfache Lösung dann:

ln -fs / bin / bash / bin / sh

Ponytech
quelle
Dies würde die Shell für alle Benutzer ändern und nicht nur für diejenigen, die bash benötigen. Außerdem würde jedes neue Upgrade den symbolischen Link entfernen (auch wenn das Reparieren von openssh das gleiche Problem hat). Wie auch immer, dies wurde wie oben beschrieben gelöst.
Gui Ambros
OK, stimmt, aber da ich der einzige Benutzer auf meinem NAS bin, funktioniert diese Lösung für mich. Trotzdem danke, dass du darauf hingewiesen hast, was du entdeckt hast.
Ponytech
0

Versuchen Sie, Bash erneut zu installieren, und prüfen Sie, ob dies hilfreich ist.

Pratap
quelle
Nein, ich habe Bash von zwei verschiedenen Quellen erhalten (eine von Optware Distribution, und ich habe auch 3.2 von der Quelle selbst kompiliert) und das gleiche Problem. Ich bin bis zum Äußersten gegangen, um Bash 4.2 zu bekommen, die Patches (alle 39) anzuwenden und Cross-Compilings durchzuführen. Genau das gleiche Verhalten. Funktioniert mit root, Berechtigung für andere verweigert . Meine letzte Vermutung ist die OpenSSH-Binärdatei, die standardmäßig von der Synology-Firmware installiert wird. Dies ist das einzige Stück, das ich noch nicht angefasst habe. Ich werde versuchen, die neueste Quelle herunterzuladen und zu kompilieren, um zu sehen, was passiert.
Gui Ambros
2
Seltsam, nicht sicher, aber das scheint ein Problem mit authconfig zu sein. Läuft LDAP auch auf dem Server? Können Sie mir eine Echtzeit-Protokollausgabe der Sicherheits- und Nachrichtendatei zum Zeitpunkt des Anmeldefehlers senden?
Pratap
2
Melden Sie sich auch als root auf dem Server an und lassen Sie die Benutzer-Shell / bin / bash sein und versuchen Sie, mit su-username zum Benutzer zu wechseln. Zeigen Sie mir auch die Ausgabe davon.
Pratap
0

Falls jemand darüber stolpert, weil er den gleichen Fehler gemacht hat, den ich gemacht habe:

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

Nein: $ sudo usermod -s bash your_username

Die zweite führt dazu, dass die Erlaubnis beim Einspielen verweigert wird.

Christy
quelle