Synology NAS에서 / bin / bash 셸을 사용하여 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의 쉘을 다시 / 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루트가 정상적으로 작동하므로 bash 바이너리 자체가 정상적으로 작동합니다.

절망 한 행동으로, 나는 / etc / passwd에서 joeuser의 uid를 0으로 변경했지만 작동하지 않았기 때문에 권한과 관련된 것으로 보이지 않습니다.

bash가 sshd가 좋아하지 않는 추가 검사를 수행하고 루트가 아닌 사용자의 연결을 차단하는 것 같습니다. 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를 쉘로 사용하여 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


여기 에 ssh -vv와 함께 sshd -dd전체 출력이 있습니다.

세게 때리다:

# 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
Michael Hampton

/ bin / bash가 / etc / shells에 나열되어 있습니까?
tink

예, / etc / shells에 나열되어 있습니다. 그리고 위에 추가 된 권한 0755.
Gui Ambros

그의 .bashrc 파일에 무언가가 실행 중일 가능성이 높습니다. ~ joeuser / .bashrc를 cat하고 그의 프로필 스크립트를 찌를 수 있습니까? 로그인 한 상태에서 / bin / bash를 실행할 수도 있습니다.
vicfn

~ joeuser / .ssh 및 프로필 스크립트가 없습니다. 방금 테스트하기 위해 만든 빈 사용자입니다.
Gui Ambros

답변:


39

나중에 참조하기 위해 :이 문제를 연구하고 디버깅하는 데 너무 많은 시간을 보낸 후에 마침내 근본 원인을 발견했습니다.

