改完 sudoers 谁都 sudo 不了:一次 /etc/sudoers 语法错误锁死的复盘

给同事的 deploy 账号加几条 sudo 权限,直接 vi /etc/sudoers 末尾敲了一行,保存退出。随手一个 sudo whoami 屏幕弹出 sudo: parse error in /etc/sudoers near line 92,后面跟着 no valid sudoers sources found, quitting——sudo 整个瘫了。想 sudo vi 改回来,这命令本身要用 sudo,而 sudo 已经废了,死循环。我只想给一个人加权限,结果整台机器所有人的 sudo 全挂。排查梳理:sudo 每次执行都要读 /etc/sudoers 判断谁能用 sudo,sudoers 语法极严格一个字符不对整个文件就解析失败;sudo 发现 sudoers 解析失败采取 fail-closed 失败即关闭策略,不会忽略坏行用好行而是整个文件作废谁的权限都不认,所以一处手误全员瘫这是正确的安全设计不是 bug;最致命的是修 sudoers 的常规手段 sudo vi 本身依赖 sudo,sudo 一废这条路就断了把自己锁在门外;真正的错是直接用 vi 改 sudoers,正确工具是 visudo 它在保存前校验语法有错根本不让你存;自救通道按优先级是现成的 root 会话、su - 输 root 密码 su 不读 sudoers、pkexec 另一套提权、重启进救援模式;改 sudoers 前先另开一个终端 su 成 root 待命垫底;加规则别动主文件放进 /etc/sudoers.d 下的独立小文件用 visudo -f 编辑;给人完整 sudo 优先把他加进 wheel 组不碰 sudoers;sudoers 文件属主必须 root 权限必须 0440 错了 sudo 同样拒绝使用。正确做法是改 sudoers 永远只用 visudo,改前先开 root 会话垫底,改后 visudo -c 校验,以及一套 sudo 与 sudoers 排查纪律。

2023 年,一次"给同事开个权限"的小操作,让我在那台机器上,把【所有人】——包括我自己——的 sudo 全废了。事情起因再普通不过:同事的 deploy 账号,需要能执行几条运维命令,要给它配点 sudo 权限。我登上服务器,熟门熟路地 vi /etc/sudoers,在文件末尾敲了一行,授权 deploy。我看了一眼,觉得没问题,:wq 保存,退出。然后我想验证一下,随手敲了个 sudo whoami——屏幕上弹出来的东西,让我手一下子凉了:sudo: parse error in /etc/sudoers near line 92,后面还跟着 sudo: no valid sudoers sources found, quittingsudo 报错了。我心想没事,我去把那行改回来就好。我敲 sudo vi /etc/sudoers——可这条命令,本身就要用 sudo,而 sudo 此刻已经瘫了,它回我的,还是那行 parse error。我又试 sudo 别的——全部一样的报错。这一刻我背后一凉:我刚刚改坏的那个文件,是 sudo 用来判断"谁能用 sudo"的;而我现在要修它,又【必须】用 sudo。我亲手锁上了一扇门,而开这扇门的钥匙,正被锁在门里面。更让我后怕的是:我只是想给【一个人】加权限,可结果是【整台机器、所有人】的 sudo 全挂了。一个文件里的一个手误,怎么会有这么大的杀伤力?这件事逼着我把 sudo 的工作机制、sudoers 文件、visudo、以及锁死之后怎么自救,这一整套彻底理清了。本文复盘这次实战。

问题背景

环境:CentOS 7,要给 deploy 用户配 sudo 权限
事故现象:
- vi /etc/sudoers 加了一行后保存
- ★ 此后【所有人】执行任何 sudo 命令,全部报错
- ★ 想 sudo vi /etc/sudoers 改回来 —— 也用不了 sudo

现场排查:
# 1. 复现 —— 随便一条 sudo 都炸
$ sudo whoami
sudo: parse error in /etc/sudoers near line 92
sudo: no valid sudoers sources found, quitting   # ★ sudo 整个瘫了

# 2. ★ 想修复,却发现修复也要 sudo
$ sudo vi /etc/sudoers
sudo: parse error in /etc/sudoers near line 92    # ★ 死循环
$ sudo cat /etc/sudoers
sudo: parse error in /etc/sudoers near line 92    # ★ 连看都看不了

