前言

   系统定制在前面的博文中我们就有谈到过了,不过那个裁减制作有简单了点,只是能让系统跑起来而,没有太多的功能,也没的用户登录入口,而这里我们将详细和深入的来谈谈Linux系统的详细定制过程和实现用户例如、远程登录和Nginx安装过程、一步一步从头开始定制属于我们自己的系统。





正文

   首先我们先来简单的介绍一下我们这里定制属于自己的Linux系统的基本元素,其中一些相关的信息也可以参考我前面写过的博文





   一个定制的linux内核+一个定制的busybox就可以定制一个小型的Linux操作系统了,安装Dropbear和Nginx,Linux的组成部分包括内核空间和用户空间、而用户空间其实就是根文件系统、用户空间中又包括有shell和init,busybox他能够模拟数百个我们系统上带用的命令、当然包括我们所需要用到的shell、init、getty、login、那定制一个Linux操作系统我们必须要了解的就是系统启动流程:    

   POST --> Boot Sequence(MBR) --> BootLoader --> kernel -->/sbin/init

POST:加电自检

Boot Sequence:读到磁盘中的第一个扇区(446)的MBR。

BootLoader:找到MBR中的BootLoader引导加载器、bootloader会找到我们选定的操作系统或内核去加载对应的内核、而这个Bootloader通常是grub。

