임베디드 장치 (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
답변
나중에 참조하기 위해 :이 문제를 연구하고 디버깅하는 데 너무 많은 시간을 보낸 후에 마침내 근본 원인을 발견했습니다.
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은 정직하고 개방적입니다.
답변
문제를 피하기 위해 ipkg를 통해 bash를 설치하고 / opt를 항상 사용할 수 있는지 (정확하게 마운트) 확신 할 수 없으므로 다음을 .profile에 넣습니다.
[ -x /opt/bin/bash ] && exec /opt/bin/bash
/ etc / passwd는 / bin / ash를 쉘로 포함합니다.
답변
보자 단일 쉘로 격리되어 있으며 sshd 디버그 출력을보고 있으므로 ~ joeuser / .ssh의 쓰기 가능한 권한 문제는 아닙니다. 그것은 대부분의 사람들을 얻는 것입니다.
동일한 문제가 발생하는지 확인하기 위해 추가 일반 사용자 (예 : joeuser가 아닌)를 작성하려고 했습니까? 그러면 사용자 구성과 시스템 전체 구성이 분리됩니다.
시스템 전체의 문제라면, 다음으로 살펴볼 것은 / etc / profile과 같은 공유 구성 파일이며 모두가 제공합니다. 사용자 이름이 root 인 경우 실행되지 않는 조건부 블록이있을 수 있습니다. (이미 테스트 한 이후 유효 사용자 ID가 아님)
아직 이상하지 않은 경우를 대비하여 세그먼트 오류 보고서가없는 경우 dmesg를 확인하십시오.
답변
/ etc / ssh / sshd_config
에서 AllowUsers를 검색해 보십시오.
거기에 joeuser를 추가하려고하면 username
또한 그것은 pam에서 차단 될 수 있습니다 … 어떤 파일인지 기억하지 못합니다 …
답변
수정 된 버전의 openssh는 /bin/sh
쉘을 찾습니다 .
쉬운 솔루션 :
ln -fs / bin / bash / bin / sh
답변
Bash를 다시 설치하고 도움이되는지 확인하십시오.
답변
내가했던 것과 똑같은 실수를했기 때문에 누군가가 넘어지는 경우를 대비하여 :
예: $ sudo usermod -s /bin/bash your_username
아니: $ sudo usermod -s bash your_username
두 번째는 ssh가 들어올 때 권한이 거부됩니다.