无法使用Synology NAS上的/ bin / bash Shell通过SSH登录到任何帐户


30

我正在尝试在嵌入式设备(Synology DS212 + NAS)上运行的ARM Linux上将bash安装为默认外壳。但是确实有什么问题,我不知道这是什么。

症状:

1)根目录将/ 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的shell更改回/ 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
$ 


为了使事情更奇怪,我可以/bin/bash使用串行控制台(!)以joeuser身份登录。另外,su - joeuser作为root可以正常工作,因此bash二进制文件本身也可以正常工作。

出于绝望之举,我在/ etc / passwd上将joeuser的uid更改为0,但也没有用,因此似乎与权限无关。

看来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,显示了使用/ bin / bash作为shell的joeuser尝试登录的失败尝试:

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 --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中列出?
2012年

是的,它在/ etc / shells中列出。并在上面添加了权限0755。
Gui Ambros

他的.bashrc文件中很可能正在运行某些内容。您能找到〜joeuser / .bashrc并戳一下他的个人资料脚本吗?您还可以尝试以他的身份登录时运行/ bin / bash。
vicfn

没有〜joeuser / .ssh,也没有配置文件脚本。我刚刚创建要测试的空白用户。
Gui Ambros 2012年

Answers:


39

供以后参考:经过大量时间研究和调试此问题,我终于找到了根本原因。

经Synology使用OpenSSH的版本是一个高度定制的版本,这并没有表现得像原来的代码。它具有许多技巧和特殊的自定义设置-例如,在接受登录名之前进行其他检查,以查看是否在Web界面内启用了SSH服务,或者从rsync命令中删除特殊字符(;,|,')。请等待... 避免普通用户使用不同于/ bin / sh或/ bin / ash的shell。是的,在二进制文件中进行了硬编码。

这是来自Synology在其源代码(DSM4.1-分支2636) file 上分发的OpenSSH 5.8p1的代码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;
}


难怪我为什么会遇到这种奇怪的行为。除rootadmin之外的其他用户只能接受shell / bin / sh和/ bin / ash 。而且这与uid无关(我也测试过让joeuser uid = 0,并且它不起作用。现在很明显为什么)。

确定原因后,修复很容易:只需删除对IsAllowShell()的调用即可。我花了一些时间来获得正确的配置来交叉编译openssh及其所有依赖项,但最终效果很好。

如果有人有兴趣这样做(或尝试为Synology交叉编译其他内核模块或二进制文件),这是我的Makefile版本。它已通过OpenSSH-5.8p1源进行了测试,并且可以与运行Marvell Kirkwood mv6281 / mv6282 CPU(例如DS212 +)的模型配合使用。我使用了运行Ubuntu 12.10 x64的主机。

底线:不好的做法,糟糕的代码,以及执行操作的一个很好的例子。我知道有时OEM需要开发特殊的自定义设置,但是在深入研究之前,他们应该三思而后行。这不仅会导致它们无法维护的代码,而且还会在将来产生各种无法预料的问题。幸运的是,GPL的存在是为了让他们保持诚实-并保持开放。


4
恒星工作的先生,正在调查这个问题并从Synology阶段撤回帷幕。我必须承认,到目前为止,我对Diskstation的评价很高,因为它非常有用,而且一旦启动,现在甚至可以在新的任务计划程序下为我运行一些脚本。但是您在这里发现了短视设计的一些缺陷。我对Diskstation仍然感到满意,但是请牢记您的帖子。支持发布和回答。
Bernard Dy 2013年

为努力而投票。如果我不想打扰谷物连接,我只想将默认的shell更改为/bin/sh,有什么办法吗?
Vicary 2015年

为何Synology会这样做呢?(
Gerhard Burger

我改名/bin/ash/bin/ash.real和链接zsh/bin/ash...到目前为止一切似乎罚款... O_O
x1a0

7

为了解决这个问题,由于我是通过ipkg安装bash的,所以我不确定/ opt是否始终可用(正确安装),因此我将以下内容放入.profile中

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

/ etc / passwd包含/ bin / ash作为shell。


1

让我们来看看。它被隔离在单个shell中,而且您正在查看sshd调试输出,因此〜joeuser / .ssh并不是世界可写的权限问题。那是吸引大多数人的那个。

您是否尝试过创建其他普通用户(即不是joeuser)以确保它遇到相同的问题?这样会将其隔离为用户的配置与系统范围的配置。

如果是系统范围的问题,那么我接下来要看的是共享配置文件,例如/ etc / profile,每个人都可以获取。如果用户名是root,则可能会触发一个条件块。(不是有效的用户ID,因为您已经对此进行了测试)

如果还没有,请检查dmesg的分段错误报告,以防万一甚至发生了一些奇怪的事情。


谢谢安德鲁。还检查了dmesg,绝对没有。创建新用户也无济于事,因此很显然这是系统范围的问题。如果我将Shell改回/ bin / ash,则joeuser可以正常登录,从而排除了/ etc / profile或其他(我也检查过,btw)。只有非root用户才能通过ssh使用bash。至此,这甚至不是一个真正的问题(我现在可以忍受),但是让我很生气的是我无法找到导致这种奇怪行为的原因。毕竟,这是一个确定性的系统。有必须是某种解释...
桂安布罗斯

1

尝试/ etc / ssh / sshd_config
搜索AllowUsers

如果在那里尝试添加joeuser,只是用户名

也可能在pam中被阻止了...我不记得是哪个文件了...


并非如此。如果是AllowUsers的问题,当我将shell更改为/ bin / ash时,它不会让我使用joeuser登录。这似乎与安全性无关,也与其他任何配置都不相关。这也可能是某种庆典手柄如何通过ssh伪终端,与灰,CSH等
桂安布罗斯

1

他们的openssh修改版正在寻找/bin/shshell?

那么简单的解决方案:

ln -fs / bin / bash / bin / sh


这将改变所有用户的外壳,而不仅仅是需要bash的用户。同样,任何新的升级都将删除符号链接(即使修复openssh也具有相同的问题)。无论如何,如上所述,解决了该问题。
Gui Ambros

好的,是的,但是由于我是NAS上的唯一用户,因此该解决方案适用于我。无论如何,感谢您指出您的发现。
Ponytech

0

尝试重新安装Bash,看看是否有帮助。


是的,我从两个不同的来源获得了bash(一个来自Optware发行版,我也从自己的来源编译了3.2),并且存在相同的问题。我走到了极端,甚至获得bash 4.2并应用补丁(共39个补丁),然后进行交叉编译。完全相同的行为。与root用户一起使用,其他人的权限被拒绝。我最后的猜测是OpenSSH二进制文件,与Synology固件默认安装的文件相同。这是我唯一没碰过的东西。我将尝试下载最新的源代码并进行交叉编译,以了解发生了什么。
Gui Ambros

2
奇怪的不确定,但这似乎是authconfig问题。ldap是否也在服务器上运行?登录失败时,可以将安全和消息文件的实时日志输出发送给我吗?
Pratap

2
还要以root用户身份登录到服务器,并让用户shell为/ bin / bash,然后尝试使用su-username切换到用户。也显示此输出。
Pratap

0

万一有人因为我犯了同样的错误而偶然发现了这个错误:

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

没有: $ sudo usermod -s bash your_username

ssh进入时,第二个将导致拒绝权限。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.