Nie można zalogować się przez SSH na żadne konta korzystające z powłoki / bin / bash na serwerze Synology NAS

30

Próbuję zainstalować bash jako domyślną powłokę w systemie ARM Linux działającym na urządzeniu wbudowanym (Synology DS212 + NAS). Ale coś jest naprawdę nie tak i nie mogę zrozumieć, co to jest.

Objawy:

1) Root ma domyślną powłokę / bin / bash i może logować się normalnie przez 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 ma domyślną powłokę / bin / bash i otrzymuje komunikat „Odmowa dostępu” podczas próby zalogowania się przez 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) zmiana powłoki joeusera z powrotem na / 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
$ 


Żeby było jeszcze bardziej dziwnie, mogę zalogować się jako joeuser przy /bin/bashużyciu konsoli szeregowej (!). Również su - joeuserjako root działa dobrze, więc sam plik bash działa dobrze.

W akcie rozpaczy zmieniłem identyfikator użytkownika joeuser na 0 na / etc / passwd, ale również nie działałem, więc nie wydaje się, aby było to związane z uprawnieniami.

Wygląda na to, że bash wykonuje dodatkowe sprawdzenia, których sshd nie lubi, i blokuje połączenia dla użytkowników innych niż root. Może jakiś rodzaj sprawdzania poprawności - lub emulacja terminala - który uruchamia SIGCHLD, ale tylko gdy jest wywoływany przez ssh.

Przejrzałem już każdy element na sshd_config, a także przełączyłem SSHD w tryb debugowania, ale nie znalazłem nic dziwnego. Oto moje /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


A oto dane wyjściowe z /usr/syno/sbin/sshd -dpokazujące nieudaną próbę zalogowania się użytkownika z / bin / bash jako powłoką:

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


Tutaj masz pełne wyjście sshd -dd wraz z ssh -vv .

Grzmotnąć:

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

Plik bash został skompilowany krzyżowo ze źródła. Próbowałem też użyć skompilowanego pliku binarnego z dystrybucji Optware , ale miałem dokładnie ten sam problem. Sprawdziłem za pomocą brakujących bibliotek współdzielonychobjdump -x , ale wszystkie one istnieją.

Wszelkie pomysły, co może być przyczyną tego „ Odmowa zezwolenia, spróbuj ponownie. Prawie nurkuję w kodzie źródłowym bash, żeby to zbadać, ale staram się unikać godzin goniących coś, co może być głupie.

EDYCJA: dodanie dodatkowych informacji o bash i systemie

$ 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
źródło
2
ls -l /bin/bash
Michael Hampton
Czy / bin / bash znajduje się w / etc / shells?
zadzwonić
Tak, jest wymieniony w / etc / shells. I uprawnienia 0755, dodane powyżej.
Gui Ambros,
Najprawdopodobniej coś jest uruchomione w jego pliku .bashrc. Czy potrafisz cat ~ joeuser / .bashrc i szturchać jego skrypty profilowe? Możesz także spróbować uruchomić / bin / bash, gdy jesteś zalogowany jako on.
vicfn
Bez ~ joeuser / .ssh i bez skryptów profilowych. To pusty użytkownik, którego właśnie stworzyłem do testowania.
Gui Ambros,

Odpowiedzi:

39

Do wykorzystania w przyszłości: po zbyt wielu godzinach badania i debugowania tego problemu w końcu odkryłem główną przyczynę.

Wersja OpenSSH używana przez Synology jest wersją wysoce dostosowaną, która nie zachowuje się jak oryginalny kod. Ma wiele modyfikacji i dostosowań ad-hoc - np. Dodatkowe sprawdzanie przed zaakceptowaniem loginu, aby sprawdzić, czy usługa SSH jest włączona w interfejsie internetowym, lub usuwanie specjalnych znaków (;, |, ') z poleceń rsync lub ... czekaj na to ... unikając zwykłych użytkowników używających powłoki innej niż / bin / sh lub / bin / ash . Tak, mocno zakodowane w pliku binarnym.

Oto fragment kodu z OpenSSH 5.8p1, rozpowszechniany przez Synology na ich kodzie źródłowym (DSM4.1 - oddział 2636) , plik 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 */
...
}


