【转】浅谈编译kernel+busybox构建拥有远程ssh登录和web功能最小linux系统(二)

转自:http://www.178linux.com/8276

忘了介绍本文的源码的版本了

dropbear-2013.58.tar.bz2   

busybox-1.21.1.tar.bz2

linux-3.13.6.tar.xz 

nginx-1.4.7

 

基于上文,我们还差group文件没有写

1
2
3
root@mysql etc]# vi group 
root:x:0:
mayershi:x:500:    #不解释,你懂的。

我们已经解决了本地登录的问题。要想模仿的更像我们要设置一下,

PS1的变量还有,以及主机名和用户支持上,不知道的可以脑补。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
[root@mysql etc]# echo "export PS1=$PS1" > /mnt/sysroot/etc/profile 
[root@mysql etc]# cat profile 
export PS1=[\u@\h \W]\$                #此段结束表示开机时自动加载PS1的变量到环境变量中
 
[root@mysql etc]# vi rc.d/rc.sysinit 
[root@mysql etc]# cat !$
cat rc.d/rc.sysinit
#!/bin/bash
#
mount -n -o remount,rw /dev/sda2 /
mount -a
mdev -s
[ -r /etc/sysconfig/network ] && source /etc/sysconfig/network
[ -z "$HOSTNAME" -o "$HOSTNAME" == '(none)' ] && hostname localhost || hostname $HOSTNAME
#倒数一二行表示,开机读取主机名的脚本,程序,不解释,我想应该能看的懂。

成功上图。

QQ截图20150920164011.png

唉,可以实现登录了把,但是居然爆出一个错误,I have no name! 我们明明已经设置了啊,

为什么没有呢。其实我们用的bash,bash是利用nsswitch来进行用户名对应UID实现名称解析

的。但是你还记得,我们之前提到的,busybox默认的shell是ash。我们切换成ash试试。o

QQ截图20150920164414.png

bingo,成功的解决了。其实是bash依赖名称解析功能,而我们又缺少名称解析的库。所以bash

也就无能为力的给你爆出一个他没有名字的名字了。接下来我们开始着手解决bash的nsswitch的问题,

让其能够实现有 name的功能。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
[root@mysql sysroot]# mkdir /mnt/sysroot/usr/lib64
[root@mysql sysroot]# cp -a -d /lib64/libnss_files* lib64/
[root@mysql sysroot]# cp -a -d /usr/lib64/{libnss_files.so,libnss3.so,\
libnssutil3.so,libnsssysinit.so,libnsspem.so} usr/lib64/
[root@www sysroot]# ls lib64/
ld-linux-x86-64.so.2  libcap.so.2  libnss_files-2.12.so  librt.so.1
libacl.so.1           libc.so.6    libnss_files.so.2     libselinux.so.1
libattr.so.1          libdl.so.2   libpthread.so.0       libtinfo.so.5
###以上都是nss所依赖的库文件
[root@www sysroot]# ls usr/lib64/
libnss3.so  libnsspem.so  libnsssysinit.so  libnssutil3.so #第一个是nss的核心文件,其余的三个
是nss自带的常用工具。
[root@www sysroot]# cp /etc/nsswitch.conf /mnt/sysroot/etc/
##nss的配置文件,其实不用这个也行。我没有移植,寄生机也是可用的我不知道原因,但是大家最
#好别这么干。还是复制过来的好。以防出现其他的不知名错误。

QQ截图20150920172254.png

显然已经ok了。bash也是支持的名称解析了。(注意不要用第一虚拟终端登录,容易卡住,目前不知道什么原因。通过ctrl+alt+f[2~6])

到此为止,我们实现了本地登录的功能,接下来可以开始对ssh登录的支持了。

 

编译安装dropbear

 安装到此结束

1
2
3
4
5
[root@mysql ~]# tar xf dropbear-2013.58.tar.bz2 -C /usr/src
[root@mysql ~]# cd /usr/src/dropbear-2013.58/
[root@mysql dropbear]# ./configure 
[root@mysql dropbear]# make PROGRAMS="dropbear dbclient dropbearkey dropbearconvert scp"
[root@mysql dropbear]# make PROGRAMS="dropbear dbclient dropbearkey dropbearconvert scp" install

