系统启动¶
在本章中,您将学习系统如何启动。
目标:在本章中,未来的 Linux 管理员将学习
启动过程的不同阶段;
Rocky Linux 如何通过使用 GRUB2 和
systemd
支持此启动;
如何保护 GRUB2 免受攻击;
如何管理服务;
如何访问
journald
的日志。
用户。
知识:
复杂性:
阅读时间: 20 分钟
启动过程¶
理解 Linux 的启动过程对于解决可能出现的问题至关重要。
启动过程包括
BIOS 启动¶
BIOS (Basic Input/Output System) 执行 POST (power on self-test,开机自检) 来检测、测试和初始化系统硬件组件。
然后加载 MBR (Master Boot Record,主引导记录)。
主引导记录 (MBR)¶
主引导记录是启动磁盘的第一个 512 字节。MBR 发现引导设备,将引导加载程序 GRUB2 加载到内存中,并将控制权转移给它。
接下来的 64 字节包含磁盘的分区表。
GRUB2 引导加载程序¶
Rocky 8 发行版的默认引导加载程序是 GRUB2 (GRand Unified Bootloader)。GRUB2 取代了旧的 GRUB 引导加载程序 (也称为 GRUB legacy)。
您可以在 /boot/grub2/grub.cfg
下找到 GRUB2 配置文件,但不应直接编辑此文件。
您可以在 /etc/default/grub
下找到 GRUB2 菜单配置设置。grub2-mkconfig
命令使用这些设置来生成 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
映像文件的内容提取到内存中的临时文件夹。
内核¶
内核启动 PID 为 1 的 systemd
进程。
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
通过执行以下初始化任务将系统置于目标定义的状
- 设置机器名
- 初始化网络
- 初始化 SELinux
- 显示欢迎横幅
- 根据启动时传递给内核的参数初始化硬件
- 挂载文件系统,包括 /proc 等虚拟文件系统
- 清理 /var 目录
- 启动虚拟内存 (swap)
保护 GRUB2 引导加载程序¶
为何要用密码保护引导加载程序?
- 防止进入单用户模式 - 如果攻击者能够启动到单用户模式,他将成为 root 用户。
- 防止访问 GRUB 控制台 - 如果攻击者能够使用 GRUB 控制台,他可以更改其配置或使用
cat
命令收集有关系统的信息。 - 防止访问不安全的操作系统。如果系统是双启动的,攻击者可以在启动时选择一个像 DOS 这样的操作系统,该操作系统会忽略访问控制和文件权限。
为 GRUB2 引导加载程序设置密码保护
-
以 root 用户身份登录操作系统并执行
grub2-mkpasswd-pbkdf2
命令。此命令的输出如下:Enter password: Reenter password: PBKDF2 hash of your password is grub.pbkdf2.sha512.10000.D0182EDB28164C19454FA94421D1ECD6309F076F1135A2E5BFE91A5088BD9EC87687FE14794BE7194F67EA39A8565E868A41C639572F6156900C81C08C1E8413.40F6981C22F1F81B32E45EC915F2AB6E2635D9A62C0BA67105A9B900D9F365860E84F1B92B2EF3AA0F83CECC68E13BA9F4174922877910F026DED961F6592BB7
您需要在交互中输入密码。密码的密文是长字符串 "grub.pbkdf2.sha512..."。
-
将密码密文粘贴到 /etc/grub.d/00_header 文件的最后一行。粘贴格式如下:
cat <<EOF set superusers='frank' password_obkdf2 frank grub.pbkdf2.sha512.10000.D0182EDB28164C19454FA94421D1ECD6309F076F1135A2E5BFE91A5088BD9EC87687FE14794BE7194F67EA39A8565E868A41C639572F6156900C81C08C1E8413.40F6981C22F1F81B32E45EC915F2AB6E2635D9A62C0BA67105A9B900D9F365860E84F1B92B2EF3AA0F83CECC68E13BA9F4174922877910F026DED961F6592BB7 EOF
您可以将 'frank' 用户替换为任何自定义用户。
您也可以设置一个明文密码,例如:
cat <<EOF set superusers='frank' password frank rockylinux8.x EOF
-
最后一步是运行命令
grub2-mkconfig -o /boot/grub2/grub.cfg
来更新 GRUB2 的设置。 -
重新启动操作系统以验证 GRUB2 的加密。选择第一个启动菜单项,按 e 键,然后输入相应的用户名和密码。
Enter username: frank Enter password:
成功验证后,输入 Ctrl+x 启动操作系统。
有时,您可能会在一些文档中看到使用 grub2-set-password
(grub2-setpassword
) 命令来保护 GRUB2 引导加载程序
命令 | 核心功能 | 配置文件修改方法 | 自动性 |
---|---|---|---|
grub2-set-password |
设置密码并更新配置 | 自动完成 | 高 |
grub2-mkpasswd-pbkdf2 |
仅生成加密的哈希值 | 需要手动编辑 | 低 |
以 root 用户身份登录操作系统,并按如下方式执行 gurb2-set-password
命令:
[root] # grub2-set-password
Enter password:
Confirm password:
[root] # cat /boot/grub2/user.cfg
GRUB2_PASSWORD=grub.pbkdf2.sha512.10000.32E5BAF2C2723B0024C1541F444B8A3656E0A04429EC4BA234C8269AE022BD4690C884B59F344C3EC7F9AC1B51973D65F194D766D06ABA93432643FC94119F17.4E16DF72AA1412599EEA8E90D0F248F7399E45F34395670225172017FB99B61057FA64C1330E2EDC2EF1BA6499146400150CA476057A94957AB4251F5A898FC3
[root] # grub2-mkconfig -o /boot/grub2/grub.cfg
[root] # reboot
执行 grub2-set-password
命令后,将自动生成 /boot/grub2/user.cfg 文件。
选择第一个启动菜单项,按 e 键,然后输入相应的用户名和密码。
Enter username:
root
Enter password:
Systemd¶
Systemd 是 Linux 操作系统的服务管理器。
systemd
的开发是为了
- 与旧的 SysV 初始化脚本保持兼容,
- 提供许多功能,例如系统启动时的系统服务并行启动、守护进程的按需激活、快照支持或服务之间的依赖关系管理。
注意
systemd
是 RedHat/CentOS 7 以来的默认初始化系统。
systemd
引入了单元文件(也称为 systemd
单元)的概念。
类型 | 文件扩展名 | 功能 |
---|---|---|
服务单元 | .service |
系统服务 |
目标单元 | .target |
一组 systemd 单元 |
挂载单元 | .automount |
文件系统的自动挂载点 |
注意
有许多类型的单元:设备单元、挂载单元、路径单元、作用域单元、切片单元、快照单元、套接字单元、交换单元和计时器单元。
-
systemd
支持系统状态快照和恢复。 -
您可以将挂载点配置为
systemd
目标。 -
启动时,
systemd
为所有支持此类激活的系统服务创建监听套接字,并在这些服务启动时立即将这些套接字传递给它们。这使得可以在不丢失网络在服务不可用期间发送给它的任何消息的情况下重新启动服务。相应的套接字在所有消息排队时保持可访问。 -
使用 D-BUS 进行进程间通信的系统服务可以在客户端第一次使用它们时按需启动。
-
systemd
只会停止或重新启动正在运行的服务。以前的版本(RHEL7 之前)会尝试直接停止服务,而不检查它们当前的状态。 -
系统服务不继承任何上下文(如 HOME 和 PATH 环境变量)。每个服务在其执行上下文中运行。
所有服务单元操作都受到 5 分钟的默认超时限制,以防止有故障的服务冻结系统。
由于空间限制,本文档不会提供 systemd
的详细介绍。如果您有兴趣进一步了解 systemd
,可以在 本文档 中找到非常详细的介绍。
管理系统服务¶
服务单元以 .service
文件扩展名结尾,其作用与 init 脚本类似。systemctl
命令用于 显示
、启动
、停止
或 重新启动
系统服务。除极少数情况外,systemctl
单行命令在大多数情况下(不限于 ".service" 单元类型)可以对一个或多个单元进行操作。您可以通过帮助系统查看。
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
使用 system targets¶
systemd
target 取代了 SysV 或 Upstart 中的运行级别概念。
systemd
targets 的表示方式是通过 target units。Target units 以 .target
文件扩展名结尾,其唯一目的是将其他 systemd
units 分组到依赖链中。
例如,启动图形会话的 graphical.target
unit 启动 GNOME 显示管理器 (gdm.service
) 或 accounts service (accounts-daemon.service
) 等系统服务,并激活 multi-user.target
unit。如果您需要查看某个 "target" 的依赖关系,请运行 systemctl list-dependencies
命令。(例如,systemctl list-dependencies multi-user.target
)。
sysinit.target
和 basic.target
是启动过程中的检查点。虽然 systemd
的设计目标之一是并行启动系统服务,但在启动其他服务和 "target" 之前,有必要启动某些服务和 "target" 的 "target"。sysinit.target
或 basic target
中的任何错误都将导致 systemd
初始化失败。此时,您的终端可能已进入 "emergency mode" (emergency.target
)。
Target Units | 描述 |
---|---|
poweroff.target | 关闭系统并将其关闭 |
rescue.target | 激活救援 shell |
multi-user.target | 激活没有图形界面的多用户系统 |
graphical.target | 激活带有图形界面的多用户系统 |
reboot.target | 关闭并重启系统 |
默认 target¶
确定默认使用的 target
systemctl get-default
此命令搜索位于 /etc/systemd/system/default.target
的符号链接的目标并显示结果。
$ systemctl get-default
graphical.target
systemctl
命令还可以提供可用 target 的列表。
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
配置系统使用不同的默认 target
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'
在当前会话中切换到不同的 target unit
systemctl isolate name.target
救援模式 在无法正常启动的情况下提供了一个简单的环境来修复您的系统。
在 rescue mode
中,系统会尝试挂载所有本地文件系统并启动几个重要的系统服务,但不会启用网络接口,也不会允许其他用户同时连接到系统。
在 Rocky 8 上,rescue mode
等同于旧的 single user mode
,并且需要 root 密码。
要更改当前 target 并进入当前会话的 rescue mode
systemctl rescue
紧急模式 提供了一个尽可能精简的环境,即使在无法进入救援模式的情况下也能修复系统。在紧急模式下,操作系统以只读方式挂载根文件系统。它不会尝试挂载任何其他本地文件系统,也不会启用任何网络接口,只会启动一些基本服务。
要更改当前 target 并进入当前会话的紧急模式
systemctl emergency
关机、挂起和休眠¶
systemctl
命令取代了以前版本使用的许多电源管理命令。
旧命令 | 新命令 | 描述 |
---|---|---|
halt |
systemctl halt |
关闭系统。 |
poweroff |
systemctl poweroff |
关闭系统。 |
reboot |
systemctl reboot |
重启系统。 |
pm-suspend |
systemctl suspend |
挂起系统。 |
pm-hibernate |
systemctl hibernate |
休眠系统。 |
pm-suspend-hybrid |
systemctl hybrid-sleep |
休眠并挂起系统。 |
journald 进程¶
您可以使用 systemd
的一个组件——journald
守护进程来管理日志文件,而不再使用 rsyslogd
。
journald
守护进程负责捕获以下类型的日志消息:
- Syslog 消息
- 内核日志消息
- Initramfs 和系统启动日志
- 所有服务的标准输出 (stdout) 和标准错误输出 (stderr) 信息
捕获后,journald
会索引这些日志,并通过结构化存储机制提供给用户。该机制以二进制格式存储日志,支持按时间顺序跟踪事件,并提供多种格式(如文本/JSON)的灵活过滤、搜索和输出功能。请注意,journald
默认不启用日志持久化,这意味着该组件只保留并记录启动以来的所有日志。操作系统重启后,历史日志将被删除。默认情况下,所有临时保存的日志文件都在 /run/log/journal/ 目录下。
journalctl 命令¶
journalctl
命令用于解析以二进制格式保存的日志文件,例如查看日志文件、过滤日志和控制输出条目。
journalctl
如果您不带任何其他选项运行该命令,输出的日志内容将类似于 /var/log/messages
文件,但 journalctl
提供了以下改进:
- 以可视方式显示条目的优先级
- 显示时间戳转换为系统的本地时区
- 显示所有记录的数据,包括轮换日志
- 显示一个特殊行标记启动的开始
使用连续显示¶
通过连续显示,日志消息会实时显示。
journalctl -f
此命令返回最近十行日志的列表。然后 journalctl
工具会继续运行,并等待发生新的更改,然后立即显示它们。
过滤消息¶
可以使用不同的过滤方法来提取满足不同需求的信息。日志消息通常用于跟踪系统上的错误行为。要查看具有选定或更高优先级的条目:
journalctl -p priority
您必须将优先级替换为以下关键字之一(或数字):
- debug (7),
- info (6),
- notice (5),
- warning (4),
- err (3),
- crit (2),
- alert (1),
- emerg (0)。
如果您想了解更多关于日志内容的信息,可以在 本文档 中找到更全面的介绍和描述。