Не удается войти через SSH в любые учетные записи с помощью оболочки / bin / bash на Synology NAS

30

Я пытаюсь установить bash в качестве оболочки по умолчанию на ARM Linux, работающем на встроенном устройстве (Synology DS212 + NAS). Но что-то действительно не так, и я не могу понять, что это такое.

Симптомы:

1) Root имеет / bin / bash в качестве оболочки по умолчанию и может нормально входить в систему через 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 имеет / bin / bash в качестве оболочки по умолчанию и получает «Отказано в доступе» при попытке войти через 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) изменение оболочки joeuser обратно на / 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
$ 


Чтобы сделать вещи еще более странными, я могу войти в систему как joeuser, используя /bin/bashпоследовательную консоль (!). Также su - joeuserкак root работает нормально, так что сам bash-файл работает нормально.

В отчаянии я изменил uid joeuser на 0 в / etc / passwd, но тоже не сработал, поэтому, похоже, это не связано с разрешениями.

Похоже, что bash делает дополнительную проверку, которая не нравится sshd, и блокирует соединения для пользователей без полномочий root. Может быть, какая-то проверка работоспособности - или эмуляция терминала - которая запускает SIGCHLD, но только при вызове через ssh.

Я уже просмотрел каждый элемент в sshd_config, а также перевел SSHD в режим отладки, но ничего странного не нашел. Вот мой /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


И вот вывод /usr/syno/sbin/sshd -d, показывающий неудачную попытку joeuser, пытающегося войти в систему, с / bin / bash в качестве оболочки:

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


Здесь у вас есть полный вывод sshd -dd вместе с ssh -vv .

Bash:

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

Двоичный файл bash был скомпилирован из исходного кода. Я также пытался использовать предварительно скомпилированный двоичный файл из дистрибутива Optware , но у меня была точно такая же проблема. Я проверил на предмет отсутствия общих библиотек objdump -x, но они все есть.

Любые идеи, что может быть причиной этого "В доступе отказано, пожалуйста, попробуйте еще раз. " Я почти погружаюсь в исходный код bash, чтобы разобраться, но стараюсь не часами гоняться за тем, что может быть глупым.

РЕДАКТИРОВАТЬ: добавление дополнительной информации о Bash и системе

$ 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
Майкл Хэмптон
Перечислен ли / bin / bash в / etc / shells?
Тинк
Да, он указан в / etc / shells. И разрешения 0755, добавленные выше.
Ги Амброс
Скорее всего, что-то запускается в его файле .bashrc. Можете ли вы кошку ~ joeuser / .bashrc и покопаться в его профилях скриптов? Вы также можете попробовать запустить / bin / bash, войдя в систему как он.
Vicfn
Нет ~ joeuser / .ssh и нет скриптов профиля. Это пустой пользователь, которого я только что создал для тестирования.
Ги Амброс

Ответы:

39

Для дальнейшего использования: после долгих часов поиска и устранения этой проблемы я, наконец, обнаружил причину.

Версия OpenSSH, используемая Synology, является сильно настроенной версией, которая не ведет себя так, как исходный код. Он имеет множество хаков и специальных настроек - например, дополнительная проверка перед принятием входа в систему, чтобы увидеть, включена ли служба SSH в веб-интерфейсе, или извлечение специальных символов (;, |, ') из команд rsync, или .. ... подождите ... избегая использования обычными пользователями оболочки, отличной от / bin / sh или / bin / ash . Да, жестко закодировано в двоичном коде.

Вот фрагмент кода из OpenSSH 5.8p1, распространяемый Synology в их исходном коде (DSM4.1 - ветвь 2636) , файл 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 */
...
}


Как вы можете себе представить, IsAllowShell(pw)виновником было:

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


Не удивительно, почему я испытывал такое странное поведение. Только оболочки / bin / sh и / bin / ash будут приняты для пользователей, отличных от root или admin . И это независимо от идентификатора пользователя (я также протестировал создание joeuser uid = 0, и это не сработало. Теперь понятно почему).

Определив причину, исправить это было легко: просто удалите вызов IsAllowShell () . Мне потребовалось некоторое время, чтобы получить правильную конфигурацию для кросс-компиляции openssh и всех его зависимостей, но в итоге это сработало хорошо.

Если кто-то заинтересован в том же (или пытается кросс-компилировать другие модули ядра или двоичные файлы для Synology), вот моя версия Makefile . Он был протестирован с источником OpenSSH-5.8p1 и хорошо работает с моделями с процессором Marvell Kirkwood mv6281 / mv6282 (например, DS212 +). Я использовал хост под управлением Ubuntu 12.10 x64.

Итог: плохая практика, ужасный код и отличный пример того, чего не следует делать. Я понимаю, что OEM-производителям необходимо разработать специальные настройки, но они должны дважды подумать, прежде чем копать слишком глубоко. Это не только приводит к неуправляемому коду для них, но и создает всевозможные непредвиденные проблемы в будущем. К счастью, GPL существуют, чтобы сохранять их честными и открытыми.

