系统启动¶
在本章中,您将学习系统是如何启动的。
目标: 在本章中,未来的 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 通过执行以下初始化任务将系统置于目标定义的状态
- 设置机器名称
- 初始化网络
- 初始化 SELinux
- 显示欢迎横幅
- 根据启动时传递给内核的参数初始化硬件
- 挂载文件系统,包括 /proc 之类的虚拟文件系统
- 清理 /var 中的目录
- 启动虚拟内存 (交换)
保护 GRUB2 引导加载程序¶
为什么要用密码保护引导加载程序?
- 防止单用户模式访问 - 如果攻击者可以引导到单用户模式,他将成为 root 用户。
- 防止访问 GRUB 控制台 - 如果攻击者设法使用 GRUB 控制台,他可以使用
cat
命令更改其配置或收集有关系统的信息。 - 阻止访问不安全的操作系统。如果系统上存在双启动,攻击者可以在启动时选择像 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
命令取代了先前版本中使用的许多电源管理命令
旧命令 | 新命令 | 描述 |
---|---|---|
halt | systemctl halt | 关闭系统。 |
poweroff | systemctl poweroff | 关闭系统。 |
reboot | systemctl reboot | 重新启动系统。 |
pm-suspend | systemctl suspend | 挂起系统。 |
pm-hibernate | systemctl hibernate | 休眠系统。 |
pm-suspend-hybrid | systemctl 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)。