kernel:加载内核、内核要完成初始化、bootloader负责把内核读到内存中、内核又通常中压缩的、所以通常内核在内存中展开、而bootloader引导内核启动起来、让内核从他的程序入口处开始执行、所以接下来内核要完成自身的初始化操作、或硬件探测、包括自身执行环境的准备等等都在这里完成。

   内核完成初始化的第一步就要去装载用户空间了、有时候为了让内核做得足够小、很有可能内核中并不具备真正的根文件系统所在设备的驱动、因此我们要借助于initramfs(CentOS5上被称为initrd)来完成去装载真正根文件系统所在的根文件系统真正的程序、但是这个initramfs可initrf(initramfs:这是一个文件系统、CentOS6上就这么称呼了,initrd:ram disk 这是一个磁盘设备)是个虚拟的根文件系统、是个虚根、他不是我们系统真正工作起来所使用的根、所以称这个为虚根、内核借助于这个虚根装载驱动之后就要去挂载真正的根设备了、kernel会自动挂载到这个跟文件下、内核会挂载真正的根到这个initramfs虚根的某个目录下、比如说挂载到/mnt/sysroot的目录下、而后再完成根切换、而后我们的真正的根就可以加载了、那我们的内核怎么知道挂载的根文件系统是什么呢、那我们的grub向内核传递参数root等于什么那就是告诉系统根文件系统所在的设备。





   /sbin/init:他通常加载四个设备、/sbin/init、/bin/bash、如果内核找不到就去找根下的init、再找不着就去找/bin/sh、/bin/bash、按照这个顺序去找、找到一个就可以启动系统、所以系统启动的第一个进程就启动了、init负责去启动用户空间中真正工作的进程、init本身本身只是负责去生成这些正正工作的进程和回收这些进程的、是内核的第一个、最顶级的管理进程、但不负责具体的工作、虽然init不负责具体工作、但他需要把一个用户空间启动为一个真正完整意义上的用户空间、所以init要结合他的配置文件inittab完成所谓系统初始化的。
   

   在CentOS6上这个文件inittab之所以保留下来是为了跟CentOS5兼容的、其实我们用不着的、因为init大多数配置文件都位于/etc/init/*.conf目录下所有以.conf结尾的文件、是用于各子系统之间协调的。





   /sbin/init作用包含以下几步:

       1、设定默认运行级别:runlevel -v:查看运行级别

       2、系统空间中的进一行初始化、这个要依赖于一个系统初始化脚本来完成的、这个脚本叫rc.sysinit、在有些系统上可能叫rcS、其实都是一个概念、这个初始化包含键盘键映射、初始化没被挂载的文件系统等等。那/etc/rc.sysinit要进行哪些工作、seLinux、udev、键映射、交换分区的激活、挂载额外文件系统、重新以读写方式挂载根文件系统等等。

       3、启动指定级别下的服务、后台的守护进程、每个级别都有一个在/etcg下rcN.d的文件、启动这个文件中所有以S开头的脚本服务、关闭所有以K开头的服务脚本、/etc/rc.local其中以S开头的最后一个服务S99包含rc.local、有些我们不便于自己写脚本定义的服务可以写到这里来、但是启动之后不会关闭、所以只是执行一些命令我们可以在这里执行、服务还是建议使用服务脚本。

       4、设定键映射

       5、启动虚拟终端、启动这个终端会调用一个叫login的程序、在虚拟终端上打印一个登录提示符让我们输入

       6、如果设备默认级别为5的话还可以启动图形终端

       init在早期是个串型的init、或者说传统意义是的init、sysV风格的、这种程序启动任何服务、运行任何程序完成系统初始化时统统以串型模式进行的、所以速度非常慢、以至于后来有了并型运行的init、启动速度也比较快。

准备工作:

系统裁减我们说过、为了可以让定制好的系统可以放到别的机器上动行、我们要把他做到一个独立的硬盘上去、所以首先我们在宿主机上添加一块SCSI的硬盘



添加硬盘,重启





# fdisk /dev/sdb

分3个主分区

第一个主分区(做boot分区):50M 

第二个主分区(做/根分区):512M

第三个主分区(做swap分区):256M





    n p 1  +50M n p 2  +512M n p 3  +256M t 3 82 w





# mke2fs -t etx4 /dev/sdb1

# mke2fs -t etx4 /dev/sdb2

# mkswap /dev/sdb3

# mkdir -pv /mnt/{boot,sysroot}

# mount /dev/sdb1 /mnt/boot

# mount /dev/sdb2 /mnt/sysroot

第一步:编译内核或定制内核

1、获取内核程序包,可以到官网下载:http://ftp.redhat.com/pub/redhat/linux/enterprise/6Server/en/os/SRPMS/

这里我们使用的内核版本是3.13.6的版本

   解压内核文件,这里我们以make allnoconfig来编译安装,自己选择要编译的功能(确保系统上的编译环境)    





# tar xf linux-3.13.6.tar.xz -C /usr/src/

# cd /usr/src

# ln -sv linux-3.13.6 linux

# cd linux

# make allnoconfig

安装依赖包

# yum install -y ncurses-devel

# make menuconfig 把我们所需要的内容整合进来

我们把这些内容全部编译进内核、不编译成模块、*号表示编译进内核(M表示以模块的方式装载)

注意:以下*号标识的选项一定要选择*号,否则系统无法正常启动

[*]64-bit kernel :64位操作系统的内核

General setup --> Local version --> -MyLinux: 给内核定一个自己的版本

Processor type and features --> Processor family --> (X)Generic-x86-64:这里是CPU类型、这个是通用x86-64

[*]Symmetric multi-processing support:选择CPU支持多核心处理

[*]Enable loadable module support:选择内核动态模块加载

Bus options (PCI etc.) --> [*]PCI suppor:支持PCI总线

Device Drivers --> <*>SCSI device support -->[*]SCSI disk support要支持SCSI硬盘

Device Drivers -->Fusion MPT device support (NEW) --> <*>Fusion MPT ScsiHost drivers for SPI、<*>Fusion MPT misc device (ioctl) driver、[*]Fusion MPT logging facility:支持对硬盘的驱动

File systems --> <*>The Extended 4 (ext4) filesystem:支持文件系统

Executable file formats / Emulations --> [*]Kernel support for ELF binaries、[*]Write ELF core dumps with partial segments (NEW)、 <*>Kernel support for scripts starting with #!:可执行文件的格式

Device Drivers -->Input device support --> [*]Keyboards -> <*>AT keyboard (NEW) [*]Mice:支持输入输出设备、比如健盘

Device Drivers > USB support  > <*>   Support for Host-side USB > <*>UHCI HCD (most Intel and VIA) support、<*>OHCI HCD (USB 1.1) support、<*>EHCI HCD (USB 2.0) support:USB设备驱动

Device Drivers > Generic Driver Options > [*] Maintain a devtmpfs filesystem to mount at /dev [*]Automount devtmpfs at /dev, after the kernel mounted the rootfs

[*] Networking support  ---> > Networking options[*] TCP/IP networking [*]IP:multicasting [*]IP: advanced router[*]IP: policy routing [*]IP: verbose route monitoring[*]   IP: kernel level autoconfiguration[*]IP: DHCP support[*]IP: BOOTP support[*]     IP: RARP
support<*>IP: tunneling <*>Unix domain sockets<*>   UNIX: socket monitoring interface:支持协议

Device Drivers > Network device support > Ethernet driver support[*]Intel devices (NEW)<*>Intel(R) PRO/1000 Gigabit Ethernet support<*>Intel(R) PRO/1000 PCI-Express Gigabit Ethernet support:只要Intel的、其他的他都去掉、这是选择网卡设备的驱动程序

[ ]Wireless:这个无线网、我们去掉去、用不着









OK、到这里保存退出、把配置文件复制一份出来、前面磁盘格式化而且都挂载好了、这里我们就把grub安装到boot下::    





# cp .config /root/config-3.13.6-x86_64

# make -j 4 bzImage

# cp arch/x86/boot/bzImage /mnt/boot/

# grub-install --root-directory=/mnt /dev/sdb



出现警告:

 warning: Clock skew detected. Your build may be incomplete

解决办法:

(使用date命令重新设置时间格式是:date -s "MM/DD/YYYY hh:mm:ss"):

****************************************************************

# date -s "03/09/2016 20:56:00"

# hwclock -s

清除编译产生的文件

# make clean

再次执行

make -j 4 bzImage

cp arch/x86/boot/bzImage /mnt/boot/

****************************************************************

第二步:编译Busybox、让busybox提供一个sh程序、busybox可以模拟n种sh、可以模拟bash的特性、上面我们有介绍过了

到busybox官网下载busybox程序包:http://www.busybox.net

   解压到当前目录下就可以了:    





# yum install -y glibc-static

# yum install -y libmcrypt-devel





==============================

报错:

Loaded plugins: fastestmirror, security

Loading mirror speeds from cached hostfile

 * base: centos.ustc.edu.cn

 * extras: centos.ustc.edu.cn

 * updates: ftp.daumkakao.com

Setting up Install Process

No package libmcrypt-devel available.

Error: Nothing to do





解决方法:

# yum  install epel-release  //扩展包更新包

# yum install -y libmcrypt-devel

==============================





# tar xf busybox-1.22.1.tar.bz2 

# cd busybox-1.22.1

# make menuconfig

# make

# make install





   make menuconfig时就选择这项就可以了、其他的都使用默认选项:

   Busybox Settings -->Build Options -->[*] Build BusyBox as a static binary (no shared libs):把busybox编译也静态二进制,不用共享库    









# cp -a _install/* /mnt/sysroot/

# cd /mnt/sysroot/

# mkdir -pv /etc/rc.d var/log root home lib lib64 dev proc sys boot mnt media tmp srv

给grub提供一个配置文件

# vim /mnt/boot/grub/grub.conf 

default=0

timeout=5

title Mini Linux (3.13.6-MyLinux_chinasoft)

    root (hd0,0)

    kernel /bzImage ro root=/dev/sda2 init=/sbin/init





   给小系统提供一个rc.sysinit、/mnt/sysroot/etc/rc.d/rc.sysinit、如果没有这个目录就自己创建、再提供一个/mnt/sysroot/etc/fstab文件 





# mkdir etc/rc.d -pv





   # vim /mnt/sysroot/etc/fstab

/dev/sda1       /boot   ext4    defaults        0 0

proc            /proc   proc    defaults        0 0

sysfs           /sys    sysfs   defaults        0 0

/dev/sda2       /       ext4    defaults        0 0

/dev/sda3       swap    swap    defaults        0 0





# vim /mnt/sysroot/etc/rc.d/rc.sysinit





==============================

#!/bin/sh

#

打印系统启动时的欢迎信息

echo -e "\tWecome to \033[34mMini\033[0m Linux"

判断/etc/sysroot/network是否存在并且可读、条件成立就source进来

[ -r /etc/sysconfig/network ] && . /etc/sysconfig/network

判断$HOSTNAME是否为空并且$HOSTNAME==NONE、如果为空就给个默认值

[ -z "$HOSTNAME" -o "$HOSTNAME" == "(none)" ] && HOSTNAME=localhost

给HOSTNAME赋值为定义好的HOSTNAME的值

/bin/hostname $HOSTNAME

挂载文件系统

echo "mounting proc filesystem..."

mount -t proc proc /proc

echo "mounting sysfs filesystem..."

mount -t sysfs sysfs /sys

自动探测各硬件设备、并且能够探测到的都装载设备文件

mdev -s

给系统配置一个IP地址

ifconfig lo 127.0.0.1

ifconfig eth0 172.16.254.188

mount -a

mkdir /dev/pts

mount -t devpts devpts /dev/pts

==============================





# vim /mnt/sysroot/etc/inittab  

==============================

::sysinit:/etc/rc.d/rc.sysinit 明确指定要找/etc/rc.d/rc.sysinit文件

::respawn:/sbin/getty 19200 tty1

::respawn:/sbin/getty 19200 tty2

::respawn:/sbin/getty 19200 tty3

::respawn:/sbin/getty 19200 tty4

::respawn:/sbin/getty 19200 tty5

::respawn:/sbin/getty 19200 tty6 :19200表示每秒钟传输的速率、getty是一个串型终端、他会调用一个登录界面让用户输入登录信息进行验证

tty6::askfirst:/bin/sh 启用6个虚拟终端

console::respawn:-/bin/sh 启用一个终端,如果出错重新启动respawn、-表示敲一回车才可以启用sh

::ctrlaltdel:/sbin/reboot 定义组合键、按ctrl+alt+del就reboot

::shutdown:/bin/umount -a -r 如果要要关机就卸载已挂载的设备、然后关机

==============================





提供系统用户登录帐号文件: 

==============================

# useradd busybox

# passwd busybox

密码也设置为:busybox

# head -1 /etc/passwd > /mnt/sysroot/etc/passwd

# tail -1 /etc/passwd >> /mnt/sysroot/etc/passwd





# vim /mnt/sysroot/etc/passwd

root:x:0:0:root:/root:/bin/sh

busybox:x:502:503::/home/busybox:/bin/sh





# head -1 /etc/group > /mnt/sysroot/etc/group

# tail -1 /etc/group >> /mnt/sysroot/etc/group

# head -1 /etc/shadow > /mnt/sysroot/etc/shadow

# tail -1 /etc/shadow >> /mnt/sysroot/etc/shadow

# cat /mnt/sysroot/etc/shadow

提供一个登录欢迎信息、创建一个issue文件

# vim /mnt/sysroot/etc/issue

MyLinux is CentOS release 6.5

Kernel \r on an \m

提供主机名

# mkdir /mnt/sysroot/etc/sysconfig

# vim /mnt/sysroot/etc/sysconfig/network

HOSTNAME=mylinux.chinasoft.com

提供命令提示符和环境变量

# vim /mnt/sysroot/etc/profile

export PS1='[\u@\h \A \W]\$ '

PATH="/usr/local/sbin:/usr/local/bin:/sbin/:/bin:/usr/sbin:/usr/bin:$PATH"





# chmod +x /mnt/sysroot/etc/rc.d/rc.sysinit

# sync  同步数据到磁盘中去

==============================





到这里我们的配置有了基本框架,此时把宿主机挂起,创建一个自定义虚拟机,把我们制作有系统的那张硬盘放到自定义的虚拟机上运行:





如果第一个终端登录不了可以切换到其他终端上登录,按ctrl+alt+F2(F3\F4\F5\F6)可以切换到不同的终端上去登录的、这里我们登录成功了:

测试

启动报错:是因为make menuconfig处没有选择文件系统支持

远程登录和ngix访问

OK、到这里我们自己定制的Linux可以跑起来了、接下来我们来实现远程登录和Nginx的访问:

   切换到宿主主上、下载dropbear-2013.58.tar.bz2和Nginx到本地:

1、解压安装dropbear

# tar xf dropbear-2013.58.tar.bz2

# cd dropbear-2013.58

# ./configure

# make

# make PROGRAMS="dropbear dbclient dropbearkey dropbearconvert scp" install

# mkdir /etc/dropbear

生成两个密钥文件

# dropbearkey -t rsa -s 1024 -f /etc/dropbear/dropbear_rsa_host_key

# dropbearkey -t dss -f /etc/dropbear/dropbear_dss_host_key

验证一下生的这两个文件

# ls /etc/dropbear

2、服务脚本/etc/rc.d/init.d/dropbear

#!/bin/bash

#

# description: dropbear ssh daemon

# chkconfig: 2345 66 33

#

dsskey=/etc/dropbear/dropbear_dss_host_key

rsakey=/etc/dropbear/dropbear_rsa_host_key

lockfile=/var/lock/subsys/dropbear

pidfile=/var/run/dropbear.pid

dropbear=/usr/local/sbin/dropbear

dropbearkey=/usr/local/bin/dropbearkey

[ -r /etc/rc.d/init.d/functions ] && . /etc/rc.d/init.d/functions

[ -r /etc/sysconfig/dropbear ] && . /etc/sysconfig/dropbear

keysize=${keysize:-1024}

port=${port:-22}

gendsskey() {

    [ -d /etc/dropbear ] || mkdir /etc/dropbear

    echo -n "Starting generate the dss key: "

    $dropbearkey -t dss -f $dsskey &> /dev/null

    RETVAL=$?

    if [ $RETVAL -eq 0 ]; then

        success

        echo

        return 0

    else

        failure

        echo

        return 1

    fi 

}

genrsakey() {

    [ -d /etc/dropbear ] || mkdir /etc/dropbear

    echo -n "Starting generate the rsa key: "

    $dropbearkey -t rsa -s $keysize -f $rsakey &> /dev/null

    RETVAL=$?

    if [ $RETVAL -eq 0 ]; then

        success

        echo

        return 0

    else

        failure

        echo

        return 1

    fi 

}

start() {

    [ -e $dsskey ] || gendsskey

    [ -e $rsakey ] || genrsakey

    if [ -e $lockfile ]; then

        echo -n "dropbear daemon is already running: "

        success

        echo

        exit 0

    fi

    echo -n "Starting dropbear: "

    daemon --pidfile="$pidfile" $dropbear -p $port -d $dsskey -r $rsakey

    RETVAL=$?

    echo

    if [ $RETVAL -eq 0 ]; then

         touch $lockfile

         return 0

     else

          rm -f $lockfile $pidfile

          return 1

      fi

}

stop() {

       if [ ! -e $lockfile ]; then

           echo -n "dropbear service is stopped: "

           success

           echo

           exit 1

        fi

            echo -n "Stopping dropbear daemon: "

            killproc dropbear

            RETVAL=$?

            echo

        if [ $RETVAL -eq 0 ]; then

            rm -f $lockfile $pidfile

            return 0

        else

            return 1

        fi

}

status() {

      if [ -e $lockfile ]; then

          echo "dropbear is running..."

      else

          echo "dropbear is stopped..."

      fi

}

usage() {

            echo "Usage: dropbear {start|stop|restart|status|gendsskey|genrsakey}"

}

case $1 in

start)

      start ;;

stop)

      stop ;;

restart)

      stop

      start

      ;;

status)

      status

      ;;

gendsskey)

      gendsskey

      ;;

genrsakey)

      genrsakey

      ;;

*)

      usage

      ;;

esac

3、脚本配置文件/etc/sysconfig/dropbear

keysize=2048

port=22022





# chmod +x /etc/rc.d/init.d/dropbear

# chkconfig --add dropbear

# vim /etc/profile.d/dropbear.sh

export PATH=/usr/local/sbin:$PATH

启动服务并查看端口22022是否已经处于监听状态、并在本地尝试连接登录:

# service dropbear start

# ss -tnl





dropbear在本机安装成功并且成功启动连接上去了





Xshell:\> ssh 192.168.8.40 22022





将该功能移植到我们的定制系统,之前我们写过一个脚本用来移植命令:  





#!/bin/bash

    #

    dirPath=/mnt/sysroot

    clearcmd(){

        if which $1 &> /dev/null;then

            cmdPath=`which --skip-alias $1`

        else

            echo "Command not exist!"

            return 4

        fi

    }

    cpCmd(){

        dirName=`dirname $1`

        [ -d ${dirPath}${dirName} ] || mkdir -p ${dirPath}${dirName}

        [ -f ${dirPath}${cmdPath} ] || cp $1 ${dirPath}${dirName}

    }

    cpLib(){     

        for i in `ldd $1 | grep -o "/[^[:space:]]\{1,\}"`;do

            dirLib=`dirname $i`

            [ -d ${dirPath}${dirLib} ] || mkdir -p ${dirPath}${dirLib}

            [ -f ${dirPath}$i ] || cp $i ${dirPath}${dirLib}

        done

    }

    while true;do

        read -p "Enter a command:" cmd

        if [ "$cmd" == 'quit' ];then

            echo "quit!"

            exit 0

        fi

        clearcmd $cmd

        [ $? -eq 4 ] && continue

        cpCmd $cmdPath

        cpLib $cmdPath

    done









把这三个命令移植过去就可以了:dropbear、dropbearkey、scp、dbclient、bash、复制完后就去创建这个目录/mnt/sysroot/etc/dropbear、而后为移植过去的dropbear生成两个密钥文件:





# mkdir /mnt/sysroot/etc/dropbear

# dropbearkey -t rsa -s 1024 -f /mnt/sysroot/etc/dropbear/dropbear_rsa_host_key

# dropbearkey -t dss -f /mnt/sysroot/etc/dropbear/dropbear_dss_host_key





dropbear要认证用户、而认证用户要用到名称解析、这就意味着libnss库要复制过去、libnss库框架、而后给nss提供配置文件:

cp -d 是指带连接的拷贝:



# cp -d /lib64/libnss_files* /mnt/sysroot/lib64

# cp -d /usr/lib64/libnss3.so /mnt/sysroot/usr/lib64/

# cp -d /usr/lib64/libnss_files.so /mnt/sysroot/usr/lib64/

# cp /etc/nsswitch.conf /mnt/sysroot/etc/

# vim /mnt/sysroot/etc/nsswitch.conf

只保留以下几项、其他的都不需要:

    passwd:     files

    shadow:     files

    group:      files 

    hosts:      files dns





在用户登录时dropbear认为用户的默认shell并不在/etc/shells下所在的用户shell中的话、他是不允许登录的、那我们就得给dropbear提供一个安全shell的配置文件了:





# vim /mnt/sysroot/etc/shells

/bin/sh

/bin/hush

/bin/ash

/sbin/nologin

/bin/bash





 dropbear启动时在/var/run/下会生成一个pid文件,而这个目录我们还没有创建

   # mkdir /mnt/sysroot/var/run



   到这里我们定制的系统还不能远程登录、当你远程登录时、所登录的终端都是远程/dev/pts的伪终端、这个伪终端是个伪文件系统、只要你的内核编译时支持这个文件系统、他就可以使用、当然、我们的目标机上还没有:

   # vim /mnt/sysroot/etc/fstab

   加一行

   devpts          /dev/pts        devpts  defaults        0 0



   再创建/dev/pts这个目录:

   # mkdir /mnt/sysroot/etc/profile.d

   # cp /etc/profile.d/dropbear.sh /mnt/sysroot/etc/profile.d/

   # mkdir /mnt/sysroot/dev/pts

   # sync

   # sync





   OK、我们先来测试一下dropbear远程登录看可不可以登录得上去、把宿主机挂起或关机、启动我们的目标机、由于我们的/dev/pts启动目标机时可以会重新挂载的问题、会把/dev/pts下的目录给覆盖掉、所以我们进入目标机后可以在/dev/下创建pts这个目录、IP要设置在同一个网段内:

   # mkdir /dev/pts

   # mount -a









   修改定制机的IP(避免和宿主机混淆)

   # vim /mnt/sysroot/etc/rc.d/rc.sysinit 

   ifconfig eth0 192.168.8.49

   route add default gw 192.168.8.254

实现页面Nginx访问

这里我们用的版本是Nginx-1.4.2、这里我们以最简单的方式进行安装并运行服务起来:

   解决依赖关系:



# yum install -y pcre-devel

# tar xf nginx-1.4.2.tar.gz

# cd nginx-1.4.2

# ./configure --prefix=/usr/local --conf-path=/etc/nginx/nginx.cnf --error-log-path=/var/log/nginx/error.log --http-log-path=/var/log/nginx/access.log --user=nginx --group=nginx --without-pcre --without-http_rewrite_module
--without-http_geo_module --without-http_uwsgi_module --without-http_fastcgi_module --without-http_scgi_module --without-http_memcached_module





--prefix=/usr/local:指定第三方软件安装目录

--conf-path=/etc/nginx/nginx.cnf:指定主配置文件的路径

--error-log-path=/var/log/nginx/error.log:指定错误日志存放路径

--http-log-path=/var/log/nginx/access.log:指定访问日志

--group=nginx:以nginx用户身份运行、反正不要以管理员的身份去运行

--group=nginx:nginx用户组

其他的选项都是nginx默认选项、我们都去掉

# make

# make install

# useradd nginx

# cd /usr/local/sbin

# ./nginx

# ss -tnl 查看80端口是否已经处于监听状态



接着移植nginx到目标机上去、用上面的那个复制命令的脚本:

# bash cpbin.sh

   Enter a command:nginx

   Enter a command:consoletype

   Enter a command:quit

   quit!





   复制nginx下的配置文件到目标机上、而启动nginx需要nginx用户、所以用户也得追加到passwd文件中去、而后再给nginx添加一个测试页面就OK了:  





# cp /etc/nginx/ /mnt/sysroot/etc/ -r

# grep "^nginx" /etc/passwd >> /mnt/sysroot/etc/passwd

# grep "^nginx" /etc/group >> /mnt/sysroot/etc/group

# grep "^nginx" /etc/shadow >> /mnt/sysroot/etc/shadow

# mkdir /mnt/sysroot/usr/local/html

# vim /mnt/sysroot/usr/local/html/index.html

<h1>Welcome to Nginx</h1>

<h1>Shenzhen huanying nin!</h1>





给nginx提供一个服务脚本

   # vim /mnt/sysroot/etc/rc.d/init.d/nginx   





#!/bin/sh

#

# nginx - this script starts and stops the nginx daemon

#

# chkconfig:   - 85 15

# description:  Nginx is an HTTP(S) server, HTTP(S) reverse \

#               proxy and IMAP/POP3 proxy server

# processname: nginx

# config:      /etc/nginx/nginx.conf

# config:      /etc/sysconfig/nginx

# pidfile:     /var/run/nginx.pid

# Source function library.

. /etc/rc.d/init.d/functions

# Source networking configuration.

. /etc/sysconfig/network

# Check that networking is up.

[ "$NETWORKING" = "no" ] && exit 0

nginx="/usr/local/sbin/nginx"

prog=$(basename $nginx)

NGINX_CONF_FILE="/etc/nginx/nginx.conf"

[ -f /etc/sysconfig/nginx ] && . /etc/sysconfig/nginx

lockfile=/var/lock/subsys/nginx

make_dirs() {

# make required directories

user=`nginx -V 2>&1 | grep "configure arguments:" | sed 's/[^*]*--user=\([^ ]*\).*/\1/g' -`

