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下:
grub主配置文件案例格式解析:
default=0 #设定默认启动的title编号,从0开始 timeout=5 #等待用户选择的超时时长,单位是秒 splashimage=(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
#添加对应条目,设置标题等信息
解析:这里标题里没有设置root (hd#,#),及指定root分区在哪个磁盘的分区上,所有可以直接使用(hd#,#)来表示root文件系统的路径然后后面跟boot目录下的对应文件路径。
#保存后重启启动机器
[[email protected] ~]# reboot
#进入系统读秒时按任意键,进入grub菜单
解析:进入grub菜单发现新增了一个刚刚在grub.conf配置文件中定义的title(MengTianba Linux),同时在菜单的下发显示了一些grub的相关操作介绍:
按上↑或下↓键可以来调整选择哪个grub引导入口,选择后按回车表示从该条目引导。
按 e 键表示对选择的条目进行编辑
按 a 键表示修改选择条目的内核参数
按 c 键进入命令行交互界面
#此时可以选择按enter回车键直接进入刚才添加的入口,这里按e键来进行编辑
解析:这里又进入了一个子菜单,而这个菜单是显示刚才选择grub 条目中的信息,也就是grub.conf文件中定义的那行信息。同时这里可以也提示了一些关键键:
按e编译内核参数
按c进入对应的子项交互编辑界面
按o表示追加一个新行,按O便是插入一个新行
按d删除指定行
按b表示自己启动引导
#这里同样可以使用对kernel项按e或者按c,于是按e键
说明:这时可以对此行进行编辑了,于是在root=/dev/sda2(指定系统所在分区)的后面加入一些参数,比如:selinux=0(关闭selinux功能)、max_loop=100(指定loop设备最大映射值)。于是添加如下:
解析:在后面添加自己想添加的内核参数后,发现上面提示有按ESC键可以取消此次编辑不保存而回到上个子菜单,而按回车键会临时保存内核参数,于是按回车回到子菜单。
解析:因为内核参过长所所有没有完全显示,这里按b键就可以让gurb按照设置好的内核参数来进行加载系统。,于是按b键--> boot启动。
2、进入系统后,可以查看刚才设置的内核是否已经生效
#查看selinux安全上下文件功能是否已经被禁用
[[email protected] ~]# getenforce Disabled
#查看本地回环设备是最大数量是否已经被修改到了100个
[[email protected] ~]# ls /dev/loop*
解析:现在可以此时本地回环设备以及提供了100个映射点,当然这只是测验,真实中是用不到这么多的本地回环设备映射的。
#那么刚才设置的这些参数又被临时保存到哪个映射文件呢
[[email protected] ~]# cat /proc/cmdline ro root=/dev/sda2 selinux=0 max_loop=100
注:这里的显示的参数只是对于内核加载后生效的并设置的参数,只是临时在内存中,重启机器后就会失效。因此还是需要修改grub.conf文件来使其永久生效:
#再次修改grub.conf文件,加入刚才设置的禁用selinux和调整回环设备最大映射数:
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条目内核设置密码
注意:口令的前面必须要password --md5参数来表示此字段为设置此条目需要的安全口令。
(3)给grub引导加密
#同样编辑grub.conf文件
[[email protected] ~]# vim /boot/grub/grub.conf
说明:在第一个title菜单选项行前面插入一行。
#然后进入末行模式,输入命令读取加密的文本读入到此行
#按回车,发现口令已经被读入此行
#此时保存文件退出,重启机器测试,按按任意键进入 grub菜单
注意:此时发现虽然能进入grub菜单,但是下面的提示却变了,只能按上下键选择选择后者按p键进入对应的grub引导,于是选择自定义添加的那一行,按p键:
解析:这里输入的密码为grub菜单设置的加密口令。输入口令后回车将再次显示此菜单,但是下面的提示将回到正常状态。
#这时选择MengTianba按ENTER回车,系统从此引导入口来加载对应的系统
解析:这时输入的密码就是title对应的MengTianba下设置的加密口令,输入正确后进入系统。
但是如果这里我们选到MengTiana LInux按c使用交互式模式调整此引导条目信息:
说明:编辑好指定的内核参数以及initrd调用后输入boot回车表示以上面设置的grub信息来进入引导。
注意:这里有一个问题,这里如果使用能通过grub交互式界面里提供的find命令来慢慢查找内核目录里的文件来判断系统或boot所在的分区及文件路径,那么只要使用c来进入交互式grub直接跳过条目中的加密设置来进入指定的grub引导。当然前提是要记住grub编辑界面的密码口令,如果不能进入编辑模式,那么想直接跳过grub自身加密是不可行的。
案例2:进入单用户模式来破解root口令
在生产环境中,很多时候因为人员的调度或者经常更改root管理员用户口令,导致在真正使用的时候而忘记root密码,这时可以利用linux中提供的单用户模式来跳过login交互式用户验证模块直接进入对应的shell界面,然后进行命令操作修改root口令。
下面假设忘记了boot用户,可以通过进入grub然后通知内核以单用户模式进入系统
#进入可编辑模式(为加密或者已经输入密码的)的grub菜单
#然后按e键编辑MengTianba Linux引导项
#然后再次按e来编辑 kernel项参数
说明:在最后跟上1或者s或者single都表示为单用户模式及进入1级别引导系统。
#最后按b键进行启动系统,系统启动完成,会直接跳过login交互登录提示,直接以root身份进入系统:
解析:这样就可以直接修改root密码了。