Jak możesz sobie wyobrazić, IsAllowShell(pw)winowajcą był:

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


Nic dziwnego, dlaczego miałem tak dziwne zachowanie. Tylko shells / bin / sh i / bin / ash będą akceptowane dla użytkowników innych niż root lub admin . I to bez względu na UID (testowałem również robiąc joeuser identyfikatora użytkownika = 0, i to nie zadziałało. Teraz jest oczywiste, dlaczego).

Po zidentyfikowaniu przyczyny naprawa była łatwa: wystarczy usunąć wywołanie IsAllowShell () . Zajęło mi trochę czasu, aby uzyskać odpowiednią konfigurację do kompilacji krzyżowej openssh i wszystkich jej zależności, ale ostatecznie działała dobrze.

Jeśli ktoś jest zainteresowany zrobieniem tego samego (lub próbą kompilacji krzyżowej innych modułów jądra lub plików binarnych dla Synology), oto moja wersja Makefile . Został przetestowany ze źródłem OpenSSH-5.8p1 i działa dobrze z modelami z procesorem Marvell Kirkwood mv6281 / mv6282 (jak DS212 +). Użyłem hosta z systemem Ubuntu 12.10 x64.

Konkluzja: zła praktyka, okropny kod i świetny przykład tego, czego nie należy robić. Rozumiem, że czasami producenci OEM muszą opracować specjalne dostosowania, ale powinni się zastanowić dwa razy, zanim zaczną zbyt głęboko sięgać. Skutkuje to nie tylko niemożliwym do utrzymania kodem, ale także tworzy różnego rodzaju nieprzewidziane problemy. Na szczęście GPL istnieje, aby zachować ich uczciwość - i otwartość.

