内核源码编译,CentOS系统安装过程和自动化安装,selinux简介,while语句(第14天)

回顾:内核组成部分、内核编译

内核组成部分如下
核心+模块组成内核
核心:/boot/vmlinuz-VERSION-RELEASE
模块:/lib/modules/VERSION-RELEASE/

模块管理的相关命令:
lsmod
modinfo
modprobe [-r]
insmod, rmmod
depmod

内核编译时,模块的选择有如下3种选择
[ ]    不选择该模块
[*]    将该模块编译进内核核心文件vmlinuz中
[M]  编译成模块,
大部分模块都可以不编译或者编译进核心里或者编译成模块,少部分模块仅能编译进核心文件里。


-------------------分割线----------------------------------------------------------------


内核编译详细步骤:
1:到kernel.org下载内核源码包,此处下载4.12的版本号的内核,你可以下载你自己所需的版本
wget -c  https://cdn.kernel.org/pub/linux/kernel/v4.x/linux-4.12.tar.xz

2:解压上一步下载的内核源码包到/usr/src目录中
tar -Jxvf linux-4.12.tar.xz -C  /usr/src/

3:进入/usr/src/目录
cd /usr/src/

4:创建链接文件linux,链接至目录linux-4.12,用链接文件的方式可以允许/usr/src目录下共存多个内核版本。
ln -sv linux-4.12  linux

5:进入linux目录
cd  linux

6:配置内核选项,就是让你选择开启内核哪些模块和特性,这里的内核特性相当多,如果有不懂的可以google之。这一步做完之后,会生成.config的配置文件,该配置文件里明确哪些模块和特性要进行编译,保存了你的选择。该配置文件里的选项以CONFIG_XXXX_XXXX=y或者CONFIG_XXXX_XXXX=m,分别表示编译进内核和编译成模块。
make menuconfig   开启文本界面选择你要编译的内核模块和特性

7:根据.config文件中的选项来编译内核
make  -j  4    这里的-j选项指定的是cpu的核心数量,可以不指定。

8:安装模块文件
make modules_install

9:安装内核,这一步会安装bzImage为/boot/vmlinuz-VERSION-RELEASE,生成initramfs文件,编辑grub的配置文件,把你此次编译的内核文件和initramfs文件的路径写进/boot/grub/grub.config文件中的新的title里。
make install

Linux内核编译(2)
(1) 配置内核选项    make XXXXconfig
支持“更新”模式进行配置:
(a) make config:基于命令行以遍历的方式去配置内核中可配置的每个选项;
(b) make menuconfig:基于curses的文本窗口界面;
(c) make gconfig:基于GTK开发环境的窗口界面;
(d) make xconfig:基于Qt开发环境的窗口界面;
支持“全新配置”模式进行配置:
(a) make defconfig:基于内核为目标平台提供的“默认”配置进行配置;
(b) make allnoconfig: 所有选项均回答为"no";
    (c) make allyesconfig 所有选项均回答为"yes"