# 3. 看我加的那行(用没坏的方式 —— 直接读)
$ cat -n /etc/sudoers | tail -3
 90  root    ALL=(ALL)       ALL
 91
 92  deploy  ALL=(ALL)      /usr/bin/systemctl    # ★ 看这行!

# 4. ★ 发现问题:第 92 行有个【中文括号】
#    正确应是  (ALL)  —— 半角英文括号
#    我打成了  (ALL) —— 右边是个全角中文括号 】
# ★ sudoers 的语法极其严格,一个字符不对,
#   整个文件就【解析失败】。

# 5. 确认:能不能 su 到 root(另一条路)
$ su -
Password:                                         # ★ 知道 root 密码
# 输入 root 密码后 —— 成功切到 root。
[root@host ~]#
# ★ su 走的是另一套机制(直接验证 root 密码),
#   它【不读 sudoers】—— 所以 sudoers 坏了,
#   su 照样能用。这是本次的救命通道。

根因(后来想清楚的):
1. ★ sudo 每次执行,都要读 /etc/sudoers,靠它
   判断"这个用户,允不允许执行这条命令"。
2. ★ sudoers 的语法【极严格】。我手误打了一个
   全角中文括号,这一个字符,就让整个文件
   【解析失败】。
3. ★ 关键:sudo 发现 sudoers 解析失败时,采取的是
   【fail-closed(失败即关闭)】策略 —— 它不会
   "忽略坏的行、用好的行",而是【整个文件作废】,
   谁的权限都不认。
4. ★ 于是,我只想动 deploy 一行,结果是 root、
   是我、是所有人的 sudo 规则,【一起】失效。
5. ★ 最致命的:修 sudoers 的常规手段(sudo vi)
   本身依赖 sudo —— sudo 一废,这条路就断了。
   我把自己锁在了门外。
6. 真正的错:我【直接用 vi 改 sudoers】。正确的
   工具是 visudo —— 它在保存前会校验语法,
   有错根本不让你存。我跳过了这道保险。
不是 sudo 太脆弱,是我用错了工具去改一个
"改坏了会锁死自己"的关键文件。

修复 1:sudo 与 sudoers——它凭什么决定让不让你

# === ★ 先搞懂 sudo 这套机制是怎么运转的 ===

# === ★ sudo 是什么 ===
# sudo(superuser do),让一个【普通用户】,在
#   【授权范围内】,以 root(或别的用户)的身份,
#   执行某条命令。
# ★ 它的意义:不用把 root 密码到处发,也不用让
#   人长期泡在 root 里 —— 需要时,精确地、临时地
#   借一下权限。

# === ★ sudo 凭什么判断"让不让你" ===
# 每次你敲 sudo 某命令,sudo 都会去读一个文件:
#   ★ /etc/sudoers —— 这就是它的"规则手册"。
# sudo 在这个文件里查:你这个用户(或你所在的组),
#   被允许以谁的身份、执行哪些命令。
# ★ 查到对应规则、且匹配 -> 放行;
#   查不到 / 不匹配     -> 拒绝。

# === ★ sudoers 里一条规则长什么样 ===
$ cat /etc/sudoers          # (在 root 下看)
root    ALL=(ALL)       ALL
%wheel  ALL=(ALL)       ALL
deploy  ALL=(ALL)       /usr/bin/systemctl, /usr/bin/journalctl
# ★ 一条规则的格式:
#   谁   在哪些主机=(可切换成哪些用户)  能跑哪些命令
#  - root  ALL=(ALL) ALL
#     -> root,在所有主机,能切成任何用户,跑任何命令。
#  - ★ %wheel ... -> 开头的 % 表示这是个【用户组】。
#     wheel 组里的所有用户,都有完整 sudo 权限。
#  - deploy ALL=(ALL) /usr/bin/systemctl,...
#     -> deploy 用户,只能跑 systemctl 和 journalctl
#        这两条(精确授权)。

