分类: LINUX
2010-12-28 19:24:26
SSH是由芬兰的一家公司开发出来的,但是由于版权和加密算法的限制,openssh作为一种安全的网络服务应用程序在业界被广泛应用。Openssh是ssh的代替软件而且免费。在上篇文档《移植OProfile到JK2410开发板》中有提到,Montavista 公司提供的应用程序开发和系统分析工具devrocket在调试和分析性能时需要在开发板和主机之间建立一条连接,通过ssh协议通信。由于JK2410开发板上没有配置sshd伺服程序,所以需要将sshd移植到JK2410开发板上。
硬件环境:
Host:
X86 PC
Target:
JK2410开发板
软件环境:
Host:
VMware 6
OS:CentOS 5
Strace 调试工具
Target:
OS: linux-
RootFS: initrd-edwin
Strace 调试工具
源码包:
openssh-4.6p1.tar.gz
openssl-
zlib-
编译工具
arm-9tdmi-linux-gnu-gcc
arm-9tdmi-linux-gnu-g++
在/work目下面创建ssh目录
# mkdir /work/lib ----〉共享库目录,通过nfs挂载
# mkdir /work/ssh -----〉工作目录
# cd /work/ssh
# mkdir compressed install source -----〉compressed 用于存放源码包
Install 软件安装目录
Source 源码包解压目录
#mv tarpakgs/openssh-4.6p1.tar.gz /work/ssh/compressed
#mv tarpakgs/openssl-
#mv tarpakgs/zlib-
交叉编译 zlib
# cd /work/ssh/compressed/
# tar xvf zlib-
# cd ../source/zlib-
# ./configure --prefix=/work/ssh/install/zlib-
# vim Makefile
CC=arm-9tdmi-linux-gnu-gcc
AR=arm-9tdmi-linux-gnu-ar rc
CPP =arm-9tdmi-linux-gnu-gcc -E
LDSHARED=arm-9tdmi-linux-gnu-gcc
# make
# make install
交叉编译openssl
# cd /work/ssh/compressed/
# tar zxvf openssl-
# cd ../source/openssl-
# ./Configure --prefix=/work/ssh/install/openssl-
# make
# make install
交叉编译openssh
# cd /work/ssh/compressed
# tar zxvf openssh-4.6p1.tar.gz –C ../source
# cd ../source/ openssh-4.6p1
#./configure --host=arm-9tdmi-linux-gnu --with-libs --with-zlib=/work/ssh/install/zlib-
打印出如下信息:
OpenSSH has been configured with the following options:
User binaries: /usr/local/bin
System binaries: /usr/local/sbin
Configuration files: /usr/local/etc
Askpass program: /usr/local/libexec/ssh-askpass
Manual pages: /usr/local/share/man/manX
PID file: /var/run
Privilege separation chroot path: /var/empty
sshd default user PATH: /usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin
Manpage format: doc
PAM support: no
OSF SIA support: no
KerberosV support: no
SELinux support: no
Smartcard support: no
S/KEY support: no
TCP Wrappers support: no
MD5 password support: no
libedit support: no
Solaris process contract support: no
IP address in $DISPLAY hack: no
Translate v
BSD Auth support: no
Random number source: OpenSSL internal ONLY
Host: arm-9tdmi-linux-gnu
Compiler: arm-9tdmi-linux-gnu-gcc
Compiler flags: -g -O2 -Wall -Wpointer-arith -Wuninitialized -Wsign-compare -std=gnu99
Preprocessor flags: -I/work/ssh/install/openssl-
-I/work/ssh/install/zlib-
Linker flags: -L/work/ssh/install/openssl-
-L/work/ssh/install/zlib-
Libraries: -lresolv -lcrypto -lutil -lz -lnsl -lcrypt
按照上面打印出的信息在根文件系统中建立相应的目录并把相应的文件拷贝进去。
我的根文件系统镜像为/tftpboot/initrd-edwin
# cd /tftpboot/
# mkdir 25 && mount –oloop initrd-edwin
#cd 25/usr/local && mkdir bin etc libexec sbin share
#cd /work/ssh/source/openssh-4.6p1
#cp scp sftp ssh ssh-add ssh-agent ssh-keygen ssh-keyscan /tftpboot/25/usr/local/bin
#cp moduli ssh_config sshd_config ssh_host_dsa_key ssh_host_dsa_key.pub ssh_host_key ssh_host_key.pub ssh_host_rsa_key ssh_host_rsa_key.pub /tftpboot/25/usr/local/etc
# cp sftp-server ssh-keysign /tftpboot/25/usr/local/libexec
# cp sshd /tftpboot/25/usr/local/sbin
a) u-boot参数设置
bootargs=root=/dev/ram0 rw console=ttySAC0,115200 mem=
bootcmd=tftpboot 0x33000000 uImage; tftpboot 0x30800000 initrd-edwin
b) 将kernel镜像uImage和根文件系统镜像initrd-edwin
c) 设置系统启动后将host机上/work目录挂载到target机上/edwin
Target:
vim /etc/init.d/rcS
echo "mount /work to /edwin .....";
mount -t nfs 192.168.167.131:/work /edwin -o nolock,rsize=1024,wsize=1024,timeo=15
d) 指定共享库搜索目录
Target:
vim /etc/profile
# Set search library path
echo "Set search library path in /etc/profile"
export LD_LIBRARY_PATH=/edwin/lib
#Set user path
echo "Set user path in /etc/profile"
PATH=/bin:/sbin:/usr/bin:/usr/sbin
export PATH
e) 启动sshd deamon程序
/usr/local/sbin/sshd
显示缺少的库文件,将其拷贝到host主机上的/work/lib目录下。
d) 用strace跟踪sshd,查询缺少的目录和文件,给与相应的添补。
strace –f –F /usr/local/sbin/sshd
e) 调试成功后将sshd加入自启动
Target:
vim /etc/profile
echo "start sshd deamon routine ....."
/usr/local/sbin/sshd
f)
[问题1]
# /usr/local/sbin/sshd
/usr/local/sbin/sshd: error while loading shared libraries: libnsl.so.1: cannot open shared object file: No such file or directory
#
[分析与解决]
[root@localhost lib]# cp libnsl* /work/lib/
[问题2]
# /usr/local/sbin/sshd
Privilege separation user sshd does not exist
#
[分析与解决]
没有sshd用户
sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin
Host:
[root@localhost etc]# cp /etc/passwd shadow group /work
Target:
mv /edwin/passwd /etc
mv /edwin/group /etc
mv /edwin/shadow /etc
注:将root:x:0:0:root:/root:/bin/bash改为root:x:0:0:root:/root:/bin/sh
[问题3]
# /usr/local/sbin/sshd
Missing privilege separation directory: /var/empty
#
[分析与解决]
# mkdir /var/empty
# /usr/local/sbin/sshd
#
[问题4]
[root@localhost .ssh]# ssh -l root 192.168.167.132
root@192.168.167.132's password:
Permission denied, please try again.
[分析与解决]
按照下面打印的消息,添补相应的文件或者目录,主要是用户帐户和密钥相关的文件。
Strace 分析如下:
stat64("/root/.ssh", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
open("/etc/passwd", O_RDONLY)= 4
fcntl64(4, F_GETFD)= 0
fcntl64(4, F_SETFD, FD_CLOEXEC)= 0
fstat64(4, {st_mode=S_IFREG|0644, st_size=1908, ...}) = 0
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb
read(4, "root:x:0:0:root:/root:/bin/bash\n"..., 4096) = 1908
close(4)= 0
munmap(0xb
open("/root/.ssh/identity", O_RDONLY|O_LARGEFILE) = -1 ENOENT (No such file or directory)
open("/root/.ssh/identity", O_RDONLY|O_LARGEFILE) = -1 ENOENT (No such file or directory)
open("/root/.ssh/identity", O_RDONLY|O_LARGEFILE) = -1 ENOENT (No such file or d = 0
fcntl64(4, F_SETFD, FD_CLOEXEC)= 0
fstat64(4, {st_mode=S_IFREG|0644, st_size=1908, ...}) = 0
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb
read(4, "root:x:0:0:root:/root:/bin/bash\n"..., 4096) = 1908
close(4) irectory)
open("/root/.ssh/identity.pub", O_RDONLY|O_LARGEFILE) = -1 ENOENT (No such file or directory)
open("/etc/passwd", O_RDONLY)= 4
fcntl64(4, F_GETFD)= 0
munmap(0xb
open("/root/.ssh/id_rsa", O_RDONLY|O_LARGEFILE) = -1 ENOENT (No such file or directory)
open("/root/.ssh/id_rsa", O_RDONLY|O_LARGEFILE) = -1 ENOENT (No such file or directory)
open("/root/.ssh/id_rsa", O_RDONLY|O_LARGEFILE) = -1 ENOENT (No such file or directory)
open("/root/.ssh/id_rsa.pub", O_RDONLY|O_LARGEFILE) = -1 ENOENT (No such file or directory)
open("/etc/passwd", O_RDONLY)= 4
fcntl64(4, F_GETFD)= 0
fcntl64(4, F_SETFD, FD_CLOEXEC)= 0
fstat64(4, {st_mode=S_IFREG|0644, st_size=1908, ...}) = 0
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb
read(4, "root:x:0:0:root:/root:/bin/bash\n"..., 4096) = 1908
close(4)= 0
munmap(0xb
open("/root/.ssh/id_dsa", O_RDONLY|O_LARGEFILE) = -1 ENOENT (No such file or directory)
open("/root/.ssh/id_dsa", O_RDONLY|O_LARGEFILE) = -1 ENOENT (No such file or directory)
open("/root/.ssh/id_dsa", O_RDONLY|O_LARGEFILE) = -1 ENOENT (No such file or directory)
open("/root/.ssh/id_dsa.pub", O_RDONLY|O_LARGEFILE) = -1 ENOENT (No such file or directory)
open("/etc/passwd", O_RDONLY)= 4
fcntl64(4, F_GETFD)= 0
fcntl64(4, F_SETFD, FD_CLOEXEC)= 0
fstat64(4, {st_mode=S_IFREG|0644, st_size=1908, ...}) = 0
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb
read(4, "root:x:0:0:root:/root:/bin/bash\n"..., 4096) = 1908
close(4)= 0
munmap(0xb
open("/etc/passwd", O_RDONLY)= 4
fcntl64(4, F_GETFD)= 0
fcntl64(4, F_SETFD, FD_CLOEXEC)= 0
fstat64(4, {st_mode=S_IFREG|0644, st_size=1908, ...}) = 0
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb
read(4, "root:x:0:0:root:/root:/bin/bash\n"..., 4096) = 1908
[问题5]
# ./ssh-keygen
Generating public/private rsa key pair.
Enter file in which to save the key (/root/.ssh/id_rsa):
Could not create directory '/root/.ssh'.
[分析与解决]
# ls /
bin etc linuxrc nfs sys var dev jffs2 lost+found proc tmpfs yaffs2 edwin lib mnt sbin usr
# cd /root
-sh: cd: can't cd to /root
# mkdir root
# cd /root
# mkdir .ssh
# ls -a
. .. .ssh
# ./ssh-keygen
Generating public/private rsa key pair.
Enter file in which to save the key (/root/.ssh/id_rsa):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /root/.ssh/id_rsa.
Your public key has been saved in /root/.ssh/id_rsa.pub.
The key fingerprint is:
76:dd:b7:c4:35:41:ce:35:97:5d:4e:36:54:fe:67:08 root@(none)
# ./ssh-keygen -d
Generating public/private dsa key pair.
Enter file in which to save the key (/root/.ssh/id_dsa):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /root/.ssh/id_dsa.
Your public key has been saved in /root/.ssh/id_dsa.pub.
The key fingerprint is:
[问题6]
# /usr/local/sbin/sshd
Missing privilege separation directory: /var/empty
[分析与解决]
# ls /var
# mkdir /var/empty
# /usr/local/sbin/sshd
#
[问题7]
[root@localhost ~]# ssh 192.168.167.132
ssh: connect to host 192.168.167.132 port 22: Connection refused
[分析与解决]
Target端sshd deamon程序没有启动。
/usr/local/sbin/sshd
[问题8]
Target 端sshd用户的创建?
[分析与解决]
用busybox制作的根文件系统提供的adduser和passwd命令和PC机上的使用方法不同。
PC机上创建帐户:
[root@localhost 25]#adduser test
[root@localhost 25]# passwd test
[root@localhost 25]# passwd test
Changing password for user test.
New UNIX password:
Target上创建帐户:
首先要用-D选项设定不设定密码,否则会提示:unknown uid
# adduser –h /test -s /bin/sh -D test
# passwd test
[问题9]
在客户端ssh到target板后,用户帐户和密码验证通过,但是没有启动shell?
[分析与解决]
Step1:用strace跟踪,没有发现任何有价值的信息。
Step2:修改openssh源码使其打印出尽可能多的debug信息。
log.c文件注释掉以下两行就可以打印所有的调试信息了。
//if (level > log_level)
//return;
Step3:重新编译openssh并按照3.2重新安装sshd
Step4:target端创建/var/log目录
Step5:启动syslogd服务
Step6:启动sshd,并且在host端ssh到target端
Host: /usr/local/sbin/sshd
Target:ssh –l root 192.168.167.132
观察var/log/messages debug信息:
Jan 1 01:27:03 (none) auth.debug sshd[436]: debug1: session_by_channel: session 0 channel 0
Jan 1 01:27:03 (none) auth.debug sshd[436]: debug1: session_input_channel_req: session 0 req pty-req
Jan 1 01:27:03 (none) auth.debug sshd[436]: debug1: Allocating pty.
Jan 1 01:27:03 (none) auth.err sshd[436]: error: openpty: No such file or directory
Jan 1 01:27:03 (none) auth.err sshd[436]: error: session_pty_req: session 0 alloc failed
Jan 1 01:27:03 (none) auth.debug sshd[436]: debug1: server_input_channel_req: channel 0 request env reply 0
Jan 1 01:27:03 (none) auth.debug sshd[436]: debug1: session_by_channel: session 0 channel 0
Jan 1 01:27:03 (none) auth.debug sshd[436]: debug1: session_input_channel_req: session 0 req env
Jan 1 01:27:03 (none) auth.debug sshd[436]: debug2: Ignoring env request LANG: disallowed name
Jan 1 01:27:03 (none) auth.debug sshd[436]: debug1: server_input_channel_req: channel 0 request shell reply 0
Jan 1 01:27:03 (none) auth.debug sshd[436]: debug1: session_by_channel: session 0 channel 0
Jan 1 01:27:03 (none) auth.debug sshd[436]: debug1: session_input_channel_req: session 0 req shell
Jan 1 01:27:03 (none) auth.err sshd[440]: error: setlogin failed: Illegal seek
Jan 1 01:27:03 (none) auth.debug sshd[436]: debug2: fd 3 setting TCP_NODELAY
Jan 1 01:27:03 (none) auth.debug sshd[436]: debug2: fd 7 setting O_NONBLOCK
在openssh源码中搜索openpty,发现在openpty函数中需要打开许多设备文件,如: /dev/ptmx, pt, /dev/ptc等,意识到是不是缺少了相应的设备文件,因为制作根文件系统时根据需要选择部分的设备文件,并没有添加完全。于是将所有的设备文件都添加进去
#cp –avf /dev/* /tftpboot/25/dev/
重新启动,还是不可以。
在网上搜索openpty,找到解决方法解决“sshd makes error 'openpty: No such file or directory”
- mknod /dev/ptmx c 5 2
chmod 666 /dev/ptmx
mkdir /dev/pts
- Add to /etc/fstab:
none /dev/pts devpts gid=5,mode=620 0 0
(Note: gid=5 is applicable for RedHat systems for which group "tty" has gid 5. Adjust according to your distribution. Use mode=600 if you want "mesg n" to be default.
- Mount /dev/pts
原贴在:
按照上面的操作,从host端ssh到target端,ok。
Sshd总算移植成功了,很大一点感触是:强烈建议制作根文件系统时,把所有的设备文件添加上。Strace是个很好的跟踪调试工具。