Linux系统启动流程之(2)grub

Linux启动流程中在引导bootloader时会检查出磁盘的前446字节,从而找出/boot/grub下的相应的配置,来去挂载假根文件系统来解压内核来完成根切换。

 

回顾启动流程:

POST --> Boot Sequence(BIOS) --> Boot Loader --> Kernel(ramdisk) --> rootfs--> switchroot--> /sbin/init-->(/etc/inittab, /etc/init/*.conf) --> 设定默认运行级别--> 系统初始化脚本rc.sysinit--> 关闭或启动对应级别的服务--> 启动终端

vgrub: GRandUnified Bootloader

grub 0.x: grub legacy

grub 1.x: grub2

grub legacy:

stage1: mbr

stage1_5: mbr之后的扇区,让stage1中的bootloader能识别stage2所在的分区上的文件系统

stage2:磁盘分区(/boot/grub/)

 

grub legacy说明:

配置文件:/boot/grub/grub.conf  <---- /etc/grub.conf

stage2及内核等通常放置于一个基本磁盘分区

grub的功能:

(1)提供启动菜单、并提供交互式接口

a:内核参数

e:编辑模式,用于编辑菜单

c:命令模式,交互式接口

(2)加载用户选择的内核或操作系统

允许传递参数给内核

可隐藏启动菜单

(3)为菜单提供了保护机制

为编辑启动菜单进行认证

为启动内核或操作系统进行认证

 

文件例子展示CentOS下:

inux系统启动流程之(2)grub

 

grub主配置文件案例格式解析:

default=0                             #设定默认启动的title编号,从0开始
timeout=5                             #等待用户选择的超时时长,单位是秒
splashp_w_picpath=(hd0,0)/grub/splash.xpm.gz  #grub菜单的背景图片文件路径
hiddenmenu                              #隐藏菜单
password redhat                      #定义grub明文密码,编辑grub时需要输入密码
password --md5 $1$6u/1v$4Jd.5YSDf9.5v1AnfJFRe0  #定义加密密码
title Mylinux                #内核菜单标题,一般为操作系统名称、字符串,可*修改
root (hd0,0)                 #grub查找stage2及kernel文件所在的设备分区;为/boot
kernel /vmlinuz-2.6.18-308.el5       #内核文件路径,及传递给内核的参数
    initrd /initrd-2.6.18-308.el5.img    #内核匹配的ramfs文件
password --md5 $1$6u/1v$4Jd.5YSDf9.5v1AnfJFRe0  #给内核加密码

注意:这里的(hd0,0)表示第1块磁盘的第一个分区,一般找内核所在分区会以此格式来指定。

 

识别硬盘设备:

(hd#,#)

hd#:磁盘编号,用数字表示;从0开始编号

#:分区编号,用数字表示;从0开始编号

解析:那么上面的gurb样板格式里的(hd0,0)表示第一块硬盘,第一个分区

 

安装grub的两种方式:

第一种:交互式设置

前提:需要事先判断grub在哪个磁盘

#输入grub命令进入交互式

[[email protected] ~]# grub
grub> root (hd0,0)    #使用 root (hd0,0)检查磁盘0的第一个分区是否有文件系统
root (hd0,0)          #显示出文件系统类型,可以使用find命令查看此目录文件是否对应 
grub> setup (hd0,0)   #确定安装在此分区
..............
grub>quit             #在系统里操作完成后退出,在救援模式使用boot启动


 

第二种方式:

grub-install --root-directory=/path/to/boot’s+parent_dir  /PATH/TO/DEVICE

如:

[[email protected] ~]# grub-install --root-directory=/ /dev/sda
Installation finished. No error reported.
This is the contents of the device map //boot/grub/device.map.
Check if this is correct or not. If any of the lines is incorrect,
fix it and re-run the script `grub-install'.
 
# this device map was generated by anaconda
(hd0)     /dev/sda

解析:这里的--root-directory=指明的是boot目录的父目录,第二个参数表示在哪个磁盘的前446字节安装grub及(bootloader)。

 

案例1:修改grub中的信息自定义菜单:

1、修改文件配置

#查看源文件信息:

[[email protected] ~]# vim /boot/grub/grub.conf

inux系统启动流程之(2)grub

#添加对应条目,设置标题等信息

inux系统启动流程之(2)grub 

解析:这里标题里没有设置root    (hd#,#),及指定root分区在哪个磁盘的分区上,所有可以直接使用(hd#,#)来表示root文件系统的路径然后后面跟boot目录下的对应文件路径。

#保存后重启启动机器

[[email protected] ~]# reboot

#进入系统读秒时按任意键,进入grub菜单

 inux系统启动流程之(2)grub

解析:进入grub菜单发现新增了一个刚刚在grub.conf配置文件中定义的title(MengTianba Linux),同时在菜单的下发显示了一些grub的相关操作介绍:

按上↑或下↓键可以来调整选择哪个grub引导入口,选择后按回车表示从该条目引导。

按 e 键表示对选择的条目进行编辑

按 a 键表示修改选择条目的内核参数

按 c 键进入命令行交互界面

 

#此时可以选择按enter回车键直接进入刚才添加的入口,这里按e键来进行编辑

 inux系统启动流程之(2)grub

解析:这里又进入了一个子菜单,而这个菜单是显示刚才选择grub 条目中的信息,也就是grub.conf文件中定义的那行信息。同时这里可以也提示了一些关键键:

按e编译内核参数

按c进入对应的子项交互编辑界面

按o表示追加一个新行,按O便是插入一个新行

按d删除指定行

按b表示自己启动引导

 

#这里同样可以使用对kernel项按e或者按c,于是按e键

inux系统启动流程之(2)grub 

说明:这时可以对此行进行编辑了,于是在root=/dev/sda2(指定系统所在分区)的后面加入一些参数,比如:selinux=0(关闭selinux功能)、max_loop=100(指定loop设备最大映射值)。于是添加如下:

inux系统启动流程之(2)grub

解析:在后面添加自己想添加的内核参数后,发现上面提示有按ESC键可以取消此次编辑不保存而回到上个子菜单,而按回车键会临时保存内核参数,于是按回车回到子菜单。

inux系统启动流程之(2)grub 

解析:因为内核参过长所所有没有完全显示,这里按b键就可以让gurb按照设置好的内核参数来进行加载系统。,于是按b键--> boot启动。

 

2、进入系统后,可以查看刚才设置的内核是否已经生效

#查看selinux安全上下文件功能是否已经被禁用

[[email protected] ~]# getenforce 
Disabled

#查看本地回环设备是最大数量是否已经被修改到了100个

[[email protected] ~]# ls /dev/loop*

inux系统启动流程之(2)grub

解析:现在可以此时本地回环设备以及提供了100个映射点,当然这只是测验,真实中是用不到这么多的本地回环设备映射的。

#那么刚才设置的这些参数又被临时保存到哪个映射文件呢

[[email protected] ~]# cat /proc/cmdline 
ro root=/dev/sda2 selinux=0 max_loop=100

注:这里的显示的参数只是对于内核加载后生效的并设置的参数,只是临时在内存中,重启机器后就会失效。因此还是需要修改grub.conf文件来使其永久生效:

#再次修改grub.conf文件,加入刚才设置的禁用selinux和调整回环设备最大映射数:

 inux系统启动流程之(2)grub

 

3、加密Grub,设置密码

(1)生成口令

当然如果不想让人随意来编辑此grub条目,可以设置对此设置密码

为了安全性,应使用加密的密码,于是可以使用下面命令来生成加密口令:

#使用专门用于生成grub中md5加密算法的grub-md5-crypt工具:

[[email protected] ~]# grub-md5-crypt << EOF > token.txt 2> /dev/null
> 123456
> 123456
> EOF

#然后查看token.txt文件中保存的**:

[[email protected] ~]# tail -n 1 token.txt 
$1$3jizv$jY.3FSjDvDkv0cpntbqvg/

 

(2)加密MengTianba单个title项

#然后进入vim界面来将刚才的加***加入指定的 title条目中

可以使用垂直分屏显示模式同时打开token.txt和 grub.conf文件

[[email protected] ~]# vim -O token.txt /boot/grub/grub.conf

#然后对应修改,对MengTianba条目内核设置密码

inux系统启动流程之(2)grub

注意:口令的前面必须要password  --md5参数来表示此字段为设置此条目需要的安全口令。

 

(3)给grub引导加密

#同样编辑grub.conf文件

[[email protected] ~]# vim /boot/grub/grub.conf

inux系统启动流程之(2)grub 

说明:在第一个title菜单选项行前面插入一行。

#然后进入末行模式,输入命令读取加密的文本读入到此行

 inux系统启动流程之(2)grub

#按回车,发现口令已经被读入此行

inux系统启动流程之(2)grub 

#此时保存文件退出,重启机器测试,按按任意键进入 grub菜单

inux系统启动流程之(2)grub 

注意:此时发现虽然能进入grub菜单,但是下面的提示却变了,只能按上下键选择选择后者按p键进入对应的grub引导,于是选择自定义添加的那一行,按p键:

inux系统启动流程之(2)grub 

解析:这里输入的密码为grub菜单设置的加密口令。输入口令后回车将再次显示此菜单,但是下面的提示将回到正常状态。

#这时选择MengTianba按ENTER回车,系统从此引导入口来加载对应的系统

inux系统启动流程之(2)grub

解析:这时输入的密码就是title对应的MengTianba下设置的加密口令,输入正确后进入系统。

 

但是如果这里我们选到MengTiana LInux按c使用交互式模式调整此引导条目信息:

inux系统启动流程之(2)grub 

说明:编辑好指定的内核参数以及initrd调用后输入boot回车表示以上面设置的grub信息来进入引导。

注意:这里有一个问题,这里如果使用能通过grub交互式界面里提供的find命令来慢慢查找内核目录里的文件来判断系统或boot所在的分区及文件路径,那么只要使用c来进入交互式grub直接跳过条目中的加密设置来进入指定的grub引导。当然前提是要记住grub编辑界面的密码口令,如果不能进入编辑模式,那么想直接跳过grub自身加密是不可行的。

 

案例2:进入单用户模式来**root口令

在生产环境中,很多时候因为人员的调度或者经常更改root管理员用户口令,导致在真正使用的时候而忘记root密码,这时可以利用linux中提供的单用户模式来跳过login交互式用户验证模块直接进入对应的shell界面,然后进行命令操作修改root口令。

下面假设忘记了boot用户,可以通过进入grub然后通知内核以单用户模式进入系统

#进入可编辑模式(为加密或者已经输入密码的)的grub菜单

inux系统启动流程之(2)grub 

#然后按e键编辑MengTianba Linux引导项

inux系统启动流程之(2)grub 

#然后再次按e来编辑 kernel项参数

inux系统启动流程之(2)grub 

说明:在最后跟上1或者s或者single都表示为单用户模式及进入1级别引导系统。

#最后按b键进行启动系统,系统启动完成,会直接跳过login交互登录提示,直接以root身份进入系统:

inux系统启动流程之(2)grub 

解析:这样就可以直接修改root密码了。