options=`$nginx -V 2>&1 | grep 'configure arguments:'`

for opt in $options; do

if [ `echo $opt | grep '.*-temp-path'` ]; then

   value=`echo $opt | cut -d "=" -f 2`

   if [ ! -d "$value" ]; then

       # echo "creating" $value

       mkdir -p $value && chown -R $user $value

   fi

fi

done

}

start() {

[ -x $nginx ] || exit 5

[ -f $NGINX_CONF_FILE ] || exit 6

make_dirs

echo -n $"Starting $prog: "

daemon $nginx -c $NGINX_CONF_FILE

retval=$?

echo

[ $retval -eq 0 ] && touch $lockfile

return $retval

}

stop() {

echo -n $"Stopping $prog: "

killproc $prog -QUIT

retval=$?

echo

[ $retval -eq 0 ] && rm -f $lockfile

return $retval

}

restart() {

configtest || return $?

stop

sleep 1

start

}

reload() {

configtest || return $?

echo -n $"Reloading $prog: "

killproc $nginx -HUP

RETVAL=$?

echo

}

force_reload() {

restart

}

configtest() {

$nginx -t -c $NGINX_CONF_FILE

}

rh_status() {

status $prog

}

rh_status_q() {

rh_status >/dev/null 2>&1

}

case "$1" in

