我编辑了 EC2 实例上的 sudoers 文件,可尝试运行 sudo 命令时,收到了语法错误。如何修复此问题?

上次更新时间:2020 年 3 月 27 日

我手动编辑了 Amazon Elastic Compute Cloud(Amazon EC2 实例)上的 sudoers 文件。现在,在尝试运行 sudo su 命令或需要特权用户访问权限的命令时,我收到类似于下面这样的语法错误:

“/etc/sudoers: syntax error near line xx” “sudo: parse error in /etc/sudoers near line xx” “sudo: no valid sudoers sources found, quitting” “sudo: unable to initialize policy plugin”

简短描述

手动编辑 /etc/sudoers 文件以更改 sudo 用户时,如果不慎在文件中添加了不需要的字符,就会发生此语法错误。结果可能是无法运行 sudo su 的受损实例,或者需要特权用户访问权限的命令。要修复此语法错误,请停止实例,分离其根卷,将其附加到恢复实例,将根卷挂载为辅助卷,然后还原对 sudoers 文件所做的更改。

警告:在开始执行此操作之前,请注意以下事项:

停止和重新启动实例会擦除实例存储卷上的所有数据。请务必备份实例存储卷上您想保存的所有数据。有关更多信息,请参阅确定实例的根设备类型。 停止和重新启动实例会更改实例的公有 IP 地址。在将外部流量路由到您的实例时,最佳做法是使用弹性 IP 地址而不是公有 IP 地址。

解决方法

注意:请勿使用文本编辑器(如 vi、nano 或 vim 等)手动编辑您可以连接、正在运行的实例上的 sudoers 文件。请始终运行 visudo 来编辑您可以连接到的实例上的 /etc/sudoers 文件。Visudo 会在您编辑的过程中检查解析错误,一旦您因编辑在文件中引入问题,它会在您保存更改之前提醒您注意。

1.打开 Amazon EC2 控制台。

2.从导航窗格中选择实例,然后选择受损实例。

3.依次选择操作实例状态停止

4.在描述选项卡中,选择根设备,然后选择 EBS ID

5.选择 操作,然后选择分离卷/dev/sda1/dev/xvda),再选择是,请分离

6.验证以确认状态可用

7.在原始实例所在的可用区中启动新的 EC2 实例。这个新实例将成为您的“救援”实例。

8.启动救援实例后,从导航窗格中选择,然后选择原始实例已分离的根卷。

9.选择操作,然后选择连接卷

10.选择救援实例 ID (1-xxxx),然后输入设备名称(例如 /dev/sdf)。

11.使用您的密钥对,通过 SSH 连接到救援实例。

12.运行 lsblk 命令以验证已附加卷的设备名称。

lsblk

示例输出如下。

NAME    MAJ:MIN RM  SIZE RO TYPE MOUNTPOINT
xvda    202:0    0    8G  0 disk
└─xvda1 202:1    0    8G  0 part /
xvdf    202:80   0  500G  0 disk
└─xvdf1 202:81   0  500G  0 part

13. 创建挂载目录,然后使用 root 权限进行挂载。

sudo mount /dev/xvdf1 /mnt

在控制台中检查新连接的卷的挂载点。通常情况下,应该是 /dev/xvdf1

14. 执行 Chroot 以进入安装目录。

for dir in {/dev,/dev/pts,/sys,/proc}; do sudo mount -o bind $dir /mnt$dir; done
chroot /mnt

15. 使用 visudo 命令编辑 sudoers 文件。

visudo

有两个选项可用于编辑该文件:

选项 1:还原造成语法错误的相应更改。

选项 2:复制恢复实例中已知正确的 /mnt/etc/sudoers 文件,替换出问题的文件。

创建原始文件的备份。

sudo mv /mnt/etc/sudoers /mnt/etc/sudoers.backup

将文件复制到您的实例。

sudo cp /etc/sudoers /mnt/etc/sudoers

16. 编辑或替换 sudoers 文件后,卸载该卷。

for dir in {/dev,/dev/pts,/sys,/proc}; do umount /mnt$dir; done
sudo umount /mnt

17.将卷附加到原始实例。将挂载点指定为 /dev/xvda/dev/sda1,因为这是原始实例的根卷。

18.启动原始实例。

19.使用 SSH 连接到实例,并尝试运行 sudo 命令。