# === ★ 加 sudo 权限,推荐的正道:把人加进 wheel 组 ===
# 大多数时候,你想给某人完整 sudo,根本不用动
#   sudoers 文件 —— 把他加进 wheel 组就行:
$ usermod -aG wheel deploy        # 把 deploy 加进 wheel 组
$ groups deploy                   # 确认
deploy : deploy wheel
# ★ sudoers 里 %wheel ALL=(ALL) ALL 这行是【系统
#   自带】的。人进了 wheel 组,自动就有 sudo 权限,
#   你【根本没碰】sudoers 文件 —— 零风险。

# === ★ 看自己当前有哪些 sudo 权限 ===
$ sudo -l
User deploy may run the following commands on host:
    (ALL) /usr/bin/systemctl, /usr/bin/journalctl
# ★ sudo -l 列出"我能用 sudo 干哪些事",不改任何
#   东西,排查授权时很有用。

# === 认知 ===
# ★ sudo 每次执行都读 /etc/sudoers 这本"规则手册",
#   靠它判断放不放行。要给人完整 sudo,首选把他
#   加进 wheel 组(usermod -aG wheel),这样压根
#   不用动 sudoers 文件 —— 不碰它,就不会改坏它。

修复 2:为什么一个手误,会让"所有人"都 sudo 不了

# === ★ 本文最反直觉的一点:一行错,全员瘫 ===

# === ★ 我以为的:改坏一行,只影响那一行 ===
# 我手误的是【第 92 行,deploy 那一行】。我潜意识
#   里以为:最坏的结果,无非是"deploy 这一行没生效,
#   deploy 用不了 sudo"。
# ★ 别人的行(root、%wheel)我一个字没动,凭什么
#   会受影响?

# === ★ 实际发生的:整个文件,一起作废 ===
# sudo 读 sudoers,是把它当成【一个整体】来解析的。
#   解析时,只要遇到【任何一处】语法错误,sudo
#   不会"跳过坏行、继续用好行",而是直接判定:
#   ★ 这个文件【整体不可信】,放弃,一条规则都不认。
$ sudo whoami
sudo: parse error in /etc/sudoers near line 92
sudo: no valid sudoers sources found, quitting
# ★ "no valid sudoers sources" —— 没有任何有效的
#   sudoers 来源。注意:它说的是【没有任何】,
#   不是"第 92 行无效"。整本手册,被它扔了。

# === ★ 这个设计有个名字:fail-closed(失败即关闭)===
# 一个权限系统,当它"读不懂自己的规则"时,有两种
#   选择:
#  - fail-open(失败即放开):规则坏了?那就都放行。
#  - ★ fail-closed(失败即关闭):规则坏了?那就
#    都【不】放行,宁可全拒,绝不误放。
# ★ sudo 选的是 fail-closed —— 这其实是【正确】的
#   安全设计:一个权限文件烂掉时,"谁都用不了"
#   远比"谁都能用 root"安全得多。
# ★ 所以"全员瘫痪",不是 bug,是 sudo 在【安全地
#   失败】。代价就是:它会很彻底地把你也关在外面。

# === ★ 于是形成那个致命的死锁 ===
# 1. sudoers 坏了 -> sudo 全废。
# 2. 修 sudoers 的常规命令是 sudo visudo / sudo vi。
# 3. ★ 但这俩都要 sudo —— 而 sudo 已经废了。
# 4. -> 你【没有任何常规手段】能改回那个文件。
# ★ 这就是为什么改 sudoers 是个"高危动作":它是
#   极少数"改坏了会让你失去修复它的能力"的文件。

# === ★ 同理:sudoers 文件的【权限/属主】错了,也会全废 ===
$ ls -l /etc/sudoers
-r--r----- 1 root root ... /etc/sudoers
# ★ sudoers 必须是 root 属主、权限 0440。如果谁
#   手贱 chmod 777 /etc/sudoers,sudo 会因为"这个
#   文件权限不安全"而【拒绝使用它】—— 同样全员瘫。
# ★ 记住:不光内容不能错,属主和权限也不能动。

# === 认知 ===
# ★ sudo 把 sudoers 当一个整体解析,任何一处语法
#   错误,都会让【整个文件作废】,所有人一起瘫 ——
#   这是 fail-closed 的安全设计,不是 bug。也因此,
#   sudoers 是少数"改坏了会让你失去修复能力"的
#   文件,必须用对工具改。

