跳至内容

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

6 分钟阅读
0

我在 Amazon Elastic Compute Cloud (Amazon EC2) 或 Amazon Lightsail 实例上更改了 /etc/sudoers 文件的所有权或删除了该文件。现在,我在运行 sudo 命令时收到错误。

简短描述

如果删除或错误配置了 /etc/sudoers 文件,您可能会收到以下语法错误或 sudo 错误:

  • "sudo: /etc/sudoers is owned by uid 1000, should be 0"
  • "sudo: /usr/bin/sudo must be owned by uid 0 and have the setuid bit set"
  • "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"

如果您收到上述错误之一,则无法向用户或用户组授予系统资源的访问权限。要修复 Amazon EC2 或 Lightsail 上的 /etc/sudoers/usr/bin/sudo 文件,请使用用户数据启动脚本修改文件权限。或者,将根磁盘连接到救援实例以手动进行更改。

**注意:**如果您删除了 /etc/sudoers 文件,则必须使用用户数据脚本来重新创建该文件。

解决方法

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

使用用户数据或启动脚本修改文件权限

要解决 "owned by uid 1000" 或 "must be owned by uid 0" 错误消息,必须修改 /etc/sudoers/usr/bin/sudo 文件权限。

对于 Amazon EC2 实例,请完成以下步骤以使用用户数据脚本修改文件权限:

  1. 打开 Amazon EC2 控制台

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

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

  4. 选择 Actions(操作),然后选择 Instance settings(实例设置)。

  5. 选择 Edit user data(编辑用户数据)。

  6. 输入以下脚本:

    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
    # To fix error sudo: /usr/bin/sudo must be owned by uid 0 and have the setuid bit set. use below commands
    chown -R root:root /usr/bin/sudo
    chmod 4755 /usr/bin/sudo
    
    # to fix below sudo errors:
    #sudo: /etc/sudoers is owned by uid 1000, should be 0
    #sudo: no valid sudoers sources found, quitting
    #sudo: error initializing audit plugin sudoers_audit
    
    chown -R root:root /etc/sudoers
    chown -R root:root /etc/sudoers.d/
    sudo service sshd restart
    --//--
  7. 启动实例,然后等待其通过状态检查。

  8. 连接到实例,然后运行以下命令来验证 /etc/sudoers/usr/bin/sudo 文件的权限是否正确:

    sudo ls -la /etc/sudoers
    sudo ls -la /usr/bin/sudo

    以下输出示例显示了正确的权限:

    $sudo ls -la /etc/sudoers /usr/bin/sudo
    -r--r----- 1 root root   1714 Jun 25 13:38 /etc/sudoers
    -rwsr-xr-x 1 root root 281624 Jun 27  2023 /usr/bin/sudo

对于 Lightsail 实例,请完成以下步骤以使用启动脚本修改文件权限:

  1. 打开 Lightsail 控制台

  2. 选择 Snapshots(快照),然后选择您的实例快照。

  3. 选择 Actions(操作),然后选择 Create new instance(创建新实例)。

  4. Optional(可选)下,选择 + Add launch script(+ 添加启动脚本)。

  5. 输入以下启动脚本:

    #!/bin/bash
    # To fix error sudo: /usr/bin/sudo must be owned by uid 0 and have the setuid bit set. use below commands
    chown -R root:root /usr/bin/sudo
    chmod 4755 /usr/bin/sudo
    
    # to fix below sudo errors:
    #sudo: /etc/sudoers is owned by uid 1000, should be 0
    #sudo: no valid sudoers sources found, quitting
    #sudo: error initializing audit plugin sudoers_audit
    
    chown -R root:root /etc/sudoers
    chown -R root:root /etc/sudoers.d/
    sudo service sshd restart
    --//--
  6. 选择 Create instance(创建实例)。

  7. 连接到实例,然后运行以下命令来检查 /etc/sudoers/usr/bin/sudo 文件的权限:

    sudo ls -la /etc/sudoers
    sudo ls -la /usr/bin/sudo

    以下输出示例显示了正确的权限:

    $sudo ls -la /etc/sudoers /usr/bin/sudo
    -r--r----- 1 root root   1714 Jun 25 13:38 /etc/sudoers
    -rwsr-xr-x 1 root root 281624 Jun 27  2023 /usr/bin/sudo

