CentOS系统在默认安装后,GRUB引导加载程序通常没有设置密码保护。这意味着任何能够物理接触服务器或通过带外管理卡(如IPMI、iDRAC)访问控制台的人,只需在系统启动时敲击几下键盘,就能轻松获得root权限。具体操作极其简单:在GRUB菜单出现时按'e'键进入编辑模式,找到以'linux'或'linux16'开头的行,在行尾添加'rd.break'或'init=/bin/bash',然后按Ctrl+X启动,几秒钟后就能进入一个具有完整root权限的shell环境,整个过程不需要任何密码验证。这种攻击方式绕过了操作系统的所有认证机制,对数据安全构成直接威胁。解决这个问题的核心方法就是为GRUB设置密码,让任何试图修改启动参数的操作都必须先通过密码验证。

GRUB密码保护的核心机制与版本差异

在动手配置之前,必须明确CentOS不同版本使用的GRUB版本存在差异,这直接影响配置文件的路径和命令语法。CentOS 6及更早版本使用传统的GRUB Legacy(0.97版本),而CentOS 7及更高版本采用GRUB2。两者的密码设置方法完全不同。GRUB Legacy的配置文件位于/boot/grub/menu.lst或/boot/grub/grub.conf,密码设置相对简单。GRUB2的配置文件则位于/boot/grub2/grub.cfg,但这个文件由系统自动生成,不能直接编辑,需要通过修改/etc/grub.d/目录下的脚本文件和/etc/default/grub配置文件来实现。当前生产环境中CentOS 7和CentOS Stream 8/9是主流,因此本文重点讲解GRUB2的密码设置方法,同时兼顾GRUB Legacy的配置方式供老系统维护人员参考。

GRUB2密码设置第一步:生成加密密码哈希

GRUB2支持明文密码和加密密码两种形式,但明文密码直接存储在配置文件中,任何能读取该文件的人都能看到密码,安全性极差。正确的做法是使用grub2-mkpasswd-pbkdf2命令生成PBKDF2加密哈希。这个命令会提示输入密码两次,然后输出一个以grub.pbkdf2开头的长字符串。操作步骤如下:

# grub2-mkpasswd-pbkdf2
Enter password: 
Reenter password: 
PBKDF2 hash of your password is grub.pbkdf2.sha512.10000.1F4E9A8B7C6D5E4F3A2B1C0D9E8F7A6B5C4D3E2F1A0B9C8D7E6F5A4B3C2D1E0F9A8B7C6D5E4F3A2B1C0D9E8F7A6B5C4D3E2F1A0B9C8D7E6F5A4B3C2D1E0F9A8B7C6D5E4F3A2B1C0D9E8F7A6B5C4D3E2F1A0B9C8D7E6F5A4B3C2D1E0F

这个哈希值需要完整记录下来,后续配置中会用到。值得注意的是,GRUB2的PBKDF2算法使用SHA512和10000次迭代,安全性相当高,即使配置文件泄露,攻击者也难以通过彩虹表或暴力破解还原出原始密码。建议密码长度至少12位,包含大小写字母、数字和特殊字符的组合。

GRUB2超级用户账号配置方法

GRUB2的权限控制分为两个层级:超级用户和普通用户。超级用户可以修改任何启动参数,普通用户只能启动已授权的菜单项。对于防止单用户模式绕过认证这个目标,设置超级用户就足够了。编辑/etc/grub.d/01_users文件,这个文件默认不存在或为空,需要手动创建或修改。在文件中添加以下内容:

#!/bin/sh -e
cat << EOF
set superusers="root"
password_pbkdf2 root grub.pbkdf2.sha512.10000.1F4E9A8B7C6D5E4F3A2B1C0D9E8F7A6B5C4D3E2F1A0B9C8D7E6F5A4B3C2D1E0F9A8B7C6D5E4F3A2B1C0D9E8F7A6B5C4D3E2F1A0B9C8D7E6F5A4B3C2D1E0F9A8B7C6D5E4F3A2B1C0D9E8F7A6B5C4D3E2F1A0B9C8D7E6F5A4B3C2D1E0F
EOF

这里"root"是超级用户的用户名,可以自定义为其他名称。第二行password_pbkdf2后面紧跟用户名和之前生成的加密哈希值。保存文件后,必须确保该文件具有可执行权限:

# chmod +x /etc/grub.d/01_users

这个文件的编号01决定了它在GRUB2配置生成过程中的执行顺序,数字越小越先执行,01_users会在其他菜单项脚本之前运行,确保用户认证机制优先加载。

限制所有菜单项需要认证

仅仅设置超级用户还不够,还需要指定哪些启动菜单项需要密码保护。如果不做额外配置,GRUB2默认允许不输入密码直接启动标准菜单项,只有编辑启动参数时才需要密码。但单用户模式本身就是通过编辑启动参数实现的,所以这个默认行为已经提供了一定保护。然而为了更严格的安全策略,建议对所有菜单项都要求认证。编辑/etc/grub.d/10_linux文件,找到生成菜单项的部分,在menuentry行中添加--users参数。更简单的方法是在/etc/default/grub文件中添加以下配置:

GRUB_ENABLE_CRYPTODISK=y

这行配置会强制所有菜单项都需要超级用户密码才能启动。如果只想保护特定的恢复模式菜单项,可以修改/etc/grub.d/10_linux中对应rescue条目的生成逻辑,在menuentry后面添加--users root参数。对于大多数安全场景,建议采用全局保护策略,即任何启动操作都需要密码验证。

重新生成GRUB2配置文件

完成上述修改后,必须重新生成/boot/grub2/grub.cfg配置文件才能使更改生效。根据系统启动模式的不同,执行以下命令之一:

对于传统BIOS启动的系统:

# grub2-mkconfig -o /boot/grub2/grub.cfg

对于UEFI启动的系统:

# grub2-mkconfig -o /boot/efi/EFI/centos/grub.cfg

如果不确定系统启动模式,可以检查/sys/firmware/efi目录是否存在,存在则为UEFI模式,否则为BIOS模式。执行grub2-mkconfig命令时,系统会读取/etc/default/grub中的配置和/etc/grub.d/目录下的所有脚本,按顺序执行并拼接成最终的grub.cfg文件。命令输出会显示找到的内核版本和生成的菜单项,可以通过检查输出来确认配置是否被正确应用。

验证密码保护效果

配置完成后不要急于重启,先在当前系统中检查生成的grub.cfg文件内容,确认密码设置是否正确写入。执行以下命令查看相关配置:

# grep -A 5 "superusers" /boot/grub2/grub.cfg
# grep -A 2 "password_pbkdf2" /boot/grub2/grub.cfg

确认输出中包含set superusers和password_pbkdf2配置行。然后重启系统进行实际测试。在GRUB菜单界面,尝试按'e'键编辑启动参数,系统应该提示输入用户名和密码。输入之前设置的超级用户账号和密码后,才能进入编辑模式。同时测试不输入密码直接按回车启动默认菜单项的行为,如果配置了全局保护,此时也应该要求认证。如果测试中发现任何问题,可以在系统启动后重新修改配置并再次生成grub.cfg文件。

GRUB Legacy系统的密码设置方法

对于仍在运行CentOS 6的老旧系统,GRUB Legacy的密码设置更加直接。可以直接编辑/boot/grub/grub.conf文件,在文件开头添加以下两行:

password --md5 $1$xyz$2f4e8a9b7c6d5e4f3a2b1c0d9e8f7a

这里的MD5哈希值可以通过grub-md5-crypt命令生成,输入密码后会输出加密字符串。或者使用明文密码,但不推荐:

password 123456

然后在每个需要保护的title段落中添加lock指令,这样在启动对应菜单项时就必须先按p键输入密码。更严格的做法是在全局配置中设置password,并在title行后添加lock,这样任何试图编辑启动参数的操作都需要密码。GRUB Legacy的密码保护强度远不如GRUB2的PBKDF2加密,建议有条件的情况下尽快升级系统版本。

多层防护策略与物理安全加固

GRUB密码是防止单用户模式绕过的第一道防线,但安全防护应该采用纵深防御策略。即使设置了GRUB密码,攻击者仍然可以通过其他途径绕过,例如拆卸硬盘挂载到其他系统读取数据,或者使用Live CD启动系统。因此建议同时采取以下补充措施:

第一,在BIOS/UEFI固件层面设置管理员密码,防止攻击者修改启动顺序从外部介质启动。大多数服务器和PC的固件都支持设置开机密码和管理员密码,这是比GRUB密码更底层的防护。第二,禁用所有不必要的外部启动设备,在固件中将硬盘设为唯一的启动设备,并锁定启动顺序。第三,对于虚拟机环境,限制控制台访问权限,确保虚拟化管理平台的认证机制健全。第四,对磁盘进行全盘加密,使用LUKS或类似技术,这样即使物理获取硬盘也无法读取数据。第五,配置GRUB密码后,确保/boot/grub2/目录的权限设置正确,grub.cfg文件应为600或400权限,仅root可读,防止普通用户通过读取配置文件获取密码哈希。

常见问题排查与注意事项

设置GRUB2密码时可能遇到几个常见问题。问题一:执行grub2-mkconfig后密码设置未生效。这通常是因为01_users文件没有可执行权限,或者文件名拼写错误。检查/etc/grub.d/目录下文件权限,确保01_users有x权限。问题二:重启后GRUB直接进入rescue模式,无法正常启动。这可能是因为grub.cfg文件生成过程中出现错误,导致配置文件损坏。可以使用安装介质进入救援模式,挂载系统后重新生成配置文件。问题三:输入密码后仍然无法编辑启动参数。检查密码哈希是否完整复制,特别注意哈希字符串中是否包含换行符或多余空格。问题四:系统更新内核后密码保护失效。每次内核更新时系统会自动重新生成grub.cfg文件,只要/etc/grub.d/01_users文件和/etc/default/grub配置正确,新生成的配置文件会自动包含密码设置。但建议在每次内核更新后检查grub.cfg文件确认。

自动化配置脚本与批量部署

在管理大量CentOS服务器时,手动逐台配置GRUB密码效率低下且容易遗漏。可以编写自动化脚本实现批量部署。以下是一个示例脚本框架:

#!/bin/bash
# 生成密码哈希,密码通过参数传入或从安全存储读取
GRUB_PASSWORD="$1"
if [ -z "$GRUB_PASSWORD" ]; then
    echo "Usage: $0 "
    exit 1
fi

# 生成加密哈希
HASH=$(echo -e "$GRUB_PASSWORD\n$GRUB_PASSWORD" | grub2-mkpasswd-pbkdf2 | grep "PBKDF2" | awk '{print $NF}')

# 创建01_users文件
cat > /etc/grub.d/01_users << EOF
#!/bin/sh -e
cat << END
set superusers="admin"
password_pbkdf2 admin $HASH
END
EOF

chmod +x /etc/grub.d/01_users

# 重新生成配置
if [ -d /sys/firmware/efi ]; then
    grub2-mkconfig -o /boot/efi/EFI/centos/grub.cfg
else
    grub2-mkconfig -o /boot/grub2/grub.cfg
fi

echo "GRUB password configuration completed."

这个脚本可以集成到系统初始化流程或配置管理工具(如Ansible、Pupet)中,确保每台新部署的服务器都自动启用GRUB密码保护。密码可以通过密钥管理服务传入,避免在脚本中硬编码。

安全审计与合规性要求

从安全审计和合规性角度,GRUB密码设置是多项安全标准的基本要求。PCI DSS要求保护对系统引导过程的访问,ISO 27001要求控制对信息系统的物理访问,等保2.0要求对服务器启动过程进行身份验证。审计人员通常会检查以下项目:GRUB是否设置了密码、密码是否加密存储、是否限制了单用户模式访问、是否在BIOS层面设置了启动密码。因此,在完成配置后,建议记录配置时间、配置内容和验证结果,形成文档化的安全配置记录。同时定期检查这些配置是否仍然有效,特别是在系统更新或维护操作后。

GRUB密码设置看似是一个简单的技术操作,但它是服务器安全防线的关键一环。物理访问一旦被突破,操作系统层面的所有安全措施都可能被绕过。通过本文介绍的GRUB2 PBKDF2加密密码设置方法,结合BIOS密码、磁盘加密等补充措施,可以构建起有效的物理安全防护体系。对于系统管理员而言,花十分钟完成这个配置,就能堵住一个可能造成数据泄露或系统破坏的高危漏洞,性价比极高。