Gui Ambros
źródło
4
Gwiezdna praca, proszę pana, w badaniu tego problemu i odsunięciu kurtyny z powrotem z etapu Synology. Muszę przyznać, że do tej pory bardzo dobrze myślałem o mojej stacji Diskstation, ponieważ była ona bardzo przydatna, a po uruchomieniu nawet teraz uruchamia dla mnie kilka skryptów w ramach nowego harmonogramu zadań. Ale ujawniłeś tutaj pewne wady krótkowzroczności. Nadal jestem zadowolony z Diskstation, ale będę pamiętać o twoim poście. Pozytywny zarówno post, jak i odpowiedź.
Bernard Dy
Wybitny za wysiłek. Jeśli nie chcę zawracać sobie głowy nawiązywaniem połączeń zbożowych, chcę po prostu zmienić domyślną powłokę na /bin/sh, czy jest na to sposób?
Wikariusz
Dlaczego synologia miałaby to zrobić, jest całkowicie poza mną :(
Gerhard Burger
I przemianowany /bin/ashna /bin/ash.reali połączone zshna /bin/ash... jak na razie wszystko wydaje się dobrze ... O_O
x1a0
7

Aby obejść ten problem, a ponieważ zainstalowałem bash przez ipkg i nie jestem pewien, czy opcja / opt będzie zawsze dostępna (poprawnie zamontowana), po prostu umieszczam w moim pliku .profile:

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

podczas gdy / etc / passwd zawiera / bin / ash jako powłokę.

Tom Regner
źródło
1

Zobaczmy. Jest izolowany do pojedynczej powłoki, a ponadto patrzysz na wynik debugowania sshd, więc nie jest to problem z uprawnieniami do zapisu na świecie z ~ joeuser / .ssh. To ten, który przyciąga większość ludzi.

Czy próbowałeś utworzyć dodatkowego normalnego użytkownika (tj. Nie joeuser), aby upewnić się, że napotyka ten sam problem? To odizolowałoby to konfigurację użytkownika od konfiguracji ogólnosystemowej.

Jeśli jest to problem ogólnosystemowy, następną rzeczą, na którą zwrócę uwagę, są udostępnione pliki konfiguracyjne, takie jak / etc / profile, które są pozyskiwane przez wszystkich. Może istnieć blok warunkowy, który nie uruchamia się, jeśli nazwa użytkownika to root. (nieefektywny identyfikator użytkownika, ponieważ już to testowałeś)

Sprawdź dmesg, aby zobaczyć raporty błędów segmentacji, jeśli jeszcze tego nie zrobiłeś, na wypadek, gdyby działo się coś jeszcze dziwniejszego.

Andrew B.
źródło
Dzięki Andrew. Sprawdziłem także dmesg i absolutnie nic. Utworzenie nowego użytkownika również nie pomogło, więc jest to kwestia ogólnosystemowa. I joeuser może zalogować się normalnie, jeśli zmienię powłokę z powrotem na / bin / ash, co wyklucza dowolny profil / etc / profile lub inny (co też sprawdziłem, btw). To tylko z rootem, używając bash, przez ssh. W tym momencie nie jest to nawet prawdziwy problem (mogę z tym żyć tak, jak jest teraz), ale denerwuje mnie przyznanie, że nie byłem w stanie znaleźć przyczyny tego dziwnego zachowania. W końcu jest to system deterministyczny; tam musi być jakiś wyjaśnień ...
Gui Ambros
1

spróbuj / etc / ssh / sshd_config
wyszukać AllowUsers

jeśli tam jest, spróbuj dodać joeuser, po prostu nazwę użytkownika

także może być zablokowany w pam ... Nie pamiętam, który to plik ...

BiG_NoBoDy
źródło
Nie tak jest. Gdyby to był problem z AllowUsers, nie pozwoliłby mi zalogować się przy użyciu joeuser, kiedy zmieniam powłokę na / bin / ash. Nie wydaje się, aby było to związane z czymkolwiek związanym z bezpieczeństwem lub inną konfiguracją. Prawdopodobnie jest to pewien sposób, w jaki bash obsługuje pseudo terminale za pośrednictwem ssh, w porównaniu do ash, csh itp.
Gui Ambros
1

Ich zmodyfikowana wersja openssh szuka /bin/shpowłoki?

Łatwe rozwiązanie to:

ln -fs / bin / bash / bin / sh

Ponytech
źródło
To zmieniłoby powłokę dla wszystkich użytkowników, a nie tylko tych, którzy potrzebowali bash. Również każda nowa aktualizacja usunęłaby dowiązanie symboliczne (nawet jeśli naprawa openssh również ma ten sam problem). W każdym razie zostało to rozwiązane, jak opisano powyżej.
Gui Ambros
OK prawda, ale ponieważ jestem jedynym użytkownikiem na moim serwerze NAS, to rozwiązanie działa dla mnie. W każdym razie dzięki za wskazanie tego, co odkryłeś.
Ponytech,
0

Spróbuj ponownie zainstalować Bash i sprawdź, czy to pomoże.

Pratap
źródło
Ups, dostałem bash z dwóch różnych źródeł (jednego z dystrybucji Optware, a także sam skompilowałem 3.2 ze źródła) i ten sam problem. Doszedłem do ekstremum nawet bash 4.2 i nakładania łat (wszystkie 39) i kompilacji krzyżowej. Dokładnie takie samo zachowanie. Działa z rootem, odmowa dostępu dla innych. Moje ostatnie przypuszczenie to plik binarny OpenSSH, który jest domyślnie instalowany przez oprogramowanie układowe Synology. To jedyny kawałek, którego jeszcze nie dotknąłem. Spróbuję pobrać najnowsze źródło i kompilację krzyżową, aby zobaczyć, co się stanie.
Gui Ambros,
2
Dziwne, nie jestem pewien, ale wydaje się, że jest to problem z authconfig. Czy ldap działa również na serwerze? Czy możesz mi przesłać w czasie rzeczywistym wyjście z bezpiecznego pliku wiadomości i pliku komunikatu w momencie niepowodzenia logowania.
Pratap
2
Zaloguj się również jako root do serwera i pozwól powłoce użytkownika być / bin / bash i spróbuj przełączyć się na użytkownika za pomocą su - nazwa użytkownika. Pokaż mi również wynik tego.
Pratap,
0

Na wypadek, gdyby ktoś natknął się na to, ponieważ popełnił ten sam błąd, co ja:

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

Nie: $ sudo usermod -s bash your_username

Drugi spowoduje odmowę dostępu podczas ssh'ing.

Christy
źródło