Synology에서 사용되는 OpenSSH의 버전은 않는 고도의 사용자 정의 버전입니다 하지 원래의 코드와 같이 동작합니다. 웹 인터페이스 내에서 SSH 서비스가 활성화되어 있는지 확인하기 위해 로그인을 수락하기 전에 추가 검사를 수행하거나 rsync 명령에서 특수 문자 (;, |, ')를 제거하는 등의 많은 해킹 및 임시 사용자 정의가 있습니다. 일반 사용자가 / bin / sh 또는 / bin / ash와 다른 쉘을 사용하지 않도록 기다리십시오 . 예, 바이너리 안에 하드 코딩되어 있습니다.

자신의 소스 코드는 Synology 배포하며, 여기에서 OpenSSH 5.8p1에서 코드의 조각,의 (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;
}


내가 왜 그렇게 이상한 행동을했는지 궁금하지 않습니다. root 또는 admin 이외의 사용자에게는 쉘 / 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
Stellar는이 문제를 조사하고 Synology 무대에서 커튼을 뒤로 끌어 당기는 일을합니다. Diskstation이 매우 유용하고 부트 스트랩이 새로운 작업 스케줄러에서 일부 스크립트를 실행하기 때문에 지금까지 Diskstation에 대해 매우 높게 생각했음을 인정해야합니다. 그러나 근시 디자인에 몇 가지 결함이 있습니다. 나는 여전히 Diskstation에 만족하지만 귀하의 게시물을 명심할 것입니다. 게시물과 답변을 모두 찬성했습니다.
Bernard Dy

노력에 찬성했다. 시리얼 연결을 귀찮게하고 싶지 않다면 기본 쉘을로 변경하고 싶습니다. 할 수 /bin/sh있는 방법이 있습니까?
Vicary

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를 쉘로 포함합니다.


1

보자 단일 쉘로 격리되어 있으며 sshd 디버그 출력을보고 있으므로 ~ joeuser / .ssh의 쓰기 가능한 권한 문제는 아닙니다. 그것은 대부분의 사람들을 얻는 것입니다.

동일한 문제가 발생하는지 확인하기 위해 추가 일반 사용자 (예 : joeuser가 아닌)를 작성하려고 했습니까? 그러면 사용자 구성과 시스템 전체 구성이 분리됩니다.

시스템 전체의 문제라면, 다음으로 살펴볼 것은 / etc / profile과 같은 공유 구성 파일이며 모두가 제공합니다. 사용자 이름이 root 인 경우 실행되지 않는 조건부 블록이있을 수 있습니다. (이미 테스트 한 이후 유효 사용자 ID가 아님)

아직 이상하지 않은 경우를 대비하여 세그먼트 오류 보고서가없는 경우 dmesg를 확인하십시오.


고마워 앤드류. 또한 dmesg를 확인했으며 전혀 아무것도 아닙니다. 새로운 사용자를 만드는 것도 도움이되지 않았으므로 분명히 시스템 차원의 문제입니다. 쉘을 / bin / ash로 다시 변경하면 joeuser가 정상적으로 로그인 할 수 있습니다. 이로 인해 / etc / profile 또는 기타 (btw도 확인)가 제외됩니다. ssh를 통해 bash를 사용하여 루트가 아닌 것입니다. 이 시점에서 그것은 실제 문제조차 아니지만 (현재와 같이 살 수는 있지만)이 이상한 행동의 원인을 찾을 수 없다는 것을 인정하게됩니다. 결국 결정 론적 시스템이다. 어떤 종류의 설명 이 있어야합니다 ...
Gui Ambros

1

/ etc / ssh / sshd_config
에서 AllowUsers를 검색해 보십시오.

거기에 joeuser를 추가하려고하면 username

또한 그것은 pam에서 차단 될 수 있습니다 ... 어떤 파일인지 기억하지 못합니다 ...


그렇지 않습니다. AllowUsers에 문제가 있다면 쉘을 / bin / ash로 변경할 때 joeuser로 로그인 할 수 없습니다. 이것은 보안 관련 또는 다른 구성과 관련이없는 것 같습니다. 아마도 bash가 ash, csh 등을 통해 ssh를 통해 의사 터미널을 처리하는 방식 일 것입니다.
Gui Ambros

1

수정 된 버전의 openssh는 /bin/sh쉘을 찾습니다 .

쉬운 솔루션 :

ln -fs / bin / bash / bin / sh


이것은 bash가 필요한 사용자뿐만 아니라 모든 사용자의 쉘을 변경합니다. 또한 새로운 업그레이드로 인해 심볼릭 링크가 제거됩니다 (openssh 수정에도 동일한 문제가 있음). 어쨌든, 이것은 위에서 설명한 것처럼 해결되었습니다.
Gui Ambros

사실이지만 NAS의 유일한 사용자이므로이 솔루션이 적합합니다. 어쨌든 발견 한 것을 지적 해 주셔서 감사합니다.
Ponytech

0

Bash를 다시 설치하고 도움이되는지 확인하십시오.


아니요, 두 가지 소스 (하나는 Optware 배포판과 소스 3.2에서 직접 컴파일)에서 bash를 얻었고 같은 문제가있었습니다. 나는 bash 4.2를 가져 와서 패치 (39 개 모두)를 적용하고 크로스 컴파일하는 극단으로 갔다. 정확히 같은 행동. 루트와 함께 작동하며 다른 사람에게는 권한이 거부 되었습니다. 마지막으로 OpenSSH 바이너리는 Synology 펌웨어에서 기본적으로 설치되는 것과 같습니다. 이것은 내가 아직 건드리지 않은 유일한 작품입니다. 최신 소스를 다운로드하고 크로스 컴파일을 수행하여 어떤 일이 발생하는지 확인하겠습니다.
Gui Ambros

2
이상하지는 않지만 authconfig 문제인 것 같습니다. 서버에서 ldap도 실행 중입니까? 로그인 실패시 보안 및 메시지 파일의 실시간 로그 출력을 보내 주시겠습니까?
Pratap

2
또한 서버에 루트로 로그인하고 사용자 쉘이 / bin / bash가되도록하고 su-username을 사용하여 사용자로 전환하십시오. 이것의 결과도 보여주세요.
Pratap

0

내가했던 것과 똑같은 실수를했기 때문에 누군가가 넘어지는 경우를 대비하여 :

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

아니: $ sudo usermod -s bash your_username

두 번째는 ssh가 들어올 때 권한이 거부됩니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.