Tidak dapat masuk melalui SSH ke akun mana pun yang menggunakan / bin / bash shell di Synology NAS

30

Saya mencoba menginstal bash sebagai shell default pada ARM Linux yang berjalan pada perangkat yang disematkan (Synology DS212 + NAS). Tetapi ada sesuatu yang sangat salah, dan saya tidak tahu apa itu.

Gejala:

1) Root memiliki / bin / bash sebagai shell default, dan dapat masuk secara normal melalui 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 memiliki / bin / bash sebagai shell default, dan menerima "Izin ditolak" ketika mencoba masuk melalui 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) mengganti shell joeuser kembali ke / 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
$ 


Untuk membuat segalanya semakin aneh, saya bisa masuk sebagai pengguna joeuser menggunakan /bin/bashkonsol serial (!). Juga su - joeusersebagai root berfungsi dengan baik, jadi biner bash itu sendiri berfungsi dengan baik.

Dalam keputusasaan, saya mengubah joeuser uid menjadi 0 di / etc / passwd, tetapi juga tidak berhasil, jadi sepertinya tidak terkait dengan izin.

Tampaknya bash melakukan beberapa pemeriksaan tambahan yang sshd tidak suka, dan memblokir koneksi untuk pengguna non-root. Mungkin semacam pemeriksaan kewarasan - atau emulasi terminal - yang memicu SIGCHLD, tetapi hanya ketika dipanggil melalui ssh.

Saya sudah memeriksa setiap item di sshd_config, dan juga memasukkan SSHD dalam mode debug, tetapi tidak menemukan sesuatu yang aneh. Ini milik saya /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


Dan inilah output dari /usr/syno/sbin/sshd -d, menunjukkan upaya gagal joeuser yang mencoba masuk, dengan / bin / bash sebagai 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


Di sini Anda memiliki hasil lengkap dari sshd -dd, bersama dengan ssh -vv .

Pesta:

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

Biner bash dikompilasi silang dari sumber. Saya juga mencoba menggunakan biner yang telah dikompilasi dari distribusi Optware , tetapi memiliki masalah yang sama persis. Saya memeriksa objdump -xapakah ada pustaka bersama yang hilang , tetapi semuanya ada di sana.

Adakah gagasan yang menyebabkan " Izin ditolak, coba lagi. "? Saya hampir menyelam dalam kode sumber bash untuk menyelidiki, tetapi mencoba untuk menghindari berjam-jam mengejar sesuatu yang mungkin konyol.

EDIT: menambahkan lebih banyak informasi tentang bash dan sistem

$ 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
Gui Ambros
sumber
2
ls -l /bin/bash
Michael Hampton
Apakah / bin / bash terdaftar di / etc / shells?
tink
Ya, terdaftar di / etc / shells. Dan izin 0755, ditambahkan di atas.
Gui Ambros
Kemungkinan besar ada sesuatu yang sedang dijalankan di file .bashrc-nya. Bisakah Anda menggambar ~ joeuser / .bashrc dan melihat-lihat skrip profilnya? Anda juga dapat mencoba menjalankan / bin / bash saat login sebagai dia.
vicfn
Tidak ada ~ joeuser / .ssh dan tidak ada skrip profil. Ini adalah pengguna kosong yang baru saja saya buat untuk menguji.
Gui Ambros

Jawaban:

39

Untuk referensi di masa mendatang: setelah terlalu banyak waktu meneliti dan men-debug masalah ini, saya akhirnya menemukan akar masalahnya.

Versi OpenSSH yang digunakan oleh Synology adalah versi yang sangat dikustomisasi, yang tidak berperilaku seperti kode asli. Ini memiliki banyak peretasan dan penyesuaian ad-hoc - misalnya, pemeriksaan tambahan sebelum menerima login untuk melihat apakah layanan SSH diaktifkan dalam antarmuka web, atau menghapus karakter khusus (;, |, ') dari perintah rsync, atau .. tunggu ... hindari pengguna biasa menggunakan shell yang berbeda dari / bin / sh atau / bin / ash . Ya, kode keras dalam biner.

Berikut bagian kode dari OpenSSH 5.8p1, yang didistribusikan oleh Synology pada kode sumbernya (DSM4.1 - branch 2636) , file 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 */
...
}


