买家拿到那台“付费解锁”的 Linux 服务器后,第一反应通常不是掏钱,而是疯狂按 e。单用户模式、init=/bin/bashrd.break——这些参数他们玩得比你还溜。不出十秒,root 密码就被清掉了,你精心布置的验证脚本和收费逻辑瞬间归零,跟没设过一样。

别指望防火墙或 systemd 服务能拦住这种近身爆破,只要他们能碰到 grub 菜单,一切后端防线都是纸糊的。

GRUB 密码:你离被白嫖就差一个回车键

开机流程跑到 grub 时,Linux 本身还没起床,更别提 NetworkManager 或 sshd。此刻能阻止手快党进入 single user 的,只有 grub 自己的口令。设置后,按 e 会被立刻要求输入用户名与 PBKDF2 哈希校验过的密码,否则光标寸步难移。

grub2-mkpasswd-pbkdf2
复制输出的一大串哈希,填进 /etc/grub.d/40_custom 末尾:
set superusers="admin"
password_pbkdf2 admin <粘贴哈希>

接着执行 ,重启即可看到密码弹窗。openEuler 24.03 LTS SP1、Kylin V10 与 Anolis 8 都采用相同接口,一条命令通吃。有人拔掉硬盘挂到另一台机器,通过 Live USB 读取全部数据——GRUB 密码此时无能为力,因此记得配合 BIOS 开机密码与 LUKS 全盘加密。三位一体,才能让“想白嫖先拆机”变成高门槛。

terminal command grub2-mkpasswd-pbkdf2 generating hash

动手跑一遍 PBKDF2 哈希,别复制漏了

上一节讲完了原理和配置文件模板,现在轮到动手环节。很多人栽在第一步——生成密码时复制漏了字符,或者以为随便输个明文就完事。老发行版(CentOS 6、Ubuntu 16.04)允许 password 指令直接写明文,或使用 MD5 哈希。但 RHEL 8+、Ubuntu 20.04+、openEuler 24.03 以及麒麟 V10 这些现代系统,强制要求 PBKDF2-SHA512。你如果照搬网上旧教程,把 写成 password,grub2-mkconfig 不会报错,但重启后密码框根本不会弹——等于白忙。

正确的做法只有一行命令:

输入两次密码后,终端会输出类似这样的东西:

grub.pbkdf2.sha512.10000.ABCDEF123456...(很长一串)

把这整串——从 grub.pbkdf2 一直复制到末尾——粘贴到 /etc/grub.d/40_custom 后面。如果少复制了末尾几个字符,grub 启动时校验失败,直接跳过密码检测。踩过这个坑的人不少。有次帮朋友排查,他反复确认密码没错,我让他把 40_custom 文件内容贴出来一看,哈希串最后少了四个字符。重新生成、完整复制、更新配置,秒好。

贴一下标准写法:

set superusers="admin"
password_pbkdf2 admin grub.pbkdf2.sha512.10000.ABCD...(完整哈希)

然后执行:

对于 UEFI 引导的机器(大部分新硬件和云服务器),路径要改成 /boot/efi/EFI/centos/grub.cfg 或对应发行版目录。不确定的话,查一下 /boot 下有没有 efi 文件夹,有就用 efi 那套路径。生成完哈希别急着关终端,先重启一次验证。按住 e 键,如果弹出用户名密码输入框,说明生效。没弹?多半是 输出路径错了,或者哈希值有残缺。回去检查 40_custom,重新跑一遍 mkconfig。这一步搞定了,后面打包教程卖资料才有底气。买家连「按 e 改参数绕过 root 密码」这招都废了,自然得乖乖走你的付费验证通道。

editing 40_custom file in terminal

在 40_custom 里写清楚谁说了算,哪些入口不能碰

密码生成好了,不等于系统就“自动”知道谁能用。真正的分水岭,是你敢不敢在 40_custom 里写得清清楚楚:谁是超级用户,哪些入口只准他碰。

用你刚跑出来的那串 ……,在 /etc/grub.d/40_custom 末尾补上两行:

set superusers="admin"
password_pbkdf2 admin grub.pbkdf2.sha512.10000.ABCDEF123456…(整串别截断)

引号用英文的;等号左右不留空格也行,看你习惯。保存退出,继续往下钉死菜单项。很多人以为设了全局密码就万事大吉,结果买家切到救援模式照样起飞。你得把每个能“救命”的入口单独上锁。打开 40_custom,把常见菜单项原样抄进来,并在 menuentry 后面加上 --users=admin。比如针对 CentOS/Anolis 常见的几个落点:默认主入口、救援模式(rescue)、旧内核回退。示例骨架如下,照猫画虎即可:

menuentry 'CentOS Linux (7 core)' --users=admin {
  linux16 /vmlinuz-3.10.0 …
  initrd16 /initramfs-3.10.0 …
}

注意两点:一是语法严格,花括号前后最好换行,二是不要顺手把 tab 写成空格,grub 很挑食。想偷懒也可以先把现有菜单通过 吐出来,复制一份再往里塞 --users=admin,省得格式翻车。写完保存,再跑一遍对应发行版的“刷新脚本”。在 CentOS/Anolis 系:

若是 Ubuntu/Debian 系:

update-grub

如果是 UEFI 机器,确认输出路径是否为 /boot/efi/EFI/centos/grub.cfg/boot/efi/EFI/ubuntu/grub.cfg,别把心血写到错的文件里。完成后重启,按住 e 键看看——现在不再是“随便按就能进”,而是弹出认证框,只有 admin 能继续。这一步走稳了,后面做资料包才有底气:买家想绕开?不好意思,先过你这道门。

堵死 rd.break 和 init=/bin/bash,别给绕过留活口

密码锁了 GRUB 菜单、给每个入口加了 --users=admin,你以为这就完事了?我见过太多人栽在这一步:买家重启机器,在启动参数尾巴上敲个 rd.break 或者 init=/bin/bash,啪,直接跳进 root shell,你前面那堆工作量全白干。GRUB 密码确实能挡住普通编辑,但如果没把内核参数的后门关死,人家按 e 进编辑模式只改一行就能绕过。

这两个参数是 dracut 和 systemd 时代的“万能绕过法”。你打开 /etc/default/grub,找到 这一行,在末尾加上:

systemd.unit=multi-user.target

这样系统永远默认以多用户模式启动,不接受任何人通过命令行临时指定 rd.breakinit=/bin/bash 切进单用户。注意别加错地方——是加在引号内部,跟其他参数用空格隔开。改完后的样子大概是这样:

GRUB_CMDLINE_LINUX="crashkernel=auto rhgb quiet systemd.unit=multi-user.target"

保存,跑 刷配置。这一步做完,至少把最常见的两条绕过路线断了。还有人会从 GRUB 菜单里选“救援模式”或者直接传 systemd.unit=rescue.target 进去。systemd 本身就提供了这两个特殊的 unit,默认情况下它们都活着。把它们 mask 掉:

mask 的意思是彻底禁用——连 symlink 都给你删干净,想 都拉不起来。执行完你试试 systemctl list-units --type=target | grep -E 'rescue|emergency',应该什么都看不到。如果某些发行版还保留了旧的 SysV init 风格的 single 模式,顺手把 /usr/lib/systemd/system/single.target 也 mask 掉更保险。别急着收工。重启机器,在 GRUB 界面按 e 进入编辑模式——现在应该弹出密码框,输入 admin 的密码才能继续。进去之后,找到 linux16 那行,在末尾手动加上 rd.break,按 Ctrl+x 启动。如果一切正常,系统会无视你塞进去的参数,照常进入 multi-user.target 的登录界面。你要是看到 rescue shell 或者紧急模式弹出来,说明有漏网之鱼。再试一下从菜单里选带“rescue”字样的启动项,看它会不会直接拒绝启动。如果它跳出一个“unit not found”或者直接黑屏返回菜单,mask 就生效了。三个地方锁死了:GRUB 密码挡编辑、内核参数固定启动目标、systemd target 被 mask。到这步,买家想绕过你的付费验证去重置 root 密码或者改启动参数,基本只能拆硬盘挂到别的机器上——那已经超出 GRUB 防护的范畴了。

变现思路:把解锁教程和 Linux 资料包做成产品

锁是做给需要“可控”的场景用的,而真正值钱的是你把整套解锁流程写成能落地的步骤,再顺手把日常运维里常用的那堆脚本和配置整理好,一起打包卖出去。我一般把教程拆成两条线。第一条线讲“怎么解开”:从 GRUB 菜单按 e 进入编辑页开始,到输入你预设的用户名(比如 admin)和 PBKDF2 口令为止;第二条线讲“怎么复现”:让对方自己也能跑通 生成哈希,再把 set superusers="admin"password_pbkdf2 admin <hash> 写进 /etc/grub.d/40_custom,最后执行 生效。

