跳至内容

系统启动

在本章中,您将学习系统是如何启动的。


目标: 在本章中,未来的 Linux 管理员将学习

✔ 引导过程的不同阶段;
✔ Rocky Linux 如何通过使用 GRUB2 和 systemd 支持此引导;
✔ 如何保护 GRUB2 免受攻击;
✔ 如何管理服务;
✔ 如何从 journald 访问日志。

🏁 用户

知识: ⭐ ⭐
复杂性: ⭐ ⭐ ⭐

阅读时间: 20 分钟


引导过程

了解 Linux 的引导过程对于解决可能出现的问题非常重要。

引导过程包括

BIOS 启动

BIOS (基本输入/输出系统) 执行POST (开机自检) 以检测、测试和初始化系统硬件组件。

然后它加载MBR (主引导记录)。

主引导记录 (MBR)

主引导记录是引导磁盘的前 512 字节。MBR 发现引导设备并将引导加载程序GRUB2 加载到内存中,并将控制权转移给它。

接下来的 64 字节包含磁盘的分区表。

GRUB2 引导加载程序

Rocky 8 发行版的默认引导加载程序是GRUB2 (GRand Unified Bootloader)。GRUB2 替换了旧的 GRUB 引导加载程序 (也称为 GRUB legacy)。

GRUB 2 配置文件位于 /boot/grub2/grub.cfg 下,但此文件不应该直接编辑。

GRUB2 菜单配置设置位于 /etc/default/grub 下,用于生成 grub.cfg 文件。

# cat /etc/default/grub
GRUB_TIMEOUT=5
GRUB_DEFAULT=saved
GRUB_DISABLE_SUBMENU=true
GRUB_TERMINAL_OUTPUT="console"
GRUB_CMDLINE_LINUX="rd.lvm.lv=rhel/swap crashkernel=auto rd.lvm.lv=rhel/root rhgb quiet net.ifnames=0"
GRUB_DISABLE_RECOVERY="true"

如果对这些参数中的一个或多个进行了更改,则必须运行 grub2-mkconfig 命令以重新生成 /boot/grub2/grub.cfg 文件。

[root] # grub2-mkconfig –o /boot/grub2/grub.cfg
  • GRUB2 在 /boot 目录中查找压缩的内核映像 (vmlinuz 文件)。
  • GRUB2 将内核映像加载到内存中,并使用 tmpfs 文件系统将 initramfs 映像文件的內容提取到内存中的临时文件夹中。

内核

内核启动 systemd 进程,其 PID 为 1。

root          1      0  0 02:10 ?        00:00:02 /usr/lib/systemd/systemd --switched-root --system --deserialize 23

systemd

Systemd 是所有系统进程的父进程。它读取 /etc/systemd/system/default.target 链接的目标 (例如,/usr/lib/systemd/system/multi-user.target) 以确定系统的默认目标。该文件定义要启动的服务。

然后,Systemd 通过执行以下初始化任务将系统置于目标定义的状态

  1. 设置机器名称
  2. 初始化网络
  3. 初始化 SELinux
  4. 显示欢迎横幅
  5. 根据启动时传递给内核的参数初始化硬件
  6. 挂载文件系统,包括 /proc 之类的虚拟文件系统
  7. 清理 /var 中的目录
  8. 启动虚拟内存 (交换)

保护 GRUB2 引导加载程序

为什么要用密码保护引导加载程序?

  1. 防止单用户模式访问 - 如果攻击者可以引导到单用户模式,他将成为 root 用户。
  2. 防止访问 GRUB 控制台 - 如果攻击者设法使用 GRUB 控制台,他可以使用 cat 命令更改其配置或收集有关系统的信息。
  3. 阻止访问不安全的操作系统。如果系统上存在双启动,攻击者可以在启动时选择像 DOS 这样的操作系统,该操作系统会忽略访问控制和文件权限。

为 GRUB2 引导程序设置密码保护

  • /etc/grub.d/10_linux 文件中 CLASS= 语句中的主 -unrestricted 中删除。

  • 如果尚未配置用户,请使用 grub2-setpassword 命令为 root 用户提供密码

# grub2-setpassword

如果 /boot/grub2/user.cfg 文件不存在,它将被创建。它包含 GRUB2 的散列密码。

注意

此命令仅支持具有单个 root 用户的配置。

[root]# cat /boot/grub2/user.cfg
GRUB2_PASSWORD=grub.pbkdf2.sha512.10000.CC6F56....A21
  • 使用 grub2-mkconfig 命令重新创建配置文件
[root]# grub2-mkconfig -o /boot/grub2/grub.cfg
Generating grub configuration file ...
Found linux image: /boot/vmlinuz-3.10.0-327.el7.x86_64
Found initrd image: /boot/initramfs-3.10.0-327.el7.x86_64.img
Found linux image: /boot/vmlinuz-0-rescue-f9725b0c842348ce9e0bc81968cf7181
Found initrd image: /boot/initramfs-0-rescue-f9725b0c842348ce9e0bc81968cf7181.img
done
  • 重新启动服务器并检查。