start)

rh_status_q && exit 0

$1

;;

stop)

rh_status_q || exit 0

$1

;;

restart|configtest)

$1

;;

reload)

rh_status_q || exit 7

$1

;;

force-reload)

force_reload

;;

status)

rh_status

;;

condrestart|try-restart)

rh_status_q || exit 0

    ;;

*)

echo $"Usage: $0 {start|stop|status|restart|condrestart|try-restart|reload|force-reload|configtest}"

exit 2

esac





而在nginx启动时需要依赖于日志目录和pid文件目录、所以我们要事先给nginx创建这两目录先、还给创建锁文件:   





# mkdir /mnt/sysroot/var/log/nginx

# mkdir /mnt/sysroot/usr/local/logs

# mkdir -pv /mnt/sysroot/var/lock/subsys

# chmod +x /mnt/sysroot/var/log/nginx

# chmod +x /mnt/sysroot/tmp/

# sync





 OK、我们启动定制的目标系统、再启动dropbear和nginx、而服务也可以正常启动了、测试我们的nginx吧、如果服务脚本使用不了那就是里面可以有一些依赖函数或一些命令没有全都移植到目标机上、不过不要紧、我们可以手动启动服务器、这个问题都不大、最后测试完没什么就poweroff关机吧、如果nginx启动不了就重新把文件系统挂载为可读写就OK了:

 # nginx