生成密钥文件

1
2
3
4
[root@mysql dropbear]# dropbearkey -t dss -f /etc/dropbear/dropbear_dss_host_key  
#生成私钥信息
[root@mysql dropbear]# dropbearkey -t rsa -s 2048 -f /etc/dropbear/dropbear_rsa_host_key
#生成公钥信息

测试dropbear是否可以启动和正常使用

1
2
3
4
5
6
7
8
9
10
11
12
[root@mysql dropbear]# dropbear -p 22022 -F -E   #开启程序然后在前台运行信息是
[6646] Sep 20 19:38:53 Not backgrounding         #标准输出在前台监听22022端口
[6659] Sep 20 19:40:15 Child connection from 192.168.199.1:59998
[6659] Sep 20 19:40:24 Password auth succeeded for 'root' from 192.168.199.1:59998
检测端口监听状态
[root@mysql dropbear]# ss -tnl | grep 22022  #已经监听了
LISTEN     0      20                       :::22022                   :::*     
LISTEN     0      20                        *:22022                    *:*   
[C:\Users\Mayershi]$ ssh 192.168.199.137 22022 #可以看见已经可以登录了
Connecting to 192.168.199.137:22022...
Connection established.
To escape to local shell, press 'Ctrl+Alt+]'.

现在可以开始进行该程序的移植了。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
[root@mysql ~]# bash bincp.sh 
Plz enter a command: dropbear
Plz enter a command: dropbearkey
Plz enter a command: dhclient
Plz enter a command: quit
[root@mysql ~]# cp /usr/local/bin/scp /mnt/sysroot/usr/local/bin/
[root@mysql ~]# dropbearkey -t dss -f /mnt/sysroot/etc/dropbear/dropbear_dss_host_key
[root@mysql ~]# dropbearkey -t rsa -s 2048 -f /mnt/sysroot/etc/dropbear/dropbear_rsa_host_key
[root@mysql sysroot]# mkdir var/run #创建dropbear运行是pidfile存放的目录
 
[root@mysql sysroot]# vim etc/shells #因为dropbear在登录的时候会检查合法shell
/bin/ash                             #,合法shell需要定义
/bin/bash
/bin/hush
/sbin/nologin
/bin/sh
 
#还要注意的是dropbear是需要nsswitch支持的,因为我们之前已经移植了nsswitch所以这里
#我们就没有在做演示了
 