Seperti yang dapat Anda bayangkan, penyebabnya IsAllowShell(pw)adalah:

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


Tidak heran mengapa saya mengalami perilaku yang aneh. Hanya shell / bin / sh dan / bin / ash yang akan diterima untuk pengguna yang berbeda dari root atau admin . Dan ini terlepas dari uid (saya telah menguji juga membuat joeuser uid = 0, dan itu tidak berhasil. Sekarang jelas mengapa).

Setelah mengidentifikasi penyebabnya, perbaikannya mudah: cukup hapus panggilan ke IsAllowShell () . Butuh beberapa saat untuk mendapatkan konfigurasi yang tepat untuk mengkompilasi silang openssh dan semua dependensinya, tetapi pada akhirnya berhasil.

Jika ada yang tertarik melakukan hal yang sama (atau mencoba melakukan cross-compile modul kernel atau binari lain untuk Synology), inilah versi Makefile saya . Itu diuji dengan sumber OpenSSH-5.8p1 , dan bekerja dengan baik dengan model yang menjalankan Marvell Kirkwood mv6281 / mv6282 CPU (seperti DS212 +). Saya menggunakan host yang menjalankan Ubuntu 12.10 x64.

Intinya: praktik buruk, kode buruk, dan contoh hebat tentang apa yang tidak boleh dilakukan. Saya mengerti kadang-kadang OEM perlu mengembangkan kustomisasi khusus, tetapi mereka harus berpikir dua kali sebelum menggali terlalu dalam. Tidak hanya ini menghasilkan kode yang tidak dapat dipertahankan bagi mereka, tetapi juga menciptakan segala macam masalah yang tidak terduga di ujung jalan. Untungnya GPL ada untuk menjaga mereka tetap jujur ​​- dan terbuka.