nginx: [alert] could not open error log file: open() "/var/log/nginx/error.log" failed (30: Read-only file system)

2016/03/10 19:22:02 [emerg] 78#0: mkdir() "/usr/local/client_body_temp" failed (30: Read-only file system)

 # mount -o remonut,rw /

至此,我们的定制linux已完成,可以根据实际情况继续增加功能

总结下主要步骤:

1、准备目标磁盘

2、提供bzImage

3、提供busybox

建议静态编译:事先安装glibc-static

4、准备根文件系统

(1) 复制编译安装完成的busybox

(2) 补全所需要的其它目录

5、为init提供配置文件

etc/inittab

etc/rc.d/rc.sysint

6、提供虚拟终端,同时帐号密钥等文件

(1)编辑etc/inittab

::respawn:/sbin/getty 19200 tty1

::respawn:/sbin/getty 19200 tty2

(2)为目标系统提供passwd, group, shadow

7、主机名和banner

(1) /etc/sysconfig/network文件

编辑rc.sysinit,添加

[ -r /etc/sysconfig/network ] && . /etc/sysconfig/network

[ -z "$HOSTNAME" -o "$HOSTNAME" == "(none)" ] && HOSTNAME="localhost"

/bin/hostname $HOSTNAME

(2) 编辑/etc/issue