[root@mysql sysroot]#tty
/dev/pts/0 #远程登录的会在/dev/pts/下生成一以数字命名的伪终端设备,我们也要实现这个功能
[root@mysql sysroot]# vi etc/fstab   
/dev/sda2 / ext4 defaults 0 0        
/dev/sda1 /boot ext4 defaults 0 0
proc /proc proc defaults 0 0
sysfs /sys sysfs defaults 0 0
devpts /dev/pts devpts defaults 0 0 
#但是最后一项,/dev/pts默认是没有的,所以我们在系统初始化,mdev -s后让其生成这个目录。
然后挂载这个目录,接下来开始着手添加这个功能。
[root@mysql sysroot]# vi etc/rc.d/rc.sysinit 
#!/bin/bash
#
mount -n -o remount,rw /dev/sda2 /
mdev -s         #生成设备文件
mkdir /dev/pts  #这时候创建这个目录,因为他是伪文件系统,所以系统关闭后就会消失
mount -a        #然后执行挂载所有文件系统,注意一下顺序,不注意也没有大问题
[ -r /etc/sysconfig/network ] && source /etc/sysconfig/network
[ -z "$HOSTNAME" -o "$HOSTNAME" == '(none)' ] && hostname localhost || hostname $HOSTNAME 
ifconfig lo 120.0.0.1 netmask 255.0.0.1
ifconfig eth0 192.168.199.55 netmask 255.255.255.0  #初始化时配置lo文件
for in /etc/rc.start/*; do
        $i start
done   #开机初始化,基本程序。

但是需要开机启动的脚本程序。以及支持开机自启动。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
[root@mysql etc]# mkdir /mnt/sysroot/etc/init.d
[root@mysql etc]# vim /mnt/sysroot/etc/init.d/dropbear
#!/bin/bash
#
dbprog='/usr/local/sbin/dropbear'
dbkeygen='/usr/local/bin/dropbearkey'
dsskey='/etc/dropbear/dropbear_dss_host_key'
rsakey='/etc/dropbear/dropbear_rsa_host_key'
rsakeysize=2048
dbport=22
 
gendsskey() {
    if [ ! -f $dsskey ]; then
        echo "Generating dss key file."
        [ -d /etc/dropbear ] || mkdir /etc/dropbear
        $dbkeygen -t dss -f $dsskey
    fi
}
 
genrsakey() {
    if [ ! -f $rsakey ]; then
    echo "Generating rsa key file."
    [ -d /etc/dropbear ] || mkdir /etc/dropbear
    $dbkeygen -t rsa -s $rsakeysize -f $rsakey
                fi
}
 
start() {
gendsskey
genrsakey
 
if ! pidof dropbear &> /dev/nullthen
echo "Starting dropbear"
$dbprog -p $dbport
retval=$?
else
echo "$dbprog is already running..."
return 1
fi
                 
if [ $retval -eq 0 ]; then
    echo "OK"
    return 0
else
    echo "Failure"
return 1
fi
}
 
stop() {
    echo "stopping dropbear"
                 
    if pidof dropbear &> /dev/nullthen
        echo "stopping dropbear"
            killall dropbear
            retval=$?
    else
        echo "$dbprog is not running..."
            return 1
            fi 
    }
 
restart() {
    stop
    sleep 1
    start
}
 
usage() {
    echo "Usage: `basename $0` {start|stop|restart}"
}
 
case $1 in 
start)
    start
    ;;
stop)
    stop
    ;;
restart)
    restart
    ;;
    *)
usage
    ;;
esac
1
2
3
4
5
6
7
8
9
10
11
12
13
[root@mysql etc]# mkdir rc.start
[root@mysql etc]# mkdir rc.stop
[root@mysql etc]# cd rc.start/
[root@mysql rc.start]# ln -sv ../init.d/dropbear 01dropbear
[root@mysql rc.stop]# ln -sv  ../init.d/dropbear  kdropbear
#需要注意的是利用相对路径,不要使用绝对路径
[root@mysql etc]# vi rc.d/rc.sysinit #在原来的基础上添加如下内容
for in /etc/rc.start/*; do
        $i start
done
[root@mysql etc]# vim inittab #修改最后一行
::shutdown:/etc/rc.d/rc.sysdown
[root@mysql etc]#chmod +x rc.d/rc.sysdown

到此我们已经dropbear远程登录已经搞定吗?其实还没有

挂起宿主机,开启另一台机器。

1
2
3
4
5
6
[C:\Users\Mayershi]$ ssh root@192.168.199.55
Connecting to 192.168.199.55:22...
Connection established.
To escape to local shell, press 'Ctrl+Alt+]'.
Connection closed by foreign host.
#会爆出客户端这个错误

我们开始查看服务器日志

QQ截图20150921084813.png

这个错我也无法理解。但是我想到了解决办法

1
2
3
4
5
6
#首先在这台启动的机器实施本地登录然后passwd重新修改下密码就可以了
[root@mysql ~]#passwd                                                       
Changing password for root
New password: 
Retype password: 
Password for root changed by root

QQ截图20150921113353.png

然后就可以实现本地登录了。到此解决了,ssh远程登录的问题。

 

 

最后一步了实现nginx的web功能

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
[root@mysql ~]# tar xf nginx-1.4.7.tar.gz -C /usr/src/
[root@mysql ~]# cd /usr/src/nginx-1.4.7
[root@mysql nginx-1.4.7]# useradd -m -s /sbin/nologin nginx 
[root@mysql nginx-1.4.7]# ./configure --user=nginx --group=nginx --conf-path=\
/etc/nginx/nginx.conf --without-pcre --without-http_rewrite_module
[root@mysql nginx-1.4.7]# make && make install
[root@mysql nginx-1.4.7]# /usr/local/nginx/sbin/nginx #开启nginx
[root@mysql nginx-1.4.7]# ss -tnl
State  Recv-Q Send-Q Local Address:Port Peer Address:Port 
LISTEN   0  128  :::52672  :::*     
LISTEN   0   50  *:3306    *:*     
LISTEN   0  128  :::111    :::*     
LISTEN   0  128  *:111     *:*     
LISTEN   0  128  *:80      *:*  #端口已经打开   
LISTEN   0  128  :::22     :::*

QQ截图20150921122242.png

ok了,接下来开始进行移植。

1
2
3
4
5
6
7
8
9
10
11
12
[root@mysql nginx-1.4.7]# cp -r /etc/nginx/ /mnt/sysroot/etc/
[root@mysql nginx-1.4.7]# cp -r /usr/local/nginx/ /mnt/sysroot/usr/local/
#以上是移植nginx的配置文件和启动程序等等
[root@mysql sysroot]# export PATH=$PATH:/usr/local/nginx/sbin/
[root@mysql sysroot]# echo $PATH
/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin:/usr/local/nginx/sbin/
[root@mysql sysroot]# echo /usr/local/nginx/ > /etc/ld.so.conf.d/nginx
#以上是为了方便移植nginx的所依赖的库文件,ldd可以查看nginx启动时所需要的库文件。
[root@mysql ~]# bash /root/bincp.sh 
Plz enter a command: nginx
Plz enter a command: quit
到此nginx的移植结束。

 挂起宿主机可以开始启动了另一台。远程链接ssh登录。因为nginx服务使用nginx用户启动的,所以要添加用户

1
2
3
4
5
6
7
8
[root@mysql ~]#adduser nginx   
Changing password for nginx
New password: 
Bad password: too short
Retype password: 
Password for shi changed by root
[root@mysql ~]#cd /usr/local/nginx/sbin/
[root@mysql sbin]#./nginx

 QQ截图20150921130409.png

QQ截图20150921124824.png

QQ截图20150921124831.png

到此全部结束

下面是本次实验中用到的bincap.sh的脚本源程序

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
#!/bin/bash
#
target=/mnt/sysroot/
 
[ -d $target ] || mkdir $target
 
preCommand() {
    if which $1 &> /dev/nullthen
    commandPath=`which --skip-alias $1`
    return 0
    else
    echo "No such command."
    return 1
    fi
}
 
commandCopy() {
    commandDir=`dirname $1`
    [ -d ${target}${commandDir} ] || mkdir -p ${target}${commandDir}
    [ -f ${target}${commandPath} ] || cp $1 ${target}${commandDir}
}
 
libCopy() {
    for lib in `ldd $1 | egrep -o "/[^[:space:]]+"`; do
    libDir=`dirname $lib`
    [ -d ${target}${libDir} ] || mkdir -p ${target}${libDir}
    [ -f ${target}${lib} ] || cp $lib ${target}${libDir}
    done
 
read -p "Plz enter a command: " command
 
until "$command" == 'quit' ]; do
 
  if preCommand $command then
    commandCopy $commandPath
    libCopy $commandPath
  fi
 
  read -p "Plz enter a command: " command
done

总结,本次实验中,了解到了,一个操作系统的原理,期间也遇到了不少错误。排查了很久。无数次尝试,都报错,差点都放弃了这篇博文,最后都自己独立解决了。不足的是,我没有提供nginx开机自启动的脚本。但是可以按照,dropbear的脚本修改,然后在/etc/rc.start目录下生成链接文件就可以了,注意链接的路径,其他的都有不用管了,因为/etc/rc.d/rc.sysinit的启动脚本中最后一段就是在系统初始化时启动,所有/etc/rc.start目录下的所有可执行脚本。

转载请注明:linux运维部落 » 浅谈编译kernel+busybox构建拥有远程ssh登录和web功能最小linux系统(二)

posted @ 2016-07-27 15:51  liangwode  阅读(965)  评论(0编辑  收藏  举报