AWS Builder Center: Learn, Build and Connect with builders in the AWS community
AWS Builder Center is the official home for builders on AWS. Share and read what others are working on, follow people who inspire you, explore training and workshops, and find tools to support what you're building.
如何修复运行 sudo 命令时 Amazon EC2 或 Lightsail 实例上的 sudo 错误?
我在 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 实例,请完成以下步骤以使用用户数据脚本修改文件权限:
-
打开 Amazon EC2 控制台。
-
在导航窗格中,选择 Instances(实例),然后选择 EC2 实例。
-
选择 Instance state(实例状态),然后选择 Stop Instance(停止实例)。
-
选择 Actions(操作),然后选择 Instance settings(实例设置)。
-
选择 Edit user data(编辑用户数据)。
-
输入以下脚本:
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 --//-- -
启动实例,然后等待其通过状态检查。
-
连接到实例,然后运行以下命令来验证 /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 实例,请完成以下步骤以使用启动脚本修改文件权限:
-
打开 Lightsail 控制台。
-
选择 Snapshots(快照),然后选择您的实例快照。
-
选择 Actions(操作),然后选择 Create new instance(创建新实例)。
-
在 Optional(可选)下,选择 + Add launch script(+ 添加启动脚本)。
-
输入以下启动脚本:
#!/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 --//-- -
选择 Create instance(创建实例)。
-
连接到实例,然后运行以下命令来检查 /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 记录。
在停止和启动实例之前,请执行以下操作:
- 如果您的实例使用实例存储,则将实例存储上的卷数据保存到永久存储。例如,您可以将数据保存到 Amazon Elastic Block Store (Amazon EBS) 卷或 Amazon Simple Storage Service (Amazon S3) 存储桶。
**重要事项:**当您停止实例时,Amazon EC2 会删除实例存储数据。 - 创建 Amazon EBS 卷的快照。如果您遇到问题,则可以使用该快照来还原您的实例。
- 暂时将实例从其 Amazon EC2 Auto Scaling 组中移除,以免在停止实例时意外终止该实例。
**注意:**EC2 Auto Scaling 可能会根据您的缩减保护设置终止自动扩缩组中已停止的实例。使用 Amazon EMR、AWS CloudFormation 或 AWS Elastic Beanstalk 启动的实例可能位于自动扩缩组中。 - 将实例关闭行为设置为 Stop(停止),确保实例在您停止时不会终止。
将根磁盘连接到救援实例
完成以下步骤:
-
从同一可用区内具有相同 Linux 操作系统 (OS) 版本的亚马逊机器映像 (AMI) 中启动恢复实例。
-
使用新的 SSH 密钥对连接到恢复实例。
-
运行以下命令以更改为根用户:
sudo su -
要确定块设备名称和分区,请从恢复实例运行以下命令:
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在上述示例中,设备名称为 xvda 和 xvdf 的卷是分区卷,而 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 实例上卷的设备名称。
-
要从工作实例中复制 /etc/sudoers 文件作为备份,请运行以下命令:
cp /etc/sudoers /mnt/etc/sudoers.bak -
要在 /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
- 要卸载根卷,请运行以下命令:
umount -fl /mnt
- 将作为辅助卷连接的根卷与恢复实例分离。然后,使用步骤 2 中的设备名称将其重新连接到原始实例。
- 启动原始实例,然后运行以下命令确认 sudo 命令是否正常运行:
sudo su
使用用户数据修改文件内容或重新创建文件
**注意:**要使用以下故障排除方法,必须为根用户设置密码。
重新创建文件
要以根用户身份访问实例以便重新创建文件,请完成以下步骤:
-
打开 Amazon EC2 控制台。
-
在导航窗格中,选择 Instances(实例),然后选择实例。
-
选择 Instance state(实例状态),然后选择 Stop Instance(停止实例)。
-
在 Stop instance?(停止实例?)下,选择 Stop(停止)。
-
选择 Actions(操作),然后选择 Instance settings(实例设置)。
-
选择 Edit user data(编辑用户数据)。
-
输入以下脚本为根用户设置临时密码:
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" --//**重要事项:**此密码使用纯文本传递密钥,并不安全。完成故障排除步骤后,请务必移除根用户的临时密码。
-
启动实例,然后以 ec2-user 身份登录。
-
要重新创建 /etc/sudoers 文件,请运行以下 pkexec 命令:
pkexec /usr/sbin/visudo -
输入根用户密码,然后使用以下值修改 /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
- 运行 sudo 命令以验证 sudo 是否正常运行。
- 停止实例。
删除用户数据脚本
要使用 Amazon EC2 控制台删除用户数据值(包括根用户密码),请完成以下步骤:
- 打开 Amazon EC2 控制台。
- 在导航窗格中,选择 Instances(实例),然后选择实例。
- 选择 Actions(操作),然后选择 Instance settings(实例设置)。
- 选择 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。
删除用户数据后,启动实例。