别只丢几行命令,用户要的是“一次过”。文档里我会把常见坑先标红:systemd.unit=rescue.target 为什么改不动、rd.break 为什么会被忽略、mask 之后要怎么验。再配一段 6~8 分钟的录屏,从开机到进 multi-user.target,中间每一步都停两秒,让他们看得出“输密码—加载内核—正常登录”这条完整链路。定价我习惯落在 99~299 这个区间:纯文字版 99,带录屏加 Q&A 小群 199,再加一份“恢复盘/救援模式”补充说明上 299。你要让他觉得贵,但又能咬咬牙接受。单卖一个“解锁”总显得薄,搭一套 Linux 运维资料包就顺很多。我常塞这几样:常用命令速查(grep/sed/awk/ip/ss/lsof/fdisk/parted/blkid/timedatectl/systemctl/journalctl/chattr/lsattr/sudoers/pam.d 这些),安全基线脚本(firewalld/nftables 最小规则、fail2ban 针对 SSH/SSHD 的 jail.local、yum/dnf/apt 源与 GPG 校验、logrotate 压缩与保留周期),再加一份“系统优化”清单(文件系统 mount options、vm.swappiness/vfs_cache_pressure、透明大页/NUMA 的基本开关、rc.local 残留服务的清理)。这套东西不炫技,但能用。很多人愿意为“少踩一个坑”付钱。

帖子标题直接打痛点:云服务器 GRUB 锁死、防止买家绕过验证、拿到机器不改 root 就跑。正文里放一张“解锁前后对比”的截图,再写三段真实会碰到的场景:对方要重置 root、要进单用户改配置、要把 rd.break 参数偷偷换掉。然后留个钩子:评论或私信获取“解锁教程+资料包”。你在 QQ 群里聊两句就能成交,因为对方也知道,这种内容不方便公开扩散。说到底,锁住只是手段,变现才是目的。

忘了密码怎么办?发行版差异和物理安全

GRUB 密码锁上了,然后呢?总有人会忘密码,总有人会换发行版,也总有人觉得上了锁就万事大吉。物理接触机器的人,永远有最后一招。拿一个 Live USB 启动盘插上,从 U 盘启动,挂载原系统的根分区(假设是 /dev/sda2,挂到 /mnt),然后 chroot /mnt。进去之后编辑 /etc/grub.d/40_custom,把之前加的那段 行删掉或者改掉。最后重新生成配置:

重启拔掉 U 盘,GRUB 菜单直接跳过密码,问都不问一声。就是这么简单。所以别觉得 GRUB 密码能拦住所有操作——它真正拦住的,是那些压根不知道还有这条路的人。你一旦知道这条道在哪儿,它就是一层纱,一捅就破。

命令名字都不一样。CentOS 7/8 和 Anolis OS(兼容 CentOS 系列)用 ,而 Ubuntu 系用的是 update-grub——其实 update-grub 是个包装脚本,底层调的也是 (路径不带 2)。大部分发行版生成 hash 的口令工具通用: 或者 ,哪个能用用哪个。我见过有人把 CentOS 上的 hash 字符串直接复制到 Ubuntu 的 40_custom,启动时报错说 hash 格式不对——检查后发现是 GRUB 版本小差异导致 pbkdf2 迭代次数不同。解决办法?老老实实在目标机器上重新跑一遍生成命令。还有一个容易忽略的:配置文件路径。CentOS 用 /boot/grub2/grub.cfg,Ubuntu 用 /boot/grub/grub.cfg。你拿 CentOS 的习惯去搞 Ubuntu,执行完 没报错但配置没更新,最后发现生成的文件写到了 /boot/grub2/grub.cfg 而系统读的是 /boot/grub/grub.cfg

前面聊到 Live USB 能绕过引导菜单——其实真要锁死,三层防护一起上才有点意思。第一层,BIOS/UEFI 设密码,把 USB 启动、CD 启动和启动顺序修改全封了;第二层,全盘加密上 LUKS,哪怕硬盘被拆下来挂到别的机器,也读不出任何数据;第三层,GRUB 密码锁住引导入口。你要是只做其中一层,基本等于留后门。BIOS 密码有人放电清零,LUKS 密码弱了能暴力破解,GRUB 密码被 Live USB 一绕就穿。可三层叠起来,大部分人就真放弃了。说白了,GRUB 密码锁的不是“铁了心要破”的人,是“懒得折腾”的人——想清楚这点,才知道你那个解锁教程该定什么价。