现在,GRUB 菜单中定义的所有条目都需要在每次启动时输入用户和密码。系统不会在没有来自控制台的直接用户干预的情况下启动内核。

  • 当请求用户时,输入 root
  • 当请求密码时,输入在 grub2-setpassword 命令中提供的密码。

要仅保护 GRUB 菜单条目的编辑和对控制台的访问,执行 grub2-setpassword 命令就足够了。在某些情况下,你可能出于正当理由而只执行此操作。在远程数据中心,每次服务器重启时都需要输入密码,这可能很困难或不可能做到。

Systemd

Systemd 是 Linux 操作系统的服务管理器。

它旨在

  • 保持与旧的 SysV 初始化脚本兼容,
  • 提供许多功能,例如在系统启动时并行启动系统服务,按需激活守护进程,支持快照或管理服务之间的依赖关系。

注意

Systemd 是 RedHat/CentOS 7 之后的默认初始化系统。

Systemd 引入了单元文件,也称为 systemd 单元。

类型文件扩展名功能
服务单元.service系统服务
目标单元.target一组 systemd 单元
挂载单元.automount文件系统的自动挂载点

注意

存在许多类型的单元:设备单元、挂载单元、路径单元、范围单元、切片单元、快照单元、套接字单元、交换单元、计时器单元。

  • Systemd 支持系统状态快照和还原。

  • 挂载点可以配置为 systemd 目标。

  • 在启动时,systemd 会为所有支持这种类型的激活的系统服务创建侦听套接字,并在这些服务启动后立即将这些套接字传递给它们。这使得可以重新启动服务,而不会丢失网络在服务不可用期间发送给它的任何消息。相应的套接字保持可访问,所有消息都会排队。

  • 使用 D-BUS 进行进程间通信的系统服务可以在它们第一次被客户端使用时按需启动。

  • Systemd 仅停止或重新启动正在运行的服务。以前的版本(在 RHEL7 之前)试图直接停止服务,而没有检查其当前状态。

  • 系统服务不继承任何上下文(如 HOME 和 PATH 环境变量)。每个服务都在其自己的执行上下文中运行。

所有服务单元操作都受默认 5 分钟超时限制,以防止出现故障的服务冻结系统。

管理系统服务

服务单元以 .service 文件扩展名结尾,与 init 脚本具有类似的目的。systemctl 命令用于 显示启动停止重新启动 系统服务

systemctl描述
systemctl start name.service启动服务
systemctl stop name.service停止服务
systemctl restart name.service重新启动服务
systemctl reload name.service重新加载配置
systemctl status name.service检查服务是否正在运行
systemctl try-restart name.service仅在服务正在运行时重新启动服务
systemctl list-units --type service --all显示所有服务的状态

systemctl 命令也用于 启用禁用 系统服务,以及显示相关服务

systemctl描述
systemctl enable name.service激活服务
systemctl disable name.service禁用服务
systemctl list-unit-files --type service列出所有服务并检查它们是否正在运行
systemctl list-dependencies --after列出在指定单元之前启动的服务
systemctl list-dependencies --before列出在指定单元之后启动的服务

示例

systemctl stop nfs-server.service
# or
systemctl stop nfs-server

列出当前加载的所有单元

systemctl list-units --type service

列出所有单元以检查它们是否已激活

systemctl list-unit-files --type service
systemctl enable httpd.service
systemctl disable bluetooth.service

postfix 服务的 .service 文件示例

postfix.service Unit File
What follows is the content of the /usr/lib/systemd/system/postfix.service unit file as currently provided by the postfix package:

[Unit]
Description=Postfix Mail Transport Agent
After=syslog.target network.target
Conflicts=sendmail.service exim.service

[Service]
Type=forking
PIDFile=/var/spool/postfix/pid/master.pid
EnvironmentFile=-/etc/sysconfig/network
ExecStartPre=-/usr/libexec/postfix/aliasesdb
ExecStartPre=-/usr/libexec/postfix/chroot-update
ExecStart=/usr/sbin/postfix start
ExecReload=/usr/sbin/postfix reload
ExecStop=/usr/sbin/postfix stop

[Install]
WantedBy=multi-user.target

使用系统目标

在 Rocky8/RHEL8 上,运行级别概念已被 Systemd 目标取代。

Systemd 目标由目标单元表示。目标单元以 .target 文件扩展名结尾,它们唯一的目的是将其他 Systemd 单元分组到依赖链中。

例如,graphical.target 单元用于启动图形会话,它会启动系统服务,例如 **GNOME 显示管理器** (gdm.service) 或 **帐户服务** (accounts-daemon.service),并激活 multi-user.target 单元。