修复 3:visudo——改 sudoers 唯一正确的工具

# === ★ 这次事故的核心教训:改 sudoers 必须用 visudo ===

# === ★ 我错在哪:直接 vi /etc/sudoers ===
# vi(或 vim、nano)是【通用文本编辑器】。它对
#   sudoers 文件的内容【一无所知】—— 你写了一个
#   全角括号,它眼皮都不眨,照存不误。
# ★ vi 的职责只是"忠实地保存你敲的字"。它【不会】
#   替你检查这些字,组成的是不是一份合法的 sudoers。
# ★ 用 vi 改 sudoers = 自己走钢丝,没有任何保护网。

# === ★ visudo 是什么:专门改 sudoers 的"带保险的"工具 ===
$ visudo
# ★ visudo 会:
#  1. 帮你打开 /etc/sudoers 进行编辑(底层还是调
#     你习惯的编辑器);
#  2. ★ 在你保存退出时,【自动校验语法】;
#  3. ★ 如果语法有错 —— 它【拒绝保存】,并提示:
#       >>> sudoers file: syntax error, line 92 <<<
#       What now?
#     给你选择:e 重新编辑 / x 放弃不存 / Q 强行存。
#  4. 语法没错,才真正写回文件。
# ★ 一句话:visudo 在"坏文件"和"磁盘"之间,加了
#   一道【语法检查】的关卡。错的东西,根本落不了盘。

# === ★ visudo 还防"两个人同时改" ===
# visudo 编辑时会加锁。若另一个人也在 visudo,
#   第二个会被提示"文件正被编辑",避免两人的修改
#   互相覆盖。vi 没有这个保护。

# === ★ 一个极有用的命令:visudo -c(只校验,不编辑)===
$ visudo -c
/etc/sudoers: parsed OK
/etc/sudoers.d/deploy: parsed OK
# ★ visudo -c 把 sudoers 整套文件校验一遍,告诉你
#   "parsed OK"还是哪里有错。
# ★ 任何时候你怀疑 sudoers 有问题,先 visudo -c。
#   改完(哪怕是用别的方式改的)也务必 visudo -c
#   确认一遍,再退出当前的 root 会话。

# === ★ 校验别的 sudoers 文件 ===
$ visudo -cf /etc/sudoers.d/deploy
# ★ -f 指定要校验的文件。改 sudoers.d/ 下的文件后,
#   用这个单独校验。

# === ★ 给 visudo 换个你顺手的编辑器 ===
$ export EDITOR=vim          # 或 nano
$ visudo                     # visudo 就会用 vim 打开
# ★ 不喜欢默认编辑器,设 EDITOR 环境变量即可。
#   但不管用哪个编辑器,visudo 的【保存时校验】
#   都还在 —— 保护网不会因为换编辑器而消失。

# === 认知 ===
# ★ 改 sudoers,永远、只用 visudo,绝不用 vi。
#   visudo 在保存时强制校验语法,语法错就拒绝落盘,
#   把"改坏 sudoers"这个高危动作,变成了"改错了
#   它不让你存"的安全动作。visudo -c 可随时校验。

修复 4:已经锁死了,怎么把自己救回来

# === ★ sudo 已经全废,这几条自救通道挨个试 ===

# === ★ 通道 1:还有一个 root 会话开着 —— 最幸运 ===
# ★ 排查任何高危操作时,有个好习惯:【再开一个
#   终端,提前 su 成 root 待命】。
# 如果你恰好还留着一个 root 的 shell:
[root@host ~]# visudo            # 直接修,root 不需要 sudo
# ★ root 执行 visudo / vi /etc/sudoers,根本不经过
#   sudo 那套权限判断 —— 畅通无阻。
# ★ 教训:动 sudoers 前,先开一个 root 会话垫底。

# === ★ 通道 2:用 su 切到 root ===
$ su -
Password:                        # ★ 输入 root 账户的密码
[root@host ~]# visudo            # 切过去就能修了
# ★ su 和 sudo 是【两套独立机制】:su 直接验证目标
#   用户(root)的密码,★【完全不读 sudoers】。
# ★ 所以 sudoers 坏了,只要你知道 root 密码,
#   su - 这条路【照样通】。本文就是靠它脱险的。
# ★ 前提:root 有密码、且你知道。很多系统默认禁用
#   root 密码登录 —— 那这条路就断了,看通道 3、4。