将根磁盘连接到救援实例

配置实例以进行停止和启动

**注意:**当停止或启动某个实例时,该实例的公有 IP 地址将发生变化。最佳做法是使用弹性 IP 地址(而不是公有 IP 地址)将外部流量路由到您的实例。如果您使用的是 Amazon Route 53,则在公有 IP 地址发生变化时可能需要更新 Route 53 DNS 记录

在停止和启动实例之前,请执行以下操作:

将根磁盘连接到救援实例

完成以下步骤:

  1. 创建新密钥对

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

  3. 停止原始实例

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

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

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

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

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

    lsblk

    输出示例

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

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

    mount -o nouuid  /dev/xvdf1 /mnt

    如果您使用基于 AWS Nitro System 构建的实例,则卷设备名称使用 /dev/nvme[0-26]n1 格式。运行以下命令将分区挂载到 /mnt 目录:

    mount -o nouuid  /dev/nvme1n1p1 /mnt

    **注意:**请将 /dev/nvme1n1p1 替换为通过 lsblk 命令确定的设备名称。有关详细信息,请参阅 Amazon EC2 实例上卷的设备名称

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

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

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

确保该文件具有以下默认设置:

# This file MUST be edited with the 'visudo' command as root.

# Please consider adding local content in /etc/sudoers.d/ instead of
# directly modifying this file.

# See the man page for details on how to write a sudoers file.

Defaults env_reset
Defaults mail_badpass
Defaults secure_path="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/snap/bin"
# Host alias specification
# User alias specification
# Cmnd alias specification
# User privilege specification
root ALL=(ALL:ALL) ALL
# Members of the admin group may gain root privileges
%admin ALL=(ALL) ALL
# Allow members of group sudo to execute any command
%sudo ALL=(ALL:ALL) ALL
# See sudoers(5) for more information on "#include" directives:
#includedir /etc/sudoers.d

**注意:**visudo 命令会锁定 sudoers 文件。
如果您在运行上述命令时收到错误,请运行以下 diff 命令将 /etc/sudoers 文件与新文件 /etc/sudoers.bak 进行比较:

diff /etc/sudoers /etc/sudoers.bak

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

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

使用用户数据修改文件内容或重新创建文件

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

重新创建文件

要以根用户身份访问实例以便重新创建文件,请完成以下步骤:

  1. 打开 Amazon EC2 控制台

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

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

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

  5. 选择 Actions(操作),然后选择 Instance settings(实例设置)。

  6. 选择 Edit user data(编辑用户数据)。

  7. 输入以下脚本为根用户设置临时密码:

    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"
    --//

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

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

  9. 要重新创建 /etc/sudoers 文件,请运行以下 pkexec 命令:

    pkexec /usr/sbin/visudo
  10. 输入根用户密码,然后使用以下值修改 /etc/sudoers 文件:

# This file MUST be edited with the 'visudo' command as root.
#
# Please consider adding local content in /etc/sudoers.d/ instead of
# directly modifying this file.
#
# See the man page for details on how to write a sudoers file.
#
Defaults    env_reset
Defaults    mail_badpass
Defaults    secure_path="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"

# Host alias specification

# User alias specification

# Cmnd alias specification

# User privilege specification
root    ALL=(ALL:ALL) ALL

# Members of the admin group may gain root privileges
%admin ALL=(ALL) ALL

# Allow members of group sudo to execute any command
%sudo   ALL=(ALL:ALL) ALL

# See sudoers(5) for more information on "#include" directives:

#includedir /etc/sudoers.d
  1. 运行 sudo 命令以验证 sudo 是否正常运行。
  2. 停止实例

删除用户数据脚本

要使用 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 官方已更新 8 个月前