类似地,multi-user.target 单元会启动其他重要的系统服务,例如 **NetworkManager** (NetworkManager.service) 或 **D-Bus** (dbus.service),并激活名为 basic.target 的另一个目标单元。

目标单元描述
poweroff.target关闭系统并将其关闭
rescue.target激活救援 shell
multi-user.target激活没有图形界面的多用户系统
graphical.target激活具有图形界面的多用户系统
reboot.target关闭并重新启动系统

默认目标

确定默认使用哪个目标

systemctl get-default

此命令搜索位于 /etc/systemd/system/default.target 的符号链接的目标,并显示结果。

$ systemctl get-default
graphical.target

systemctl 命令还可以提供可用目标的列表

systemctl list-units --type target
UNIT                   LOAD   ACTIVE SUB    DESCRIPTION
basic.target           loaded active active Basic System
bluetooth.target       loaded active active Bluetooth
cryptsetup.target      loaded active active Encrypted Volumes
getty.target           loaded active active Login Prompts
graphical.target       loaded active active Graphical Interface
local-fs-pre.target    loaded active active Local File Systems (Pre)
local-fs.target        loaded active active Local File Systems
multi-user.target      loaded active active Multi-User System
network-online.target  loaded active active Network is Online
network.target         loaded active active Network
nss-user-lookup.target loaded active active User and Group Name Lookups
paths.target           loaded active active Paths
remote-fs.target       loaded active active Remote File Systems
slices.target          loaded active active Slices
sockets.target         loaded active active Sockets
sound.target           loaded active active Sound Card
swap.target            loaded active active Swap
sysinit.target         loaded active active System Initialization
timers.target          loaded active active Timers

配置系统以使用不同的默认目标

systemctl set-default name.target

示例

# systemctl set-default multi-user.target
rm '/etc/systemd/system/default.target'
ln -s '/usr/lib/systemd/system/multi-user.target' '/etc/systemd/system/default.target'

在当前会话中切换到不同的目标单元

systemctl isolate name.target

**救援模式** 在无法执行正常启动过程的情况下提供一个简单的环境来修复你的系统。

救援模式 中,系统会尝试挂载所有本地文件系统并启动几个重要的系统服务,但不会启用网络接口,也不允许其他用户同时连接到系统。

在 Rocky 8 上,救援模式 等同于旧的 单用户模式,需要 root 密码。

在当前会话中更改当前目标并进入 救援模式

systemctl rescue

**紧急模式** 提供尽可能简约的环境,即使在系统无法进入救援模式的情况下也能让系统得到修复。在紧急模式下,系统仅以只读方式挂载根文件系统。它不会尝试挂载任何其他本地文件系统,也不会激活任何网络接口,只会启动一些基本服务。

在当前会话中更改当前目标并进入紧急模式

systemctl emergency

关闭、挂起和休眠

systemctl 命令取代了先前版本中使用的许多电源管理命令

旧命令新命令描述
haltsystemctl halt关闭系统。
poweroffsystemctl poweroff关闭系统。
rebootsystemctl reboot重新启动系统。
pm-suspendsystemctl suspend挂起系统。
pm-hibernatesystemctl hibernate休眠系统。
pm-suspend-hybridsystemctl hybrid-sleep休眠并挂起系统。

journald 进程

除了 rsyslogd 之外,日志文件还可以由 journald 守护进程管理,它是 systemd 的一个组件。

journald 守护进程捕获 Syslog 消息、内核日志消息、初始 RAM 磁盘和启动开始时的消息,以及写入所有服务标准输出和标准错误输出的消息,然后对它们进行索引,并使它们可供用户使用。

本机日志文件格式是一个结构化和索引的二进制文件,它改进了搜索并允许更快地操作,它还存储元数据信息,例如时间戳或用户 ID。

journalctl 命令

journalctl 命令显示日志文件。

journalctl

该命令列出系统上生成的所有日志文件。此输出的结构类似于 /var/log/messages/ 中使用的结构,但它提供了一些改进

  • 条目的优先级以视觉方式标记;
  • 时间戳转换为系统本地时区;
  • 显示所有记录的数据,包括循环日志;
  • 启动的开始用特殊行标记。

使用持续显示

使用持续显示,日志消息会实时显示。

journalctl -f

此命令返回十个最新的日志行的列表。然后,journalctl 实用程序继续运行,并等待发生新的更改,然后再立即显示它们。

过滤消息

可以使用不同的过滤方法来提取满足不同需求的信息。日志消息通常用于跟踪系统上的错误行为。要查看具有选定或更高优先级的条目

journalctl -p priority

你必须用以下关键字(或数字)之一替换 priority

  • debug (7),
  • info (6),
  • notice (5),
  • warning (4),
  • err (3),
  • crit (2),
  • alert (1),
  • 以及 emerg (0)。