# === ★ 通道 3:pkexec(PolicyKit,另一套提权)===
$ pkexec visudo
# ★ pkexec 是 PolicyKit 提供的提权工具,它和 sudo
#   是【不同的体系】,不读 /etc/sudoers。
# ★ sudo 废了,pkexec 可能还能用 —— 值得一试。

# === ★ 通道 4:重启进 rescue / 单用户模式 ===
# 上面都不行(没 root 会话、不知道 root 密码、
#   pkexec 也没有),最后的兜底是【重启】:
# - 开机 GRUB 菜单,在内核行末尾加  systemd.unit=rescue.target
#   (老系统加 single 或 1),进入救援模式;
# - ★ 救援模式会给你一个 root shell,不需要任何密码
#   验证(或只需 root 密码);
# - 在里面 visudo 修好文件,再 reboot 正常启动。
# ★ 这是"物理/控制台访问"级别的终极手段 —— 也
#   说明:能碰到机器控制台的人,本就拥有最高权限。

# === ★ 修复后,务必校验再退出 ===
[root@host ~]# visudo -c
/etc/sudoers: parsed OK          # ★ 必须看到 OK
[root@host ~]# exit
$ sudo whoami                    # ★ 普通用户验证 sudo 恢复
root
# ★ 黄金纪律:在【确认 sudo 恢复正常】之前,
#   【绝对不要】关掉手里那个 root 会话 —— 它是你
#   唯一的退路。

# === 认知 ===
# ★ sudoers 锁死的自救通道,按优先级:① 现成的
#   root 会话;② su - 输 root 密码(su 不读
#   sudoers);③ pkexec(另一套提权);④ 重启进
#   救援模式。核心纪律:动 sudoers 前先开一个
#   root 会话垫底,修好并 visudo -c 通过前绝不
#   关掉它。

修复 5:sudoers 怎么写、怎么改才安全

# === ★ 既然非改不可,怎么改才把风险降到最低 ===

# === ★ 安全做法 1:别动主文件,把规则放进 /etc/sudoers.d/ ===
# /etc/sudoers 主文件里通常有这么一行:
$ grep includedir /etc/sudoers
#includedir /etc/sudoers.d
# ★ (别被开头的 # 骗了,在 sudoers 里 #includedir
#   是一个【特殊指令】,不是注释。)它的意思是:
#   把 /etc/sudoers.d/ 目录下的所有文件,也都当作
#   sudoers 规则读进来。
# ★ 所以:要加规则,【别去改主文件】,而是在
#   sudoers.d/ 下新建一个【独立的小文件】:
$ visudo -f /etc/sudoers.d/deploy
# 在里面写:
deploy  ALL=(ALL)  /usr/bin/systemctl, /usr/bin/journalctl
# ★ 好处:① 即使这个小文件写坏了,影响面也小,
#   而且容易定位、容易删掉恢复;② 主文件 /etc/sudoers
#   始终保持系统原装、不被你动过 —— 最大程度降险。
# ★ 注意:改 sudoers.d 下的文件,也【一样要用
#   visudo -f】,不要用 vi。

# === ★ 安全做法 2:一条 sudoers 规则的正确语法 ===
# 用户名  主机=(可切换的用户)  允许的命令
deploy   ALL=(ALL)   /usr/bin/systemctl
# %组名  主机=(可切换的用户)  允许的命令
%devops  ALL=(ALL)   /usr/bin/systemctl, /bin/journalctl
# ★ 逐项注意:
#  - 括号必须是【半角英文】( ) —— 本文的事故就
#    死在一个全角中文括号上;
#  - 多条命令之间,用【英文逗号】隔开;
#  - 命令要写【绝对路径】(/usr/bin/systemctl),
#    不能只写 systemctl;
#  - 组规则,组名前面要加 %。