(2) 编译
make [-j #]

如何只编译内核中的一部分功能:
(a) 只编译某子目录中的相关代码:
# cd /usr/src/linux   记住,编译内核源码时要站在源码树的根目录下进行编译
# make dir/

(b) 只编译一个特定的模块:
# cd /usr/src/linux      记住,编译时要站在源码树的根目录下进行编译
# make dir/file.ko

例如:只为e1000编译驱动:
# make drivers/net/ethernet/intel/e1000/e1000.ko
          e1000.ko文件编译完成之后,就可以被放入/lib/modules/目录下相应的目录中

如何交叉编译内核:
编译的目标平台与当前平台不相同;

# make ARCH=arch_name
        例如  make ARCH=arm     编译适合于arm平台

要获取特定目标平台的使用帮助
# make ARCH=arch_name help


如何在已经执行过编译操作的内核源码树做重新编译:
事先清理操作:
# make clean:清理大多数编译生成的文件,但会保留config文件等;
# make mrproper: 清理所有编译生成的文件、config及某些备份文件;
# make distclean:mrproper、patches以及编辑器备份文件;



screen命令:在一个终端上模拟出来多个screen
当你使用ssh链接上服务器编译内核的时候,编译的过程比较长,中间可能网络断开,
那么编译过程就终止,则必须从头编译,为了解决这种问题,可以使用screen命令。
screen命令可以在一个终端上模拟出来screen,然后你在screen上编译内核,之后使用Ctrl+a,d
玻璃终端,这样一来,即便你当前网络断开,只要你从新用ssh连接上服务器,之后使用screen -r后面
跟上SESSION号码就可以恢复编译过程。

打开新的screen:
# screen
退出并关闭screen:
# exit
剥离当前screen和终端,当终端挂掉,当前screen还在:
Ctrl+a,d
显示所有已经打开的screen:
screen -ls
恢复某screen
screen -r [SESSION]


CentOS系统安装

centos启动过程:
bootloader-->kernel(initramfs)-->rootfs-->运行rootfs上的/sbin/init程序

anaconda: CentOS的安装程序是anaconda,该安装程序有tui和gui两种界面
tui: 基于curses的文本窗口;
gui:图形窗口;


CentOS 6 的安装程序(anaconda)的启动过程:
MBR:  在光盘的isolinux目录下的boot.cat文件会装在到MBR中
stage2: 在光盘的isolinux目录下的isolinux.bin文件被boot.cat加载进内存
isolinux.bin根据 配置文件isolinux/isolinux.cfg  加载菜单选项  供用户选择
该配置文件中每个对应的菜单选项有如下可配置项:
加载内核:isolinux/vmlinuz
向内核传递参数:append initrd=initrd.img ...

之后isolinux.bin装载内核(isolinux/vmlinuz)和根文件系统(isolinux/initrd.img),并启动anaconda,然后使用anaconda程序来安装操作系统及其操作系统上的软件包等等。

isolinux.cfg配置文件片段概览:

上面文件中的label  linux ,lebel vesa,label rescue, label local , label memtest86这些linux,vesa,rescue等表示标签,在启动光盘之后,敲esc键,会进入有boot:提示符的命令行界面,在该界面下输入linux或者vesa或者rescue等就表示以该模式进入内核。比如敲入rescue,就表示进入紧急救援模式,就会带上参数initrd=initrd.img和rescue参数加载内核vmlinuz文件,以此来启动内核。

anaconda默认启动GUI接口,若是要显式指定使用TUI接口:
向内核传递“text”参数即可,具体做法有如下2种;
  在boot: 提示符下,输入 linux text
    在光盘启动界面下,敲tab键盘,进入编辑编辑菜单,输入 text

注意:上述内容一般应位于引导设备;而后续的anaconda程序及其安装用到的程序包等是可以存放在非本地光盘的,具体可以的位置有如下几种:
本地光盘
本地硬盘
ftp server: yum repository
http server: yum repostory
nfs server

如果想手动指定安装源:
boot:提示符下:敲入  linux method  可以指定源位置

anaconda应用的工作过程:分为3个阶段
安装前配置阶段
  安装过程使用的语言
  键盘类型
  安装至哪种存储设备
Basic Storage:本地磁盘
  特种设备:iSCSI
  设定主机名
  配置网络接口
  时区
  管理员密码
  设定分区方式及MBR的安装位置
  创建一个普通用户
  选定要安装的程序包
安装阶段
  在目标磁盘创建分区,执行格式化操作等
  将选定的程序包安装至目标位置
  安装bootloader
首次启动配置阶段
  iptables
  selinux
  core dump  核心转储

anaconda的配置方式:
(1) 交互式配置方式;
(2) 通过读取事先给定的配置文件自动完成配置;
该配置文件按特定语法给出的配置选项,一般叫做kickstart文件,可以参考/root/anaconda_ks.cfg文件;
因为anaconda可以通过读取配置文件来安装操作系统和软件包,所以通过提供配置文件就可以实行anaconda的自动化。


安装引导选项:也就是在光盘启动的时候,敲esc键,进入有boot:提示符的模式,在该模式下可以输入许多命令,这些功能是isolinux.bin文件提供的。提供的命令有如下:

text    文本安装方式

method  手动指定使用的安装方法

与网络相关的引导选项:
      ip=IPADDR
      netmask=MASK
      gateway=GW
      dns=DNS_SERVER_IP
      ifname=NAME:MAC_ADDR

与远程访问功能相关的引导选项:
      vnc
      vncpassword='PASSWORD'

指明kickstart文件的获取位置
      ks=
            DVD drive: ks=cdrom:/PATH/TO/KICKSTART_FILE
            Hard drive: ks=hd:/device/drectory/KICKSTART_FILE
            HTTP server: ks=http://host:port/path/to/KICKSTART_FILE
            FTP server: ks=ftp://host:port/path/to/KICKSTART_FILE
            HTTPS server: ks=https://host:port/path/to/KICKSTART_FILE

rescue   启动紧急救援模式

其他安装引导选项,请参考官方文档:《Installation Guide》


kickstart文件的格式:该文件有多个段组成,具体各段如何配置如下:
命令段:指明各种安装前配置,如键盘类型等;
程序包段:指明要安装的程序包组或程序包,不安装的程序包等;
      %packages   程序包段的开始
      @group_name
      package
      -package
      %end             程序包段的结束
脚本段:
       %pre: 安装前脚本,该脚本运行于安装介质上的微型Linux环境

      %post: 安装后脚本,该脚本运行于安装完成的系统;

kickstart文件中的命令段中的命令分为必备命令和可选命令
必备命令如下:
      authconfig: 认证方式配置
            authconfig --useshadow  --passalgo=sha512
      bootloader:bootloader的安装位置及相关配置
            bootloader --location=mbr --driveorder=sda --append="crashkernel=auto  rhgb quiet"
      keyboard: 设定键盘类型
      lang: 语言类型
      part: 创建分区
      rootpw: 指明root用户的密码
      timezone: 时区

可选命令如下:
      install OR upgrade
      text: 文本安装界面
      network
      firewall
      selinux
      halt
      poweroff
      reboot
      repo
      user:安装完成后为系统创建新用户
      url: 指明安装源

创建kickstart文件的方式有如下2种:
(1) 直接手动编辑;
依据某模板修改;
(2) 可使用创建工具:system-config-kickstart (CentOS 6)
依据某模板修改并生成新配置;

检查ks文件的语法错误:ksvalidator
# ksvalidator /PATH/TO/KICKSTART_FILE


使用kickstart文件自动安装操作系统:
光盘启动之后,敲esc键,进入有boot:提示符的模式下,输入linux  ip=IPADDR netmask=NETMASK gateway=GW dns=DNS_IP ks=http://............


创建引导光盘:
# mkdir -pv  /tmp/myiso/isolinux/
# cp /media/CentOS_6.6_Final_/isolinux/*   /tmp/myiso/isolinux/
# cd  /tmp/
# mkisofs -R -J -T -v --no-emul-boot --boot-load-size 4 --boot-info-table -V "CentOS 6.6 x86_64 boot" -b isolinux/isolinux.bin -c isolinux/boot.cat -o /root/boot.iso myiso/
上面的命令表示将myiso目录做成光盘镜像,保存成/root/boot.iso。-b和-c指明引导文件。

---------------------------------分割线-----------------------------------------------------


SELinux
生产环境使用SELinux的并不多

SELinux: Secure Enhanced Linux,安全加强的linux,工作于Linux内核中

DAC:自主访问控制;
MAC:强制访问控制;

提供外部服务的应用程序应该使用普通用户运行,但是,即便使用普通用户运行的应用也可能有漏洞,而被恶意代码劫持,提权等等,所以这种提供外部服务的应用放置于沙箱中运行。

SELinux有两种工作级别:
strict: 每个进程都受到selinux的控制;
targeted: 仅有限个进程受到selinux控制;只监控容易被入侵的进程

subject operation object   表示主体操作boject
比如:认为subject是进程,object是文件,operation可以是open, read, write, close, chown, chmod等等。

subject: domain
object: type

SELinux为每个文件提供了安全标签,也为进程提供了安全标签;安全标签有5种,对于CentOS只有user,role,type有用。
user: SELinux的user;
role: 角色;
type: 类型;

SELinux规则库:
规则:哪种域能访问哪种或哪些种类型内文件;


配置SELinux:
SELinux是否启用;
给文件重新打标;
设定某些布型特性;设定程序的某些功能是否开启


配置SELinux启用与否
enforcing: 强制,每个受限的进程都必然受限;
permissive: 启用,每个受限的进程违规操作不会被禁止,但会被记录于审计日志;
disabled: 关闭;

相关命令:
getenforce: 获取selinux当前状态;
setenforce 0|1      其中,0表示设置为permissive     1表示设置为enforcing
此设定:重启系统后无效;

配置文件:/etc/sysconfig/selinux, /etc/selinux/config
      SELINUX={disabled|enforcing|permissive}


给文件重新打标:使用chcon命令
      chcon [OPTION]... CONTEXT FILE...
      chcon [OPTION]... [-u USER] [-r ROLE] [-t TYPE] FILE...
      chcon [OPTION]... --reference=RFILE FILE...

    -R:递归打标;

还原文件的默认标签:
restorecon  [-R]  /path/to/somewhere

布尔型规则:
getsebool
setsebool

getsebool命令:
getsebool [-a] [boolean]
例如  getsebool -a  显示所有

setsebool命令:
setsebool [ -P] boolean value | bool1=val1 bool2=val2 ...
-P  表示使之永久有效
例如 setsebool ftp_home_dir on

------------------------------分割线---------------------------------------------------

bash脚本编程:

顺序执行
选择执行:if语句,case语句
循环执行:while语句,until语句,for语句

函数:
函数是结构化编程及代码重用
使用function关键字用于定义函数


for循环语法:
for NAME in LIST; do
      循环体
done

在bash中列表的生成方式有如下几种:
(1) 整数列表
{start..end}
$(seq start [[step] end])
(2) glob
/etc/rc.d/rc3.d/K*
(3) 使用命令生成列表

例子:通过ping命令探测172.16.250.1-254范围内的所有主机的在线状态;

#!/bin/bash
#
net='172.16.250'
uphosts=0          #在线的主机的数量
downhosts=0     #下线的主机的数量

for i in {1..20}; do
    ping -c 1 -w 1 ${net}.${i} &> /dev/null
        if [ $? -eq 0 ]; then
            echo "${net}.${i} is up."
            let uphosts++
        else
            echo "${net}.${i} is down."
            let downhosts++
        fi
done
 
echo "Up hosts: $uphosts."
echo "Down hosts: $downhosts."


while循环的格式:
while CONDITION; do
       循环体
done

CONDITION:循环控制条件;进入循环之前,先做一次判断;每一次循环之后会再次做判断;
条件为“true”,则执行一次循环;直到条件测试状态为“false”终止循环;

因此:CONDTION一般应该有循环控制变量;而此变量的值会在循环体不断地被修正;

示例:求100以内所有正整数之和;

#!/bin/bash
#
declare -i sum=0
declare -i i=1   #声明变量i为整数,并赋值为1

while [ $i -le 100 ]; do
    let sum+=$i
    let i++
done

echo "$i"
echo "Summary: $sum."

练习:添加10个用户
#!/bin/bash
#
declare -i i=1
declare -i users=0

while [ $i -le 10 ]; do
   if ! id user$i &> /dev/null; then
useradd user$i
  echo "Add user: user$i  success!"
         let users++
   fi
   let i++
done

echo "Add $users users."

练习:通过ping命令探测172.16.250.1-254范围内的所有主机的在线状态;(用while循环)
#!/bin/bash
#
declare -i i=1
declare -i uphosts=0
declare -i downhosts=0
net='192.168.62'

while [ $i -le 254 ]; do
     if ping -c 1 -w 1 $net.$i &> /dev/null; then
echo "$net.$i is up."
let uphosts++
   else
echo "$net.$i is down."
let downhosts++
   fi
   let i++
done

echo "Up hosts: $uphosts."
echo "Down hosts: $downhosts."

练习:打印九九乘法表;(分别使用for和while循环实现)

#!/bin/bash
# for   循环的实现方式
for line in {1..9}; do
    for col in `seq 1  $line` ; do
        echo -n -e "$line×$col=$[$line*$col]\t"
    done
    echo
done


#!/bin/bash
#while 循环的实现方式
declare -i  col=1
declare -i  line=1

while [ $line -le 9  ];do
    while [ $col -le $line ]; do
         echo -n -e "$line×$col=$[$line*$col]\t"
         let col++
    done
    echo
    let col=1
    let line++
done

练习:利用RANDOM生成10个随机数字,输出这个10数字,并显示其中的最大者和最小者;

#!/bin/bash
#
declare -i max=0
declare -i min=0
declare -i i=1

while [ $i -le 10 ]; do
      rand=$RANDOM
      echo $rand

       if [ $i -eq 1 ]; then
             max=$rand
             min=$rand
       fi

       if [ $rand -gt $max ]; then
             max=$rand
       fi

       if [ $rand -lt $min ]; then
             min=$rand
       fi
       let i++
done

echo "MAX: $max."
echo "MIN: $min."



评论

此博客中的热门博文

OAuth 2教程

网格策略

apt-get详细使用