Ги Амброс
источник
4
Звездная работа, сэр, в исследовании этой проблемы и отодвижении занавеса со стадии Синологии. Я должен признать, что до сегодняшнего дня я очень высоко ценил свою Diskstation, поскольку она была очень полезна, и после начальной загрузки теперь даже запускает для меня несколько сценариев в новом планировщике задач. Но вы выявили здесь некоторые недостатки близорукого дизайна. Я все еще доволен работой Diskstation, но буду помнить ваш пост. Проголосовал как пост, так и ответ.
Бернард Ди
Поддержал за усилия. Если я не хочу беспокоиться о подключении к зерновым, я просто хочу изменить оболочку по умолчанию на /bin/sh, есть ли способ сделать это?
Vicary
Почему синология так поступила, я совершенно не знаю :(
Герхард Бургер,
Я переименовал /bin/ashв /bin/ash.realи связан zshна /bin/ash... до сих пор все кажется нормально ... Им
x1a0
7

Чтобы обойти проблему, и поскольку я установил bash через ipkg, и я не могу быть уверен, что / opt всегда будет доступен (смонтирован правильно), я просто помещаю следующее в мой .profile

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

в то время как / etc / passwd содержит / bin / ash в качестве оболочки.

Том Регнер
источник
1

Посмотрим. Он изолирован от одной оболочки, кроме того, вы просматриваете выходные данные отладки sshd, так что это не проблемы с правами на запись в ~ ~ joeuser / .ssh. Это тот, который получает большинство людей.

Вы пытались создать дополнительного обычного пользователя (т.е. не joeuser), чтобы убедиться, что он испытывает ту же проблему? Это изолировало бы его от конфигурации пользователя против конфигурации всей системы.

Если это общесистемная проблема, то на следующую вещь я бы обратил внимание на общие файлы конфигурации, такие как / etc / profile, которые получают все. Там может быть условный блок, который не срабатывает, если имя пользователя root. (не эффективный ID пользователя, так как вы уже проверены на это)

Проверьте dmesg на наличие сообщений об ошибках сегментации, если вы этого еще не сделали, на случай, если что-то происходит, даже более странно.

Андрей Б
источник
Спасибо, Андрей. Также проверил dmesg, и абсолютно ничего. Создание нового пользователя также не помогло, поэтому очевидно, что это проблема всей системы. И joeuser может войти в систему нормально, если я переключу оболочку обратно на / bin / ash, что исключает любой / etc / profile или другой (который я также проверял, кстати) Это просто с не-root, используя bash, через ssh. Поскольку этот вопрос даже не является реальной проблемой (я могу жить с этим, как сейчас), но меня раздражает признание того, что я не смог найти причину этого странного поведения. В конце концов, это детерминированная система; там должна быть какая - то объяснение ...
Гуй Ambros
1

попробуйте / etc / ssh / sshd_config
найти AllowUsers

если он есть, попробуйте добавить joeuser, просто имя пользователя

также он может быть заблокирован в pam ... Я не помню, какой файл это ...

BiG_NoBoDy
источник
Не тот случай. Если бы это была проблема с AllowUsers, я бы не смог войти в систему с joeuser, когда я изменил оболочку на / bin / ash. Похоже, это не связано ни с чем, связанным с безопасностью, или с любой другой конфигурацией. Это, наверное , какая - то , как Баш ручки псевдо терминалов через SSH, по сравнению с золой, CSH и т.д.
Gui Ambros
1

Их модифицированная версия openssh ищет /bin/shоболочку?

Простое решение тогда:

ln -fs / bin / bash / bin / sh

Ponytech
источник
Это изменит оболочку для всех пользователей, а не только для тех, кто нуждается в bash. Также любое новое обновление удалит символическую ссылку (хотя исправление openssh также имеет ту же проблему). Во всяком случае, это было решено, как описано выше.
Ги Амброс
Хорошо, правда, но, поскольку я единственный пользователь на моем NAS, это решение работает для меня. В любом случае, спасибо, что указали на то, что вы обнаружили.
Ponytech
0

Попробуйте переустановить Bash и посмотрите, поможет ли это.

Pratap
источник
Нет, я получил bash из двух разных источников (один из дистрибутива Optware, и я сам скомпилировал 3.2 из источника), и та же проблема. Я дошел до крайности, даже получив bash 4.2, применив патчи (все 39 из них) и кросс-компиляцию. Точно такое же поведение. Работает с рутом, в других отказано в доступе. Мое последнее предположение - двоичный файл OpenSSH, который по умолчанию устанавливается в прошивке Synology. Это единственная часть, которую я еще не трогал. Я попытаюсь загрузить последний исходный код и выполнить кросс-компиляцию, чтобы посмотреть, что произойдет.
Ги Амброс
2
Странно, не уверен, но это, кажется, проблема authconfig. Ldap также работает на сервере? Можете ли вы выслать мне в режиме реального времени вывод журнала безопасности и файла сообщений во время сбоя входа в систему.
Пратап
2
Также войдите в систему как root на сервере, и пусть пользовательская оболочка будет / bin / bash и попытайтесь переключиться на пользователя, используя su - username. Покажите мне вывод этого тоже.
Пратап
0

В случае, если кто-то наткнется на это, потому что они совершили ту же ошибку, что и я:

да: $ sudo usermod -s /bin/bash your_username

нет: $ sudo usermod -s bash your_username

Второе приведет к отказу в разрешении, когда ssh'ing in.

Кристи
источник