# === ★ 安全做法 3:NOPASSWD —— 免密码执行(慎用)===
deploy  ALL=(ALL) NOPASSWD: /usr/bin/systemctl restart myapp
# ★ 加了 NOPASSWD,deploy 跑这条命令时不用输密码。
#   方便,但等于放宽了安全 —— 只在确有必要(如脚本
#   自动化)时用,且把命令限制得越具体越好。

# === ★ 安全做法 4:改之前,先备份 ===
$ cp /etc/sudoers /root/sudoers.bak       # 改前先备份
# ★ 万一改出问题,有 root 会话时,一条 cp 就能
#   恢复原状。养成"动关键文件前先备份"的习惯。

# === ★ 安全做法 5:用 visudo -c 收尾,别凭感觉 ===
$ visudo -c
/etc/sudoers: parsed OK
/etc/sudoers.d/deploy: parsed OK
# ★ 不管你怎么改的,最后一定 visudo -c 全量校验,
#   看到每一项都 OK,才算改完。

# === 认知 ===
# ★ 改 sudoers 的安全姿势:规则放进 /etc/sudoers.d/
#   的独立小文件(别动主文件),用 visudo -f 编辑,
#   括号逗号用半角、命令写绝对路径,改前备份、
#   改后 visudo -c 校验。能用 wheel 组解决的,
#   就根本别碰 sudoers 文件。

修复 6:sudo 与 sudoers 排查纪律

# === 这次事故暴露的认知盲区,定几条纪律 ===

# === 1. ★ 改 /etc/sudoers 永远用 visudo,绝不用 vi/vim/nano ===

# === 2. ★ visudo 在保存时校验语法,有错拒绝落盘 —— 这是唯一的保护网 ===

# === 3. ★ sudoers 一处语法错,整个文件作废,全员 sudo 瘫痪(fail-closed)===

# === 4. ★ 动 sudoers 前,先另开一个终端 su 成 root 待命垫底 ===

# === 5. su - 不读 sudoers,sudo 废了还能靠 su 切 root 自救(需 root 密码)===

# === 6. ★ 改完用 visudo -c 全量校验,看到 parsed OK 才算数 ===
$ visudo -c

# === 7. ★ 加规则别动主文件,放进 /etc/sudoers.d/ 的独立小文件(visudo -f)===

# === 8. 给人完整 sudo 优先把他加进 wheel 组(usermod -aG wheel),不碰 sudoers ===

# === 9. sudoers 规则:括号逗号用半角、命令写绝对路径、组名前加 % ===

# === 10. sudoers 文件属主必须 root、权限 0440,权限错了 sudo 同样拒绝使用 ===
$ ls -l /etc/sudoers          # 应为 -r--r----- root root

口诀:改 sudoers 只用 visudo,改前先开 root 会话垫底,改后 visudo -c 校验。

命令速查

需求                        命令
=============================================================
改 sudoers(唯一正确方式)   visudo
改 sudoers.d 下的文件        visudo -f /etc/sudoers.d/xxx
全量校验 sudoers 语法        visudo -c
校验指定 sudoers 文件        visudo -cf /etc/sudoers.d/xxx
看自己有哪些 sudo 权限       sudo -l
给某用户完整 sudo 权限       usermod -aG wheel 用户名
看用户属于哪些组             groups 用户名
sudo 废了切到 root           su -
另一套提权(sudo 废时)      pkexec 命令
看 sudoers 文件属主/权限     ls -l /etc/sudoers

口诀:改 sudoers 永远用 visudo 不用 vi,它保存时校验语法有错不让存
      动它之前先开一个 root 会话垫底,改完 visudo -c 看到 OK 再退出

