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

我正在尝试将bash安装为在嵌入式设备(Synology DS212 NAS)上运行的ARM Linux上的默认shell.但是有些事情确实存在问题,我无法弄清楚它是什么.

症状:

1)Root有/ bin / bash作为默认shell,可以通过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作为默认shell,并在尝试通过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的输出,显示了joeuser尝试登录失败的尝试,使用/ bin / bash作为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

在这里你有full output of sshd -dd,together with 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 distribution的预编译二进制文件,但是遇到了完全相同的问题.我使用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

解决方法

供将来参考:经过太多时间研究和调试这个问题,我终于找到了根本原因.

Synology使用的OpenSSH版本是一个高度定制的版本,其行为与原始代码不同.它有很多hacks和ad-hoc自定义 – 例如,在接受登录之前进行额外检查以查看是否在Web界面中启用了SSH服务,或者从rsync命令中剥离特殊字符(;,|,’),或者..等待它…避免普通用户使用不同于/ bin / sh或/ bin / ash的shell.是的,在二进制文件中硬编码.

这是OpenSSH 5.8p1的代码片段,由Synology在其源代码(DSM4.1 – branch 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;
}

难怪我为什么会遇到这种奇怪的行为.对于不同于root或admin的用户,只接受shells / bin / sh和/ bin / ash.这不管是什么uid(我测试过也使joeuser uid = 0,它没有用.现在很明显为什么).

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

如果有人有兴趣做同样的事情(或尝试交叉编译Synology的其他内核模块或二进制文件),here’s my version of Makefile.它已经过OpenSSH-5.8p1 source测试,适用于运行Marvell Kirkwood mv6281 / mv6282 CPU(如DS212)的模型.我使用了运行Ubuntu 12.10 x64的主机.

底线:糟糕的做法,可怕的代码,以及不做的事情的一个很好的例子.我理解有时OEM需要开发特殊的自定义,但是在挖掘太深之前他们应该三思而后行.这不仅会导致代码无法维护,还会产生各种不可预见的问题.值得庆幸的是,GPL的存在是为了让他们诚实 – 并且开放.

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


linux常用进程通信方式包括管道(pipe)、有名管道(FIFO)、信号(signal)、消息队列、共享内存、信号量、套接字(socket)。管道用于具有亲缘关系的进程间通信,有名管道的每个管道具有名字,使没有亲缘关系的进程间也可以通信。信号是比较复杂的通信方式,用于通知接受进程有某种事件发生,除
Linux性能观测工具按类别可分为系统级别和进程级别,系统级别对整个系统的性能做统计,而进程级别则具体到进程,为每个进程维护统计信息。

按实现原理分,可分为基于计数器和跟踪以及剖析。含义如下:

计数器:内核维护的统计数据,通常为无符号整型,用于对发生的事件计数,比如,网络包接收计数器,磁
本文详细介绍了curl命令基础和高级用法,包括跳过https的证书验证,详细追踪整个交互过程,可用于调用网络后端接口,诊断http和https网络服务故障。
本文包含作者工作中常用到的一些命令,用于诊断网络、磁盘占满、fd泄漏等问题。命令包括ping、fping、tcpdump、lsof、netstat、/proc/$pid/fd、du、grep、traceroute、dig。
linux的平均负载表示运行态和就绪态及不可中断状态(正在io)的进程数目,用uptime查看到负载很高,既有可能是CPU利用率高,也可能是大量在等待io的进程导致,用mpstat查看每个CPU的使用情况,查看CPU的使用率或者CPU花在等待io的时间,接着用pidstat定位具体的进程
CPU上下文频繁切换会导致系统性能下降,切换分为进程切换、线程切换及中断切换,进程切换的开销较大,除了需要保存寄存器和程序计数器中的值还需保存全局变量、栈等到内存中,以便下次运行恢复,而同一进程中的线程切换开销会小很多,只需更新寄存器和线程独有的栈,共享资源如打开的文件、全局变量等无需切换,当硬件中
1.top命令 作用:该命令可以按CPU使用.内存使用和执行时间对任务进行排序,常用来监控系统中占用CPU或内存较高的程序及CPU和内存的负载。 默认视图: 当想看系统负载时,可观察汇总的%CPU中的us用户进程和sy系统进程是否占用CPU很高,相加接近100%就说明占用很高了,有些程序可能得不到及
文章浏览阅读1.8k次,点赞63次,收藏54次。Linux下的目录权限!!!粘滞位!!!超详解!!!
文章浏览阅读1.6k次,点赞44次,收藏38次。关于Qt的安装、Windows、Linux、MacBook_mack book 安装qt
本文介绍了使用shell脚本编写一个 Hello
文章浏览阅读1.5k次,点赞37次,收藏43次。【Linux】初识Linux——了解操作系统的发展历史以及初次体验Linux编程环境
文章浏览阅读3k次,点赞34次,收藏156次。Linux超详细笔记,个人学习时很认真的记录的,觉得好的麻烦点个赞。
文章浏览阅读6.8k次,点赞109次,收藏114次。【Linux】 OpenSSH_9.3p1 升级到 OpenSSH_9.5p1(亲测无问题,建议收藏)_openssh_9.5p1
文章浏览阅读3.5k次,点赞93次,收藏78次。初识Linux中的线程,理解线程的各种概念,理解进程地址空间中的页表转换,介绍pthread线程库并理解线程库!
文章浏览阅读863次。出现此问题为Linux文件权限问题,解决方案为回到引擎目录执行命令。输入用户密码后运行./UnrealEditor。_increasing per-process limit of core file size to infinity.
文章浏览阅读2.9k次。使用文本编辑器:打开CSV文件,并使用文本编辑器(如Notepad++、Sublime Text、Visual Studio Code等)来查看文件的字符编码格式。通常在编辑器的底部状态栏或设置中可以找到当前编码的显示。请注意,上述方法并非绝对准确,特别是当文件没有明确的编码标识时。因此,如果你发现CSV文件在不同的工具或方法中显示不同的编码格式,可能需要进行进一步的分析和判断,或者尝试使用不同的编码转换方法。该命令将输出文件的MIME类型和编码信息。使用命令行工具:在命令行中,你可以使用。_shell读取csv文件逐行处理
本文介绍了如何在Linux系统中升级gcc版本,以便更好地支持C++11及以上版本的新特性。通过升级gcc,可以提升编译器的功能和性能,获得更好的开发体验。详细的步骤和方法请参考原文链接。
文章浏览阅读4.4k次,点赞6次,收藏19次。Mosquitto是一个开源的MQTT消息代理服务器。MQTT是一个轻量级的、基于发布/订阅模式的消息传输协议。 mosquitto的安装使用比较简单,可以方便的来进行一些测试。_linux mosquitto
文章浏览阅读7.2k次,点赞2次,收藏12次。Linux中,用于根目录下有一个.ssh目录,保存了ssh相关的key和一些记录文件。_~/.ssh/
文章浏览阅读4.5k次,点赞5次,收藏18次。首先需要安装 snmp ,使用下面的命令进行安装安装完毕之后,使用下面的命令查看是否安装成功当命令行显示如图即为安装成功。_snmp工具