Gui Ambros
sumber
4
Stellar bekerja Pak, dalam menyelidiki masalah ini dan menarik tirai dari panggung Synology. Saya harus mengakui bahwa saya memikirkan Diskstation saya sampai sekarang karena sangat berguna dan sekali bootstrap sekarang bahkan menjalankan beberapa skrip untuk saya di bawah penjadwal tugas baru. Tetapi Anda telah mengungkapkan beberapa kekurangan dalam desain yang picik di sini. Saya masih senang dengan Diskstation tetapi akan mengingat posting Anda. Terpilih untuk posting dan jawaban.
Bernard Dy
Terpilih untuk upaya ini. Jika saya tidak ingin repot melakukan koneksi sereal, saya hanya ingin mengganti shell default /bin/sh, apakah ada cara untuk melakukannya?
Vicary
Mengapa synology melakukan ini benar-benar di luar saya :(
Gerhard Burger
Saya berganti nama /bin/ashmenjadi /bin/ash.realdan ditautkan zshpada /bin/ash... sejauh ini semuanya tampak baik-baik saja ... o_o
x1a0
7

Untuk menghindari masalah, dan karena saya menginstal bash melalui ipkg dan saya tidak yakin / opt akan selalu tersedia (dipasang dengan benar), saya cukup memasukkan yang berikut ini di .profile saya

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

sedangkan / etc / passwd berisi / bin / ash sebagai shell.

Tom Regner
sumber
1

Ayo lihat. Ini diisolasi untuk satu shell, ditambah Anda sedang melihat keluaran debug sshd, jadi itu bukan masalah izin yang dapat ditulis dunia dengan ~ joeuser / .ssh. Itulah yang membuat kebanyakan orang.

Sudahkah Anda mencoba membuat pengguna normal tambahan (yaitu bukan joeuser) untuk memastikan ia mengalami masalah yang sama? Itu akan mengisolasinya ke konfigurasi pengguna vs konfigurasi seluruh sistem.

Jika ini adalah masalah seluruh sistem, hal berikutnya yang akan saya lihat adalah file konfigurasi bersama seperti / etc / profile yang didapat dari semua orang. Mungkin ada blok bersyarat yang tidak menembak jika nama pengguna adalah root. (tidak userid efektif, karena Anda sudah diuji untuk itu)

Periksa dmesg untuk laporan kesalahan segmentasi jika Anda belum melakukannya, kalau-kalau ada sesuatu yang lebih aneh terjadi.

Andrew B
sumber
Andrew terima kasih. Juga memeriksa dmesg, dan sama sekali tidak ada. Membuat pengguna baru juga tidak membantu, jadi jelas ini adalah masalah sistem. Dan joeuser dapat login secara normal jika saya mengganti shell kembali ke / bin / ash, yang mengesampingkan / etc / profile atau lainnya (yang juga saya periksa, btw). Hanya dengan non-root, menggunakan bash, via ssh. Karena poin ini bahkan bukan masalah nyata (saya bisa hidup seperti sekarang), tapi itu mengganggu saya untuk mengakui bahwa saya tidak dapat menemukan penyebab perilaku aneh ini. Bagaimanapun, ini adalah sistem deterministik; ada harus menjadi semacam penjelasan ...
Gui Ambros
1

coba / etc / ssh / sshd_config
cari untuk AllowUsers

jika di sana coba tambahkan joeuser di sana, cukup nama pengguna

juga mungkin diblokir di pam ... Saya tidak ingat file mana itu ...

BiG_NoBoDy
sumber
Bukan kasusnya. Jika masalah dengan AllowUsers, itu tidak akan membiarkan saya masuk dengan joeuser ketika saya mengganti shell ke / bin / ash. Ini sepertinya tidak terkait dengan apa pun yang berhubungan dengan keamanan, atau konfigurasi lainnya. Mungkin semacam bagaimana bash menangani terminal palsu melalui ssh, dibandingkan ash, csh, dll.
Gui Ambros
1

Versi openssh mereka yang dimodifikasi mencari /bin/shshell?

Maka solusi mudah:

ln-fs / bin / bash / bin / sh

Ponytech
sumber
Ini akan mengubah shell untuk semua pengguna, dan tidak hanya mereka yang membutuhkan bash. Juga setiap peningkatan baru akan menghapus tautan simbolik (meskipun memperbaiki openssh juga memiliki masalah yang sama). Bagaimanapun, ini diselesaikan, seperti dijelaskan di atas.
Gui Ambros
OK benar, tetapi karena saya adalah satu-satunya pengguna di NAS saya, solusi ini berfungsi untuk saya. Pokoknya terima kasih telah menunjukkan apa yang Anda temukan.
Ponytech
0

Coba instal ulang Bash dan lihat apakah itu membantu.

Pratap
sumber
Tidak, saya mendapat bash dari dua sumber berbeda (satu dari distribusi Optware, dan saya juga mengkompilasi 3,2 dari sumber sendiri), dan masalah yang sama. Saya pergi ke ekstrim bahkan mendapatkan bash 4.2 dan menerapkan tambalan (semuanya 39), dan kompilasi silang. Perilaku yang sama persis. Bekerja dengan root, Izin ditolak untuk orang lain. Tebakan terakhir saya adalah binari OpenSSH, yang sama diinstal secara default oleh firmware Synology. Ini adalah satu-satunya karya yang belum saya sentuh. Saya akan mencoba mengunduh sumber terbaru dan kompilasi silang, untuk melihat apa yang terjadi.
Gui Ambros
2
Aneh tidak yakin tapi ini sepertinya masalah authconfig. Apakah ldap juga berjalan di server? Dapatkah Anda mengirim saya output log waktu nyata file aman dan pesan pada saat kegagalan login.
Pratap
2
Juga login sebagai root ke server dan biarkan shell pengguna menjadi / bin / bash dan cobalah untuk beralih ke pengguna menggunakan su-username. Tunjukkan pada saya output dari ini juga.
Pratap
0

Kalau-kalau ada yang tersandung di ini karena mereka melakukan kesalahan yang sama saya lakukan:

iya nih: $ sudo usermod -s /bin/bash your_username

tidak: $ sudo usermod -s bash your_username

Yang ke-2 akan menghasilkan izin yang ditolak saat melakukan ssh.

Christy
sumber