避坑清单

  1. 改 /etc/sudoers 永远只用 visudo,绝不要用 vi 或 vim 或 nano 这类通用编辑器直接改
  2. visudo 会在你保存退出时自动校验语法,语法有错就拒绝落盘,这是改 sudoers 唯一的保护网
  3. sudoers 文件里任何一处语法错误,都会让整个文件作废,所有人的 sudo 一起瘫这是 fail-closed
  4. 动 sudoers 之前先另开一个终端 su 成 root 待命垫底,这是改坏之后最可靠的自救通道
  5. su - 走的是验证 root 密码的独立机制根本不读 sudoers,所以 sudo 废了 su 通常还能用
  6. 改完 sudoers 一定用 visudo -c 做全量校验,看到每个文件都 parsed OK 才算改对了
  7. 加 sudo 规则别去动主文件,放进 /etc/sudoers.d/ 下的独立小文件并用 visudo -f 编辑
  8. 给某人完整 sudo 权限优先把他加进 wheel 组,这样根本不用碰 sudoers 文件零风险
  9. sudoers 规则里括号和逗号必须用半角英文,命令必须写绝对路径,组名前面要加百分号
  10. sudoers 文件属主必须是 root 权限必须是 0440,属主或权限被改错 sudo 同样会拒绝使用它

总结

这次"一个手误锁死全员 sudo"的事故,纠正了我一个关于"修改"的、藏得很深的盲区。在我过去的操作习惯里,"改一个文件",是一件极其轻飘飘的事——打开,敲字,保存。这个动作我一天做几十次,它在我脑子里,几乎不带任何重量。所以当我要给同事加个权限时,我用的就是这个"轻飘飘"的动作:vi 打开,敲一行,保存。我对待 /etc/sudoers 的态度,和对待一个随手记的便签,没有任何区别。可这个文件,根本不是便签。它是一份特殊的文件——它是【决定"我还能不能修改文件"这件事本身】的文件。我一直以为,所有文件都是平等的"被修改对象",我永远站在它们之上,手握修改它们的权力。可 sudoers 不是。它是那个【定义我这份权力】的源头。当我改坏了它,我改坏的不是一份普通的内容,我改坏的是【我自己那只手】。复盘到根上我才看清,这世界上的文件、配置、规则,其实分两种。一种是"普通的"——你改坏了,顶多是它对应的功能坏了,你随时可以回来再改。另一种是"元层级的(meta)"——它定义的,恰恰是"你能不能改东西"这件事本身;你一旦改坏它,就【同时失去了修复它的能力】。sudoers 如此,SSH 的配置如此(改错了把自己关在门外),防火墙规则如此(一条规则就能切断你自己的连接),用户和权限的配置也如此。这类文件,危险的不是"改错的后果有多严重",而是——【改错之后,你连补救的资格都一并丢了】。它会把你和"修复它的钥匙",一起锁进同一个盒子。这次最大的收获,是我学会了在动手之前,先给文件【掂一掂分量】:我现在要改的这个东西,它是"普通的",还是"元层级的"?如果它管的是"我还有没有能力改东西""我还进不进得来""我还连不连得上"——那它就是元层级的,我对它的每一个字符,都得用十倍的郑重去对待。而对待这种文件,有两条铁律是我用这次的惊吓换来的:第一,【永远用带校验的专用工具去改它】(visudo 之于 sudoers),不要用那个"轻飘飘的、忠实地保存任何垃圾"的通用编辑器——专用工具会在你即将坠落时,先拦你一把。第二,【动手之前,先备好一条不依赖它的退路】——动 sudoers 前,先开一个 root 会话;它的精髓在于:你要修复的那个东西,和你用来修复的那个工具,【绝对不能是同一个】、也不能互相依赖。所以下一次,当我要去改任何一个配置时,我会先停三秒,问自己一句:如果这一改,把它彻底改瘫了,我【还有没有别的路】回来?如果答案是"没有,因为修它的路也得经过它"——那我就绝不轻举妄动,我会先想办法,在它之外,给自己留一扇怎么都关不上的后门。因为真正会要命的操作,从来不是那些"改错了会出事"的操作;而是那些"改错了,连让你回头补救的那条路,都一起断掉"的操作。

—— 别看了 · 2026
声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理 邮箱1846861578@qq.com。
Linux教程

程序一启动就报 cannot open shared object file:一次 Linux 动态链接库路径的排查复盘

2026-5-20 23:59:02

Linux教程

df 说磁盘满了 du 却找不到空间:一次 Linux 幽灵文件占用磁盘的复盘

2026-5-21 0:09:23

0 条回复 A文章作者 M管理员
    暂无讨论,说说你的看法吧
个人中心
购物车
优惠劵
今日签到
有新私信 私信列表
搜索