Welcome to MageEdu MiniLinux

kernel \r

8、提供ssh服务

(1) 

9、提供nginx服务

(1) 编辑安装并移植nginx

(2) 为目标系统上的nginx提供配置文件

(3) 提供测试网页

最新文章

  1. 用spring+hibernate+struts 项目记录以及常用的用法进等
  2. Android访问C#的WebService要注意的问题
  3. PHP 插入排序法
  4. A Statistical View of Deep Learning (I): Recursive GLMs
  5. thinkphp 内置函数详解
  6. 1、Sencha cmd学习笔记(一) 使你的sencha cmd跑起来
  7. 原生Jdbc操作Mysql数据库开发步骤
  8. Linux中的官方源、镜像源汇总
  9. Linux中shell和子shell一点点理解
  10. python框架之Django(3)-模版
  11. java 生成Http 头部date格式的string-RFC 1123 Date Representation in java
  12. sql server数据库自动备份
  13. node.js实现WebSocket
  14. 使用Docker调试Asp.Net Core
  15. DELPHI动态创建窗体
  16. angular5 路由变化监听
  17. EBS常用接口表
  18. webpack的正确安装方式
  19. JSP数据交互(一)
  20. HTML5 地理定位 【来自百度应用分享平台】

热门文章

  1. Ubuntu16.04常用软件源
  2. 51nod1238 最小公倍数之和 V3
  3. spread与react
  4. 【BLUESKY的NOIp模拟赛】解题报告
  5. C#.Net 持久化对象为XML文件
  6. 反射attr以及模块动态导入
  7. Feature Selection Can Reduce Overfitting And RF Show Feature Importance
  8. CM记录-JVM调优
  9. Idea默认的全局设置,如Maven等
  10. xml合并工具【原】