跳至内容

如何修复运行 sudo 命令时 EC2 实例上的 sudo 错误?

3 分钟阅读
0

我在 Amazon Elastic Compute Cloud (Amazon EC2) 实例上编辑或删除了 /etc/sudoers 文件。然后,我在运行 sudo 命令时收到了语法错误或 sudo 错误。

简短描述

当删除或错误地配置 /etc/sudoers 文件时,会出现以下语法错误或 sudo 错误:

  • "/etc/sudoers:abc:x: syntax error"
  • "sudo: unable to open /etc/sudoers: No such file or directory"
  • "sudo: no valid sudoers sources found, quitting"
  • "sudo: error initializing audit plugin sudoers_audit"

如果您收到上述错误之一,则无法向用户或用户组授予系统资源的访问权限。要修复 /etc/sudoers 文件,请将根磁盘连接到救援实例。如果您无法将根磁盘连接到救援实例,请使用用户数据修改该文件。

解决方法

如果您在运行 AWS 命令行界面 (AWS CLI) 命令时收到错误,请参阅 AWS CLI 错误故障排除。此外,请确保您使用的是最新版本的 AWS CLI

将根磁盘连接到救援实例

最佳做法是将根磁盘连接到救援实例来修改 /etc/sudoers 文件。

**先决条件:**当停止或启动某个实例时,实例存储卷上的数据将被清除。请备份要保留的实例存储卷上的所有数据。有关详细信息,请参阅根设备类型。此外,当停止或启动某个实例时,该实例的公共 IP 地址将发生变化。当您将外部流量路由到您的实例时,最佳做法是使用弹性 IP 地址而不是公共 IP 地址。

要将根磁盘连接到救援实例,请完成以下步骤:

  1. 创建新密钥对

  2. 获取原始实例的根卷的卷 ID 和设备名称

  3. 停止原始实例

  4. 从同一可用区内具有相同 Linux 操作系统 (OS) 版本的 AMI(亚马逊机器映像)中启动恢复实例

  5. 将根卷与原始实例分离,然后将其作为辅助卷连接到恢复实例

  6. 使用新的 SSH 密钥对连接到恢复实例。

  7. 运行以下命令以更改为根用户:

    [ec2-user ~]$ sudo su
  8. 要确定块设备名称和分区,请从恢复实例运行以下命令:

    [root ~]$ lsblkNAME    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  101G  0 disk
    └─xvdf1 202:81   0  101G  0 part
    xvdg    202:96   0   30G  0 disk

    在前面的示例中,设备名称为 /dev/xvda/dev/xvdf 的卷是分区卷,而 /dev/xvdg 不是分区卷。
    如果卷已分区,请运行以下命令来挂载分区 /dev/xvdf1,而不是原始设备 /dev/xvdf

    [root ~]$ mount -o nouuid  /dev/xvdf1 /mnt

    如果使用基于 AWS Nitro System 的实例,则卷设备名称将类似于 /dev/nvme[0-26]n1。如果您的实例是在带有 NVMe 的 Nitro System 上构建的,请在 /mnt 目录下挂载分区。使用您通过 lsblk 命令确定的设备名称:

    [root ~]$ mount -o nouuid  /dev/nvme1n1p1 /mnt

    有关详细信息,请参阅 Amazon EC2 实例上卷的设备名称

  9. 要从工作实例中复制 /etc/sudoers 文件作为备份,请运行以下命令:

    [root ~]$ cp /etc/sudoers /mnt/etc/sudoers.bak
  10. 要在 /mnt 目录中创建 chroot 环境,请运行以下命令:

[root ~]$ for i in dev proc sys run; do mount -o bind /$i /mnt/$i; done; chroot /mnt

在前面的示例中,/dev/proc/sys/run 目录是从原始根文件系统绑定挂载的。这让在 chroot 环境中运行的进程能够访问这些系统目录。 要编辑 /etc/sudoers 文件,请在 chroot 环境中运行 visudo 命令:

[root ~]$ visudo

**注意:**必须运行 visudo 命令来编辑 sudoers 文件。visudo 命令会锁定 sudoers 文件。
如果您从前面的命令中收到错误,请运行下面的 diff 命令将 /etc/sudoers 文件与新文件 /etc/sudoers.bak 进行比较:

[root ~]$ diff /etc/sudoers /etc/sudoers.bak

**注意:**如果您在编辑文件之前没有进行自定义更改,请将 /etc/sudoers.bak 文件恢复为 /etc/sudoers。 要退出 chroot 环境,请运行以下命令:

[root ~]$ exit
  1. 要卸载根卷,请运行以下命令:
[root ~]$ umount -fl /mnt
  1. 将作为辅助卷连接的根卷与恢复实例分离。然后,使用步骤 2 中的设备名称将其重新连接到原始实例。
  2. 启动原始实例,然后确认 sudo 命令是否正常运行。

使用用户数据修改文件

**注意:**以下故障排除方法使用用户数据输入。要使用此方法,必须为根用户设置密码。

要使用用户数据修改文件,请完成以下步骤:

  1. 打开 Amazon EC2 控制台

  2. 在导航窗格中,选择 Instances(实例),然后选择实例。

  3. 选择 Instance state(实例状态),然后选择 Stop Instance(停止实例)。

  4. Stop instance?(停止实例?)下,选择 Stop(停止)。

  5. 为根用户设置临时密码。
    示例:

                Content-Type: multipart/mixed; boundary="//"
                MIME-Version: 1.0
    
                --//
                Content-Type: text/cloud-config; charset="us-ascii"
                MIME-Version: 1.0
                Content-Transfer-Encoding: 7bit
                Content-Disposition: attachment; filename="cloud-config.txt"
    
                #cloud-config
                cloud_final_modules:
                - [scripts-user, always]
    
                --//
                Content-Type: text/x-shellscript; charset="us-ascii"
                MIME-Version: 1.0
                Content-Transfer-Encoding: 7bit
                Content-Disposition: attachment; filename="userdata.txt"
    
                #!/bin/bash
                chpasswd <<<"root:root"
                --//

    **重要事项:**此密码使用纯文本传递密钥,并不安全。完成故障排除步骤后,请务必删除根用户的临时密码。

  6. 启动实例,然后以 ec2-user 身份登录。

  7. 要访问 /etc/sudoers 文件,请运行以下 pkexec 命令:

    pkexec /usr/sbin/visudo
  8. 输入根用户密码,然后修改 /etc/sudoers 文件。

  9. 运行 sudo 命令以验证 sudo 是否正常运行。

  10. 停止实例

要使用 Amazon EC2 控制台删除用户数据值(包括根用户密码),请完成以下步骤:

  1. 打开 Amazon EC2 控制台
  2. 在导航窗格中,选择 Instances(实例),然后选择实例。
  3. 选择 Actions(操作),然后选择 Instance settings(实例设置)。
  4. 选择 Edit user data(编辑用户数据),然后删除所有用户数据。

要使用 AWS CLI 界面删除用户数据值(包括根用户密码),请运行下面的 modify-instance-attribute 命令:

aws ec2 modify-instance-attribute --instance-id example-instance-id --user-data Value=""

**注意:**请将 example-instance-id 替换为您的实例 ID。

要验证是否删除了用户数据,请运行下面的 describe-instance-attribute 命令:

aws ec2 describe-instance-attribute --instance-id example-instance-id --attribute userData

**注意:**请将 example-instance-id 替换为您的实例 ID。

删除用户数据后,启动实例

相关信息

为什么我无法在 EC2 Linux 实例上运行 sudo 命令?

AWS 官方已更新 1 年前